/******************************************************************************* * Copyright (c) 2015 Voyager Search and MITRE * All rights reserved. This program and the accompanying materials * are made available under the terms of the Apache License, Version 2.0 which * accompanies this distribution and is available at * http://www.apache.org/licenses/LICENSE-2.0.txt ******************************************************************************/ package org.locationtech.spatial4j.context.jts; import org.locationtech.spatial4j.context.SpatialContext; import org.locationtech.spatial4j.io.ShapeReader; import org.locationtech.spatial4j.shape.Rectangle; import org.locationtech.spatial4j.shape.Shape; import org.locationtech.spatial4j.shape.jts.JtsGeometry; import org.locationtech.spatial4j.shape.jts.JtsPoint; import org.locationtech.spatial4j.shape.jts.JtsShapeFactory; import com.vividsolutions.jts.geom.*; import java.util.List; /** * Enhances the default {@link SpatialContext} with support for Polygons (and * other geometries) using <a href="https://sourceforge.net/projects/jts-topo-suite/">JTS</a>. * To the extent possible, our {@link JtsGeometry} adds some amount of geodetic support over * vanilla JTS which only has a Euclidean (flat plane) model. */ public class JtsSpatialContext extends SpatialContext { public static final JtsSpatialContext GEO; static { JtsSpatialContextFactory factory = new JtsSpatialContextFactory(); factory.geo = true; GEO = new JtsSpatialContext(factory); } /** * Called by {@link org.locationtech.spatial4j.context.jts.JtsSpatialContextFactory#newSpatialContext()}. */ public JtsSpatialContext(JtsSpatialContextFactory factory) { super(factory); } // TODO I expect to delete this eventually once the other deprecated methods in this class disappear @Override public JtsShapeFactory getShapeFactory() { return (JtsShapeFactory) super.getShapeFactory(); } /** * If geom might be a multi geometry of some kind, then might multiple * component geometries overlap? Strict OGC says this is invalid but we * can accept it by computing the union. Note: Our ShapeCollection mostly * doesn't care but it has a method related to this * {@link org.locationtech.spatial4j.shape.ShapeCollection#relateContainsShortCircuits()}. */ @Deprecated public boolean isAllowMultiOverlap() { return getShapeFactory().isAllowMultiOverlap(); } /** * Returns the rule used to handle geometry objects that have dateline crossing considerations. */ @Deprecated public DatelineRule getDatelineRule() { return getShapeFactory().getDatelineRule(); } /** * Returns the rule used to handle errors when creating a JTS {@link Geometry}, particularly after it has been * read from one of the {@link ShapeReader}s. */ @Deprecated public ValidationRule getValidationRule() { return getShapeFactory().getValidationRule(); } /** * If JtsGeometry shapes should be automatically "prepared" (i.e. optimized) when read via from a {@link ShapeReader}. * * @see org.locationtech.spatial4j.shape.jts.JtsGeometry#index() */ @Deprecated public boolean isAutoIndex() { return getShapeFactory().isAutoIndex(); } /** * Gets a JTS {@link Geometry} for the given {@link Shape}. Some shapes hold a * JTS geometry whereas new ones must be created for the rest. * @param shape Not null * @return Not null */ @Deprecated public Geometry getGeometryFrom(Shape shape) { return getShapeFactory().getGeometryFrom(shape); } /** Should {@link #makePoint(double, double)} return {@link JtsPoint}? */ @Deprecated public boolean useJtsPoint() { return getShapeFactory().useJtsPoint(); } /** Should {@link #makeLineString(java.util.List)} return {@link JtsGeometry}? */ @Deprecated public boolean useJtsLineString() { return getShapeFactory().useJtsLineString(); } /** * INTERNAL Usually creates a JtsGeometry, potentially validating, repairing, and indexing ("preparing"). This method * is intended for use by {@link ShapeReader} instances. * * If given a direct instance of {@link GeometryCollection} then it's contents will be * recursively converted and then the resulting list will be passed to * {@link SpatialContext#makeCollection(List)} and returned. * * If given a {@link com.vividsolutions.jts.geom.Point} then {@link SpatialContext#makePoint(double, double)} * is called, which will return a {@link JtsPoint} if {@link JtsSpatialContext#useJtsPoint()}; otherwise * a standard Spatial4j Point is returned. * * If given a {@link LineString} and if {@link JtsSpatialContext#useJtsLineString()} is true then * then the geometry's parts are exposed to call {@link SpatialContext#makeLineString(List)}. */ @Deprecated public Shape makeShapeFromGeometry(Geometry geom) { return getShapeFactory().makeShapeFromGeometry(geom); } /** * INTERNAL * @see #makeShape(com.vividsolutions.jts.geom.Geometry) * * @param geom Non-null * @param dateline180Check if both this is true and {@link #isGeo()}, then JtsGeometry will check * for adjacent coordinates greater than 180 degrees longitude apart, and * it will do tricks to make that line segment (and the shape as a whole) * cross the dateline even though JTS doesn't have geodetic support. * @param allowMultiOverlap See {@link #isAllowMultiOverlap()}. */ @Deprecated public JtsGeometry makeShape(Geometry geom, boolean dateline180Check, boolean allowMultiOverlap) { return getShapeFactory().makeShape(geom, dateline180Check, allowMultiOverlap); } /** * INTERNAL: Creates a {@link Shape} from a JTS {@link Geometry}. Generally, this shouldn't be * called when one of the other factory methods are available, such as for points. The caller * needs to have done some verification/normalization of the coordinates by now, if any. Also, * note that direct instances of {@link GeometryCollection} isn't supported. * * Instead of calling this method, consider {@link JtsShapeFactory#makeShapeFromGeometry(Geometry)} * which */ @Deprecated public JtsGeometry makeShape(Geometry geom) { return getShapeFactory().makeShape(geom); } @Deprecated public GeometryFactory getGeometryFactory() { return getShapeFactory().getGeometryFactory(); } @Override public String toString() { if (this.equals(GEO)) { return GEO.getClass().getSimpleName()+".GEO"; } else { return super.toString(); } } /** * INTERNAL: Returns a Rectangle of the JTS {@link Envelope} (bounding box) of the given {@code geom}. This asserts * that {@link Geometry#isRectangle()} is true. This method reacts to the {@link DatelineRule} setting. * @param geom non-null * @return null equivalent Rectangle. */ @Deprecated public Rectangle makeRectFromRectangularPoly(Geometry geom) { return getShapeFactory().makeRectFromRectangularPoly(geom); } }