// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.plugins.jts; import java.util.List; import org.openstreetmap.josm.data.osm.Node; import org.openstreetmap.josm.data.osm.OsmPrimitive; import org.openstreetmap.josm.data.osm.Relation; import org.openstreetmap.josm.data.osm.Way; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.CoordinateSequence; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.LineString; import com.vividsolutions.jts.geom.LinearRing; import com.vividsolutions.jts.geom.Point; import com.vividsolutions.jts.geom.Polygon; import com.vividsolutions.jts.geom.PrecisionModel; import com.vividsolutions.jts.geom.impl.CoordinateArraySequence; /** * Methods to convert JOSM geometry to JTS geometry */ public class JTSConverter { private PrecisionModel precisionModel; private GeometryFactory geometryFactory; private boolean useEastNorth; /** * Conversions will use latitude/longitude for coordinates */ public JTSConverter() { this(false); } /** * Conversions will use LatLon if useEastNorth is false, otherwise EastNorth * (the currently selected projection) will be used for coordinates. */ public JTSConverter(boolean useEastNorth) { this.useEastNorth = useEastNorth; if (useEastNorth) precisionModel = new PrecisionModel(); else precisionModel = new OsmPrecisionModel(); geometryFactory = new GeometryFactory(precisionModel); } public PrecisionModel getPrecisionModel() { return precisionModel; } public GeometryFactory getGeometryFactory() { return geometryFactory; } /** * Simple subclass to match precision with the OSM data model (7 decimal * places) */ public class OsmPrecisionModel extends com.vividsolutions.jts.geom.PrecisionModel { public OsmPrecisionModel() { super(10000000); } } public Coordinate convertNodeToCoordinate(Node node) { if (useEastNorth) return new Coordinate(node.getEastNorth().getX(), node.getEastNorth().getY()); else return new Coordinate(node.getCoor().getX(), node.getCoor().getY()); } public CoordinateSequence convertNodesToCoordinateSequence(List<Node> nodes) { Coordinate[] coords = new Coordinate[nodes.size()]; for (int i = 0; i < nodes.size(); i++) { coords[i] = convertNodeToCoordinate(nodes.get(i)); } return new CoordinateArraySequence(coords); } public Point convertNode(Node node) { Coordinate[] coords = {convertNodeToCoordinate(node)}; return new com.vividsolutions.jts.geom.Point(new CoordinateArraySequence(coords), getGeometryFactory()); } public Geometry convertWay(Way way) { CoordinateSequence coordSeq = convertNodesToCoordinateSequence(way.getNodes()); // TODO: need to check tags to determine whether area or not if (way.isClosed()) { LinearRing ring = new LinearRing(coordSeq, getGeometryFactory()); return new Polygon(ring, null, getGeometryFactory()); } else { return new LineString(coordSeq, getGeometryFactory()); } } public Geometry convert(OsmPrimitive prim) { if (prim instanceof Node) { return convertNode((Node) prim); } else if (prim instanceof Way) { return convertWay((Way) prim); } else if (prim instanceof Relation) { throw new UnsupportedOperationException("Relations not supported yet."); } else { throw new UnsupportedOperationException("Unknown primitive."); } } }