Class TLcdGeoJsonModelEncoder

java.lang.Object
com.luciad.format.geojson.TLcdGeoJsonModelEncoder
All Implemented Interfaces:
ILcdOutputStreamFactoryCapable, ILcdModelEncoder, Serializable

@LcdService(service=ILcdModelEncoder.class, priority=20000) public class TLcdGeoJsonModelEncoder extends Object implements ILcdModelEncoder, ILcdOutputStreamFactoryCapable
Encodes models to a single GeoJson FeatureCollection

Overview

Encodes models to a single GeoJson FeatureCollection.

Any instance of ILcdModel is encoded as a single FeatureCollection.

GeoJson Format

GeoJson is a text-format to represent geographic vector data. It may represent a geometry, a feature or a collection of features. See the GeoJson specification for details about the format.

Encoding a FeatureCollection

In GeoJson, a collection of domain objects are represented by a FeatureCollection. The model encoder will convert an ILcdModel to a single FeatureCollection.

Encoding a Feature

In GeoJson, domain objects are represented by a Feature.
A Feature is a combination of a GeoJson geometry, a set of properties and their values, and an optional identifier. To encode an object as a Feature, the object must either:
  • implement or have at least one of the supported shape interfaces. For a list of the supported shape interfaces, see the next section.
  • implement ILcdDataObject. The properties of this data object are converted to key-value pairs in the properties member of the Feature. A shape is not required in this case, but if the object does have (or is) a shape, it must be one of the supported shapes.

Encoding a Geometry

GeoJson supports following geometry-types: Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, GeometryCollection.
The encoder will transform a ILcdShape to one of these types.

Following shapes can be encoded to a GeoJson geometry:

  • ILcdPoint: encoded as a Point
  • ILcdPolyline: encoded as a LineString
  • ILcdPolygon: encoded as a Polygon
  • ILcdComplexPolygon:
    • when encoding strictly
      • the first polygon in the complex polygon is an outer ring and encloses all other polygons: encoded as a Polygon
      • the first polygon in not an outer ring, and the other polygons may cross or fall outside it: encoded as a MultiPolygon
    • when encoding loosely
      • all are encoded as a Polygon
  • ILcdPolypoint: encoded as a MultiPoint
  • ILcdSurface: encoded as a Polygon, providing the exterior ring and interior rings are instances of ILcdPointList
  • ILcdCurve: encoded as a LineString, provided that the object is also an instance of ILcdPointList, or is a ILcdCompositeCurve with a single ILcdPointList inside
  • ILcdRing: encoded as a Polygon with only a single ring, providing the object is also an instance of ILcdPointList
  • ILcdShapeList:
    • contains a single shape: this shape is encoded individually.
    • contains multiple shapes:
      • all are ILcdPoint: encoded as a MultiPoint
      • all are ILcdPolyline: encoded as a MultiLineString
      • all other cases: encoded as GeometryCollection, where each shape in the list is encoded individually
  • ILcdExtrudedShape: the baseShape is encoded individually.
A geometry will also be encoded if the domain object is an ILcdDataObject with a type that has a TLcdHasGeometryAnnotation and the value of the geometry property is one of the geometries listed above. When the domain object is not or does not have a geometry, null is encoded as value for the geometry property.

Customizing the encoding of geometries

In order to override the way shapes are encoded to GeoJSON, or to extend the shape types that are supported, a custom shape encoder can be configured with setCustomShapeEncoder(com.luciad.format.geojson.ILcdGeoJsonShapeEncoder). This custom shape encoder will get priority for every shape that it can encode (see ILcdGeoJsonShapeEncoder.canEncode(com.luciad.shape.ILcdShape)). Shapes for which ILcdGeoJsonShapeEncoder.canEncode(com.luciad.shape.ILcdShape) returns false, will be handled by the default encoding logic, as documented above.

For an example implementation of a custom shape encoder, see the ILcdGeoJsonShapeEncoder class javadoc.

Encoding Properties

