Search in sources :

Example 1 with Vec2d

use of com.wdtinc.mapbox_vector_tile.util.Vec2d in project Osmand by osmandapp.

the class JtsAdapter method ptsToGeomCmds.

/**
 * <p>Convert a {@link Point} or {@link MultiPoint} geometry to a list of MVT geometry drawing commands. See
 * <a href="https://github.com/mapbox/vector-tile-spec">vector-tile-spec</a>
 * for details.</p>
 *
 * <p>WARNING: The value of the {@code cursor} parameter is modified as a result of calling this method.</p>
 *
 * @param geom input of type {@link Point} or {@link MultiPoint}. Type is NOT checked and expected to be correct.
 * @param cursor modified during processing to contain next MVT cursor position
 * @return list of commands
 */
private static List<Integer> ptsToGeomCmds(final Geometry geom, final Vec2d cursor) {
    // Guard: empty geometry coordinates
    final Coordinate[] geomCoords = geom.getCoordinates();
    if (geomCoords.length <= 0) {
        Collections.emptyList();
    }
    /**
     * Tile commands and parameters
     */
    final List<Integer> geomCmds = new ArrayList<>(geomCmdBuffLenPts(geomCoords.length));
    /**
     * Holds next MVT coordinate
     */
    final Vec2d mvtPos = new Vec2d();
    /**
     * Length of 'MoveTo' draw command
     */
    int moveCmdLen = 0;
    // Insert placeholder for 'MoveTo' command header
    geomCmds.add(0);
    Coordinate nextCoord;
    for (int i = 0; i < geomCoords.length; ++i) {
        nextCoord = geomCoords[i];
        mvtPos.set(nextCoord.x, nextCoord.y);
        // Ignore duplicate MVT points
        if (i == 0 || !equalAsInts(cursor, mvtPos)) {
            ++moveCmdLen;
            moveCursor(cursor, geomCmds, mvtPos);
        }
    }
    if (moveCmdLen <= GeomCmdHdr.CMD_HDR_LEN_MAX) {
        // Write 'MoveTo' command header to first index
        geomCmds.set(0, GeomCmdHdr.cmdHdr(GeomCmd.MoveTo, moveCmdLen));
        return geomCmds;
    } else {
        // Invalid geometry, need at least 1 'MoveTo' value to make points
        return Collections.emptyList();
    }
}
Also used : Coordinate(com.vividsolutions.jts.geom.Coordinate) ArrayList(java.util.ArrayList) Vec2d(com.wdtinc.mapbox_vector_tile.util.Vec2d) Point(com.vividsolutions.jts.geom.Point) MultiPoint(com.vividsolutions.jts.geom.MultiPoint)

Example 2 with Vec2d

use of com.wdtinc.mapbox_vector_tile.util.Vec2d in project Osmand by osmandapp.

the class JtsAdapter method linesToGeomCmds.

/**
 * <p>Convert a {@link LineString} or {@link Polygon} to a list of MVT geometry drawing commands.
 * A {@link MultiLineString} or {@link MultiPolygon} can be encoded by calling this method multiple times.</p>
 *
 * <p>See <a href="https://github.com/mapbox/vector-tile-spec">vector-tile-spec</a> for details.</p>
 *
 * <p>WARNING: The value of the {@code cursor} parameter is modified as a result of calling this method.</p>
 *
 * @param geom input of type {@link LineString} or {@link Polygon}. Type is NOT checked and expected to be correct.
 * @param closeEnabled whether a 'ClosePath' command should terminate the command list
 * @param cursor modified during processing to contain next MVT cursor position
 * @param minLineToLen minimum allowed length for LineTo command.
 * @return list of commands
 */
private static List<Integer> linesToGeomCmds(final Geometry geom, final boolean closeEnabled, final Vec2d cursor, final int minLineToLen) {
    final Coordinate[] geomCoords = geom.getCoordinates();
    // Check geometry for repeated end points
    final int repeatEndCoordCount = countCoordRepeatReverse(geomCoords);
    final int minExpGeomCoords = geomCoords.length - repeatEndCoordCount;
    // Guard/Optimization: Not enough geometry coordinates for a line
    if (minExpGeomCoords < 2) {
        Collections.emptyList();
    }
    /**
     * Tile commands and parameters
     */
    final List<Integer> geomCmds = new ArrayList<>(geomCmdBuffLenLines(minExpGeomCoords, closeEnabled));
    /**
     * Holds next MVT coordinate
     */
    final Vec2d mvtPos = new Vec2d();
    // Initial coordinate
    Coordinate nextCoord = geomCoords[0];
    mvtPos.set(nextCoord.x, nextCoord.y);
    // Encode initial 'MoveTo' command
    geomCmds.add(GeomCmdHdr.cmdHdr(GeomCmd.MoveTo, 1));
    moveCursor(cursor, geomCmds, mvtPos);
    /**
     * Index of 'LineTo' 'command header'
     */
    final int lineToCmdHdrIndex = geomCmds.size();
    // Insert placeholder for 'LineTo' command header
    geomCmds.add(0);
    /**
     * Length of 'LineTo' draw command
     */
    int lineToLength = 0;
    for (int i = 1; i < minExpGeomCoords; ++i) {
        nextCoord = geomCoords[i];
        mvtPos.set(nextCoord.x, nextCoord.y);
        // Ignore duplicate MVT points in sequence
        if (!equalAsInts(cursor, mvtPos)) {
            ++lineToLength;
            moveCursor(cursor, geomCmds, mvtPos);
        }
    }
    if (lineToLength >= minLineToLen && lineToLength <= GeomCmdHdr.CMD_HDR_LEN_MAX) {
        // Write 'LineTo' 'command header'
        geomCmds.set(lineToCmdHdrIndex, GeomCmdHdr.cmdHdr(GeomCmd.LineTo, lineToLength));
        if (closeEnabled) {
            geomCmds.add(GeomCmdHdr.closePathCmdHdr());
        }
        return geomCmds;
    } else {
        // Invalid geometry, need at least 1 'LineTo' value to make a Multiline or Polygon
        return Collections.emptyList();
    }
}
Also used : Coordinate(com.vividsolutions.jts.geom.Coordinate) ArrayList(java.util.ArrayList) Vec2d(com.wdtinc.mapbox_vector_tile.util.Vec2d) Point(com.vividsolutions.jts.geom.Point) MultiPoint(com.vividsolutions.jts.geom.MultiPoint)

