Skip to content

proj4string-issue - leading spaces

6 messages · Edzer Pebesma, Roger Bivand, Jon Olav Skoien

#
Dear list,

Leading spaces seems to be a tricky thing in proj4strings, I think the 
issue below is related to the following post where leading spaces where 
removed:
http://r-sig-geo.2731867.n2.nabble.com/a-minor-bug-in-rgdal-tt7581906.html#none

It seems the stripping of leading spaces has created another issue in my 
case, when overlaying objects with (from outside R) and without (created 
in R) these spaces, as over calls identical to check if the proj4strings 
are equal.  Below is an example where I add a space to the proj4string, 
similar to the object I actually get from outside R:

# (R 2.15-1, sp_1.0-5, rgdal_0.8-01)
library(rgdal)
spdf = SpatialPixelsDataFrame(matrix(c(0,0,1,1,0,1,1,0), ncol = 2), 
proj4string = CRS("+init=epsg:4326"), data = data.frame(dat = 1:4))
P1 = Polygon(cbind(c(0,0,1,1,0),c(0,1,1,0,0)))
P2 = Polygons(list(P1), "p1")
SpP = SpatialPolygons(list(P2), proj4string = CRS(" +init=epsg:4326"))
over(SpP, spdf)

# Up to here it works fine, as the leading space in SpP was stripped by 
the CRS function. Then I add this space directly to projargs, as the 
objects I am loading:
spdf at proj4string@projargs = SpP at proj4string@projargs = paste(" 
",proj4string(spdf), sep = "")
proj4string(spdf)
over(SpP, spdf)

#However, when setting the proj4string with CRS on one of them and doing 
the overlay:
proj4string(spdf) = CRS(proj4string(spdf))
over(SpP, spdf)

#  I get an error because of the missing space in one of the objects. In 
my case this error comes when spdf is transformed to a different 
projection and back again:
spdfb = spTransform(spdf, CRS("+proj=moll +lon_0+x_0+y_0") )
# do something with spdfb
spdfc = spTransform(spdfb, CRS(proj4string(spdf)))
over(SpP, spdfc) # will then fail in the same way as above.

Is there a simple way to solve this, not having check and modify the 
proj4string of all objects? Or could the call to identical in functions 
like over be replaced by an identicalCRS()-function?

identicalCRS = function(x,y) {
   identical(CRS(proj4string(x)), CRS(proj4string(y)))
}

Thanks,
Jon
#
On 01/11/2013 12:10 PM, Jon Olav Skoien wrote:
Great suggestion, Jon; I added this to sp on r-forge.
#
On Fri, 11 Jan 2013, Jon Olav Skoien wrote:

            
Well, preferably:

https://stat.ethz.ch/pipermail/r-sig-geo/2012-December/016913.html

but also see:

http://cran.r-project.org/web/packages/rgdal/ChangeLog

or

library(rgdal)
file.show(system.file("ChangeLog", package="rgdal"))

See also:

https://r-forge.r-project.org/scm/viewvc.php/pkg/R/Class-CRSx.R?root=rgdal&r1=378&r2=401

https://r-forge.r-project.org/scm/viewvc.php/pkg/src/projectit.cpp?root=rgdal&r1=361&r2=401

The underlying problem is the very widespread use of identical() in all 
kinds of code in lots of places. Since the rgdal release in December, 
entry into libproj is not going to prepend spaces anymore. So over time, 
workarounds to add spaces will cease to be needed. In the mean time, all 
use of identical() for comparing these character strings remains 
problematic. Extending to a dependency from sp to the compare package 
seems unnecessary, but the sp package could offer a function to compare 
CRS directly - contributions welcome!

Roger

  
    
#
On Fri, 11 Jan 2013, Edzer Pebesma wrote:

            
Not so great, it doesn't address the problem that users with different 
versions of rgdal (and/or with stored objects from older versions of 
rgdal) may have extraneous prepended spaces. The function nees to test for 
NA or not, then length, if lengths equal, OK, test, if differ by one check 
whether space and if so trim, ...

Roger

  
    
#
On 11-Jan-13 12:42, Roger Bivand wrote:
You mean that the suggestion does not solve the problem when using CRS 
from sp instead of rgdal as the sp-version does not trim leading spaces? 
Then I think an alternative sp version could use gsub without being too 
complicated. Leading spaces can be removed from the proj4string if they 
exists, NAs are not touched:

ch = "+init=epsg:4326"
gsub("^ .", "", ch)
ch = " +init=epsg:4326"
gsub("^ .", "", ch)
ch = NA
gsub("^ .", "", ch)

and the function could be something like:

identicalCRS = function(x,y) {
   if (inherits(x, "Spatial")) x = proj4string(x)
   if (inherits(y, "Spatial")) y = proj4string(y)
   x = gsub("^ .", "", y)
   y = gsub("^ .", "", y)
   identical(x,y)
}

Two NA-proj4strings will be treated as identical, same as they are now. 
However, it will not catch the similarity between "+init=epsg:4326" and 
"+init=epsg:4326 +proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs 
+towgs84=0,0,0" such as a possible rgdal-version (first suggestion 
above) can do.

Cheers,
Jon
#
On Fri, 11 Jan 2013, Jon Olav Skoien wrote:

            
There is only one user-facing CRS(), but it behaves differently when rgdal 
is loaded (checking against projlib), or not available (no check against 
projlib). The problem arose because (lazy programming in projlib?) a space 
gets prepended to the string when it passes through projlib (and we 
certainly want to use the output from projlib, because it completes tags 
while going through - it parses the tags as input, and re-assembles them 
on the way back out).

Roger