/* (c) 2016 Open Source Geospatial Foundation - all rights reserved * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geogig.geoserver.gwc; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.CoordinateFilter; import com.vividsolutions.jts.geom.CoordinateSequence; import com.vividsolutions.jts.geom.CoordinateSequenceFilter; import com.vividsolutions.jts.geom.Dimension; import com.vividsolutions.jts.geom.Envelope; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryComponentFilter; import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.GeometryFilter; import com.vividsolutions.jts.geom.MultiPoint; import com.vividsolutions.jts.geom.Point; import com.vividsolutions.jts.geom.PrecisionModel; import com.vividsolutions.jts.geom.impl.PackedCoordinateSequenceFactory; /** * A growable {@link MultiPoint} that saves all points in a single * {@link GrowableCoordinateSequence} */ class CompactMultiPoint extends MultiPoint { private static final long serialVersionUID = 1L; public static final GeometryFactory GEOM_FACTORY = new GeometryFactory(new PrecisionModel(1E6), 0, new PackedCoordinateSequenceFactory(PackedCoordinateSequenceFactory.FLOAT)); private final GrowableCoordinateSequence coordSeq; public CompactMultiPoint() { this(new GrowableCoordinateSequence(), new Envelope()); } private CompactMultiPoint(GrowableCoordinateSequence coordSeq, Envelope envelope) { super(new Point[0], GEOM_FACTORY); super.envelope = envelope; this.coordSeq = coordSeq; } public void add(double x, double y) { coordSeq.add(x, y); super.envelope.expandToInclude(x, y); } // /////////////// GeometryCollection overrides /////////////////////// @Override public void apply(CoordinateFilter filter) { final int size = coordSeq.size(); for (int i = 0; i < size; i++) { getGeometryN(i).apply(filter); } } @Override public void apply(CoordinateSequenceFilter filter) { final int size = coordSeq.size(); if (size == 0) { return; } for (int i = 0; i < size; i++) { getGeometryN(i).apply(filter); if (filter.isDone()) { break; } } if (filter.isGeometryChanged()) { geometryChanged(); } } @Override public void apply(GeometryComponentFilter filter) { filter.filter(this); final int size = coordSeq.size(); for (int i = 0; i < size; i++) { getGeometryN(i).apply(filter); } } @Override public void apply(GeometryFilter filter) { filter.filter(this); final int size = coordSeq.size(); for (int i = 0; i < size; i++) { getGeometryN(i).apply(filter); } } @Override public boolean equalsExact(Geometry other, double tolerance) { if (!(other instanceof MultiPoint)) { return false; } if (getNumGeometries() != other.getNumGeometries()) { return false; } for (int i = 0; i < getNumGeometries(); i++) { if (!getGeometryN(i).equalsExact(other.getGeometryN(i), tolerance)) { return false; } } return true; } @Override public Object clone() { return new CompactMultiPoint(coordSeq.clone(), new Envelope(envelope)); } @Override public double getArea() { return 0D; } @Override public boolean isEmpty() { return envelope.isNull(); } @Override public int getDimension() { return 0; } @Override public int getBoundaryDimension() { return Dimension.FALSE; } @Override public Coordinate getCoordinate() { if (isEmpty()) { return null; } return coordSeq.getCoordinate(0); } @Override public Coordinate[] getCoordinates() { return coordSeq.toCoordinateArray(); } @Override public Geometry getGeometryN(int n) { CoordinateSequence subSequence = coordSeq.subSequence(n, n); return GEOM_FACTORY.createPoint(subSequence); } @Override public double getLength() { return 0D; } @Override public int getNumGeometries() { return coordSeq.size(); } @Override public int getNumPoints() { return getNumGeometries(); } @Override public void normalize() { // nothing to do } @Override public Geometry reverse() { // nothing to do return (Geometry) clone(); } // //////////////////// Geometry overrides //////////////////////// @Override public boolean isSimple() { return true; } @Override public boolean isValid() { return true; } }