Example 3 with Vec2d

use of com.wdtinc.mapbox_vector_tile.util.Vec2d in project Osmand by osmandapp.

the class JtsAdapter method toFeatures.

/**
 * <p>Convert a flat list of JTS {@link Geometry} to a list of vector tile features.
 * The Geometry should be in MVT coordinates.</p>
 *
 * <p>Each geometry will have its own ID.</p>
 *
 * @param flatGeoms flat list of JTS geometry to convert
 * @param layerProps layer properties for tagging features
 * @param userDataConverter convert {@link Geometry#userData} to MVT feature tags
 * @see #flatFeatureList(Geometry)
 * @see #createTileGeom(Geometry, Envelope, GeometryFactory, MvtLayerParams, IGeometryFilter)
 */
public static List<VectorTile.Tile.Feature> toFeatures(Collection<Geometry> flatGeoms, MvtLayerProps layerProps, IUserDataConverter userDataConverter) {
    // Guard: empty geometry
    if (flatGeoms.isEmpty()) {
        return Collections.emptyList();
    }
    final List<VectorTile.Tile.Feature> features = new ArrayList<>();
    final Vec2d cursor = new Vec2d();
    VectorTile.Tile.Feature nextFeature;
    for (Geometry nextGeom : flatGeoms) {
        cursor.set(0d, 0d);
        nextFeature = toFeature(nextGeom, cursor, layerProps, userDataConverter);
        if (nextFeature != null) {
            features.add(nextFeature);
        }
    }
    return features;
}
Also used : Geometry(com.vividsolutions.jts.geom.Geometry) ArrayList(java.util.ArrayList) VectorTile(net.osmand.binary.VectorTile) VectorTile(net.osmand.binary.VectorTile) Vec2d(com.wdtinc.mapbox_vector_tile.util.Vec2d)

Example 4 with Vec2d

use of com.wdtinc.mapbox_vector_tile.util.Vec2d in project Osmand by osmandapp.

the class MvtReader method loadMvt.

/**
 * Load an MVT to JTS geometries using coordinates. Uses {@code tagConverter} to create user data
 * from feature properties.
 *
 * @param is             stream with MVT data
 * @param geomFactory    allows for JTS geometry creation
 * @param tagConverter   converts MVT feature tags to JTS user data object.
 * @param ringClassifier determines how rings are parsed into Polygons and MultiPolygons
 * @return JTS geometries in using MVT coordinates
 * @throws IOException failure reading MVT from stream
 * @see Geometry
 * @see Geometry#getUserData()
 * @see RingClassifier
 */
public static List<Geometry> loadMvt(InputStream is, GeometryFactory geomFactory, ITagConverter tagConverter, RingClassifier ringClassifier) throws IOException {
    final List<Geometry> tileGeoms = new ArrayList<>();
    final VectorTile.Tile mvt = VectorTile.Tile.parseFrom(is);
    final Vec2d cursor = new Vec2d();
    for (VectorTile.Tile.Layer nextLayer : mvt.getLayersList()) {
        final List<String> keysList = nextLayer.getKeysList();
        final List<VectorTile.Tile.Value> valuesList = nextLayer.getValuesList();
        for (VectorTile.Tile.Feature nextFeature : nextLayer.getFeaturesList()) {
            final Long id = nextFeature.hasId() ? nextFeature.getId() : null;
            final VectorTile.Tile.GeomType geomType = nextFeature.getType();
            if (geomType == VectorTile.Tile.GeomType.UNKNOWN) {
                continue;
            }
            final List<Integer> geomCmds = nextFeature.getGeometryList();
            cursor.set(0d, 0d);
            final Geometry nextGeom = readGeometry(geomCmds, geomType, geomFactory, cursor, ringClassifier);
            if (nextGeom != null) {
                tileGeoms.add(nextGeom);
                nextGeom.setUserData(tagConverter.toUserData(id, nextFeature.getTagsList(), keysList, valuesList));
            }
        }
    }
    return tileGeoms;
}
Also used : ArrayList(java.util.ArrayList) VectorTile(net.osmand.binary.VectorTile) LineString(com.vividsolutions.jts.geom.LineString) MultiLineString(com.vividsolutions.jts.geom.MultiLineString) Vec2d(com.wdtinc.mapbox_vector_tile.util.Vec2d) Geometry(com.vividsolutions.jts.geom.Geometry) VectorTile(net.osmand.binary.VectorTile)

Aggregations

Vec2d (com.wdtinc.mapbox_vector_tile.util.Vec2d)4 ArrayList (java.util.ArrayList)4 Coordinate (com.vividsolutions.jts.geom.Coordinate)2 Geometry (com.vividsolutions.jts.geom.Geometry)2 MultiPoint (com.vividsolutions.jts.geom.MultiPoint)2 Point (com.vividsolutions.jts.geom.Point)2 VectorTile (net.osmand.binary.VectorTile)2 LineString (com.vividsolutions.jts.geom.LineString)1 MultiLineString (com.vividsolutions.jts.geom.MultiLineString)1