Search in sources :

Example 1 with AffineTransformation

use of com.vividsolutions.jts.geom.util.AffineTransformation in project spatial-portal by AtlasOfLivingAustralia.

the class Util method fixWkt.

public static String fixWkt(String wkt) {
    if (wkt == null || !(wkt.startsWith("POLYGON") || wkt.startsWith("MULTIPOLYGON"))) {
        return wkt;
    }
    String newWkt = wkt;
    try {
        WKTReader wktReader = new WKTReader();
        com.vividsolutions.jts.geom.Geometry g = wktReader.read(wkt);
        // NC 20130319: Ensure that the WKT is valid according to the WKT standards.
        // if outside -180 to 180, cut and fit
        Envelope env = g.getEnvelopeInternal();
        if (env.getMinX() < -180 || env.getMaxX() > 180) {
            int minx = -180;
            while (minx > env.getMinX()) {
                minx -= 360;
            }
            int maxx = 180;
            while (maxx < env.getMaxX()) {
                maxx += 360;
            }
            // divide, translate and rejoin
            Geometry newGeometry = null;
            for (int i = minx; i < maxx; i += 360) {
                Geometry cutter = wktReader.read("POLYGON((" + i + " -90," + i + " 90," + (i + 360) + " 90," + (i + 360) + " -90," + i + " -90))");
                Geometry part = cutter.intersection(g);
                // offset cutter
                if (i != -180) {
                    AffineTransformation at = AffineTransformation.translationInstance(-180 - i, 0);
                    part.apply(at);
                }
                if (part.getArea() > 0) {
                    if (newGeometry == null) {
                        newGeometry = part;
                    } else {
                        newGeometry = newGeometry.union(part);
                    }
                }
            }
            newWkt = newGeometry.toText();
        }
        IsValidOp op = new IsValidOp(g);
        if (!op.isValid()) {
            // this will fix some issues
            g = g.buffer(0);
            op = new IsValidOp(g);
        }
        if (!op.isValid()) {
        // give up?
        } else if (g.isRectangle()) {
            // NC 20130319: When the shape is a rectangle ensure that the points a specified in the correct order.
            // get the new WKT for the rectangle will possibly need to change the order.
            com.vividsolutions.jts.geom.Envelope envelope = g.getEnvelopeInternal();
            newWkt = StringConstants.POLYGON + "((" + envelope.getMinX() + " " + envelope.getMinY() + "," + envelope.getMaxX() + " " + envelope.getMinY() + "," + envelope.getMaxX() + " " + envelope.getMaxY() + "," + envelope.getMinX() + " " + envelope.getMaxY() + "," + envelope.getMinX() + " " + envelope.getMinY() + "))";
        }
    } catch (ParseException parseException) {
        LOGGER.error("error fixing WKT", parseException);
    }
    return newWkt;
}
Also used : WKTReader(com.vividsolutions.jts.io.WKTReader) com.vividsolutions.jts.geom(com.vividsolutions.jts.geom) AffineTransformation(com.vividsolutions.jts.geom.util.AffineTransformation) IsValidOp(com.vividsolutions.jts.operation.valid.IsValidOp) ParseException(com.vividsolutions.jts.io.ParseException)

Example 2 with AffineTransformation

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

the class JtsAdapter method createTileGeom.

/**
 * Create geometry clipped and then converted to MVT 'extent' coordinates. Result
 * contains both clipped geometry (intersection) and transformed geometry for encoding to MVT.
 *
 * @param g original 'source' geometry, passed through {@link #flatFeatureList(Geometry)}
 * @param tileEnvelope world coordinate bounds for tile
 * @param geomFactory creates a geometry for the tile envelope
 * @param mvtLayerParams specifies vector tile properties
 * @param filter geometry values that fail filter after transforms are removed
 * @return tile geometry result
 * @see TileGeomResult
 */
