Search in sources :

Example 71 with Point

use of com.vividsolutions.jts.geom.Point in project Osmand by osmandapp.

the class JtsAdapter method flatFeatureList.

/**
 * <p>Recursively convert a {@link Geometry}, which may be an instance of {@link GeometryCollection} with mixed
 * element types, into a flat list containing only the following {@link Geometry} types:</p>
 * <ul>
 *     <li>{@link Point}</li>
 *     <li>{@link LineString}</li>
 *     <li>{@link Polygon}</li>
 *     <li>{@link MultiPoint}</li>
 *     <li>{@link MultiLineString}</li>
 *     <li>{@link MultiPolygon}</li>
 * </ul>
 * <p>WARNING: Any other Geometry types that were not mentioned in the list above will be discarded!</p>
 * <p>Useful for converting a generic geometry into a list of simple MVT-feature-ready geometries.</p>
 *
 * @param geom geometry to flatten
 * @return list of MVT-feature-ready geometries
 */
public static List<Geometry> flatFeatureList(Geometry geom) {
    final List<Geometry> singleGeoms = new ArrayList<>();
    final Stack<Geometry> geomStack = new Stack<>();
    Geometry nextGeom;
    int nextGeomCount;
    geomStack.push(geom);
    while (!geomStack.isEmpty()) {
        nextGeom = geomStack.pop();
        if (nextGeom instanceof Point || nextGeom instanceof MultiPoint || nextGeom instanceof LineString || nextGeom instanceof MultiLineString || nextGeom instanceof Polygon || nextGeom instanceof MultiPolygon) {
            singleGeoms.add(nextGeom);
        } else if (nextGeom instanceof GeometryCollection) {
            // Push all child geometries
            nextGeomCount = nextGeom.getNumGeometries();
            for (int i = 0; i < nextGeomCount; ++i) {
                geomStack.push(nextGeom.getGeometryN(i));
            }
        }
    }
    return singleGeoms;
}
Also used : MultiPoint(com.vividsolutions.jts.geom.MultiPoint) MultiLineString(com.vividsolutions.jts.geom.MultiLineString) ArrayList(java.util.ArrayList) Point(com.vividsolutions.jts.geom.Point) MultiPoint(com.vividsolutions.jts.geom.MultiPoint) Point(com.vividsolutions.jts.geom.Point) MultiPoint(com.vividsolutions.jts.geom.MultiPoint) Stack(java.util.Stack) Geometry(com.vividsolutions.jts.geom.Geometry) GeometryCollection(com.vividsolutions.jts.geom.GeometryCollection) LineString(com.vividsolutions.jts.geom.LineString) MultiLineString(com.vividsolutions.jts.geom.MultiLineString) MultiPolygon(com.vividsolutions.jts.geom.MultiPolygon) MultiPolygon(com.vividsolutions.jts.geom.MultiPolygon) Polygon(com.vividsolutions.jts.geom.Polygon)

Example 72 with Point

use of com.vividsolutions.jts.geom.Point in project Osmand by osmandapp.

the class MvtReader method readPoints.

/**
 * Create {@link Point} or {@link MultiPoint} from MVT geometry drawing commands.
 *
 * @param geomFactory creates JTS geometry
 * @param geomCmds    contains MVT geometry commands
 * @param cursor      contains current MVT extent position
 * @return JTS geometry or null on failure
 */
private static Geometry readPoints(GeometryFactory geomFactory, List<Integer> geomCmds, Vec2d cursor) {
    // Guard: must have header
    if (geomCmds.isEmpty()) {
        return null;
    }
    /**
     * Geometry command index
     */
    int i = 0;
    // Read command header
    final int cmdHdr = geomCmds.get(i++);
    final int cmdLength = GeomCmdHdr.getCmdLength(cmdHdr);
    final GeomCmd cmd = GeomCmdHdr.getCmd(cmdHdr);
    // Guard: command type
    if (cmd != GeomCmd.MoveTo) {
        return null;
    }
    // Guard: minimum command length
    if (cmdLength < 1) {
        return null;
    }
    // (require header and at least 1 value * 2 params)
    if (cmdLength * GeomCmd.MoveTo.getParamCount() + 1 > geomCmds.size()) {
        return null;
    }
    final CoordinateSequence coordSeq = geomFactory.getCoordinateSequenceFactory().create(cmdLength, 2);
    int coordIndex = 0;
    Coordinate nextCoord;
    while (i < geomCmds.size() - 1) {
        cursor.add(ZigZag.decode(geomCmds.get(i++)), ZigZag.decode(geomCmds.get(i++)));
        nextCoord = coordSeq.getCoordinate(coordIndex++);
        nextCoord.setOrdinate(0, cursor.x);
        nextCoord.setOrdinate(1, cursor.y);
    }
    return coordSeq.size() == 1 ? geomFactory.createPoint(coordSeq) : geomFactory.createMultiPoint(coordSeq);
}
Also used : CoordinateSequence(com.vividsolutions.jts.geom.CoordinateSequence) Coordinate(com.vividsolutions.jts.geom.Coordinate) GeomCmd(com.wdtinc.mapbox_vector_tile.encoding.GeomCmd) Point(com.vividsolutions.jts.geom.Point) MultiPoint(com.vividsolutions.jts.geom.MultiPoint)

