Class TLcdGeoJsonModelDecoder

java.lang.Object
com.luciad.format.geojson.TLcdGeoJsonModelDecoder
All Implemented Interfaces:
ILcdInputStreamFactoryCapable, ILcdModelDecoder

@LcdService(service=ILcdModelDecoder.class, priority=20000) public class TLcdGeoJsonModelDecoder extends Object implements ILcdModelDecoder, ILcdInputStreamFactoryCapable
Decodes a GeoJson FeatureCollection to a Luciad ILcdModel.

Input files

The decoder only accepts source-paths ending with the extension .json, .geojson, or .js.

Format at-a-glance

GeoJson is a text format to represent geospatial vector data.

The input file must contain a single FeatureCollection. See the geojson specification for more details.

A FeatureCollection must at least contain 2 members:

  • type: with a value equal to "FeatureCollection"
  • features: an array containing zero or more domain objects. In turn, each Feature must at least have:
    • type: with a value equal to "Feature"
    • geometry: a GeoJson geometry
    • properties: properties (as key-value pairs) of the feature
    • id (optional): a unique identifier

A valid GeoJson FeatureCollection containing a single point feature.


  {
    type: "FeatureCollection",
    features: [
     {
       type: "Feature",
       geometry: {
        type: "Point",
        coordinates: [4.668864,50.864871],
       },
       properties: {
          poi: "Luciad NV HQ"
       }
     }
    ]
  }
  

Supported file transfer protocols

This model decoder supports all transfer protocols that are supported by the input stream factory of this decoder.

Model structure

  • This model decoder creates a model per GeoJson file.
  • All models returned by this model decoder implement ILcd2DBoundsIndexedModel.

Model descriptor

The model descriptor of this model is a TLcdGeoJsonModelDescriptor.

Model elements

Each feature of the feature collection is decoded to a domain object. Each domain object implements ILcdShapeList and ILcdDataObject.

Geometries

The decoder supports all 7 GeoJson geometries: Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, GeometryCollection. These geometries can be consumed through existing Luciad shape interfaces.

Properties summary

The properties of the GeoJson feature can be accessed through the methods of the ILcdDataObject interface.

It is typically the case that all features in a GeoJson FeatureCollection share the same properties. However, this is not required.

The decoder will construct a single TLcdDataType which is shared by all Features in the collection.

Below are some typical examples.

Example 1: the ILcdDataType of the features in this collection has 2 properties: "poi" and "country".


 {
    type: "FeatureCollection",
    features: [
     {
       type: "Feature",
       geometry: {
        type: "Point",
        coordinates: [4.668864,50.864871]
       },
       properties: {
          poi: "Luciad NV HQ",
          country: "Belgium"
       }
     },
     {
       type: "Feature",
       geometry: {
        type: "Point",
        coordinates: [-77.340020,38.946660],
       },
       properties: {
          poi: "Luciad Inc HQ",
          country: "United States of America"
       }
     }
    ]
  }
  

Example 2: the ILcdDataType of the features in this collection have 3 properties: "poi", "country" and "state". The value of the "state" property of the first feature is null.

 {
    type: "FeatureCollection",
    features: [
     {
       type: "Feature",
       geometry: {
        type: "Point",
        coordinates: [4.668864,50.864871],
        properties: {
          poi: "Luciad NV HQ",
          country: "Belgium"
        }
       }
     },
     {
       type: "Feature",
       geometry: {
        type: "Point",
        coordinates: [-77.340020,38.946660],
        properties: {
          poi: "Luciad Inc HQ",
          country: "United States of America",
          state: "VA"
        }
       }
     }
    ]
  }


  

id summary

When an id-property is present on a geojson-feature, it is added to the data-type and annotated with a PrimaryKey annotation. The name of this id-property is dynamically determined so it does not conflict with an existing property-name which is present on the properties object. Typically, this name is "uid", if there is not already a property named like that. To determine the property name of the id-property, you can do:

        String primaryKeyPropertyName = null;
        TLcdPrimaryKeyAnnotation annotation = aDataType.getAnnotation(TLcdPrimaryKeyAnnotation.class);
        if(annotation != null){
          primaryKeyPropertyName = annotation.getProperty().getName();
        }
 

Data Model Name

It is often useful to identify the model with an appropriate name. For example, you might have other components in your code that - depending on a given model - perform different actions.

You can configure the name of the data model and the name of the data type explicitly using

When these are not set, default values based on the name of the model source will be used.

Property names

Property names must be a String.


   {
     "this is a string": "good property name",
     thisIsAString: "also a good property name",
     0: "bad property name. This json is illegal and cannot be decoded."
   }
 

Property type conversion

For details about the Json format, please visit json.org

A value in Json can only be one of these types: String, number, object (a collection of key-value pairs), array (a list of values), true, false, and null.

