/**
* Copyright (c) Cohesive Integrations, LLC
* Copyright (c) Codice Foundation
*
* This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details. A copy of the GNU Lesser General Public License is distributed along with this program and can be found at
* <http://www.gnu.org/licenses/lgpl.html>.
*
**/
package net.di2e.ecdr.search.transform.geo.formatter;
import java.util.List;
import java.util.Map;
import org.apache.abdera.ext.geo.Position;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
/**
* Abstract class that represents the geometric portion of GeoJSON.
*
*/
public abstract class CompositeGeometry {
public static final String TYPE_KEY = "type";
public static final String COORDINATES_KEY = "coordinates";
public static final String PROPERTIES_KEY = "properties";
public static final String GEOMETRY_KEY = "geometry";
public static final String GEOMETRIES_KEY = "geometries";
protected static final GeometryFactory GEOMETRY_FACTORY = new GeometryFactory();
/**
* Creates a Map that mimics the GeoJSON structure.
*
* @throws UnsupportedOperationException
* when the object cannot write into the map
*/
public abstract Map toJsonMap();
/**
* @return well-known text of underlying equivalent Geometric object
*/
public abstract String toWkt();
public abstract List<Position> toGeoRssPositions();
/**
*
* @return equivalent geometric object
*/
public abstract Geometry getGeometry();
/**
* Deciphers the {@link CompositeGeometry} object to return based on {@link Geometry}
*
* @param geometry
* @return {@link CompositeGeometry}
*/
public static CompositeGeometry getCompositeGeometry( Geometry geometry ) {
if ( geometry != null ) {
if ( Point.TYPE.equals( geometry.getGeometryType() ) ) {
return new Point( geometry );
}
if ( LineString.TYPE.equals( geometry.getGeometryType() ) ) {
return new LineString( geometry );
}
if ( MultiPoint.TYPE.equals( geometry.getGeometryType() ) ) {
return new MultiPoint( geometry );
}
if ( MultiLineString.TYPE.equals( geometry.getGeometryType() ) ) {
return new MultiLineString( geometry );
}
if ( Polygon.TYPE.equals( geometry.getGeometryType() ) ) {
return new Polygon( geometry );
}
if ( MultiPolygon.TYPE.equals( geometry.getGeometryType() ) ) {
return new MultiPolygon( geometry );
}
if ( GeometryCollection.TYPE.equals( geometry.getGeometryType() ) ) {
return new GeometryCollection( geometry );
}
}
return null;
}
/**
*
* @param type
* case-sensitive String of the geometric type, must match the exact spelling in the GeoJSON standard
* (geojson.org)
* @param jsonObject
* Map of coordinates or geometries
* @return {@link CompositeGeometry} based on the <code>type</code> passed in, returns <code>null</code> if the type
* is not one of the standard GeoJSON geometric strings.
*/
public static CompositeGeometry getCompositeGeometry( String type, Map jsonObject ) {
if ( type != null ) {
if ( GeometryCollection.TYPE.equals( type ) ) {
List geometries = (List) jsonObject.get( CompositeGeometry.GEOMETRIES_KEY );
return GeometryCollection.toCompositeGeometry( geometries );
} else {
List coordinates = (List) jsonObject.get( CompositeGeometry.COORDINATES_KEY );
if ( Point.TYPE.equals( type ) ) {
return Point.toCompositeGeometry( coordinates );
}
if ( LineString.TYPE.equals( type ) ) {
return LineString.toCompositeGeometry( coordinates );
}
if ( MultiPoint.TYPE.equals( type ) ) {
return MultiPoint.toCompositeGeometry( coordinates );
}
if ( MultiLineString.TYPE.equals( type ) ) {
return MultiLineString.toCompositeGeometry( coordinates );
}
if ( Polygon.TYPE.equals( type ) ) {
return Polygon.toCompositeGeometry( coordinates );
}
if ( MultiPolygon.TYPE.equals( type ) ) {
return MultiPolygon.toCompositeGeometry( coordinates );
}
}
}
return null;
}
/**
*
* @param primitiveCoordinates
* requires x and y coordinate information as a {@link List}, x coordinate is the first item in the list
* @return {@link Coordinate} object
*/
protected static Coordinate getCoordinate( List primitiveCoordinates ) {
if ( primitiveCoordinates != null && !primitiveCoordinates.isEmpty() ) {
double x = getDouble( primitiveCoordinates.get( 0 ) );
double y = getDouble( primitiveCoordinates.get( 1 ) );
return new Coordinate( x, y );
} else {
return new Coordinate();
}
}
/**
* This method is to retrieve numerical information when it is not known how that number will be provided
* beforehand.
*
* @param object
* @return double
*/
private static double getDouble( Object object ) {
if ( object instanceof Double ) {
return (Double) object;
} else {
if ( object != null ) {
return Double.valueOf( object.toString() );
} else {
return 0.0;
}
}
}
/**
*
* @param primitiveCoordinatesList
* a List of [x,y] coordinates. The [x,y] coordinates is a list of two objects where x coordinate is
* first and the y coordinate is second in the list
* @return an array of {@link Coordinate} objects, if input is <code>null</code> or empty, it will return an empty
* array
*/
protected static Coordinate[] getCoordinates( List<List<String>> primitiveCoordinatesList ) {
if ( primitiveCoordinatesList != null && !primitiveCoordinatesList.isEmpty() ) {
Coordinate[] coordinatesArray = new Coordinate[primitiveCoordinatesList.size()];
for ( int i = 0; i < coordinatesArray.length; i++ ) {
coordinatesArray[i] = getCoordinate( primitiveCoordinatesList.get( i ) );
}
return coordinatesArray;
} else {
return new Coordinate[0];
}
}
}