Example 73 with Point

use of com.vividsolutions.jts.geom.Point in project OsmAnd by osmandapp.

the class JtsAdapter method toFeature.

/**
 * Create and return a feature from a geometry. Returns null on failure.
 *
 * @param geom flat geometry via {@link #flatFeatureList(Geometry)} that can be translated to a feature
 * @param cursor vector tile cursor position
 * @param layerProps layer properties for tagging features
 * @return new tile feature instance, or null on failure
 */
private static VectorTile.Tile.Feature toFeature(Geometry geom, Vec2d cursor, MvtLayerProps layerProps, IUserDataConverter userDataConverter) {
    // Guard: UNKNOWN Geometry
    final VectorTile.Tile.GeomType mvtGeomType = JtsAdapter.toGeomType(geom);
    if (mvtGeomType == VectorTile.Tile.GeomType.UNKNOWN) {
        return null;
    }
    final VectorTile.Tile.Feature.Builder featureBuilder = VectorTile.Tile.Feature.newBuilder();
    final boolean mvtClosePath = MvtUtil.shouldClosePath(mvtGeomType);
    final List<Integer> mvtGeom = new ArrayList<>();
    featureBuilder.setType(mvtGeomType);
    if (geom instanceof Point || geom instanceof MultiPoint) {
        // Encode as MVT point or multipoint
        mvtGeom.addAll(ptsToGeomCmds(geom, cursor));
    } else if (geom instanceof LineString || geom instanceof MultiLineString) {
        // Encode as MVT linestring or multi-linestring
        for (int i = 0; i < geom.getNumGeometries(); ++i) {
            mvtGeom.addAll(linesToGeomCmds(geom.getGeometryN(i), mvtClosePath, cursor, 1));
        }
    } else if (geom instanceof MultiPolygon || geom instanceof Polygon) {
        // Encode as MVT polygon or multi-polygon
        for (int i = 0; i < geom.getNumGeometries(); ++i) {
            final Polygon nextPoly = (Polygon) geom.getGeometryN(i);
            boolean valid = true;
            // Add exterior ring
            final LineString exteriorRing = nextPoly.getExteriorRing();
            // Area must be non-zero
            final double exteriorArea = CGAlgorithms.signedArea(exteriorRing.getCoordinates());
            if (((int) Math.round(exteriorArea)) == 0) {
                continue;
            }
            // Check CCW Winding (must be positive area)
            if (exteriorArea < 0d) {
                CoordinateArrays.reverse(exteriorRing.getCoordinates());
            }
            final List<Integer> nextPolyGeom = new ArrayList<>(linesToGeomCmds(exteriorRing, mvtClosePath, cursor, 2));
            // Add interior rings
            for (int ringIndex = 0; ringIndex < nextPoly.getNumInteriorRing(); ++ringIndex) {
                final LineString nextInteriorRing = nextPoly.getInteriorRingN(ringIndex);
                // Area must be non-zero
                final double interiorArea = CGAlgorithms.signedArea(nextInteriorRing.getCoordinates());
                if (((int) Math.round(interiorArea)) == 0) {
                    continue;
                }
                // Check CW Winding (must be negative area)
                if (interiorArea > 0d) {
                    CoordinateArrays.reverse(nextInteriorRing.getCoordinates());
                }
                // Interior ring area must be < exterior ring area, or entire geometry is invalid
                if (Math.abs(exteriorArea) <= Math.abs(interiorArea)) {
                    valid = false;
                    break;
                }
                nextPolyGeom.addAll(linesToGeomCmds(nextInteriorRing, mvtClosePath, cursor, 2));
            }
            if (valid) {
                mvtGeom.addAll(nextPolyGeom);
            }
        }
    }
    if (mvtGeom.size() < 1) {
        return null;
    }
    featureBuilder.addAllGeometry(mvtGeom);
    // Feature Properties
    userDataConverter.addTags(geom.getUserData(), layerProps, featureBuilder);
    return featureBuilder.build();
}
Also used : MultiPoint(com.vividsolutions.jts.geom.MultiPoint) MultiLineString(com.vividsolutions.jts.geom.MultiLineString) ArrayList(java.util.ArrayList) VectorTile(net.osmand.binary.VectorTile) Point(com.vividsolutions.jts.geom.Point) MultiPoint(com.vividsolutions.jts.geom.MultiPoint) Point(com.vividsolutions.jts.geom.Point) MultiPoint(com.vividsolutions.jts.geom.MultiPoint) LineString(com.vividsolutions.jts.geom.LineString) MultiLineString(com.vividsolutions.jts.geom.MultiLineString) MultiPolygon(com.vividsolutions.jts.geom.MultiPolygon) VectorTile(net.osmand.binary.VectorTile) MultiPolygon(com.vividsolutions.jts.geom.MultiPolygon) Polygon(com.vividsolutions.jts.geom.Polygon)

