How do I access my GeoJSON data after I deserialised it into an object using Jackson

Viewed 852

I have created a Java object by deserialising JSON file using Jackson. I want to render the data in the map template provided but I am not sure how to access it.

Below is the code and the JSON file. Am I on the right track? Someone advised that I can access the object if I use that Feature class in the main method. Something like ex: Feature obj = new Feature(); then access any of the variables by using obj.getType(). I want to access the whole file actually so it renders that data shows up on the WorldWind Map.

{
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "geometry": {
                "type": "Point",
                "coordinates": [102.0, 0.6]
            },
            "properties": {
                "prop0": "value0"
            }
        },
        {
            "type": "Feature",
            "geometry": {
                "type": "LineString",
                "coordinates": [
                    [102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0]
                ]
            },
            "properties": {
                "prop1": 0.0,
                "prop0": "value0"
            }
        },
        {
            "type": "Feature",
            "geometry": {
                "type": "Polygon",
                "coordinates": [
                    [
                        [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0],
                        [100.0, 0.0]
                    ]
                ]
            },
            "properties": {
                "prop1": {
                    "this": "that"
                },
                "prop0": "value0"
            }
        }
    ]
}

and here is my code:

public class NetworkVisualizer extends ApplicationTemplate {

  public static class AppFrame extends ApplicationTemplate.AppFrame {

    public AppFrame() {
      super(true, true,
            false);

      // Size the World Window to take up the space typically used by the layer panel.
      Dimension size = new Dimension(1400, 800);
      this.setPreferredSize(size);
      this.pack();
      WWUtil.alignComponent(null, this, AVKey.CENTER);

      makeMenu(this);
    }


    protected static void makeMenu(final AppFrame appFrame) {
      final JFileChooser fileChooser = new JFileChooser();
      fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("JSON File", "json", "json"));

      JMenuBar menuBar = new JMenuBar();
      appFrame.setJMenuBar(menuBar);
      JMenu fileMenu = new JMenu("File");
      menuBar.add(fileMenu);

      JMenuItem openFileMenuItem = new JMenuItem(new AbstractAction("Open File...") {
        public void actionPerformed(ActionEvent actionEvent) {
          try {
            int status = fileChooser.showOpenDialog(appFrame);
            if (status == JFileChooser.APPROVE_OPTION) {

              //TODO Likely need to start here when handling parsing of GeoJSON!

              @JsonInclude(JsonInclude.Include.NON_NULL)
              @JsonPropertyOrder({
                      "type",
                      "geometry",
                      "properties"
              })
              class Feature {

                @JsonProperty("type")
                private String type;
                @JsonProperty("geometry")
                private Geometry geometry;
                @JsonProperty("properties")
                private Properties properties;
                @JsonIgnore
                private Map<String, Object> additionalProperties = new HashMap<String, Object>();

                @JsonProperty("type")
                public String getType() {
                  return type;
                }

                @JsonProperty("type")
                public void setType(String type) {
                  this.type = type;
                }

                @JsonProperty("geometry")
                public Geometry getGeometry() {
                  return geometry;
                }

                @JsonProperty("geometry")
                public void setGeometry(Geometry geometry) {
                  this.geometry = geometry;
                }

                @JsonProperty("properties")
                public Properties getProperties() {
                  return properties;
                }

                @JsonProperty("properties")
                public void setProperties(Properties properties) {
                  this.properties = properties;
                }

                @JsonAnyGetter
                public Map<String, Object> getAdditionalProperties() {
                  return this.additionalProperties;
                }

                @JsonAnySetter
                public void setAdditionalProperty(String name, Object value) {
                  this.additionalProperties.put(name, value);
                }
              }
            }
          } catch (Exception e) {
            e.printStackTrace();
          }
        }
      });

      fileMenu.add(openFileMenuItem);


    }




  }
  public static void main(String[] args) {

    final AppFrame af = (AppFrame) start("World Wind JSON Network Viewer", AppFrame.class);
  }
}

Here is where I am getting the error

public static void main(String[] args) {

    final AppFrame af = (AppFrame) start("World Wind JSON Network Viewer", AppFrame.class);

    File selectedFile = jfc.getSelectedFile();
    ObjectMapper objectMapper = new ObjectMapper();
    FeatureCollection features = objectMapper.readValue(selectedFile, FeatureCollection.class);

  }

jfc is saying create local variable readValue is throwing an unhandled exception

1 Answers

For working with GeoJSON JSON payloads you can use for example, geojson-jackson library which is available in 1.12 version. To use it you just need to add it to your Maven configuration:

<dependency>
    <groupId>de.grundid.opendatalab</groupId>
    <artifactId>geojson-jackson</artifactId>
    <version>1.12</version>
</dependency>

Since now you can read your JSON configuration as below:

import com.fasterxml.jackson.databind.ObjectMapper;
import org.geojson.FeatureCollection;

import java.io.File;
import java.io.IOException;

public class GeoJSON {

    public static void main(String[] args) throws IOException {
        File jsonFile = new File("./resource/test.json").getAbsoluteFile();

        ObjectMapper objectMapper = new ObjectMapper();
        FeatureCollection features = objectMapper.readValue(jsonFile, FeatureCollection.class);
        features.forEach(System.out::println);
    }
}

Above code prints:

Feature{properties={prop0=value0}, geometry=Point{coordinates=LngLatAlt{longitude=102.0, latitude=0.6, altitude=NaN}} GeoJsonObject{}, id='null'}
Feature{properties={prop1=0.0, prop0=value0}, geometry=LineString{} MultiPoint{} Geometry{coordinates=[LngLatAlt{longitude=102.0, latitude=0.0, altitude=NaN}, LngLatAlt{longitude=103.0, latitude=1.0, altitude=NaN}, LngLatAlt{longitude=104.0, latitude=0.0, altitude=NaN}, LngLatAlt{longitude=105.0, latitude=1.0, altitude=NaN}]} GeoJsonObject{}, id='null'}
Feature{properties={prop1={this=that}, prop0=value0}, geometry=Polygon{} Geometry{coordinates=[[LngLatAlt{longitude=100.0, latitude=0.0, altitude=NaN}, LngLatAlt{longitude=101.0, latitude=0.0, altitude=NaN}, LngLatAlt{longitude=101.0, latitude=1.0, altitude=NaN}, LngLatAlt{longitude=100.0, latitude=1.0, altitude=NaN}, LngLatAlt{longitude=100.0, latitude=0.0, altitude=NaN}]]} GeoJsonObject{}, id='null'}

As you can see, you have an access to each property in very structured way. You do not need to create your own POJO, just use already implemented and tested POJO model. In your example you can do that in this way:

if (status == JFileChooser.APPROVE_OPTION) {
    File selectedFile = jfc.getSelectedFile();
    ObjectMapper objectMapper = new ObjectMapper();
    FeatureCollection features = objectMapper.readValue(selectedFile, FeatureCollection.class);
}

See also:

Related