1

I am using FeatureJSON from geotools to read in a GeoJson file containing a FeatureCollection and convert it to a SimpleFeatureSource. It all works fine except the feature bounds are null, so if I try to plot the SimpleFeatureSource as a layer on JMapFrame I get the following null pointer issues...

2018-10-12T18:08:19.087+0100  WARNING  Unable to determine bounds of org.geotools.map.FeatureLayer[, VISIBLE]
java.lang.NullPointerException
    at org.geotools.map.FeatureLayer.getBounds(FeatureLayer.java:194)
    at org.geotools.map.MapContent.getMaxBounds(MapContent.java:611)
    at org.geotools.map.MapContent.getViewport(MapContent.java:680)
    at org.geotools.swing.AbstractMapPane.doSetMapContent(AbstractMapPane.java:521)
    at org.geotools.swing.AbstractMapPane.<init>(AbstractMapPane.java:198)
    at org.geotools.swing.JMapPane.<init>(JMapPane.java:72)
    at org.geotools.swing.JMapPane.<init>(JMapPane.java:61)
    at org.geotools.swing.JMapFrame.<init>(JMapFrame.java:179)
    at org.geotools.swing.JMapFrame.doShowMap(JMapFrame.java:151)
    at org.geotools.swing.JMapFrame.access$000(JMapFrame.java:71)
    at org.geotools.swing.JMapFrame$1.run(JMapFrame.java:144)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
    at java.awt.EventQueue.access$500(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:709)
    at java.awt.EventQueue$3.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

2018-10-12T18:08:19.129+0100  WARNING  Unable to determine bounds of org.geotools.map.FeatureLayer[, VISIBLE]
java.lang.NullPointerException
    at org.geotools.map.FeatureLayer.getBounds(FeatureLayer.java:194)
    at org.geotools.map.MapContent.getMaxBounds(MapContent.java:611)
    at org.geotools.swing.AbstractMapPane.setFullExtent(AbstractMapPane.java:891)
    at org.geotools.swing.AbstractMapPane.doSetMapContent(AbstractMapPane.java:541)
    at org.geotools.swing.AbstractMapPane.<init>(AbstractMapPane.java:198)
    at org.geotools.swing.JMapPane.<init>(JMapPane.java:72)
    at org.geotools.swing.JMapPane.<init>(JMapPane.java:61)
    at org.geotools.swing.JMapFrame.<init>(JMapFrame.java:179)
    at org.geotools.swing.JMapFrame.doShowMap(JMapFrame.java:151)
    at org.geotools.swing.JMapFrame.access$000(JMapFrame.java:71)
    at org.geotools.swing.JMapFrame$1.run(JMapFrame.java:144)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
    at java.awt.EventQueue.access$500(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:709)
    at java.awt.EventQueue$3.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

2018-10-12T18:08:20.484+0100  SEVERE  null
java.lang.NullPointerException
    at org.geotools.renderer.lite.StreamingRenderer.getDeclaredSRS(StreamingRenderer.java:2274)
    at org.geotools.renderer.lite.StreamingRenderer.reprojectSpatialFilters(StreamingRenderer.java:2256)
    at org.geotools.renderer.lite.StreamingRenderer.createLiteFeatureTypeStyles(StreamingRenderer.java:1835)
    at org.geotools.renderer.lite.StreamingRenderer.processStylers(StreamingRenderer.java:1975)
    at org.geotools.renderer.lite.StreamingRenderer.paint(StreamingRenderer.java:861)
    at org.geotools.swing.RenderingTask.call(RenderingTask.java:102)
    at org.geotools.swing.RenderingTask.call(RenderingTask.java:39)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

Here's my method I use for the conversion...

public static SimpleFeatureSource convertFromGeojsonFile(Path path) throws IOException { FeatureJSON fjson = new FeatureJSON(); fjson.setEncodeFeatureBounds(true); fjson.setEncodeFeatureCollectionBounds(true);

FileReader reader = null;
SimpleFeatureCollection collection = null;
try {
    reader = new FileReader(path.toFile());
    collection = (SimpleFeatureCollection) fjson.readFeatureCollection(reader);
} catch (IOException e) {
    e.printStackTrace();
} finally {
    reader.close();
}

return DataUtilities.source(collection);

}

Example of the json file...

{
  "type": "FeatureCollection",
  "crs": {
    "type": "name",
    "properties": {
      "name": "EPSG:4326"
    }
  },
  "features": [
    {
      "type": "Feature",
      "crs": {
        "type": "name",
        "properties": {
          "name": "EPSG:4326"
        }
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              68.309,
              4.4916
            ],
            [
              68.309,
              8.9832
            ],
            [
              73.1241,
              8.9832
            ],
            [
              73.1241,
              4.4916
            ],
            [
              68.309,
              4.4916
            ]
          ]
        ]
      },
      "properties": {
        "geom_a": {
          "type": "Point",
          "coordinates": [
            70.7166,
            6.7374
          ]
        },
        "ref_id": "+006.39600,+072.64200",
        "geom_b": {
          "type": "Point",
          "coordinates": [
            72.642,
            6.396
          ]
        }
      },
      "id": "+006.73740,+070.71655"
    }
  ]
}
0

According to the GeoJSON Validator it is invalid GeoJSON.

Invalid GeoJSON

Line 1: old-style crs member is not recommended

Line 10: old-style crs member is not recommended

Line 18: Polygons and MultiPolygons should follow the right-hand rule

  • I guess that GeoTools does not even try to follow the current specification just because it does not support other coordinate systems. New spec would make it complicated to use for example either GML or GeoJSON as output format of WFS. – user30184 Oct 12 '18 at 18:22
  • Geotools probably has no issues with the crs but might care about the winding order, though I suspect it doesn't care about that either – Ian Turton Oct 12 '18 at 18:24
  • 1
    Thanks @IanTurton , I have experimented with the input geojson and found that GeoTools doesn't care about the winding order but it does care about the crs defined at the Feature. When a Feature crs is defined I get null bounds. Interestingly a crs defined at the FeatureCollection level does not cause any issue. – user3188040 Oct 13 '18 at 10:09

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.