Example 74 with Point

use of com.vividsolutions.jts.geom.Point in project OsmAnd by osmandapp.

the class MvtReader method readPolys.

/**
 * Create {@link Polygon} or {@link MultiPolygon} from MVT geometry drawing commands.
 *
 * @param geomFactory    creates JTS geometry
 * @param geomCmds       contains MVT geometry commands
 * @param cursor         contains current MVT extent position
 * @param ringClassifier
 * @return JTS geometry or null on failure
 */
private static Geometry readPolys(GeometryFactory geomFactory, List<Integer> geomCmds, Vec2d cursor, RingClassifier ringClassifier) {
    // Guard: must have header
    if (geomCmds.isEmpty()) {
        return null;
    }
    /**
     * Geometry command index
     */
    int i = 0;
    int cmdHdr;
    int cmdLength;
    GeomCmd cmd;
    List<LinearRing> rings = new ArrayList<>(1);
    CoordinateSequence nextCoordSeq;
    Coordinate nextCoord;
    while (i <= geomCmds.size() - MIN_POLYGON_LEN) {
        // --------------------------------------------
        // Expected: MoveTo command of length 1
        // --------------------------------------------
        // Read command header
        cmdHdr = geomCmds.get(i++);
        cmdLength = GeomCmdHdr.getCmdLength(cmdHdr);
        cmd = GeomCmdHdr.getCmd(cmdHdr);
        // Guard: command type and length
        if (cmd != GeomCmd.MoveTo || cmdLength != 1) {
            break;
        }
        // Update cursor position with relative move
        cursor.add(ZigZag.decode(geomCmds.get(i++)), ZigZag.decode(geomCmds.get(i++)));
        // --------------------------------------------
        // Expected: LineTo command of length > 1
        // --------------------------------------------
        // Read command header
        cmdHdr = geomCmds.get(i++);
        cmdLength = GeomCmdHdr.getCmdLength(cmdHdr);
        cmd = GeomCmdHdr.getCmd(cmdHdr);
        // Guard: command type and length
        if (cmd != GeomCmd.LineTo || cmdLength < 2) {
            break;
        }
        // (require at least (2 values * 2 params) + (current index 'i') + (1 for ClosePath))
        if ((cmdLength * GeomCmd.LineTo.getParamCount()) + i + 1 > geomCmds.size()) {
            break;
        }
        nextCoordSeq = geomFactory.getCoordinateSequenceFactory().create(2 + cmdLength, 2);
        // Set first point from MoveTo command
        nextCoord = nextCoordSeq.getCoordinate(0);
        nextCoord.setOrdinate(0, cursor.x);
        nextCoord.setOrdinate(1, cursor.y);
        // Set remaining points from LineTo command
        for (int lineToIndex = 0; lineToIndex < cmdLength; ++lineToIndex) {
            // Update cursor position with relative line delta
            cursor.add(ZigZag.decode(geomCmds.get(i++)), ZigZag.decode(geomCmds.get(i++)));
            nextCoord = nextCoordSeq.getCoordinate(lineToIndex + 1);
            nextCoord.setOrdinate(0, cursor.x);
            nextCoord.setOrdinate(1, cursor.y);
        }
        // --------------------------------------------
        // Expected: ClosePath command of length 1
        // --------------------------------------------
        // Read command header
        cmdHdr = geomCmds.get(i++);
        cmdLength = GeomCmdHdr.getCmdLength(cmdHdr);
        cmd = GeomCmdHdr.getCmd(cmdHdr);
        if (cmd != GeomCmd.ClosePath || cmdLength != 1) {
            break;
        }
        // Set last point from ClosePath command
        nextCoord = nextCoordSeq.getCoordinate(nextCoordSeq.size() - 1);
        nextCoord.setOrdinate(0, nextCoordSeq.getOrdinate(0, 0));
        nextCoord.setOrdinate(1, nextCoordSeq.getOrdinate(0, 1));
        rings.add(geomFactory.createLinearRing(nextCoordSeq));
    }
    // Classify rings
    final List<Polygon> polygons = ringClassifier.classifyRings(rings, geomFactory);
    if (polygons.size() < 1) {
        return null;
    } else if (polygons.size() == 1) {
        return polygons.get(0);
    } else {
        return geomFactory.createMultiPolygon(polygons.toArray(new Polygon[0]));
    }
}
Also used : CoordinateSequence(com.vividsolutions.jts.geom.CoordinateSequence) Coordinate(com.vividsolutions.jts.geom.Coordinate) ArrayList(java.util.ArrayList) GeomCmd(com.wdtinc.mapbox_vector_tile.encoding.GeomCmd) LinearRing(com.vividsolutions.jts.geom.LinearRing) MultiPolygon(com.vividsolutions.jts.geom.MultiPolygon) Polygon(com.vividsolutions.jts.geom.Polygon) Point(com.vividsolutions.jts.geom.Point) MultiPoint(com.vividsolutions.jts.geom.MultiPoint)