These types are mapped to a TLcdDataType (in the case of primitives) or a TLcdDataProperty.CollectionType (in the case of collections) in the following manner:

  • String: TLcdCoreDataTypes.STRING_TYPE
  • Number:
    • TLcdCoreDataTypes.INTEGER_TYPE: if the number has no decimal point.
    • TLcdCoreDataTypes.LONG_TYPE: if the number has no decimal point and does not fit in a 32 bit integer.
    • TLcdCoreDataTypes.DOUBLE_TYPE: if the number has a decimal point.
  • true/false: TLcdCoreDataTypes.BOOLEAN_TYPE
  • array: TLcdDataProperty.CollectionType.LIST.
  • object: TLcdDataProperty.CollectionType.MAP.

Model reference

The decoder supports named spatial references, but not linked spatial references. Please refer to the geojson specification for details.

The decoder only supports references from the EPSG organization, as well as the standard OGC CRS:84 reference.

When a given spatial reference cannot be decoded, an error will be thrown.

When no spatial reference is present, the default WGS 84 geographic reference will be used.

Only spatial references are parsed which are present on the FeatureCollection. Nested spatial references are ignored.

Example 3: An example GeoJson file with a valid named spatial reference.


 {
    type: "FeatureCollection",
    "crs": {
      "type": "name",
      "properties": {
        "name": "urn:ogc:def:crs:OGC:1.3:CRS84"
      }
     },
    features: [
     {
       type: "Feature",
       geometry: {
        type: "Point",
        coordinates: [4.668864,50.864871],
        properties: {
          poi: "Luciad NV HQ",
          country: "Belgium"
        }
       }
     },
     {
       type: "Feature",
       geometry: {
        type: "Point",
        coordinates: [-77.340020,38.946660],
        properties: {
          poi: "Luciad Inc HQ",
          country: "United States of America",
          state: "VA"
        }
       }
     }
    ]
  }
  

Sample code


 ILcdModelDecoder decoder = new TLcdGeoJsonModelDecoder();
 ILcdModel model = decoder.decode("world.geojson");
 

Thread safety

  • The decoded models are thread-safe for read access when taking a read lock.
