Am I doing something stupid, when converting shape file features to geojson its not valid geojson

328 views
Skip to first unread message

Brian Norman

unread,
Sep 28, 2017, 5:21:44 AM9/28/17
to NetTopologySuite
Hi Everyone

see my code below, I am trying to take a shape file and split each feature into its own geojson file. The code works and creates geojson but the geojson doesnt appear to meet the current spec https://tools.ietf.org/html/rfc7946 and therefore doesn't work well in qgis and other tools. The two issues I can see are its not creating a "type" property at the top level and its creating the features attributes using "attributes" as the property name not "properties". I suspect Im just missing something?


                var factory = new GeometryFactory();
                var reader = new ShapeDataReader(options.InputFile);
                var mbr = reader.ShapefileBounds;
                var result = reader.ReadByMBRFilter(mbr);
                var coll = result.GetEnumerator();
                var processed = 0;

                while (coll.MoveNext())
                {
                    var feature = coll.Current;
                    var attributevalue = (string)feature.Attributes[options.AttributeName];

                    Console.WriteLine($"Processing {attributevalue}");

                    using (var outputfile = File.CreateText(Path.Combine(options.OutputDirectory, attributevalue + ".geojson")))

                    using (var jsonwriter = new JsonTextWriter(outputfile))
                    {
                        var serializer = new GeoJsonSerializer();
                        jsonwriter.Formatting = Formatting.Indented;
                        serializer.Serialize(jsonwriter, feature);
                        jsonwriter.Flush();
                        processed++;
                        Console.WriteLine($"Processed {processed}");
                    }
                }

example geojson

{
  "Geometry": {
    "type": "MultiPolygon",
    "coordinates": [
      [
        [
          [
            71.8344427,
            -5.2482257
          ],
          [
            71.8351122,
            -5.2488923
          ],
          [
            71.8347861,
            -5.2492513
          ],
          [
            71.8344427,
            -5.2482257
          ]
        ]
      ],
      
          [
            72.430013765845871,
            -7.3384866
          ]
        ]
      ]
    ]
  },
  "Attributes": {
    "ISO": "IO",
    "COMMENTS": "",
    "ISO2": "IO",
    "PARENT_OSM": "**********",
    "OSMNAME": "British Indian Ocean Territory",
    "LASTCHANGE": "2014-11-05T12:06:26Z",
    "SUBREGION": "Southern Asia",
    "NAME": "British Indian Ocean Territory",
    "CODE": 1202.0,
    "FCLASS": "national",
    "OSM_ID": 1993867.0,
    "GID": 303642.0,
    "REGION": "Asia & the Pacific"
  },
  "FeatureId": 86
}


xivk

unread,
Sep 28, 2017, 5:50:43 AM9/28/17
to NetTopologySuite
I'm not 100% sure, but I think this line 'var feature = coll.Current;' gives you a geometry or some other object instead of a feature.

I think you need to create a Feature object passing (geometry, attributes) and then pass it to the serializer, but again, I'm not sure.

Brian Norman

unread,
Sep 28, 2017, 6:18:00 AM9/28/17
to NetTopologySuite
Yes that seems to have done it thank you! Only issue now is the ring order is not per the spec which at least suggests the right-hand rule for ordering. Is there something I can do on the geometry to re-order?

Diego Guidi

unread,
Sep 28, 2017, 6:32:04 AM9/28/17
to NetTopologySuite


On Thursday, September 28, 2017 at 12:18:00 PM UTC+2, Brian Norman wrote:
Yes that seems to have done it thank you! Only issue now is the ring order is not per the spec which at least suggests the right-hand rule for ordering. Is there something I can do on the geometry to re-order

ordering is something that you should leave "as is", at least for SQL-Geometry specs 

FObermaier

unread,
Sep 29, 2017, 3:58:28 AM9/29/17
to NetTopologySuite
Microsoft SQL Server requires geometries according to the right hand rule, too.
NTS is not as picky, especially it does not change the orientation when reading geometry data. Unfortunately, when it creates new geometries (e.g. Buffer) it does so using the left-hand-rule.

So, when you need to have right-hand-rule geometries, you need to create and use a geometry factory that changes the orientation accordingly. Such a factory is provided here:

So you would need to instantiate your GeoJsonSerializer like this:
```C#
var serializerSettings = new JsonSerializerSettings {
    Formatting = Formatting.Indented,
    // maybe more
};
var serializer = GeoJsonSerializer.Create(serializerSettings, new OgcCompliantGeometryFactory());
```
You can reuse the serializer, so you may want to declare and instantiate it outside of the loop.

FObermaier

unread,
Sep 29, 2017, 4:04:47 AM9/29/17
to NetTopologySuite
I'm sorry, you would have to use that right-hand-rule factory on the ShapeDataReader object:
var reader = new ShapeDataReader(options.InputFile, new OgcCompliantGeometryFactory());
Reply all
Reply to author
Forward
0 new messages