Example 75 with Point

use of com.vividsolutions.jts.geom.Point in project OsmAnd by osmandapp.

the class MapillaryVectorLayer method getImagesFromPoint.

private void getImagesFromPoint(RotatedTileBox tb, PointF point, List<? super MapillaryImage> images) {
    Map<QuadPointDouble, Map<?, ?>> points = this.visiblePoints;
    float ex = point.x;
    float ey = point.y;
    final int rp = getRadius(tb);
    int radius = rp * 3 / 2;
    float x, y;
    double minSqDist = Double.NaN;
    double sqDist;
    MapillaryImage img = null;
    for (Entry<QuadPointDouble, Map<?, ?>> entry : points.entrySet()) {
        double tileX = entry.getKey().x;
        double tileY = entry.getKey().y;
        Map<?, ?> userData = entry.getValue();
        PointF pixel = NativeUtilities.getPixelFromLatLon(getMapRenderer(), tb, MapUtils.getLatitudeFromTile(MIN_IMAGE_LAYER_ZOOM, tileY), MapUtils.getLongitudeFromTile(MIN_IMAGE_LAYER_ZOOM, tileX));
        x = pixel.x;
        y = pixel.y;
        if (Math.abs(x - ex) <= radius && Math.abs(y - ey) <= radius) {
            sqDist = (x - ex) * (x - ex) + (y - ey) * (y - ey);
            if (img == null || minSqDist > sqDist) {
                minSqDist = sqDist;
                double lat = MapUtils.getLatitudeFromTile(MIN_IMAGE_LAYER_ZOOM, tileY);
                double lon = MapUtils.getLongitudeFromTile(MIN_IMAGE_LAYER_ZOOM, tileX);
                img = new MapillaryImage(lat, lon);
                if (!img.setData(userData)) {
                    img = null;
                }
            }
        }
    }
    if (img != null) {
        images.add(img);
    }
}
Also used : PointF(android.graphics.PointF) HashMap(java.util.HashMap) Map(java.util.Map) Point(com.vividsolutions.jts.geom.Point) Paint(android.graphics.Paint) QuadPointDouble(net.osmand.data.QuadPointDouble)

Aggregations

Point (com.vividsolutions.jts.geom.Point)157 Geometry (com.vividsolutions.jts.geom.Geometry)53 MultiPoint (com.vividsolutions.jts.geom.MultiPoint)49 Coordinate (com.vividsolutions.jts.geom.Coordinate)46 ArrayList (java.util.ArrayList)27 Polygon (com.vividsolutions.jts.geom.Polygon)26 LineString (com.vividsolutions.jts.geom.LineString)25 SamplePoint (org.datanucleus.samples.jtsgeometry.SamplePoint)22 List (java.util.List)20 PersistenceManager (javax.jdo.PersistenceManager)19 Transaction (javax.jdo.Transaction)19 MultiLineString (com.vividsolutions.jts.geom.MultiLineString)18 Query (javax.jdo.Query)17 Test (org.junit.Test)17 MultiPolygon (com.vividsolutions.jts.geom.MultiPolygon)15 HashMap (java.util.HashMap)15 GeometryFactory (com.vividsolutions.jts.geom.GeometryFactory)12 QuadPointDouble (net.osmand.data.QuadPointDouble)12 GeometryCollection (com.vividsolutions.jts.geom.GeometryCollection)10 LinearRing (com.vividsolutions.jts.geom.LinearRing)10