When the domain object implements ILcdDataObject, its properties are encoded as well. The Json format only supports following types: String, number, object (a collection of key-value pairs), array (a list of values), true, false, and null.
The following conversions are used:
  • TLcdCoreDataTypes.STRING_TYPE: encoded to String
  • TLcdCoreDataTypes.NUMBER_TYPE: encoded to Number
  • TLcdCoreDataTypes.BOOLEAN_TYPE: encoded to true/false
  • TLcdDataProperty.CollectionType.LIST/SET: encoded to array
  • TLcdDataProperty.CollectionType.MAP: encoded to Object. The key of the map is converted to a string.
When the property does not have one of these types, the encoding of the object is not guaranteed, and may be a null value.

When the data type of the domain object has a property annotated as primary key using a TLcdPrimaryKeyAnnotation, the value of that property will be used as id value of the GeoJson Feature. It will then be omitted from the properties list.

Customizing the output for properties.

By using a TLcdFeatureMetaDataProvider, it is possible to customize how a domain object from the model is encoded.
It allows you to:
  • Specify which property should be used as the unique identifier of the domain object. This property-value is then used as the id value of the GeoJson Feature
  • Omit properties from the output by specifying only the properties of the object you would like to include.
  • Override the default serialization. This may be useful if a property-value has a complex representation which you would want to simplify in the resulting Json-document
