3

I have a GeoJSON file with mixed geometry types, something like this:

{ "type": "FeatureCollection", "features": 
    [{ "type": "Feature", "geometry": 
        { "type": "GeometryCollection", "geometries": 
            [{ "type": "MultiLineString", "coordinates": [
                    [[-4.66065, 19.70386],[-4.66053, 19.70377],[-4.66026, 19.70358],[-4.66011, 19.70349],[-4.66009, 19.70352],[-4.66008, 19.70358]],
                    [[-4.66008, 19.70358],[-4.66009, 19.70352],[-4.66011, 19.70349],[-4.66026, 19.70358],[-4.66053, 19.70377],[-4.66065, 19.70386]]
                ] }, { "type": "Point", "coordinates": [-4.66012, 19.70362] }
            ] }, 
                "id": "1",
                "properties": { "feature_count": 3 } }, 
    { "type": "Feature", "geometry": 
        { "type": "LineString", "coordinates": [
                [-4.60419, 19.76303],[-4.60456, 19.7629],[-4.60481, 19.76260]
            ] }, 
            "id": "2",
            "properties": { "feature_count": 1 }
    }] 
}

I'm trying to extract out the LineString/MultiLineString geometries from the file (including those nested within GeometryCollections) with ogr2ogr, so I tried this:

ogr2ogr -f sqlite -dsco SPATIALITE=YES -dialect SQLITE -sql "select CollectionExtract(geometry,2), feature_count from 'mixed_types'" mixed_types.sqlite mixed_types.geojson

but I get ERROR 1: Unexpected geometry type MULTILINESTRING as part of GEOMETRYCOLLECTION. Which doesn't make sense, because fixing the mismatched geometries is the whole point of the query.

If I were to first load the GeoJSON into PostGIS and then run a similar SQL query, I don't have any issues. However, I'm trying to remove the PostGIS step and normalize the data just within a quick shell script. It doesn't seem like Spatialite's CollectionExtract() function is working properly within my query.

I've also tried using ogr2ogr's -explodecollections flag, but this creates a duplicate feature for each constituent geometry. I'm trying to end up with the same number of features as I started with.

What would make my Spatialite query work as intended?

2

Your GeoJSON contains 2 features, one is a geometrycollection and another is a linestring. If your aim is to discard the geometrycollection and keep just the linestrings and multilinestrings, use SQL like in this ogrinfo example:

ogrinfo -dialect sqlite -sql "select * from collection where GeometryType(geometry) in ('LINESTRING','MULTILINESTRING')" collection.geojson

Command works correctly even it gives the same error ERROR 1: Unexpected geometry type MULTILINESTRING as part of GEOMETRYCOLLECTION. That is odd because there is nothing wrong in having just one single part multipolygon in a geometrycollection. Write a mail to gdal-dev mailing list if it bothers you.

If your aim is something else, like to keep the second feature as it was and explode the geometrycollection and take only the (multi)linestring part, please edit your question and make it clear.

EDIT:

GDAL seems to prefer simple presentations. The error goes away if you write your simple multilinestring as linestring, or if multilinestring has several parts as in this (slightly odd) geometry

{"type":"MultiLineString","coordinates":[[[311,447],[472,389],[540,460]],[[311,447],[472,389],[540,460]]]}

EDIT 2:

There is something odd going on with selecting that geometrycollection from GeoJSON. Using collectionextract with a geometry that is created inline works as supposed and this ogrinfo command select just a POINT from a geometrycollection

ogrinfo -dialect sqlite -sql "select collectionextract(st_geomfromtext('GEOMETRYCOLLECTION ( MULTILINESTRING (( 280 420, 540 420, 560 440, 540 440 ), ( 300 460, 480 460, 520 500 )),POINT(1 3))'),1) as geom" collection.geojson
INFO: Open of `collection.geojson'
      using driver `GeoJSON' successful.

Layer name: SELECT
Geometry: Unknown (any)
Feature Count: 1
Extent: (1.000000, 3.000000) - (1.000000, 3.000000)
Layer SRS WKT:
(unknown)
Geometry Column = geom
OGRFeature(SELECT):0
  POINT (1 3)
  • Yes, I'm trying to extract the multilinestring from within the GeometryCollection (discarding the point) as well as selecting any bare linestrings and multilinestrings. I edited the question to hopefully make this more clear. – dericke Dec 11 '19 at 19:43
  • Explodecollections and then filtering the result for deleting points and polygons does not feel like a bad option for general use. If your geometrycollection contains many (multi)linestrings then it is hard to avoid getting multiple new features. But if you know your data and that only one (multi)linestring can appear then some other solution may work as well. – user30184 Dec 11 '19 at 19:49

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.