com.backendless.persistence.GeoJSONParser Maven / Gradle / Ivy
package com.backendless.persistence;
import com.backendless.util.JSONUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class GeoJSONParser
{
private final Class extends Geometry> geomClass;
private SpatialReferenceSystemEnum srs;
public GeoJSONParser()
{
this( null, null );
}
public GeoJSONParser( SpatialReferenceSystemEnum srs )
{
this( srs, null );
}
public GeoJSONParser( String geomClassName )
{
this( null, geomClassName );
}
GeoJSONParser( SpatialReferenceSystemEnum srs, String geomClassName )
{
this.srs = srs;
if( geomClassName != null )
{
try
{
@SuppressWarnings( "unchecked" )
Class extends Geometry> uncheckedClazz = (Class extends Geometry>) Class.forName( geomClassName );
this.geomClass = uncheckedClazz;
}
catch( ClassNotFoundException e )
{
throw new IllegalArgumentException( "'geomClassName' contains unknown class '" + geomClassName + "'." );
}
}
else
this.geomClass = null;
}
public Geometry read( String geoJson )
{
if( geoJson == null || geoJson.isEmpty() )
return null;
Map geoJsonMap;
try
{
geoJsonMap = JSONUtil.getJsonConverter().readObject( geoJson, Map.class );
}
catch( Exception e )
{
throw new GeoJSONParserException( e );
}
return read( geoJsonMap );
}
@SuppressWarnings( "unchecked" )
public Geometry read( Map geoJson )
{
String type = (String) geoJson.get( "type" );
Object coordinatesObj = geoJson.get( "coordinates" );
if( this.srs == null )
{
Integer srsId = (Integer) geoJson.get( "srsId" );
if( srsId != null )
this.srs = SpatialReferenceSystemEnum.valueBySRSId( srsId );
else
this.srs = SpatialReferenceSystemEnum.DEFAULT;
}
Object[] coordinates = null;
if( coordinatesObj instanceof List )
coordinates = ((List) coordinatesObj).toArray();
else if( coordinatesObj != null )
coordinates = (Object[]) coordinatesObj;
if( type == null || coordinates == null )
throw new GeoJSONParserException( "Both 'type' and 'coordinates' should be present in GeoJSON object." );
if( this.geomClass == null || this.geomClass == Geometry.class || Point.class == this.geomClass || LineString.class == this.geomClass || Polygon.class == this.geomClass )
{
switch( type )
{
case Point.GEOJSON_TYPE:
return constructPointFromCoordinates( coordinates );
case LineString.GEOJSON_TYPE:
return constructLineStringFromCoordinates( coordinates );
case Polygon.GEOJSON_TYPE:
return constructPolygonFromCoordinates( coordinates );
}
}
else
throw new GeoJSONParserException( "Unknown geometry class: '" + this.geomClass + "'" );
throw new GeoJSONParserException( "Unknown geometry type: '" + type + "'" );
}
private Point constructPointFromCoordinates( Object[] coordinatePair )
{
return new Point( this.srs ).setX( ((Number) coordinatePair[ 0 ]).doubleValue() ).setY( ((Number) coordinatePair[ 1 ]).doubleValue() );
}
private LineString constructLineStringFromCoordinates( Object[] arrayOfCoordinatePairs )
{
ArrayList points = new ArrayList<>();
Object[] coordinatePairNumbers;
for( Object coordinatePairObj : arrayOfCoordinatePairs )
{
if( coordinatePairObj instanceof List )
coordinatePairNumbers = ((List) coordinatePairObj).toArray();
else
coordinatePairNumbers = (Object[]) coordinatePairObj;
points.add( new Point( this.srs ).setX( ((Number) coordinatePairNumbers[ 0 ]).doubleValue() ).setY( ((Number) coordinatePairNumbers[ 1 ]).doubleValue() ) );
}
return new LineString( points, this.srs );
}
private Polygon constructPolygonFromCoordinates( Object[] arrayOfCoordinateArrayPairs )
{
ArrayList lineStrings = new ArrayList<>();
Object[] arrayOfCoordinatePairs;
for( Object arrayOfCoordinatePairsObj : arrayOfCoordinateArrayPairs )
{
if( arrayOfCoordinatePairsObj instanceof List )
arrayOfCoordinatePairs = ((List) arrayOfCoordinatePairsObj).toArray();
else
arrayOfCoordinatePairs = (Object[]) arrayOfCoordinatePairsObj;
LineString lineString = constructLineStringFromCoordinates( arrayOfCoordinatePairs );
lineStrings.add( lineString );
}
if( lineStrings.isEmpty() )
throw new GeoJSONParserException( "Polygon's GeoJSON should contain at least one LineString." );
LineString shell = lineStrings.get( 0 );
List holes = lineStrings.subList( 1, lineStrings.size() );
return new Polygon( shell, holes, srs );
}
public static class GeoJSONParserException extends RuntimeException
{
public GeoJSONParserException( String message )
{
super( message );
}
public GeoJSONParserException( String message, Throwable cause )
{
super( message, cause );
}
public GeoJSONParserException( Throwable cause )
{
super( cause );
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy