Decimator { public final Geometry decimateTransformGeneralize(Geometry geometry, MathTransform transform) throws TransformException { if (geometry instanceof GeometryCollection) { GeometryCollection collection = (GeometryCollection) geometry; final int length = collection.getNumGeometries(); boolean cloned = false; Class elementType = null; Geometry[] elements = null; for (int i = 0; i < length; i++) { Geometry source = collection.getGeometryN(i); Geometry generalized = decimateTransformGeneralize(source, transform); if(generalized != source) { cloned = true; if(elements == null) { elements = new Geometry[collection.getNumGeometries()]; for (int j = 0; j < i; j++) { Geometry element = collection.getGeometryN(j); elements[j] = element; accumulateGeometryType(elementType, element); } } } if(cloned) { elements[i] = generalized; elementType = accumulateGeometryType(elementType, generalized); } } if(cloned) { if(elementType == Point.class) { Point[] points = new Point[elements.length]; System.arraycopy(elements, 0, points, 0, elements.length); return collection.getFactory().createMultiPoint(points); } else if (elementType == LineString.class) { LineString[] lines = new LineString[elements.length]; System.arraycopy(elements, 0, lines, 0, elements.length); return collection.getFactory().createMultiLineString(lines); } else if (elementType == Polygon.class) { Polygon[] polys = new Polygon[elements.length]; System.arraycopy(elements, 0, polys, 0, elements.length); return collection.getFactory().createMultiPolygon(polys); } else { return collection.getFactory().createGeometryCollection(elements); } } else { return collection; } } else if (geometry instanceof Point) { LiteCoordinateSequence seq = (LiteCoordinateSequence) ((Point) geometry) .getCoordinateSequence(); decimateTransformGeneralize(seq, transform, false, spanx, spany); return geometry; } else if (geometry instanceof Polygon) { Polygon polygon = (Polygon) geometry; LinearRing shell = (LinearRing) decimateTransformGeneralize(polygon.getExteriorRing(), transform); boolean cloned = shell != polygon.getExteriorRing(); final int length = polygon.getNumInteriorRing(); LinearRing[] holes = cloned ? new LinearRing[length] : null; for (int i = 0; i < length; i++) { LineString hole = polygon.getInteriorRingN(i); LinearRing generalized = (LinearRing) decimateTransformGeneralize(hole, transform); cloned |= generalized != hole; if (cloned) { if (holes == null) { holes = new LinearRing[length]; for (int j = 0; j < i; j++) { holes[j] = (LinearRing) polygon.getInteriorRingN(j); } } holes[i] = generalized; } } if (cloned) { return polygon.getFactory().createPolygon(shell, holes); } else { return polygon; } } else if (geometry instanceof LineString) { double spanx = this.spanx; double spany = this.spany; LineString ls = (LineString) geometry; if (ls instanceof CurvedGeometry<?>) { CurvedGeometry<LineString> curved = (CurvedGeometry<LineString>) ls; ls = curved.linearize(Math.min(Math.abs(spanx), Math.abs(spany))); spanx = -1; spany = -1; } LiteCoordinateSequence seq = LiteCoordinateSequenceFactory.lite(ls .getCoordinateSequence()); boolean loop = ls instanceof LinearRing; if (!loop && seq.size() > 1) { double x0 = seq.getOrdinate(0, 0); double y0 = seq.getOrdinate(0, 1); double x1 = seq.getOrdinate(seq.size() - 1, 0); double y1 = seq.getOrdinate(seq.size() - 1, 1); loop = Math.abs(x0 - x1) < EPS && Math.abs(y0 - y1) < EPS; } decimateTransformGeneralize(seq, transform, loop, spanx, spany); return ls; } else { return geometry; } } Decimator(MathTransform screenToWorld, Rectangle paintArea, double pixelDistance);  Decimator(MathTransform screenToWorld, Rectangle paintArea);  Decimator(MathTransform screenToWorld);  Decimator(double spanx, double spany); double getSpanX(); double getSpanY(); static double[] computeGeneralizationDistances(MathTransform screenToWorld, Rectangle paintArea, double pixelDistance); final Geometry decimateTransformGeneralize(Geometry geometry,
			MathTransform transform); final void decimate(Geometry geom);  }
@Test public void testDecimateOpenTriangle() throws Exception { LineString g = gf.createLineString(csf.create(new double[] {0,0,0,2,2,2,0,0})); assertTrue(g.isValid()); Decimator d = new Decimator(3, 3); d.decimateTransformGeneralize(g, new AffineTransform2D(new AffineTransform())); g.geometryChanged(); assertTrue(g.isValid()); assertEquals(4, g.getCoordinateSequence().size()); }
@Test public void testDistance() throws Exception { LineString ls = gf.createLineString(csf.create(new double[] {0,0,1,1,2,2,3,3,4,4,5,5})); Decimator d = new Decimator(identity, new Rectangle(0,0,5,5), 0.8); d.decimateTransformGeneralize((Geometry) ls.clone(), identity); assertEquals(6, ls.getNumPoints()); d = new Decimator(identity, new Rectangle(0,0,5,5), 1); d.decimateTransformGeneralize(ls, identity); assertEquals(4, ls.getNumPoints()); d = new Decimator(identity, new Rectangle(0,0,5,5), 6); d.decimateTransformGeneralize(ls, identity); assertEquals(2, ls.getNumPoints()); }
@Test public void testDecimate3DPoint() throws Exception { Point p = gf.createPoint(csf.create(new double[] {0,1,2}, 3)); Decimator d = new Decimator(identity, new Rectangle(0,0,5,5), 0.8); d.decimateTransformGeneralize(p, identity); assertEquals(1, p.getNumPoints()); assertEquals(2, p.getCoordinateSequence().getDimension()); }
@Test public void testDecimate3DLine() throws Exception { LineString ls = gf.createLineString(csf.create(new double[] {0,0,1, 1,2,1, 3,3,4 ,4,5,5}, 3)); assertEquals(4, ls.getNumPoints()); Decimator d = new Decimator(identity, new Rectangle(0,0,5,5), 0.8); d.decimateTransformGeneralize(ls, identity); assertEquals(4, ls.getNumPoints()); assertEquals(2, ls.getCoordinateSequence().getDimension()); }
@Test public void testDecimateCollection() throws Exception { WKTReader2 reader = new WKTReader2(); MultiLineString origin = (MultiLineString) reader .read("MULTICURVE((0 0, 5 5),CIRCULARSTRING(4 0, 4 4, 8 4))"); Decimator d = new Decimator(0.1, 0.1); MultiLineString simplified = (MultiLineString) d.decimateTransformGeneralize(origin, identity); assertEquals(origin.getGeometryN(0), simplified.getGeometryN(0)); assertNotEquals(origin.getGeometryN(1), simplified.getGeometryN(1)); assertEquals("CircularString", origin.getGeometryN(1).getGeometryType()); assertEquals("LineString", simplified.getGeometryN(1).getGeometryType()); }