package com.revolsys.geometry.index.quadtree; import java.util.List; import com.revolsys.collection.map.WeakKeyValueMap; import com.revolsys.geometry.model.BoundingBox; import com.revolsys.geometry.model.Geometry; import com.revolsys.geometry.model.Point; import com.revolsys.geometry.model.coordinates.filter.LineSegmentCoordinateDistanceFilter; import com.revolsys.geometry.model.segment.Segment; import com.revolsys.util.Property; public class GeometrySegmentQuadTree extends IdObjectQuadTree<Segment> { private static final long serialVersionUID = 1L; private static final WeakKeyValueMap<Geometry, GeometrySegmentQuadTree> CACHE = new WeakKeyValueMap<>(); public static GeometrySegmentQuadTree get(final Geometry geometry) { if (Property.hasValue(geometry)) { GeometrySegmentQuadTree index = CACHE.get(geometry); if (index == null) { index = new GeometrySegmentQuadTree(geometry); CACHE.put(geometry, index); } return index; } else { return null; } } private final Geometry geometry; public GeometrySegmentQuadTree(final Geometry geometry) { super(geometry.getGeometryFactory()); this.geometry = geometry; if (geometry != null) { setGeometryFactory(geometry.getGeometryFactory()); for (final Segment segment : geometry.segments()) { final BoundingBox boundingBox = segment.getBoundingBox(); insertItem(boundingBox, segment); } } } @Override protected Object getId(final Segment segment) { return segment.getSegmentId(); } @Override protected Segment getItem(final Object id) { final int[] segmentId = (int[])id; return this.geometry.getSegment(segmentId); } public List<Segment> getWithinDistance(final Point point, final double maxDistance) { BoundingBox boundingBox = point.getBoundingBox(); boundingBox = boundingBox.expand(maxDistance); final LineSegmentCoordinateDistanceFilter filter = new LineSegmentCoordinateDistanceFilter( point, maxDistance); return getItems(boundingBox, filter); } @Override protected boolean intersectsBounds(final Object id, final double x, final double y) { final Segment segment = getItem(id); final BoundingBox boundingBox = segment.getBoundingBox(); return boundingBox.intersects(x, y, x, y); } @Override protected boolean intersectsBounds(final Object id, final double minX, final double minY, final double maxX, final double maxY) { final Segment segment = getItem(id); final BoundingBox boundingBox = segment.getBoundingBox(); return boundingBox.intersects(minX, minY, maxX, maxY); } }