/* * This is part of Geomajas, a GIS framework, http://www.geomajas.org/. * * Copyright 2008-2015 Geosparc nv, http://www.geosparc.com/, Belgium. * * The program is available in open source according to the GNU Affero * General Public License. All contributions in this program are covered * by the Geomajas Contributors License Agreement. For full licensing * details, see LICENSE.txt in the project root. */ package org.geomajas.gwt.client.spatial.geometry; import org.geomajas.geometry.Coordinate; import org.geomajas.gwt.client.spatial.Bbox; /** * The main factory class for creating geometry objects on the GWT client. * * @author Pieter De Graef */ public class GeometryFactory { public static final int PARAM_DEFAULT_PRECISION = 5; private int srid; private int precision; // ------------------------------------------------------------------------- // Constructors: // ------------------------------------------------------------------------- public GeometryFactory(int srid, int precision) { this.srid = srid; this.precision = precision; } // ------------------------------------------------------------------------- // Getters and setters: // ------------------------------------------------------------------------- public int getSrid() { return srid; } /** * Set a new Spatial Reference id for this factory. */ public void setSrid(int srid) { this.srid = srid; } public int getPrecision() { return precision; } /** * Set a new precision for this factory. */ public void setPrecision(int precision) { this.precision = precision; } // ------------------------------------------------------------------------- // Class specific functions: // ------------------------------------------------------------------------- /** * Create a new {@link Point}, given a coordinate. * * @param coordinate * The {@link Coordinate} object that positions the point. * @return Returns a {@link Point} object. */ public Point createPoint(Coordinate coordinate) { if (coordinate == null) { return new Point(srid, precision); } return new Point(srid, precision, coordinate.getX(), coordinate.getY()); } /** * Create a new {@link LineString}, given an array of coordinates. * * @param coordinates * An array of {@link Coordinate} objects. * @return Returns a {@link LineString} object. */ public LineString createLineString(Coordinate[] coordinates) { if (coordinates == null) { return new LineString(srid, precision); } Coordinate[] clones = new Coordinate[coordinates.length]; for (int i = 0; i < coordinates.length; i++) { clones[i] = (Coordinate) coordinates[i].clone(); } return new LineString(srid, precision, clones); } /** * Create a new {@link MultiLineString}, given an array of LineStrings. * * @param lineStrings * An array of {@link LineString} objects. * @return Returns a {@link MultiLineString} object. */ public MultiLineString createMultiLineString(LineString[] lineStrings) { if (lineStrings == null) { return new MultiLineString(srid, precision); } LineString[] clones = new LineString[lineStrings.length]; for (int i = 0; i < lineStrings.length; i++) { clones[i] = (LineString) lineStrings[i].clone(); } return new MultiLineString(srid, precision, clones); } /** * Create a new {@link LinearRing}, given an array of coordinates. * * @param coordinates * An array of {@link Coordinate} objects. This function checks if the array is closed, and does so * itself if needed. * @return Returns a {@link LinearRing} object. */ public LinearRing createLinearRing(Coordinate[] coordinates) { if (coordinates == null || coordinates.length == 0) { return new LinearRing(srid, precision); } boolean isClosed = true; if (coordinates.length == 1 || !coordinates[0].equals(coordinates[coordinates.length - 1])) { isClosed = false; } Coordinate[] clones; if (isClosed) { clones = new Coordinate[coordinates.length]; } else { clones = new Coordinate[coordinates.length + 1]; } for (int i = 0; i < coordinates.length; i++) { clones[i] = (Coordinate) coordinates[i].clone(); } if (!isClosed) { clones[coordinates.length] = (Coordinate) clones[0].clone(); } return new LinearRing(srid, precision, clones); } /** * Create a new {@link LinearRing} from a {@link Bbox}. * * @param bbox * Bounding box to convert into a {@link LinearRing}. * @return Returns a {@link LinearRing} object. */ public LinearRing createLinearRing(Bbox bbox) { Coordinate tl = new Coordinate(bbox.getX(), bbox.getY()); Coordinate tr = new Coordinate(bbox.getX() + bbox.getWidth(), bbox.getY()); Coordinate br = new Coordinate(bbox.getX() + bbox.getWidth(), bbox.getY() + bbox.getHeight()); Coordinate bl = new Coordinate(bbox.getX(), bbox.getY() + bbox.getHeight()); return new LinearRing(srid, precision, new Coordinate[] { tl, tr, br, bl, tl }); } /** * Create a new {@link Polygon}, given a shell and and array of holes. * * @param exteriorRing * A {@link LinearRing} object that represents the outer ring. * @param interiorRings * An array of {@link LinearRing} objects representing the holes. * @return Returns a {@link Polygon} object. */ public Polygon createPolygon(LinearRing exteriorRing, LinearRing[] interiorRings) { if (exteriorRing == null) { return new Polygon(srid, precision); } LinearRing[] clones = null; if (interiorRings != null) { clones = new LinearRing[interiorRings.length]; for (int i = 0; i < interiorRings.length; i++) { clones[i] = (LinearRing) interiorRings[i].clone(); } } return new Polygon(srid, precision, (LinearRing) exteriorRing.clone(), clones); } /** * Create a new {@link Polygon} from a {@link Bbox}. * * @param bbox * Bounding box to convert into a {@link Polygon}. * @return Returns a {@link Polygon} object. */ public Polygon createPolygon(Bbox bbox) { Coordinate tl = new Coordinate(bbox.getX(), bbox.getY()); Coordinate tr = new Coordinate(bbox.getX() + bbox.getWidth(), bbox.getY()); Coordinate br = new Coordinate(bbox.getX() + bbox.getWidth(), bbox.getY() + bbox.getHeight()); Coordinate bl = new Coordinate(bbox.getX(), bbox.getY() + bbox.getHeight()); return new Polygon(srid, precision, new LinearRing(srid, precision, new Coordinate[] { tl, tr, br, bl, tl }), null); } /** * Create a new {@link MultiPolygon}, given an array of polygons. * * @param polygons * An array of {@link Polygon} objects . * @return Returns a {@link MultiPolygon} object. */ public MultiPolygon createMultiPolygon(Polygon[] polygons) { if (polygons == null) { return new MultiPolygon(srid, precision); } Polygon[] clones = new Polygon[polygons.length]; for (int i = 0; i < polygons.length; i++) { clones[i] = (Polygon) polygons[i].clone(); } return new MultiPolygon(srid, precision, clones); } /** * Create a new {@link MultiPoint}, given an array of points. * * @param points * An array of {@link Point} objects. * @return Returns a {@link MultiPoint} geometry. */ public MultiPoint createMultiPoint(Point[] points) { if (points == null) { return new MultiPoint(srid, precision); } Point[] clones = new Point[points.length]; for (int i = 0; i < points.length; i++) { clones[i] = (Point) points[i].clone(); } return new MultiPoint(srid, precision, clones); } /** * Create a new geometry from an existing geometry. This will basically create a clone. * * @param geometry * The original geometry. * @return Returns a clone. */ public Geometry createGeometry(Geometry geometry) { if (geometry instanceof Point) { return createPoint(geometry.getCoordinate()); } else if (geometry instanceof LinearRing) { return createLinearRing(geometry.getCoordinates()); } else if (geometry instanceof LineString) { return createLineString(geometry.getCoordinates()); } else if (geometry instanceof Polygon) { Polygon polygon = (Polygon) geometry; LinearRing exteriorRing = createLinearRing(polygon.getExteriorRing().getCoordinates()); LinearRing[] interiorRings = new LinearRing[polygon.getNumInteriorRing()]; for (int n = 0; n < polygon.getNumInteriorRing(); n++) { interiorRings[n] = createLinearRing(polygon.getInteriorRingN(n).getCoordinates()); } return new Polygon(srid, precision, exteriorRing, interiorRings); } else if (geometry instanceof MultiPoint) { Point[] clones = new Point[geometry.getNumGeometries()]; for (int n = 0; n < geometry.getNumGeometries(); n++) { clones[n] = createPoint(geometry.getGeometryN(n).getCoordinate()); } return new MultiPoint(srid, precision, clones); } else if (geometry instanceof MultiLineString) { LineString[] clones = new LineString[geometry.getNumGeometries()]; for (int n = 0; n < geometry.getNumGeometries(); n++) { clones[n] = createLineString(geometry.getGeometryN(n).getCoordinates()); } return new MultiLineString(srid, precision, clones); } else if (geometry instanceof MultiPolygon) { Polygon[] clones = new Polygon[geometry.getNumGeometries()]; for (int n = 0; n < geometry.getNumGeometries(); n++) { clones[n] = (Polygon) createGeometry(geometry.getGeometryN(n)); } return new MultiPolygon(srid, precision, clones); } return null; } }