public static TileGeomResult createTileGeom(List<Geometry> g, Envelope tileEnvelope, GeometryFactory geomFactory, MvtLayerParams mvtLayerParams, IGeometryFilter filter) {
    final Geometry tileEnvelopeGeom = geomFactory.toGeometry(tileEnvelope);
    final AffineTransformation t = new AffineTransformation();
    final double xDiff = tileEnvelope.getWidth();
    final double yDiff = tileEnvelope.getHeight();
    final double xOffset = -tileEnvelope.getMinX();
    final double yOffset = -tileEnvelope.getMinY();
    // Transform Setup: Shift to 0 as minimum value
    t.translate(xOffset, yOffset);
    // Transform Setup: Scale X and Y to tile extent values, flip Y values
    t.scale(1d / (xDiff / (double) mvtLayerParams.extent), -1d / (yDiff / (double) mvtLayerParams.extent));
    // Transform Setup: Bump Y values to positive quadrant
    t.translate(0d, (double) mvtLayerParams.extent);
    // The area contained in BOTH the 'original geometry', g, AND the 'tile envelope geometry' is the 'tile geometry'
    final List<Geometry> intersectedGeoms = flatIntersection(tileEnvelopeGeom, g);
    final List<Geometry> transformedGeoms = new ArrayList<>(intersectedGeoms.size());
    // Transform intersected geometry
    Geometry nextTransformGeom;
    Object nextUserData;
    for (Geometry nextInterGeom : intersectedGeoms) {
        nextUserData = nextInterGeom.getUserData();
        nextTransformGeom = t.transform(nextInterGeom);
        // Floating --> Integer, still contained within doubles
        nextTransformGeom.apply(RoundingFilter.INSTANCE);
        // TODO: Refactor line simplification
        // Can't use 0d, specify value < .5d
        nextTransformGeom = TopologyPreservingSimplifier.simplify(nextTransformGeom, .1d);
        nextTransformGeom.setUserData(nextUserData);
        // Apply filter on transformed geometry
        if (filter.accept(nextTransformGeom)) {
            transformedGeoms.add(nextTransformGeom);
        }
    }
    return new TileGeomResult(intersectedGeoms, transformedGeoms);
}
Also used : Geometry(com.vividsolutions.jts.geom.Geometry) AffineTransformation(com.vividsolutions.jts.geom.util.AffineTransformation) ArrayList(java.util.ArrayList)

Example 3 with AffineTransformation

use of com.vividsolutions.jts.geom.util.AffineTransformation in project OpenTripPlanner by opentripplanner.

the class TileRendererManager method renderTile.

public BufferedImage renderTile(final TileRequest tileRequest, String layer) {
    TileRenderContext context = new TileRenderContext() {

        @Override
        public Envelope expandPixels(double marginXPixels, double marginYPixels) {
            Envelope retval = new Envelope(bbox);
            retval.expandBy(marginXPixels / tileRequest.width * (bbox.getMaxX() - bbox.getMinX()), marginYPixels / tileRequest.height * (bbox.getMaxY() - bbox.getMinY()));
            return retval;
        }
    };
    context.graph = graph;
    TileRenderer renderer = renderers.get(layer);
    if (renderer == null)
        throw new IllegalArgumentException("Unknown layer: " + layer);
    // The best place for caching tiles may be here
    BufferedImage image = new BufferedImage(tileRequest.width, tileRequest.height, renderer.getColorModel());
    context.graphics = image.createGraphics();
    Envelope2D trbb = tileRequest.bbox;
    context.bbox = new Envelope(trbb.x, trbb.x + trbb.width, trbb.y, trbb.y + trbb.height);
    context.transform = new AffineTransformation();
    double xScale = tileRequest.width / trbb.width;
    double yScale = tileRequest.height / trbb.height;
    context.transform.translate(-trbb.x, -trbb.y - trbb.height);
    context.transform.scale(xScale, -yScale);
    context.metersPerPixel = Math.toRadians(trbb.height) * 6371000 / tileRequest.height;
    context.tileWidth = tileRequest.width;
    context.tileHeight = tileRequest.height;
    long start = System.currentTimeMillis();
    renderer.renderTile(context);
    LOG.debug("Rendered tile at {},{} in {} ms", tileRequest.bbox.y, tileRequest.bbox.x, System.currentTimeMillis() - start);
    return image;
}
Also used : TileRenderContext(org.opentripplanner.inspector.TileRenderer.TileRenderContext) AffineTransformation(com.vividsolutions.jts.geom.util.AffineTransformation) Envelope(com.vividsolutions.jts.geom.Envelope) Envelope2D(org.geotools.geometry.Envelope2D) BufferedImage(java.awt.image.BufferedImage)

Aggregations

AffineTransformation (com.vividsolutions.jts.geom.util.AffineTransformation)3 com.vividsolutions.jts.geom (com.vividsolutions.jts.geom)1 Envelope (com.vividsolutions.jts.geom.Envelope)1 Geometry (com.vividsolutions.jts.geom.Geometry)1 ParseException (com.vividsolutions.jts.io.ParseException)1 WKTReader (com.vividsolutions.jts.io.WKTReader)1 IsValidOp (com.vividsolutions.jts.operation.valid.IsValidOp)1 BufferedImage (java.awt.image.BufferedImage)1 ArrayList (java.util.ArrayList)1 Envelope2D (org.geotools.geometry.Envelope2D)1 TileRenderContext (org.opentripplanner.inspector.TileRenderer.TileRenderContext)1