/** * make sure outer ring is CCW and holes are CW * * @param p polygon to check */ Polygon makeGoodSHAPEPolygon(Polygon p) { LinearRing outer; LinearRing[] holes = new LinearRing[p.getNumInteriorRing()]; Coordinate[] coords; coords = p.getExteriorRing().getCoordinates(); if (cga.isCCW(coords)) { outer = reverseRing((LinearRing) p.getExteriorRing()); } else { outer = (LinearRing) p.getExteriorRing(); } for (int t = 0; t < p.getNumInteriorRing(); t++) { coords = p.getInteriorRingN(t).getCoordinates(); if (!(cga.isCCW(coords))) { holes[t] = reverseRing((LinearRing) p.getInteriorRingN(t)); } else { holes[t] = (LinearRing) p.getInteriorRingN(t); } } return new Polygon(outer, holes, new PrecisionModel(), 0); }
private void validate(final Geometry geom, final List<ValidationResult> validationErrors) { if (geom.isEmpty()) { return; } if (geom instanceof GeometryCollection) { final GeometryCollection gc = (GeometryCollection) geom; for (int numGeom = 0; numGeom < gc.getNumGeometries(); numGeom++) { validate(gc.getGeometryN(numGeom), validationErrors); } } final ValidationResult result = new ValidationResult(); result.setWkt(geom.toText()); final List<String> messages = new ArrayList<String>(); if (!geom.isValid()) { messages.add("Error en topología básica"); } if (!geom.isSimple()) { messages.add("No es una geometría simple"); } if (repeatedPointTester.hasRepeatedPoint(geom)) { messages.add("Se encuentran vértices repetidos"); } if (geom instanceof Polygon) { final Polygon polygon = (Polygon) geom; if (CGAlgorithms.isCCW(polygon.getExteriorRing().getCoordinates())) { messages.add("Error en orientación del polígono"); } else { for (int numRing = 0; numRing < polygon.getNumInteriorRing(); numRing++) { if (!CGAlgorithms.isCCW(polygon.getInteriorRingN(numRing).getCoordinates())) { messages.add("Error en orientación del polígono en anillos interiores"); break; } } } if (!validateMinPolygonArea(geom)) { messages.add("Error en validación mínima de area de un polígono"); } } if (!validateMinSegmentLength(geom)) { messages.add("Error en validación mínima de longitud de segmento"); } if (!messages.isEmpty()) { result.setMessages(messages); validationErrors.add(result); } }
/** * Sets the orientation of an array of coordinates. * * @param coord the coordinates to inspect * @param desiredOrientation CGAlgorithms.CLOCKWISE or CGAlgorithms.COUNTERCLOCKWISE * @return a new array with entries in reverse order, if the orientation is incorrect; otherwise, * the original array */ public static Coordinate[] ensureOrientation(Coordinate[] coord, int desiredOrientation) { if (coord.length == 0) { return coord; } int orientation = cga.isCCW(coord) ? CGAlgorithms.COUNTERCLOCKWISE : CGAlgorithms.CLOCKWISE; if (orientation != desiredOrientation) { Coordinate[] reverse = (Coordinate[]) coord.clone(); CoordinateArrays.reverse(reverse); return reverse; } return coord; }
/** * Check if it's CW. * * @param linearRing * @return true if the ring has a clock wise orientation */ private boolean isCW(final LinearRing linearRing) { Coordinate[] ringCoord = linearRing.getCoordinates(); return !CGAlgorithms.isCCW(ringCoord); }
private static boolean isClockwiseRectangle(Geometry geo) { return geo != null && geo.isRectangle() && !CGAlgorithms.isCCW(geo.getCoordinates()); }
/** * Tests whether this ring is a hole. Due to the way the edges in the polyongization graph are * linked, a ring is a hole if it is oriented counter-clockwise. * * @return <code>true</code> if this ring is a hole */ public boolean isHole() { LinearRing ring = getRing(); return CGAlgorithms.isCCW(ring.getCoordinates()); }