public void testParsePolygonNoHoles() throws IOException { XContentBuilder polygonGeoJson = XContentFactory.jsonBuilder() .startObject() .field("type", "Polygon") .startArray("coordinates") .startArray() .startArray().value(100.0).value(1.0).endArray() .startArray().value(101.0).value(1.0).endArray() .startArray().value(101.0).value(0.0).endArray() .startArray().value(100.0).value(0.0).endArray() .startArray().value(100.0).value(1.0).endArray() .endArray() .endArray() .endObject(); List<Coordinate> shellCoordinates = new ArrayList<>(); shellCoordinates.add(new Coordinate(100, 0)); shellCoordinates.add(new Coordinate(101, 0)); shellCoordinates.add(new Coordinate(101, 1)); shellCoordinates.add(new Coordinate(100, 1)); shellCoordinates.add(new Coordinate(100, 0)); LinearRing shell = GEOMETRY_FACTORY.createLinearRing(shellCoordinates.toArray(new Coordinate[shellCoordinates.size()])); Polygon expected = GEOMETRY_FACTORY.createPolygon(shell, null); assertGeometryEquals(jtsGeom(expected), polygonGeoJson); }
private Polygon osmPolygon2JTS(DataReaderContext readerCntx, LongArrayList osmNodeIds) { // collect all coordinates in ArrayList if (_coordinates == null || _coordinates.length < osmNodeIds.size()) _coordinates = new Coordinate[osmNodeIds.size()]; for (int i = 0; i < osmNodeIds.size(); i++) { long osmNodeId = osmNodeIds.get(i); int internalID = readerCntx.getNodeMap().get(osmNodeId); _coordinates[i] = new Coordinate(readerCntx.getNodeLongitude(internalID), readerCntx.getNodeLatitude(internalID)); } Coordinate[] coords = Arrays.copyOf(_coordinates, osmNodeIds.size()); LinearRing ring = geometryFactory.createLinearRing(coords); LinearRing holes[] = null; // a JTS polygon consists of a ring and holes return geometryFactory.createPolygon(ring, holes); }
private static Polygon readPolygon(JSONArray value) { int n = value.length(); LinearRing shell = null; LinearRing[] holes = new LinearRing[n-1]; for (int i = 0; i < n; i++) { JSONArray arrLineString = value.getJSONArray(i); if (i == 0) shell = factory.createLinearRing(readCoordinates(arrLineString)); else holes[i-1] = factory.createLinearRing(readCoordinates(arrLineString)); } if (holes == null || holes.length == 0) return factory.createPolygon(shell); else return factory.createPolygon(shell, holes); }
private static LinearRing coordsToLinearRing(final List<LngLatAlt> exteriorRing, final GISUtils.SRID srid) { if (exteriorRing.isEmpty()) { throw new IllegalArgumentException("Empty ring"); } final Stream<Coordinate> stream = exteriorRing.stream() .map(lngLatAlt -> new Coordinate(lngLatAlt.getLongitude(), lngLatAlt.getLatitude())); final LngLatAlt first = exteriorRing.get(0); final LngLatAlt last = exteriorRing.get(exteriorRing.size() - 1); final Coordinate[] coords; if (first.equals(last)) { coords = stream.toArray(Coordinate[]::new); } else { // Complete partial ring final Coordinate firstCoordinate = new Coordinate(first.getLongitude(), first.getLatitude()); coords = Stream.concat(stream, Stream.of(firstCoordinate)).toArray(Coordinate[]::new); } return GISUtils.getGeometryFactory(srid).createLinearRing(coords); }
public static Geometry toPolygons(List<List<LatLon>> outer, List<List<LatLon>> inner) { Map<LinearRing, ArrayList<LinearRing>> shellsWithHoles = toShellsWithHoles(outer, inner); Polygon[] polys = new Polygon[shellsWithHoles.size()]; int i = 0; for(Map.Entry<LinearRing, ArrayList<LinearRing>> shellWithHoles : shellsWithHoles.entrySet()) { LinearRing shell = shellWithHoles.getKey(); ArrayList<LinearRing> holesList = shellWithHoles.getValue(); LinearRing[] holes = null; if(holesList != null) { holes = holesList.toArray(new LinearRing[holesList.size()]); } polys[i++] = factory.createPolygon(shell, holes); } if(polys.length == 1) return polys[0]; else return factory.createMultiPolygon(polys); }
private LinearRing translateLinearRingType(LinearRingType ring) throws GeometryException { if (ring.getPosList() == null) { throw new DeprecatedGeometrySpecificationException("Geen post list voor ring gespecificeerd"); } CoordinateArraySequence sequence = gmlToPointConvertor.translateOrdinates(ring.getPosList()); int length = sequence.size(); Coordinate firstCoordinate = length == 0 ? null : sequence.getCoordinate(0); if (length < NUMBER_OF_COORDINATES_NEEDED_FOR_RING) { throw new InvalidGeometryException(GeometryValidationErrorType.TOO_FEW_POINTS, firstCoordinate); } if (!isClosed(sequence)) { throw new InvalidGeometryException(GeometryValidationErrorType.RING_NOT_CLOSED, firstCoordinate); } return geometryFactory.createLinearRing(sequence); }
/** * Returns this ring as a {@link LinearRing}, or null if an Exception occurs while * creating it (such as a topology problem). Details of problems are written to * standard output. */ public LinearRing getRing() { if (this.ring != null) { return this.ring; } this.getCoordinates(); if (this.ringPts.length < 3) { System.out.println(Arrays.toString(ringPts)); } try { this.ring = this.factory.createLinearRing(this.ringPts); } catch (Exception ex) { System.out.println(Arrays.toString(ringPts)); } return this.ring; }
/** * Create a GeoTools geometric linear-ring from coordinates in json. * * @param json the json array of coordinates * @return the linear-ring */ public static LinearRing createLinearRingFromJson( JsonNode json ) { // Native array of coordinates to pass to GeoFactory Coordinate[] coords = new Coordinate[MapUtils.getNonEmptyNodes( json )]; // Read the json array of coordinates for ( int i = 0; i < json.size(); i++ ) { JsonNode node = json.get( i ); if ( MapUtils.nodeIsNonEmpty( node ) ) { coords[i] = createCoordinateFromJson( node ); } } // Create the linear-ring from factory return FACTORY.createLinearRing( coords ); }
/** * Calcule l'homothétie d'une géométrie. * @param geom géométrie, geometry * @param x0 position en X du centre de l'homothétie, X position of the center * of the operation * @param y0 position en Y du centre de l'homothétie, Y position of the center * of the operation * @param scaleX facteur d'échelle en X, X scale factor * @param scaleY facteur d'échelle en Y, Y scale factor * @return polygon résultant de l'homothétie, resulting polygon */ public static Polygon homothetie(Polygon geom, double x0, double y0, double scaleX, double scaleY) { // le contour externe Coordinate[] coord = geom.getExteriorRing().getCoordinates(); Coordinate[] coord_ = new Coordinate[coord.length]; for (int i = 0; i < coord.length; i++) { coord_[i] = new Coordinate(x0 + scaleX * (coord[i].x - x0), y0 + scaleY * (coord[i].y - y0)); } LinearRing lr = geom.getFactory().createLinearRing(coord_); // les trous LinearRing[] trous = new LinearRing[geom.getNumInteriorRing()]; for (int j = 0; j < geom.getNumInteriorRing(); j++) { Coordinate[] hole_coord = geom.getInteriorRingN(j).getCoordinates(); Coordinate[] hole_coord_ = new Coordinate[hole_coord.length]; for (int i = 0; i < hole_coord.length; i++) { hole_coord_[i] = new Coordinate(x0 + scaleY * (hole_coord[i].x - x0), y0 + scaleY * (hole_coord[i].y - y0)); } trous[j] = geom.getFactory().createLinearRing(hole_coord_); } return geom.getFactory().createPolygon(lr, trous); }
/** * Find a point from the list of testCoords * that is NOT a node in the edge for the list of searchCoords * * @return the point found, or <code>null</code> if none found */ public static Coordinate findPtNotNode( Coordinate[] testCoords, LinearRing searchRing, GeometryGraph graph) { // find edge corresponding to searchRing. Edge searchEdge = graph.findEdge(searchRing); // find a point in the testCoords which is not a node of the searchRing EdgeIntersectionList eiList = searchEdge.getEdgeIntersectionList(); // somewhat inefficient - is there a better way? (Use a node map, for instance?) for (Coordinate pt : testCoords) { if (!eiList.isIntersection(pt)) { return pt; } } return null; }
/** * Checks validity of a LinearRing. */ private void checkValid(LinearRing g) { this.checkInvalidCoordinates(g.getCoordinates()); if (this.validErr != null) { return; } this.checkClosedRing(g); if (this.validErr != null) { return; } GeometryGraph graph = new GeometryGraph(0, g); this.checkTooFewPoints(graph); if (this.validErr != null) { return; } LineIntersector li = new RobustLineIntersector(); graph.computeSelfNodes(li, true); this.checkNoSelfIntersectingRings(graph); }
/** * Tests that no element polygon is wholly in the interior of another element polygon. * <p> * Preconditions: * <ul> * <li>shells do not partially overlap * <li>shells do not touch along an edge * <li>no duplicate rings exist * </ul> * This routine relies on the fact that while polygon shells may touch at one or * more vertices, they cannot touch at ALL vertices. */ private void checkShellsNotNested(MultiPolygon mp, GeometryGraph graph) { for (int i = 0; i < mp.getNumGeometries(); i++) { Polygon p = (Polygon) mp.getGeometryN(i); LinearRing shell = (LinearRing) p.getExteriorRing(); for (int j = 0; j < mp.getNumGeometries(); j++) { if (i == j) { continue; } Polygon p2 = (Polygon) mp.getGeometryN(j); this.checkShellNotNested(shell, p2, graph); if (this.validErr != null) { return; } } } }
/** * This routine checks to see if a shell is properly contained in a hole. * It assumes that the edges of the shell and hole do not * properly intersect. * * @return <code>null</code> if the shell is properly contained, or * a Coordinate which is not inside the hole if it is not */ private Coordinate checkShellInsideHole(LinearRing shell, LinearRing hole, GeometryGraph graph) { Coordinate[] shellPts = shell.getCoordinates(); Coordinate[] holePts = hole.getCoordinates(); // TODO: improve performance of this - by sorting pointlists for instance? Coordinate shellPt = findPtNotNode(shellPts, hole, graph); // if point is on shell but not hole, check that the shell is inside the hole if (shellPt != null) { boolean insideHole = CGAlgorithms.isPointInRing(shellPt, holePts); if (!insideHole) { return shellPt; } } Coordinate holePt = findPtNotNode(holePts, shell, graph); // if point is on hole but not shell, check that the hole is outside the shell if (holePt != null) { boolean insideShell = CGAlgorithms.isPointInRing(holePt, shellPts); if (insideShell) { return holePt; } return null; } Assert.shouldNeverReachHere("points in shell and hole appear to be equal"); return null; }
/** * Adds an offset curve for a polygon ring. * The side and left and right topological location arguments * assume that the ring is oriented CW. * If the ring is in the opposite orientation, * the left and right locations must be interchanged and the side flipped. * * @param coord the coordinates of the ring (must not contain repeated points) * @param offsetDistance the distance at which to create the buffer * @param side the side of the ring on which to construct the buffer line * @param cwLeftLoc the location on the L side of the ring (if it is CW) * @param cwRightLoc the location on the R side of the ring (if it is CW) */ private void addPolygonRing(Coordinate[] coord, double offsetDistance, int side, int cwLeftLoc, int cwRightLoc) { // don't bother adding ring if it is "flat" and will disappear in the output if (offsetDistance == 0.0 && coord.length < LinearRing.MINIMUM_VALID_SIZE) { return; } int leftLoc = cwLeftLoc; int rightLoc = cwRightLoc; if (coord.length >= LinearRing.MINIMUM_VALID_SIZE && CGAlgorithms.isCCW(coord)) { leftLoc = cwRightLoc; rightLoc = cwLeftLoc; side = Position.opposite(side); } Coordinate[] curve = this.curveBuilder.getRingCurve(coord, side, offsetDistance); this.addCurve(curve, leftLoc, rightLoc); }
/** * Converts a flat path to a {@link Geometry}. * * @param pathIt the path to convert * @return a Geometry representing the path */ public Geometry read(PathIterator pathIt) { List pathPtSeq = toCoordinates(pathIt); List polys = new ArrayList(); int seqIndex = 0; while (seqIndex < pathPtSeq.size()) { // assume next seq is shell // TODO: test this Coordinate[] pts = (Coordinate[]) pathPtSeq.get(seqIndex); LinearRing shell = this.geometryFactory.createLinearRing(pts); seqIndex++; List holes = new ArrayList(); // add holes as long as rings are CCW while (seqIndex < pathPtSeq.size() && this.isHole((Coordinate[]) pathPtSeq.get(seqIndex))) { Coordinate[] holePts = (Coordinate[]) pathPtSeq.get(seqIndex); LinearRing hole = this.geometryFactory.createLinearRing(holePts); holes.add(hole); seqIndex++; } LinearRing[] holeArray = GeometryFactory.toLinearRingArray(holes); polys.add(this.geometryFactory.createPolygon(shell, holeArray)); } return this.geometryFactory.buildGeometry(polys); }
/** * Translate une géométrie. * Translate a geometry. * * @param geom une géométrie, a geometry * @param dx translation suivant l'axe des x, translation along the X axis * @param dy translation suivant l'axe des Y, translation along the Y axis * @return polygone résultant de la translation, resulting polygon. */ public static Polygon translation(Polygon geom, double dx, double dy){ GeometryFactory gf=new GeometryFactory(); //le contour externe Coordinate[] coord=geom.getExteriorRing().getCoordinates(); Coordinate[] coord_=new Coordinate[coord.length]; for(int i=0;i<coord.length;i++) coord_[i]=new Coordinate(coord[i].x+dx, coord[i].y+dy); LinearRing lr=gf.createLinearRing(coord_); //les trous LinearRing[] trous=new LinearRing[geom.getNumInteriorRing()]; for(int j=0;j<geom.getNumInteriorRing();j++){ Coordinate[] hole_coord=geom.getInteriorRingN(j).getCoordinates(); Coordinate[] hole_coord_=new Coordinate[hole_coord.length]; for(int i=0;i<hole_coord.length;i++) hole_coord_[i]=new Coordinate(hole_coord[i].x+dx, hole_coord[i].y+dy); trous[j]=gf.createLinearRing(hole_coord_); } return gf.createPolygon(lr,trous); }
public static boolean containsPointInPolygon(Coordinate p, Polygon poly) { if (poly.isEmpty()) { return false; } LinearRing shell = (LinearRing) poly.getExteriorRing(); if (!isPointInRing(p, shell)) { return false; } // now test if the point lies in or on the holes for (int i = 0; i < poly.getNumInteriorRing(); i++) { LinearRing hole = (LinearRing) poly.getInteriorRingN(i); if (isPointInRing(p, hole)) { return false; } } return true; }
/** * This method will cause the ring to be computed. * It will also check any holes, if they have been assigned. */ public boolean containsPoint(Coordinate p) { LinearRing shell = this.getLinearRing(); Envelope env = shell.getEnvelopeInternal(); if (!env.contains(p)) { return false; } if (!CGAlgorithms.isPointInRing(p, shell.getCoordinates())) { return false; } for (Object hole1 : holes) { EdgeRing hole = (EdgeRing) hole1; if (hole.containsPoint(p)) { return false; } } return true; }
/** * Calcul de l'affinité vectorielle. * * @param geom une géométrie, a geometry * @param c coordonnées d'un point par lequel passe l'axe de l'affinité * @param angle angle de la direction de l'affinite, à partir de l'axe des x * @param coef coefficient de l'homothétie * @return polygone polygone résultant de l'application de l'affinité, resulting polygon */ public static Polygon affinite(Polygon geom, Coordinate c, double angle, double coef){ //pivote le polygone Polygon rot=rotation(geom, c, -1.0*angle); //le contour externe Coordinate[] coord=rot.getExteriorRing().getCoordinates(); Coordinate[] coord_=new Coordinate[coord.length]; for(int i=0;i<coord.length;i++) coord_[i]=new Coordinate(c.x+coef*(coord[i].x-c.x), coord[i].y); LinearRing lr=geom.getFactory().createLinearRing(coord_); //les trous LinearRing[] trous=new LinearRing[rot.getNumInteriorRing()]; for(int j=0;j<rot.getNumInteriorRing();j++){ Coordinate[] hole_coord=rot.getInteriorRingN(j).getCoordinates(); Coordinate[] hole_coord_=new Coordinate[hole_coord.length]; for(int i=0;i<hole_coord.length;i++) hole_coord_[i]=new Coordinate(c.x+coef*(hole_coord[i].x-c.x), coord[i].y); trous[j]=geom.getFactory().createLinearRing(hole_coord_); } return rotation(geom.getFactory().createPolygon(lr,trous), c, angle); }
private void addPolygon(Polygon p) { this.addPolygonRing( (LinearRing) p.getExteriorRing(), Location.EXTERIOR, Location.INTERIOR); for (int i = 0; i < p.getNumInteriorRing(); i++) { LinearRing hole = (LinearRing) p.getInteriorRingN(i); // Holes are topologically labelled opposite to the shell, since // the interior of the polygon lies on their opposite side // (on the left, if the hole is oriented CW) this.addPolygonRing( hole, Location.INTERIOR, Location.EXTERIOR); } }
/** * Compute self-nodes, taking advantage of the Geometry type to * minimize the number of intersection tests. (E.g. rings are * not tested for self-intersection, since they are assumed to be valid). * * @param li the LineIntersector to use * @param computeRingSelfNodes if <false>, intersection checks are optimized to not test rings for self-intersection * @return the SegmentIntersector used, containing information about the intersections found */ public SegmentIntersector computeSelfNodes(LineIntersector li, boolean computeRingSelfNodes) { SegmentIntersector si = new SegmentIntersector(li, true, false); EdgeSetIntersector esi = this.createEdgeSetIntersector(); // optimized test for Polygons and Rings if (!computeRingSelfNodes && (this.parentGeom instanceof LinearRing || this.parentGeom instanceof Polygon || this.parentGeom instanceof MultiPolygon)) { esi.computeIntersections(this.edges, si, false); } else { esi.computeIntersections(this.edges, si, true); } //System.out.println("SegmentIntersector # tests = " + si.numTests); this.addSelfIntersectionNodes(this.argIndex); return si; }
/** * Calcule l'homothétie d'une géométrie. * @param geom géométrie, geometry * @param x0 position en X du centre de l'homothétie, X position of the center of the operation * @param y0 position en Y du centre de l'homothétie, Y position of the center of the operation * @param scaleX facteur d'échelle en X, X scale factor * @param scaleY facteur d'échelle en Y, Y scale factor * @return polygon résultant de l'homothétie, resulting polygon */ public static Polygon homothetie(Polygon geom, double x0, double y0, double scaleX, double scaleY){ //le contour externe Coordinate[] coord=geom.getExteriorRing().getCoordinates(); Coordinate[] coord_=new Coordinate[coord.length]; for(int i=0;i<coord.length;i++) coord_[i]=new Coordinate(x0+scaleX*(coord[i].x-x0), y0+scaleY*(coord[i].y-y0)); LinearRing lr=geom.getFactory().createLinearRing(coord_); //les trous LinearRing[] trous=new LinearRing[geom.getNumInteriorRing()]; for(int j=0;j<geom.getNumInteriorRing();j++){ Coordinate[] hole_coord=geom.getInteriorRingN(j).getCoordinates(); Coordinate[] hole_coord_=new Coordinate[hole_coord.length]; for(int i=0;i<hole_coord.length;i++) hole_coord_[i]=new Coordinate(x0+scaleY*(hole_coord[i].x-x0), y0+scaleY*(hole_coord[i].y-y0)); trous[j]=geom.getFactory().createLinearRing(hole_coord_); } return geom.getFactory().createPolygon(lr,trous); }
@Override public final Geometry edit(Geometry geometry, GeometryFactory factory) { if (geometry instanceof LinearRing) { return factory.createLinearRing(this.edit(geometry.getCoordinates(), geometry)); } if (geometry instanceof LineString) { return factory.createLineString(this.edit(geometry.getCoordinates(), geometry)); } if (geometry instanceof Point) { Coordinate[] newCoordinates = this.edit(geometry.getCoordinates(), geometry); return factory.createPoint((newCoordinates.length > 0) ? newCoordinates[0] : null); } return geometry; }
@Override public final Geometry edit(Geometry geometry, GeometryFactory factory) { if (geometry instanceof LinearRing) { return factory.createLinearRing(this.edit( ((LinearRing) geometry).getCoordinateSequence(), geometry)); } if (geometry instanceof LineString) { return factory.createLineString(this.edit( ((LineString) geometry).getCoordinateSequence(), geometry)); } if (geometry instanceof Point) { return factory.createPoint(this.edit( ((Point) geometry).getCoordinateSequence(), geometry)); } return geometry; }
/** * Creates a <code>Polygon</code> using the next token in the stream. * * @param tokenizer tokenizer over a stream of text in Well-known Text * format. The next tokens must form a <Polygon Text>. * @return a <code>Polygon</code> specified by the next token * in the stream * @throws ParseException if the coordinates used to create the <code>Polygon</code> * shell and holes do not form closed linestrings, or if an unexpected * token was encountered. * @throws IOException if an I/O error occurs */ private Polygon readPolygonText() throws IOException, ParseException { String nextToken = this.getNextEmptyOrOpener(); if (nextToken.equals(EMPTY)) { return this.geometryFactory.createPolygon(this.geometryFactory.createLinearRing( new Coordinate[] {}), new LinearRing[] {}); } ArrayList holes = new ArrayList(); LinearRing shell = this.readLinearRingText(); nextToken = this.getNextCloserOrComma(); while (nextToken.equals(COMMA)) { LinearRing hole = this.readLinearRingText(); holes.add(hole); nextToken = this.getNextCloserOrComma(); } LinearRing[] array = new LinearRing[holes.size()]; return this.geometryFactory.createPolygon(shell, (LinearRing[]) holes.toArray(array)); }
/** * Does what it says, reverses the order of the Coordinates in the ring. * <p> * This is different then lr.reverses() in that a copy is produced using a * new coordinate sequence. * </p> * * @param lr The ring to reverse. * @return A new ring with the reversed Coordinates. */ public static final LinearRing reverseRing(LinearRing lr) { GeometryFactory gf = lr.getFactory(); CoordinateSequenceFactory csf = gf.getCoordinateSequenceFactory(); CoordinateSequence csOrig = lr.getCoordinateSequence(); int numPoints = csOrig.size(); int dimensions = csOrig.getDimension(); CoordinateSequence csNew = csf.create(numPoints, dimensions); for (int i = 0; i < numPoints; i++) { for (int j = 0; j < dimensions; j++) { csNew.setOrdinate(numPoints - 1 - i, j, csOrig.getOrdinate(i, j)); } } return gf.createLinearRing(csNew); }
private void writePolygon(Polygon p, Writer writer, int level) throws IOException { this.startLine(level, writer); this.startGeomTag(GMLConstants.GML_POLYGON, p, writer); this.startLine(level + 1, writer); this.startGeomTag(GMLConstants.GML_OUTER_BOUNDARY_IS, null, writer); this.writeLinearRing((LinearRing) p.getExteriorRing(), writer, level + 2); this.startLine(level + 1, writer); this.endGeomTag(GMLConstants.GML_OUTER_BOUNDARY_IS, writer); for (int t = 0; t < p.getNumInteriorRing(); t++) { this.startLine(level + 1, writer); this.startGeomTag(GMLConstants.GML_INNER_BOUNDARY_IS, null, writer); this.writeLinearRing((LinearRing) p.getInteriorRingN(t), writer, level + 2); this.startLine(level + 1, writer); this.endGeomTag(GMLConstants.GML_INNER_BOUNDARY_IS, writer); } this.startLine(level, writer); this.endGeomTag(GMLConstants.GML_POLYGON, writer); }
private void mergeHoles(ArrayList<LinearRing> rings) { if(rings.size() == 1) return; // need to be converted to polygons and back because linearring is a lineal data structure, // we want to merge by area ArrayList<Polygon> polygons = new ArrayList<>(rings.size()); for (LinearRing ring : rings) { polygons.add(factory.createPolygon(ring)); } mergePolygons(polygons); // something was merged. Convert polygons back to rings if(polygons.size() != rings.size()) { rings.clear(); for (Polygon polygon : polygons) { rings.add((LinearRing) polygon.getExteriorRing()); } } }
/** * Transforme une liste de {@link GM_Ring}s GeOxygene en {@link LinearRing}s * JTS * @param factory factory JTS * @param list liste de {@link GM_Ring}s * @return tableau de {@link LinearRing}s JTS équivalents * @throws Exception renvoie une exception si le type de géométrie n'est pas * géré. */ public static LinearRing[] toLinearRingArray(GeometryFactory factory, List<IRing> list) throws Exception { // LinearRing[] rings = new LinearRing[list.size()]; List<LinearRing> rings = new ArrayList<LinearRing>(); for (int i = 0; i < list.size(); i++) { LinearRing ring = (LinearRing) AdapterFactory.toGeometry(factory, list.get(i)); if (ring != null) { rings.add(ring); } else { return null; } } return rings.toArray(new LinearRing[0]); }
/** * Calcule l'homothétie d'une géométrie. * @param geom géométrie, geometry * @param x0 position en X du centre de l'homothétie, X position of the center of the operation * @param y0 position en Y du centre de l'homothétie, Y position of the center of the operation * @param scale facteur d'échelle, scale factor * @return polygon résultant de l'homothétie, resulting polygon */ public static Polygon homothetie(Polygon geom, double x0, double y0, double scale){ //le contour externe Coordinate[] coord=geom.getExteriorRing().getCoordinates(); Coordinate[] coord_=new Coordinate[coord.length]; for(int i=0;i<coord.length;i++) coord_[i]=new Coordinate(x0+scale*(coord[i].x-x0), y0+scale*(coord[i].y-y0)); LinearRing lr=geom.getFactory().createLinearRing(coord_); //les trous LinearRing[] trous=new LinearRing[geom.getNumInteriorRing()]; for(int j=0;j<geom.getNumInteriorRing();j++){ Coordinate[] hole_coord=geom.getInteriorRingN(j).getCoordinates(); Coordinate[] hole_coord_=new Coordinate[hole_coord.length]; for(int i=0;i<hole_coord.length;i++) hole_coord_[i]=new Coordinate(x0+scale*(hole_coord[i].x-x0), y0+scale*(hole_coord[i].y-y0)); trous[j]=geom.getFactory().createLinearRing(hole_coord_); } return geom.getFactory().createPolygon(lr,trous); }
/** * Supprime les trous d'un polygone inférieurs à une aire minimale. Remove the * holes smaller than a minimum area from a polygon . * * @param poly un polygone, a polygon */ public static Polygon supprimeTrous(Polygon poly, double minArea) { List<LinearRing> holes = new ArrayList<>(); for (int i = 0; i < poly.getNumInteriorRing(); i++) { LinearRing ring = (LinearRing) poly.getInteriorRingN(i); if (ring.getArea() < minArea) continue; holes.add(ring); } LinearRing[] holesArray = new LinearRing[holes.size()]; for (int i = 0; i < holes.size(); i++) holesArray[i] = holes.get(i); return new Polygon((LinearRing) poly.getExteriorRing(), holesArray, poly.getFactory()); }
/** * Calcule l'homothétie d'une géométrie. * @param geom géométrie, geometry * @param x0 position en X du centre de l'homothétie, X position of the center * of the operation * @param y0 position en Y du centre de l'homothétie, Y position of the center * of the operation * @param scale facteur d'échelle, scale factor * @return polygon résultant de l'homothétie, resulting polygon */ public static Polygon homothetie(Polygon geom, double x0, double y0, double scale) { // le contour externe Coordinate[] coord = geom.getExteriorRing().getCoordinates(); Coordinate[] coord_ = new Coordinate[coord.length]; for (int i = 0; i < coord.length; i++) { coord_[i] = new Coordinate(x0 + scale * (coord[i].x - x0), y0 + scale * (coord[i].y - y0)); } LinearRing lr = geom.getFactory().createLinearRing(coord_); // les trous LinearRing[] trous = new LinearRing[geom.getNumInteriorRing()]; for (int j = 0; j < geom.getNumInteriorRing(); j++) { Coordinate[] hole_coord = geom.getInteriorRingN(j).getCoordinates(); Coordinate[] hole_coord_ = new Coordinate[hole_coord.length]; for (int i = 0; i < hole_coord.length; i++) { hole_coord_[i] = new Coordinate(x0 + scale * (hole_coord[i].x - x0), y0 + scale * (hole_coord[i].y - y0)); } trous[j] = geom.getFactory().createLinearRing(hole_coord_); } return geom.getFactory().createPolygon(lr, trous); }
/** */ public static GeometryCollection explodeMultiPolygon (MultiPolygon mp) { List<LinearRing> result = new ArrayList<LinearRing>(mp.getNumGeometries()*2); for (int i = 0; i < mp.getNumGeometries(); i += 1) { Polygon p = (Polygon)mp.getGeometryN(i); result.add((LinearRing)p.getExteriorRing()); for (int j = 0; j < p.getNumInteriorRing(); j += 1) { result.add((LinearRing)p.getInteriorRingN(j)); } } return mp.getFactory().createGeometryCollection(GeometryFactory.toGeometryArray(result)); }
protected Polygon toPolygon(GeometryFactory factory) { final LinearRing shell = linearRing(factory, this.shell.coordinates); final LinearRing[] holes = new LinearRing[this.holes.size()]; Iterator<LineStringBuilder> iterator = this.holes.iterator(); for (int i = 0; iterator.hasNext(); i++) { holes[i] = linearRing(factory, iterator.next().coordinates); } return factory.createPolygon(shell, holes); }
public static Polygon createPolygon(Coordinate[] coordinates, int SRID) { LinearRing r = gm.createLinearRing(coordinates); Polygon p = gm.createPolygon(r, null); p.setSRID(SRID); return p; }
/** * Creates a new {@code Polygon} whose exterior shell is a smoothed * version of the input {@code Polygon}. * <p> * Note: this method presently ignores holes. * * @param p the input {@code Polygon} * * @param alpha a value between 0 and 1 (inclusive) specifying the tightness * of fit of the smoothed boundary (0 is loose) * * @return the smoothed {@code Polygon} */ public Polygon smooth(Polygon p, double alpha) { Coordinate[] coords = p.getExteriorRing().getCoordinates(); final int N = coords.length - 1; // first coord == last coord Coordinate[][] controlPoints = getPolygonControlPoints(coords, N, alpha); List<Coordinate> smoothCoords = new ArrayList<Coordinate>(); double dist; for (int i = 0; i < N; i++) { int next = (i + 1) % N; dist = coords[i].distance(coords[next]); if (dist < control.getMinLength()) { // segment too short - just copy input coordinate smoothCoords.add(new Coordinate(coords[i])); } else { int smoothN = control.getNumVertices(dist); Coordinate[] segment = cubicBezier( coords[i], coords[next], controlPoints[i][1], controlPoints[next][0], smoothN); int copyN = i < N - 1 ? segment.length - 1 : segment.length; for (int k = 0; k < copyN; k++) { smoothCoords.add(segment[k]); } } } LinearRing shell = geomFactory.createLinearRing(smoothCoords.toArray(new Coordinate[0])); return geomFactory.createPolygon(shell, null); }
private static Geometry smoothLineString(GeometryFactory factory, GeometrySmoother smoother, Geometry geom, double fit) { if (geom instanceof LinearRing) { // Treat as a Polygon Polygon poly = factory.createPolygon((LinearRing) geom, null); Polygon smoothed = smoother.smooth(poly, fit); return smoothed.getExteriorRing(); } else { return smoother.smooth((LineString) geom, fit); } }
/** * Removes collinear vertices from the provided {@link Polygon}. * * @param polygon the instance of a {@link Polygon} to remove collinear vertices from. * @return a new instance of the provided {@link Polygon} without collinear vertices. */ static Polygon removeCollinearVertices(final Polygon polygon) { if (polygon == null) { throw new NullPointerException("The provided Polygon is null"); } // reuse existing factory final GeometryFactory gf = polygon.getFactory(); // work on the exterior ring LineString exterior = polygon.getExteriorRing(); LineString shell = removeCollinearVertices(exterior); if ((shell == null) || shell.isEmpty()) { return null; } // work on the holes List<LineString> holes = new ArrayList<LineString>(); final int size = polygon.getNumInteriorRing(); for (int i = 0; i < size; i++) { LineString hole = polygon.getInteriorRingN(i); hole = removeCollinearVertices(hole); if ((hole != null) && !hole.isEmpty()) { holes.add(hole); } } return gf.createPolygon((LinearRing) shell, holes.toArray(new LinearRing[holes.size()])); }