3

Is there a gdal or python based tool for converting Polygons and MultiPolygons inside of GeoJSON to LineStrings and MultiLineStrings? I'm using rasterio / rio rasterize or gdal_rasterize to rasterize GeoTIFF w/ GeoJSON.

I need to read in GeoJSON files and be able to convert any (Multi)Polygons into LineStrings and MultiLineStrings so I can rasterize just the boundary or outline of the (Multi)Polygons onto GeoTIFFs (this includes exterior and interior polygons) and not have it fill in the entire shape.

Any ideas?

  • 1
    Read how linestrings and polygons are encoded in GeoJSON from tools.ietf.org/html/rfc7946#section-3.1.6. It might not be too hard to change the names of the types and remove some brackets with a script from the GeoJSON text at least if your polygons do not have holes. – user30184 Dec 1 '17 at 6:14
2

With ogr2ogr you can do it with the SQLite dialect and the ExteriorRing function from SpatiaLite http://www.gaia-gis.it/gaia-sins/spatialite-sql-latest.html

Test with ogrinfo and shapefile

ogrinfo polygons.shp -dialect SQLite -sql "select exteriorring(geometry) from polygons limit
 1"
INFO: Open of `polygons.shp'
      using driver `ESRI Shapefile' successful.

Layer name: SELECT
Geometry: Unknown (any)
Feature Count: 1
Extent: (453.000000, 636.000000) - (598.000000, 736.000000)
Layer SRS WKT:
(unknown)
Geometry Column = exteriorring(geometry)
OGRFeature(SELECT):0
  LINESTRING (453 683,598 736,564 636,453 683)

This should work for you:

ogr2ogr -f GeoJSON -dialect SQLite -sql "select exteriorring(geometry) from my_layer" output.json my_file.json

Check first with ogrinfo my_file.json what is the layer name in your source data.

I believe that you can use the same SQL of SQlite dialect directly as an input for gdal_rasterize http://www.gdal.org/gdal_rasterize.html without creating an interim file.

  • Thanks that works for exterior, but need to somehow select all the potential interior rings as well, looks like you have to specify a particular interior ring by a known index with InteriorRingN: InteriorRingN( polyg Polygon , n Integer ) : LineString I need to be able to do that dynamically in the same query for all interior rings too – beaorn Dec 1 '17 at 15:15
  • Please edit your question, you wrote so I can rasterize just the "boundary" or "exterior". – user30184 Dec 1 '17 at 16:31
  • updated, sorry for confusion. – beaorn Dec 1 '17 at 16:39
  • replacing exteriorring(geometry) with boundary(geometry) worked, thanks! – beaorn Dec 1 '17 at 17:17
1

i think shapely is what you need...

for example, to open a geojson in a dictionary format just do:

from shapely import geometry
json = {'type':'Polygon','coordinates':[[[0,0],[0,10],[10,10],[10,0],[0,0]],
[[2,2],[2,4],[4,4],[4,2],[2,2]]]}
polygon = geometry.asShape(json)

if you want to get the exterior ring just do polygon.exterior which will give you a LineString, or polygon.exterior.xy will give you the coordinates:

>>>polygon.exterior.xy
(array('d', [0.0, 0.0, 10.0, 10.0, 0.0]), array('d', [0.0, 10.0, 10.0, 0.0, 0.0]))

like so polygon.interiors[n] will give you the interior LineStrings

>>>polygon.interiors[0].xy
(array('d', [2.0, 2.0, 4.0, 4.0, 2.0]), array('d', [2.0, 4.0, 4.0, 2.0, 2.0]))

in the case of multipolygons shapely has a MultiPolygon iterable, and also a Collection iterable (for mixed type of features).

Hope it helps

1

User 31084 is on the right track. You can do what you want to do with nothing more than Python and its json module.

The exterior ring of a GeoJSON Polygon p as a LineString is:

{'type': 'LineString', 'coordinates': p['coordinates'][0]}

The exterior rings of the members of a GeoJSON MultiPolygon m as a MultiLineString is:

{'type': 'MultiLineString', 'coordinates': [p[0] for p in m['coordinates']]}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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