Since:
2012.1
  • Constructor Details

    • TLcdGeoJsonModelDecoder

      public TLcdGeoJsonModelDecoder()
      Create a new model decoder for GeoJson sources.
      
       TLcdGeoJsonModelDecoder myGeoJsonModelDecoder = new TLcdGeoJsonModelDecoder();
       
  • Method Details

    • setModelElementType

      public void setModelElementType(TLcdDataType aDataType)
      Sets a user provided data type. When decoding a model, the decoder will apply this data type to the elements in the model. When this is not set, the decoder will derive the data type automatically from the input GeoJson. It must be possible to map the values of the GeoJson features into the properties of this data type. Missing GeoJson values will be ignored. Note that this method and both setDataModelName(java.lang.String) and setDataTypeName(java.lang.String) are mutually exclusive. The data model name and type name of aDataType have priority over any names that were set with the setDataModelName(java.lang.String) or setDataTypeName(java.lang.String) methods.
      Parameters:
      aDataType - the data type to use when decoding. It may only contain properties of the primitive types INTEGER_TYPE, LONG_TYPE, FLOAT_TYPE, DOUBLE_TYPE, NUMBER_TYPE, STRING_TYPE, OBJECT_TYPE, STRING_TYPE, BOOLEAN_TYPE, STRING_TYPE, OBJECT_TYPE or of the collection types MAP and LIST.
      Since:
      2013.1
    • getDataType

      public TLcdDataType getDataType()
      Get the user provided data type. By default, this value is null.
      Returns:
      the user provided data type
    • getDisplayName

      public String getDisplayName()
      A short label for the format. For example, this is often used in open-file dialogs.
      Specified by:
      getDisplayName in interface ILcdModelDecoder
      Returns:
      geojson.org:GeoJSON
    • canDecodeSource

      public boolean canDecodeSource(String aSourceName)
      The method will return true only when aSourceName ends in .geojson, .json, or .js.
      Specified by:
      canDecodeSource in interface ILcdModelDecoder
      Parameters:
      aSourceName - the data source to be verified; typically a file name or a URL.
      Returns:
      boolean indicating whether the source can be decoded.
      See Also:
    • decode

      public ILcdModel decode(String aSourceName) throws IOException

      Creates a new model from the source. This model implements ILcdModel.

      The source must contain a valid GeoJson FeatureCollection. For convenience, it will also support a single GeoJson Feature, a single GeoJson Geometry, or a an array of GeoJson features. To decode a single feature, note that you can also use the static decodeFeature(java.io.InputStream, com.luciad.model.ILcdModelReference, com.luciad.datamodel.TLcdDataType) method.

      Specified by:
      decode in interface ILcdModelDecoder
      Parameters:
      aSourceName - the data source to be decoded; typically a file name or a URL.
      Returns:
      the model
      Throws:
      IOException
      See Also:
    • setInputStreamFactory

      public void setInputStreamFactory(ILcdInputStreamFactory aInputStreamFactory)
      Description copied from interface: ILcdInputStreamFactoryCapable
      Sets the input stream factory to be used.
      Specified by:
      setInputStreamFactory in interface ILcdInputStreamFactoryCapable
      Parameters:
      aInputStreamFactory - the input stream factory to be used.
    • getInputStreamFactory

      public ILcdInputStreamFactory getInputStreamFactory()
      Description copied from interface: ILcdInputStreamFactoryCapable
      Returns the input stream factory that is used.
      Specified by:
      getInputStreamFactory in interface ILcdInputStreamFactoryCapable
      Returns:
      the input stream factory that is used.
    • getModelReferenceParser

      public ILcdModelReferenceParser getModelReferenceParser()
      Get the reference parser that is used by this decoder.
      Returns:
      The reference parser used by this decoder.
      Since:
      2016.1
    • setModelReferenceParser

      public void setModelReferenceParser(ILcdModelReferenceParser aModelReferenceParser)
      Set the reference parser the decoder will use to parse a spatial reference.
      Parameters:
      aModelReferenceParser - The reference parser for the decoder to use.
      Since:
      2016.1
    • setDefaultModelReference

      public void setDefaultModelReference(ILcdModelReference aModelReference)
      Sets the default model reference. This is a fallback reference that will be used when no reference is present in the input file. If no default model reference is set, EPSG:4326 will be used as default when the file only contains 2D coordinates, or EPSG:4979 if the file also contains Z-coordinates.
      Parameters:
      aModelReference - the model reference used as a default, or null if no custom default model reference should be set.
    • getDefaultModelReference

      public ILcdModelReference getDefaultModelReference()
      Retrieve the default model reference.
      Returns:
      the default model reference, or null if no custom default model reference is set.
    • setDataTypeName

      public void setDataTypeName(String aDataTypeName)
      Sets the data type name used by the decoder. The model-elements contained in the decoded model will have this name. Note that this name is not used if the user has set the data type explicitly with setModelElementType(com.luciad.datamodel.TLcdDataType).
      Parameters:
      aDataTypeName - the data type name
    • getDataTypeName

      public String getDataTypeName()
      Gets the data type name.
      Returns:
      the data type name
    • setDataModelName

      public void setDataModelName(String aDataModelName)
      Sets the data model name. When decoding a source-file, this value will be used for the data model name of the model. The default value is null. If this value is null, the file-name will be used for the data model name. Note that this name is not used if the user has set the data type explicitly with setModelElementType(com.luciad.datamodel.TLcdDataType).
      Parameters:
      aDataModelName - the data model name
    • getDataModelName

      public String getDataModelName()
      Gets the data model name.
      Returns:
      the data model name.
    • decodeFeature

      public static ILcdDataObject decodeFeature(InputStream aGeoJsonFeatureInputStream, ILcdModelReference aModelReference, TLcdDataType aDataType) throws IOException
      Decodes a geojson string to a data object. See also the TLcdGeoJsonModelEncoder.exportFeature(Object, java.io.OutputStream) static method for the reverse operation. Note: When using this method to decode a feature, parseCustomGeometry(String, ILcdModelReference) is not called.
      Parameters:
      aGeoJsonFeatureInputStream - the json feature. It must be a stream for a UTF-8 string.
      aModelReference - the model reference of the feature. If this is null, the WGS86 geodetic reference is used.
      aDataType - the data type of the feature.
      Returns:
      the data object.
      Throws:
      IOException - Thrown when the feature cannot be decoded. This is often caused by invalid GeoJson.
      Since:
      2013.1
    • parseGeometry

      public static ILcdShape parseGeometry(InputStream aInputStream, ILcdModelReference aModelReference) throws IOException
      Parses a single GeoJson geometry object to an ILcdShape.

      The following table shows which geometries are parsed to which shape types:

      Geometry Parsed to
      Point An ILcdPoint
      MultiPoint An ILcdShapeList containing zero or more ILcdPoint instances
      LineString An ILcdPolyline
      MultiLineString An ILcdShapeList containing zero or more ILcdPolyline instances
      Polygon An ILcdPolygon if the polygon consists of only one ring, or an ILcdComplexPolygon otherwise
      MultiPolygon An ILcdShapeList containing zero or more ILcdPolygon or ILcdComplexPolygon instances
      GeometryCollection An ILcdShapeList containing any combination of above-mentioned shapes.
      null An empty ILcdShapeList.
      Note: When using this method to decode a geometry, parseCustomGeometry(String, ILcdModelReference) is not called.
      Parameters:
      aInputStream - the GeoJson geometry object to parse.
      aModelReference - the model reference in which the geometry is defined.
      Returns:
      the parsed geometry.
      Throws:
      IOException - If the parsing fails.
      Since:
      2021.1
    • parseCustomGeometry

      protected ILcdShape parseCustomGeometry(String aJsonNode, ILcdModelReference aModelReference) throws IOException
      This method is used by the decoder to parse custom geometry that is normally not allowed in GeoJSON. To support custom shapes this method needs to be overwritten, the default implementation throws an IOException.
      Parameters:
      aJsonNode - the json node representing the custom geometry
      aModelReference - the model reference
      Returns:
      the parsed shape, the default implementation throws an IOException.
      Throws:
      IOException
      Since:
      2016.1