private DataStore createLatLonDataStore() throws Exception { SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder(); tb.setName("latlon"); tb.add("the_geom", LineString.class, CRS.decode("EPSG:4326", true)); tb.add("level", Integer.class); SimpleFeatureType type = tb.buildFeatureType(); MemoryDataStore ds = new MemoryDataStore(); ds.createSchema(type); FeatureWriter<SimpleFeatureType, SimpleFeature> writer; writer = ds.getFeatureWriterAppend("latlon", Transaction.AUTO_COMMIT); for (int lon = -180; lon < 180; lon += 5) { for (int lat = -90; lat < 90; lat += 5) { LineString geom; int level; geom = gf.createLineString( new Coordinate[] {new Coordinate(lon, lat), new Coordinate(lon, lat + 5)}); level = 1; if (lon % 10 == 0) { level = 10; } if (lon % 30 == 0) { level = 30; } SimpleFeature f; f = writer.next(); f.setAttribute(0, geom); f.setAttribute(1, Integer.valueOf(level)); writer.write(); geom = gf.createLineString( new Coordinate[] {new Coordinate(lon, lat), new Coordinate(lon + 5, lat)}); level = 1; if (lat % 10 == 0) { level = 10; } if (lat % 30 == 0) { level = 30; } f = writer.next(); f.setAttribute(0, geom); f.setAttribute(1, Integer.valueOf(level)); writer.write(); } } writer.close(); return ds; }
/** We must be able to transform specialized collections to GeometryCollectionValues */ @Test public void testGeometryCollectionConversions() throws Exception { Value val = ValueFactory.createValue( gf.createMultiPoint( new Coordinate[] {new Coordinate(0, 0, 0), new Coordinate(1, 2, 3)})); assertTrue(val instanceof DefaultMultiPointValue); Value val2 = val.toType(Type.GEOMETRYCOLLECTION); assertTrue(val2 instanceof DefaultGeometryCollectionValue); // Let's be sure it's not a GeometryCollection just thanks to the inheritance assertFalse(val2 instanceof DefaultMultiPointValue); val = ValueFactory.createValue( gf.createMultiLineString( new LineString[] { gf.createLineString( new Coordinate[] {new Coordinate(0, 0, 0), new Coordinate(4, 2, 3)}), gf.createLineString( new Coordinate[] {new Coordinate(5, 6, 9), new Coordinate(5, 7, 1)}) })); assertTrue(val instanceof DefaultMultiLineStringValue); val2 = val.toType(Type.GEOMETRYCOLLECTION); assertTrue(val2 instanceof DefaultGeometryCollectionValue); // Let's be sure it's not a GeometryCollection just thanks to the inheritance assertFalse(val2 instanceof DefaultMultiPointValue); val = ValueFactory.createValue( gf.createMultiPolygon( new Polygon[] { gf.createPolygon( gf.createLinearRing( new Coordinate[] { new Coordinate(0, 3, 0), new Coordinate(9, 0, 0), new Coordinate(8, 7, 0), new Coordinate(0, 3, 0) }), null), gf.createPolygon( gf.createLinearRing( new Coordinate[] { new Coordinate(10, 3, 0), new Coordinate(9, 0, 0), new Coordinate(8, 7, 0), new Coordinate(10, 3, 0) }), null) })); assertTrue(val instanceof DefaultMultiPolygonValue); val2 = val.toType(Type.GEOMETRYCOLLECTION); assertTrue(val2 instanceof DefaultGeometryCollectionValue); // Let's be sure it's not a GeometryCollection just thanks to the inheritance assertFalse(val2 instanceof DefaultMultiPointValue); }
/** decimates JTS geometries. */ public final Geometry decimate(Geometry geom) { GeometryFactory gFac = new GeometryFactory(geom.getPrecisionModel(), geom.getSRID()); if (spanx == -1) return geom; if (geom instanceof MultiPoint) { // TODO check geometry and if its bbox is too small turn it into a 1 // point geom return geom; } if (geom instanceof GeometryCollection) { // TODO check geometry and if its bbox is too small turn it into a // 1-2 point geom // takes a bit of work because the geometry will need to be // recreated. GeometryCollection collection = (GeometryCollection) geom; Geometry[] result = new Geometry[collection.getDimension()]; final int numGeometries = collection.getNumGeometries(); for (int i = 0; i < numGeometries; i++) { result[i] = decimate(collection.getGeometryN(i)); } return gFac.createGeometryCollection(result); } else if (geom instanceof LineString) { LineString line = (LineString) geom; CoordinateSequence seq = (CoordinateSequence) line.getCoordinateSequence(); LiteCoordinateSequence lseq = new LiteCoordinateSequence(seq.toCoordinateArray()); if (decimateOnEnvelope(line, lseq)) { if (lseq.size() >= 2) return gFac.createLineString(lseq); } if (lseq.size() >= 2) return gFac.createLineString(decimate(lseq)); return null; } else if (geom instanceof Polygon) { Polygon line = (Polygon) geom; Coordinate[] exterior = decimate(line.getExteriorRing()).getCoordinates(); forceClosed(exterior); if (exterior.length > 3) { LinearRing ring = gFac.createLinearRing(exterior); final int numRings = line.getNumInteriorRing(); List<LinearRing> rings = new ArrayList<LinearRing>(); for (int i = 0; i < numRings; i++) { Coordinate[] interior = decimate(line.getInteriorRingN(i)).getCoordinates(); forceClosed(interior); if (interior.length > 3) rings.add(gFac.createLinearRing(interior)); } return gFac.createPolygon(ring, rings.toArray(new LinearRing[] {})); } return null; } return geom; }
public void testEqualsExactForLineStrings() throws Exception { LineString x = geometryFactory.createLineString( new Coordinate[] { new Coordinate(0, 0), new Coordinate(100, 0), new Coordinate(100, 100) }); LineString somethingExactlyEqual = geometryFactory.createLineString( new Coordinate[] { new Coordinate(0, 0), new Coordinate(100, 0), new Coordinate(100, 100) }); LineString somethingNotEqualButSameClass = geometryFactory.createLineString( new Coordinate[] { new Coordinate(0, 0), new Coordinate(100, 0), new Coordinate(100, 555) }); LineString sameClassButEmpty = geometryFactory.createLineString((Coordinate[]) null); LineString anotherSameClassButEmpty = geometryFactory.createLineString((Coordinate[]) null); CollectionFactory collectionFactory = new CollectionFactory() { public Geometry createCollection(Geometry[] geometries) { return geometryFactory.createMultiLineString( GeometryFactory.toLineStringArray(Arrays.asList(geometries))); } }; doTestEqualsExact( x, somethingExactlyEqual, somethingNotEqualButSameClass, sameClassButEmpty, anotherSameClassButEmpty, collectionFactory); CollectionFactory collectionFactory2 = new CollectionFactory() { public Geometry createCollection(Geometry[] geometries) { return geometryFactory.createMultiLineString( GeometryFactory.toLineStringArray(Arrays.asList(geometries))); } }; doTestEqualsExact( x, somethingExactlyEqual, somethingNotEqualButSameClass, sameClassButEmpty, anotherSameClassButEmpty, collectionFactory2); }
private void addEnv(@Nullable Bounded node) { if (node == null) { return; } Envelope env = envBuff; env.setToNull(); node.expand(env); if (env.isNull()) { return; } if (isPoint(env)) { points.add(env.getMinX(), env.getMinY()); } else if (isOrthoLine(env)) { // handle the case where the envelope is given by an orthogonal line so we don't add a // zero area polygon double width = env.getWidth(); GrowableCoordinateSequence cs = new GrowableCoordinateSequence(); if (width == 0D) { cs.add(env.getMinX(), env.getMinY()); cs.add(env.getMinX(), env.getMaxY()); } else { cs.add(env.getMinX(), env.getMinY()); cs.add(env.getMaxX(), env.getMinY()); } nonPoints.add(GEOM_FACTORY.createLineString(cs)); } else { nonPoints.add(JTS.toGeometry(env, GEOM_FACTORY)); } }
private LineString[] parseLineStrings(JsonNode array) { LineString[] strings = new LineString[array.size()]; for (int i = 0; i != array.size(); ++i) { strings[i] = gf.createLineString(parseLineString(array.get(i))); } return strings; }
public void writeLineStringZone2ZoneOdPairsFromZones2Shapefile(String shapeFilename) { List<SimpleFeature> featureCollection = new ArrayList<SimpleFeature>(); SimpleFeatureTypeBuilder b = new SimpleFeatureTypeBuilder(); b.setCRS(crs); b.setName("zone2destOdPairs"); b.add("location", LineString.class); b.add("from_zone", String.class); b.add("to_dest", String.class); b.add("no trips", Double.class); SimpleFeatureBuilder builder = new SimpleFeatureBuilder(b.buildFeatureType()); int featureId = 1; for (DgZone zone : this.zones.values()) { for (DgDestination destination : zone.getDestinations()) { Coordinate startCoordinate = zone.getCoordinate(); Coordinate endCoordinate = destination.getCoordinate(); Coordinate[] coordinates = {startCoordinate, endCoordinate}; LineString lineString = geoFac.createLineString(coordinates); Object[] atts = { lineString, zone.getId(), destination.getId(), destination.getNumberOfTrips() }; SimpleFeature feature = builder.buildFeature(Integer.toString(featureId), atts); featureId++; featureCollection.add(feature); } } ShapeFileWriter.writeGeometries(featureCollection, shapeFilename); }
private Geometry parseGeometry(JsonNode root) { String typeName = root.get("type").asText(); if (typeName.equals("Point")) { return gf.createPoint(parseCoordinate((ArrayNode) root.get("coordinates"))); } else if (typeName.equals("MultiPoint")) { return gf.createMultiPoint(parseLineString(root.get("coordinates"))); } else if (typeName.equals("LineString")) { return gf.createLineString(parseLineString(root.get("coordinates"))); } else if (typeName.equals("MultiLineString")) { return gf.createMultiLineString(parseLineStrings(root.get("coordinates"))); } else if (typeName.equals("Polygon")) { JsonNode arrayOfRings = root.get("coordinates"); return parsePolygonCoordinates(arrayOfRings); } else if (typeName.equals("MultiPolygon")) { JsonNode arrayOfPolygons = root.get("coordinates"); return gf.createMultiPolygon(parsePolygons(arrayOfPolygons)); } else if (typeName.equals("GeometryCollection")) { return gf.createGeometryCollection(parseGeometries(root.get("geometries"))); } else { throw new UnsupportedOperationException(); } }
private void updateGeometry() { final List<Geometry> geoms = new ArrayList<>(); if (coords.size() == 1) { // single point final Geometry geom = GEOMETRY_FACTORY.createPoint(coords.get(0)); JTS.setCRS(geom, map.getCanvas().getObjectiveCRS2D()); geoms.add(geom); } else if (coords.size() == 2) { // line final Geometry geom = GEOMETRY_FACTORY.createLineString(coords.toArray(new Coordinate[coords.size()])); JTS.setCRS(geom, map.getCanvas().getObjectiveCRS2D()); geoms.add(geom); } else if (coords.size() > 2) { // polygon final Coordinate[] ringCoords = coords.toArray(new Coordinate[coords.size() + 1]); ringCoords[coords.size()] = coords.get(0); final LinearRing ring = GEOMETRY_FACTORY.createLinearRing(ringCoords); final Geometry geom = GEOMETRY_FACTORY.createPolygon(ring, new LinearRing[0]); JTS.setCRS(geom, map.getCanvas().getObjectiveCRS2D()); geoms.add(geom); } layer.getGeometries().setAll(geoms); if (geoms.isEmpty()) { uiArea.setText("-"); } else { uiArea.setText( NumberFormat.getNumberInstance() .format( MeasureUtilities.calculateArea( geoms.get(0), map.getCanvas().getObjectiveCRS2D(), uiUnit.getValue()))); } }
/** * Creates a elliptical arc, as a LineString. * * @return an elliptical arc */ public LineString createArc(double startAng, double endAng) { Envelope env = dim.getEnvelope(); double xRadius = env.getWidth() / 2.0; double yRadius = env.getHeight() / 2.0; double centreX = env.getMinX() + xRadius; double centreY = env.getMinY() + yRadius; double angSize = (endAng - startAng); if (angSize <= 0.0 || angSize > 2 * Math.PI) angSize = 2 * Math.PI; double angInc = angSize / nPts; Coordinate[] pts = new Coordinate[nPts]; int iPt = 0; for (int i = 0; i < nPts; i++) { double ang = startAng + i * angInc; double x = xRadius * Math.cos(ang) + centreX; double y = yRadius * Math.sin(ang) + centreY; Coordinate pt = new Coordinate(x, y); geomFact.getPrecisionModel().makePrecise(pt); pts[iPt++] = pt; } LineString line = geomFact.createLineString(pts); return line; }
@Test public void test3DGeoms() throws Exception { Coordinate[] coords2D = new Coordinate[] { new Coordinate(10, 10, 10), new Coordinate(40, 10, 10), new Coordinate(40, 40, 10), new Coordinate(10, 40, 10), new Coordinate(10, 10, 10), }; Coordinate[] coords3D = new Coordinate[] { new Coordinate(10, 10), new Coordinate(40, 10), new Coordinate(40, 40), new Coordinate(10, 40), new Coordinate(10, 10), }; Value p1 = ValueFactory.createValue(gf.createPoint(new Coordinate(10, 10, 10))); Value p2 = ValueFactory.createValue(gf.createPoint(new Coordinate(10, 10))); checkDifferent(p1, p2); LineString l1 = gf.createLineString(coords2D); p1 = ValueFactory.createValue(l1); LineString l2 = gf.createLineString(coords3D); p2 = ValueFactory.createValue(l2); checkDifferent(p1, p2); p1 = ValueFactory.createValue(gf.createMultiPoint(coords2D)); p2 = ValueFactory.createValue(gf.createMultiPoint(coords3D)); checkDifferent(p1, p2); Polygon pol1 = gf.createPolygon(gf.createLinearRing(coords2D), null); p1 = ValueFactory.createValue(pol1); Polygon pol2 = gf.createPolygon(gf.createLinearRing(coords3D), null); p2 = ValueFactory.createValue(pol2); checkDifferent(p1, p2); p1 = ValueFactory.createValue(gf.createMultiLineString(new LineString[] {l1})); p2 = ValueFactory.createValue(gf.createMultiLineString(new LineString[] {l2})); checkDifferent(p1, p2); p1 = ValueFactory.createValue(gf.createMultiPolygon(new Polygon[] {pol1})); p2 = ValueFactory.createValue(gf.createMultiPolygon(new Polygon[] {pol2})); checkDifferent(p1, p2); }
public LineString createGeometry(Vertex a, Vertex b) { GeometryFactory factory = new GeometryFactory(); Coordinate[] cs = new Coordinate[2]; cs[0] = a.getCoordinate(); cs[1] = b.getCoordinate(); return factory.createLineString(cs); }
public LineString nextLineString(final Envelope envelope) { final int n = getNumberOfNodesPerLine(); final SortedSet<Coordinate> nodes = new TreeSet<Coordinate>(); while (n > nodes.size()) { nodes.add(nextCoordinate(envelope)); } return gf.createLineString(nodes.toArray(new Coordinate[0])); }
/** * Transforms a LinearRing. The transformation of a LinearRing may result in a coordinate sequence * which does not form a structurally valid ring (i.e. a degnerate ring of 3 or fewer points). In * this case a LineString is returned. Subclasses may wish to override this method and check for * this situation (e.g. a subclass may choose to eliminate degenerate linear rings) * * @param geom the ring to simplify * @param parent the parent geometry * @return a LinearRing if the transformation resulted in a structurally valid ring * @return a LineString if the transformation caused the LinearRing to collapse to 3 or fewer * points */ protected Geometry transformLinearRing(LinearRing geom, Geometry parent) { CoordinateSequence seq = transformCoordinates(geom.getCoordinateSequence(), geom); if (seq == null) return factory.createLinearRing((CoordinateSequence) null); int seqSize = seq.size(); // ensure a valid LinearRing if (seqSize > 0 && seqSize < 4 && !preserveType) return factory.createLineString(seq); return factory.createLinearRing(seq); }
public static LineString makeLineString(double... coords) { GeometryFactory factory = getGeometryFactory(); Coordinate[] coordinates = new Coordinate[coords.length / 2]; for (int i = 0; i < coords.length; i += 2) { coordinates[i / 2] = new Coordinate(coords[i], coords[i + 1]); } return factory.createLineString(coordinates); }
public static Feature createLineSegmentFeature( FeatureSchema fs, Coordinate p0, Coordinate p1, String msg) { Feature feature = new BasicFeature(fs); LineString lineSeg = fact.createLineString(new Coordinate[] {p0, p1}); feature.setGeometry(lineSeg); feature.setAttribute(MESG_ATTR_NAME, msg); return feature; }
private LineString createAdjustedSegment( final Coordinate firstIntersection, final Coordinate secondIntersection, final GeometryFactory factory) { Coordinate[] adjustedSegmentCoords = new Coordinate[] {firstIntersection, secondIntersection}; return factory.createLineString(adjustedSegmentCoords); }
@Test public void multiLineString() throws Exception { MultiLineString multiLineString = gf.createMultiLineString( new LineString[] { gf.createLineString( new Coordinate[] {new Coordinate(100.0, 0.0), new Coordinate(101.0, 1.0)}), gf.createLineString( new Coordinate[] {new Coordinate(102.0, 2.0), new Coordinate(103.0, 3.0)}) }); assertRoundTrip(multiLineString); assertThat( toJson(multiLineString), equalTo( "{\"type\":\"MultiLineString\",\"coordinates\":[[[100.0,0.0],[101.0,1.0]],[[102.0,2.0],[103.0,3.0]]]}")); }
public static LineString getLineString3D() { return gf.createLineString( new Coordinate[] { new Coordinate(0, 0, 0), new Coordinate(10, 2, 5), new Coordinate(110, 0, 4), new Coordinate(10, 240, 10), }); }
public static LineString getLinestring() { return gf.createLineString( new Coordinate[] { new Coordinate(0, 0), new Coordinate(10, 0), new Coordinate(110, 0), new Coordinate(10, 240), }); }
/** * Generate LineStrings from two dimensional ordinates * * @param xy * @return LineStirng */ public LineString line(int[] xy) { Coordinate[] coords = new Coordinate[xy.length / 2]; for (int i = 0; i < xy.length; i += 2) { coords[i / 2] = new Coordinate(xy[i], xy[i + 1]); } return gf.createLineString(coords); }
@Test public void lineString() throws Exception { LineString lineString = gf.createLineString( new Coordinate[] {new Coordinate(100.0, 0.0), new Coordinate(101.0, 1.0)}); assertRoundTrip(lineString); assertThat( toJson(lineString), equalTo("{\"type\":\"LineString\",\"coordinates\":[[100.0,0.0],[101.0,1.0]]}")); }
/** * An approximation to the space surrounding the given meridian. * * <p>Draws a rhombus (in latitude & longitude space) centered on {@code meridian} from the north * pole to the south pole with a small constant width at the equator. */ static Geometry aroundMeridian(double meridian) { GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null); Coordinate northPole = new Coordinate(meridian, MAX_LATITUDE); Coordinate equatorEpsilonEast = new Coordinate(meridian + MERIDIAN_CROP_WIDTH_AT_EQUATOR, EQUATOR_LATITUDE); Coordinate equatorEpsilonWest = new Coordinate(meridian - MERIDIAN_CROP_WIDTH_AT_EQUATOR, EQUATOR_LATITUDE); Coordinate southPole = new Coordinate(meridian, MIN_LATITUDE); LineString easternLine = geometryFactory.createLineString( new Coordinate[] {northPole, equatorEpsilonEast, southPole}); LineString westernLine = geometryFactory.createLineString( new Coordinate[] {northPole, equatorEpsilonWest, southPole}); return easternLine.union(westernLine).convexHull(); }
protected MultiLineString decodeMultiLineString(JsonNode node, GeometryFactory fac) throws GeoJSONException { JsonNode coordinates = requireCoordinates(node); LineString[] lineStrings = new LineString[coordinates.size()]; for (int i = 0; i < coordinates.size(); ++i) { JsonNode coords = coordinates.get(i); lineStrings[i] = fac.createLineString(decodeCoordinates(coords)); } return fac.createMultiLineString(lineStrings); }
private static Geometry convertSegStrings(Iterator it) { GeometryFactory fact = new GeometryFactory(); List lines = new ArrayList(); while (it.hasNext()) { SegmentString ss = (SegmentString) it.next(); LineString line = fact.createLineString(ss.getCoordinates()); lines.add(line); } return fact.buildGeometry(lines); }
/** * Converts an array of coordinates to a line or point, as appropriate. * * @param coords the coordinates of a line or point * @param fact a factory used to create the Geometry * @return a line if there is more than one coordinate; a point if there is just one coordinate; * an empty point otherwise */ public static Geometry toLineOrPoint(Coordinate[] coords, GeometryFactory fact) { if (coords.length > 1) { return fact.createLineString(coords); } if (coords.length == 1) { return fact.createPoint(coords[0]); } return fact.createPoint((Coordinate) null); }
private Geometry intersectionWithSegment( Coordinate[] holeCoords, int i, Geometry intersectingSegment) { Coordinate[] holeSegmentCoord = new Coordinate[] {holeCoords[i], holeCoords[i + 1]}; LineString holeSegment; GeometryFactory geomFact = intersectingSegment.getFactory(); holeSegment = geomFact.createLineString(holeSegmentCoord); Geometry intersection = holeSegment.intersection(intersectingSegment); return intersection; }
private void updateGeometry() { final List<Geometry> geoms = new ArrayList<Geometry>(); if (coords.size() == 1) { // single point geoms.add(GEOMETRY_FACTORY.createPoint(coords.get(0))); } else if (coords.size() > 1) { // line geoms.add(GEOMETRY_FACTORY.createLineString(coords.toArray(new Coordinate[coords.size()]))); } deco.setGeometries(geoms); }
@Test public void createComplexGeometryCollectionTest() throws Exception { Coordinate ptc = new Coordinate(10, 20); Point point = geometryFactory.createPoint(ptc); point.setSRID(4326); Coordinate[] lsc = new Coordinate[8]; lsc[0] = new Coordinate(5.0d, 5.0d); lsc[1] = new Coordinate(6.0d, 5.0d); lsc[2] = new Coordinate(6.0d, 6.0d); lsc[3] = new Coordinate(7.0d, 6.0d); lsc[4] = new Coordinate(7.0d, 7.0d); lsc[5] = new Coordinate(8.0d, 7.0d); lsc[6] = new Coordinate(8.0d, 8.0d); lsc[7] = new Coordinate(9.0d, 9.0d); LineString lineString = geometryFactory.createLineString(lsc); lineString.setSRID(4326); Coordinate[] lrc = new Coordinate[10]; lrc[0] = new Coordinate(7, 7); lrc[1] = new Coordinate(6, 9); lrc[2] = new Coordinate(6, 11); lrc[3] = new Coordinate(7, 12); lrc[4] = new Coordinate(9, 11); lrc[5] = new Coordinate(11, 12); lrc[6] = new Coordinate(13, 11); lrc[7] = new Coordinate(13, 9); lrc[8] = new Coordinate(11, 7); lrc[9] = new Coordinate(7, 7); LinearRing linearRing = geometryFactory.createLinearRing(lrc); linearRing.setSRID(4326); Geometry polygon = reader.read( "POLYGON ((35 10, 10 20, 15 40," + " 45 45, 35 10), (20 30, 35 35, 30 20, 20 30))"); polygon.setSRID(4326); Geometry multiPoint = reader.read("MULTIPOINT ((10 40), (40 30), " + "(20 20), (30 10))"); multiPoint.setSRID(4326); Geometry multiPolygon = reader.read( "MULTIPOLYGON (((40 40, 20 45," + " 45 30, 40 40)), ((20 35, 45 20, 30 5, " + "10 10, 10 30, 20 35), (30 20, 20 25, 20 15, 30 20)))"); multiPolygon.setSRID(4326); GeometryCollection geometryCollection = new GeometryCollection( new Geometry[] {point, linearRing, lineString, polygon, multiPoint, multiPolygon}, geometryFactory); String geometryCollectionGeoJsonString = mapper.writeValueAsString(geometryCollection); logger.info( ":::::::::::::::::::::::GEO_JSON_GEOMETRY_COLLECTION : \n{}\n", geometryCollectionGeoJsonString); org.geojson.GeometryCollection p = mapper.readValue(geometryCollectionGeoJsonString, org.geojson.GeometryCollection.class); mapper.writeValue(new File("./target/GeometryCollectionComplex.json"), p); }
static Geometry densify(Geometry geom, CoordinateReferenceSystem crs, double maxAreaError) throws FactoryException, TransformException { // basic checks if (maxAreaError <= 0) { throw new IllegalArgumentException("maxAreaError must be greater than 0"); } if (!(geom instanceof Polygon) && !(geom instanceof MultiPolygon)) { throw new IllegalArgumentException("Geom must be poligonal"); } if (crs == null) { throw new IllegalArgumentException("CRS cannot be set to null"); } double previousArea = 0.0; CoordinateReferenceSystem targetCRS = CRS.parseWKT(ECKERT_IV_WKT); MathTransform firstTransform = CRS.findMathTransform(crs, targetCRS); GeometryFactory geomFactory = new GeometryFactory(); int ngeom = geom.getNumGeometries(); Geometry densifiedGeometry = geom; double areaError = 1.0d; int maxIterate = 0; do { double max = 0; maxIterate++; // check the maximum side length of the densifiedGeometry for (int j = 0; j < ngeom; j++) { Geometry geometry = densifiedGeometry.getGeometryN(j); Coordinate[] coordinates = geometry.getCoordinates(); int n = coordinates.length; for (int i = 0; i < (n - 1); i++) { Coordinate[] coords = new Coordinate[2]; coords[0] = coordinates[i]; coords[1] = coordinates[i + 1]; LineString lineString = geomFactory.createLineString(coords); if (lineString.getLength() > max) max = lineString.getLength(); } } // calculate the denified geometry densifiedGeometry = Densifier.densify(densifiedGeometry, max / 2); // reproject densifiedGeometry to Eckert IV Geometry targetGeometry = JTS.transform(densifiedGeometry, firstTransform); double nextArea = targetGeometry.getArea(); // evaluate the current error areaError = Math.abs(previousArea - nextArea) / nextArea; // logger3.info("AREA ERROR"+areaError); previousArea = nextArea; // check whether the current error is greater than the maximum allowed } while (areaError > maxAreaError && maxIterate < 10); return densifiedGeometry; }