Use setFeatureMetaDataProvider(TLcdFeatureMetaDataProvider) to set the TLcdFeatureMetaDataProvider for the encoder.
Since:
2012.1
See Also:
  • Constructor Details

  • Method Details

    • setModelReferenceFormatter

      public void setModelReferenceFormatter(ILcdModelReferenceFormatter aFormatter)
      Set the reference formatter the encoder will use to format a spatial reference.
      Parameters:
      aFormatter - the formatter for the encoder to use
    • getModelReferenceFormatter

      public ILcdModelReferenceFormatter getModelReferenceFormatter()
      Get the reference formatter that is used by the encoder.
      Returns:
      the reference formatter
    • setTextEncodingCharset

      public void setTextEncodingCharset(String aCharSet)
      Set the text encoding character set: for example "UTF-8".
      Parameters:
      aCharSet - the identifier of the character set.
    • getTextEncodingCharset

      public String getTextEncodingCharset()
      return the text encoding character set.
      Returns:
      the text encoding character set.
    • setPrettyJson

      public void setPrettyJson(boolean aPretty)
      Sets whether the output json needs to be human readable or not.

      Use true to make the json output "pretty". For example, this would be a point in pretty GeoJson.

      
         {
           "type":"Point",
           "coordinates":[10.1,12.3]
         }
       

      Use false to optimize the json output. For example, this would be a point in optimized GeoJson.

      
         {"type":"Point","coordinates":[10.1,12.3]}
       
      The above format is more efficient for machin readable applications (for example, a webservice supporting a rich internet application).

      Parameters:
      aPretty - is json pretty or not.
    • isPrettyJson

      public boolean isPrettyJson()
      Is the Json output pretty or not?
      Returns:
      true when pretty, false when optimized.
    • set2DJson

      public void set2DJson(boolean a2d)

      true: output coordinates will have 2 dimensions (x,y or lon,lat). Use this when the geometries to encode are 2-dimensional, or the 3rd dimension is irrelevant. For instance, you might want to use this option to limit the size of the data when building web applications.

      false: output coordinates have 3 dimensions.

      Parameters:
      a2d - is the coordinate output 2-dimensional or not.
    • is2DJson

      public boolean is2DJson()
      Is the coordinate output 2-dimensional or not?
      Returns:
      true when 2d, false when 3d.
    • setPolygonEncodingStrict

      public void setPolygonEncodingStrict(boolean aPolygonEncodingStrict)
      Set polygon encoding to strict.

      true: validate and correct polygons.

      Instances of ILcdComplexPolygon will be strictly validated before encoding.

      • A ILcdComplexPolygon may be encoded as a GeoJson MultiPolygon, instead of a GeoJson Polygon with multiple rings. This is the case when the first polygon in the ComplexPolygon does not contain all other Polygons.
      • The order of the points in some of the polygons in the ILcdComplexPolygon may be flipped. This happens when the orientation of the first polygon in the ComplexPolygon is not opposite to the orientation of the points in the other polygons. Note that this is not strictly enforced by the GeoJson specification. (v 1.0)

      Setting to true is more performance intensive.

      false: do not validate polygons

      Use this when you are certain the first polygon of a ComplexPolygons contains all other polygons. If this is not the case in your data, the output will be invalid GeoJson and may cause unexpected behaviour in some clients. Setting to false may be used to improve performance when encoding models.

      Parameters:
      aPolygonEncodingStrict - is polygon encoding strict or not
    • isPolygonEncodingStrict

      public boolean isPolygonEncodingStrict()
      Is polygon encoding strict or not?
      Returns:
      true when strict validation of polygons, false when not.
    • setSkipUnsupportedFeature

      public void setSkipUnsupportedFeature(boolean aSkip)
      Set to true if unsupported features in the model may be omitted from the exported GeoJson file.

      This is useful when objects in the model that do no implement a supported shape interface can safely be discarded.

      See the constructor documentation for more information about which shapes are supported.

      When set to false, an IllegalArgumentException will be thrown. This is the default behavior.

      Parameters:
      aSkip - should unsupported features be ignored? The default is false.
    • isSkipUnsupportedFeature

      public boolean isSkipUnsupportedFeature()
      Are unsupported features ignored? When false, an error will be thrown when exporting a model containing unsupported features. When true, a warning will be logged to the console when an unsupported feature is encountered.
      Returns:
      whether unsupported features are omitted from the exported GeoJson file.
    • setFeatureMetaDataProvider

      public void setFeatureMetaDataProvider(TLcdFeatureMetaDataProvider aFeatureMetaDataProvider)
      Sets the metadata provider to be used by the encoder. Such a provider can be used to specify which properties should be included when encoding a model.
      Parameters:
      aFeatureMetaDataProvider - the feature metadata provider to use
    • getFeatureMetaDataProvider

      public TLcdFeatureMetaDataProvider getFeatureMetaDataProvider()
      Get the metadata provider that is used by this encoder.
    • getCustomShapeEncoder

      public ILcdGeoJsonShapeEncoder getCustomShapeEncoder()
      Returns the custom shape encoder that is used by this model encoder, or null if no shape encoder was set.
      Returns:
      the custom shape encoder that is used by this model encoder, or null if no shape encoder was set.
      Since:
      2024.0
      See Also:
    • setCustomShapeEncoder

      public void setCustomShapeEncoder(ILcdGeoJsonShapeEncoder aCustomShapeEncoder)
      Sets a custom GeoJSON shape encoder on this model encoder. This can be used to override the way shapes are encoded, or to allow encoding otherwise unsupported shape types. The custom shape encoder gets priority over the default encoding functionality. Its canEncode method gets invoked for every shape that needs to be encoded, and when that returns true, encoding is delegated to its encode method. Otherwise, when canEncode returns false, the shape is handled by the default encoding logic as documented in the TLcdGeoJsonModelEncoder class javadoc.

      For an example implementation of a custom shape encoder, see the ILcdGeoJsonShapeEncoder class javadoc.

      Parameters:
      aCustomShapeEncoder - the custom shape encoder to be used by this model encoder.
      Since:
      2024.0
    • getDisplayName

      public String getDisplayName()
      Description copied from interface: ILcdModelEncoder
      Returns a short, displayable name for the format this ILcdModelEncoder encodes to.
      Specified by:
      getDisplayName in interface ILcdModelEncoder
      Returns:
      the displayable name of this ILcdModelEncoder.
    • canSave

      public boolean canSave(ILcdModel aModel)
      Description copied from interface: ILcdModelEncoder
      Returns whether this model encoder can save the specified model to the location it originally came from. Often this will only be a simple test, for example checking the type of the model's model descriptor.
      Specified by:
      canSave in interface ILcdModelEncoder
      Parameters:
      aModel - the model to be verified.
      Returns:
      true if this encoder can save the model in the location where it originally came from, false otherwise.
      See Also:
    • save

      public void save(ILcdModel aModel) throws IllegalArgumentException, IOException
      Description copied from interface: ILcdModelEncoder
      Saves the model to the location where it originally came from.
      Specified by:
      save in interface ILcdModelEncoder
      Parameters:
      aModel - the model to be saved.
      Throws:
      IllegalArgumentException - if the model cannot be saved by this encoder (!canSave(aModel)).
      IOException - if an I/O error occurs during encoding.
    • canExport

      public boolean canExport(ILcdModel aModel, String aDestinationName)
      Verifies whether this encoder can export the specified model to the specified destination.

      To keep this method fast, the encoder does a heuristic check to see if some elements in the given model can be converted to a GeoJson Feature. There may always be elements that cannot be encoded. You can configure if unsupported features may be skipped during encoding by using setSkipUnsupportedFeature(boolean).

      Specified by:
      canExport in interface ILcdModelEncoder
      Parameters:
      aModel - the model to be verified.
      aDestinationName - the location where the model should be exported to.
      Returns:
      true if this encoder can export the specified model to the specified location, false otherwise.
      See Also:
    • canExportFeature

      public boolean canExportFeature(Object aObject)
      Verifies whether this encoder can encode the given object to a GeoJSON feature. See the class documentation for details on which objects can be encoded to features exactly.
      Parameters:
      aObject - the domain object to encode.
      Returns:
      whether the given domain object can be encoded to a GeoJSON feature.
      Since:
      2024.0
      See Also:
    • exportFeature

      public void exportFeature(Object aObject, OutputStream aOutputStream) throws IOException
      A convenience method to encode a domain object to a GeoJson Feature. See also the TLcdGeoJsonModelDecoder.decodeFeature(java.io.InputStream, com.luciad.model.ILcdModelReference, com.luciad.datamodel.TLcdDataType) static method for the reverse operation.
      Parameters:
      aObject - the domain object to encode. Usually, this object would implement both ILcdDataObject as well as implement one of the supported shape interfaces (see the class documentation for details on the supported shape types).
      aOutputStream - the outputstream to which the Feature is written.
      Throws:
      IOException - if an I/O error occurs during encoding.
      Since:
      2013.1
    • canExportGeometry

      public boolean canExportGeometry(ILcdShape aShape)
      Verifies whether this encoder can encode the given shape to a GeoJSON geometry. See the class documentation for details on which shapes can be encoded to geometries exactly.
      Parameters:
      aShape - the shape to encode.
      Returns:
      whether the given shape can be encoded to a GeoJSON geometry.
      Since:
      2024.0
      See Also:
    • exportGeometry

      public void exportGeometry(ILcdShape aShape, OutputStream aOutputStream) throws IOException
      A convenience method to encode a shape to a GeoJson geometry.
      Parameters:
      aShape - the shape to encode.
      aOutputStream - the output stream to which the geometry is written
      Throws:
      IOException - if an I/O error occurs during encoding.
      Since:
      2013.1
      See Also:
    • export

      public void export(ILcdModel aModel, String aDestinationName) throws IllegalArgumentException, IOException
      Exports a model to the specified destination.

      This method will throw a runtime exception when one of the domain objects cannot be encoded. Before exporting a model, please verify it can be exported first by calling canExport(com.luciad.model.ILcdModel, java.lang.String).
      Specified by:
      export in interface ILcdModelEncoder
      Parameters:
      aModel - the model to be exported.
      aDestinationName - the location where the model should be saved. Typically, this is a name for the output file, but it can also point to a file containing the required properties to create a set of data files.
      Throws:
      IllegalArgumentException
      IOException
    • setOutputStreamFactory

      public void setOutputStreamFactory(ILcdOutputStreamFactory aOutputStreamFactory)
      Description copied from interface: ILcdOutputStreamFactoryCapable
      Sets the output stream factory to be used.
      Specified by:
      setOutputStreamFactory in interface ILcdOutputStreamFactoryCapable
      Parameters:
      aOutputStreamFactory - the output stream factory to be used.
    • getOutputStreamFactory

      public ILcdOutputStreamFactory getOutputStreamFactory()
      Description copied from interface: ILcdOutputStreamFactoryCapable
      Returns the output stream factory that is used.
      Specified by:
      getOutputStreamFactory in interface ILcdOutputStreamFactoryCapable
      Returns:
      the output stream factory that is used.