1

I'having trouble using writeOGR to write GeoJSON files, when there are MultiPolygon objects. Here is an example: I'm creating a SpatialPolygonsDataFrame object from GeoJSON, with a single feature made of two polygons. When I export to GeoJSON, the file that's written has a single feature with one polygon and a hole.

Why is this, and how can I persuade writeOGR to write two polygons?

# Create SpatialPolygonsDataFrame with one feature, two polygons
spdf <- readOGR(layer='OGRGeoJSON', verbose=FALSE, '{
"type": "FeatureCollection",
"features": [{
 "type": "Feature",
 "id": 0,
 "properties": {"label":"CENTRAL"},
 "geometry": {
     "type": "MultiPolygon",
     "coordinates": [[[[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]]],
                     [[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]]]]
     } }] }')

# When I save and reload this object, coordinates has length 1,
# i.e. the feature is a polygon and a hole.
fn <- tempfile()
writeOGR(spdf, fn, layer='whatever', driver='GeoJSON')
length(fromJSON(file=fn)$features[[1]]$geometry$coordinates)

I'm using R 3.1.2 and rgdal 0.9.1 on OSX Yosemite.

UPDATE: Here is the GeoJSON tempfile that is created. As you can see, the coordinates array has been modified from the original.

{
"type": "FeatureCollection",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
    { "type": "Feature",
      "id": 0,
      "properties": { "label": "CENTRAL" },
      "geometry": {
          "type": "MultiPolygon",
          "coordinates": [ [ [ [ 102.0, 2.0 ], [ 102.0, 3.0 ], [ 103.0, 3.0 ], [ 103.0, 2.0 ], [ 102.0, 2.0 ] ],
                             [ [ 100.0, 0.0 ], [ 100.0, 1.0 ], [ 101.0, 1.0 ], [ 101.0, 0.0 ], [ 100.0, 0.0 ] ] ] ] } }
    ]
}
8
  • What is the result that you wait from the length test? Could you convert the source feature and the saved feature into WKT? That way it would be easier to read what has changed.
    – user30184
    Mar 8, 2015 at 13:52
  • The input GeoJSON has length(coordinates)=2, signifying "union of two disjoint polygons", so I expect the output to have length(coordinates)=2. Instead it has length(coordinates)=1, signifying "polygon with hole".
    – DamonJW
    Mar 9, 2015 at 17:58
  • There's definitely a problem with conversion somewhere (either readOGR/writeOGR, or my own understanding). Therefore I won't attempt to convert the features into WKT, for fear of muddling the issue further.
    – DamonJW
    Mar 9, 2015 at 18:00
  • Could you paste then the contents of the tempfile? I made a simple test by converting your source GeoJSON into another GeoJSON file with ogr2ogr and your multipolygon stayed as an identical multipolygon.
    – user30184
    Mar 9, 2015 at 21:23
  • Update: I added the tempfile output to my question.
    – DamonJW
    Mar 11, 2015 at 3:58

2 Answers 2

1

I haven't found a way to get writeOGR to work -- so instead, I wrote my own toGeoJSON function. I won't paste the full code, but the bit that's most useful is the following, for an object x of class 'Polygons':

require(maptools)
require(rgeos)
y <- maptools::checkPolygonsHoles(x)
insideWhich <- as.numeric(strsplit(rgeos::createPolygonsComment(y),' ')[[1]])
plotOrder <- y@plotOrder

For example, you might get

plotOrder = c(3,5,4,1,2)
insideWhich = c(4,3,0,0,0)

This means: "Plot polygon 4, then 5, then 1, then 3, then 2. Also, polygon 1 is a hole inside 4, and 2 is a hole inside 3." The two functions checkPolygonsHoles and createPolygonsComment work together to compute these facts. With this information, the rest of creating a GeoJSON object is fairly straightforward.

0

Please follow up on this thread:

https://stat.ethz.ch/pipermail/r-sig-geo/2015-October/023609.html

as rgdal developers do not read SO, the bug affects multiple drivers, so the whole point of using GDAL as a single interface to all data formats is defeated by spreading effort.

The issue is in how wkbtype MultiPolygon objects are written through the OGR class system - rgdal (OGR_write.cpp for this wkbtype) may not be doing it in a way that suits all drivers, and seems to fail on SFS-compliant ones.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.