com.vividsolutions.jts.algorithm.CGAlgorithms Java Examples

The following examples show how to use com.vividsolutions.jts.algorithm.CGAlgorithms. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: CoordinateUtil.java    From geowe-core with GNU General Public License v3.0 6 votes vote down vote up
public Coordinate[] ensureOrientation(
		final int desiredOrientation, final Coordinate... coord) {
	if (coord.length == 0) {
		return coord;
	}

	final int orientation = CGAlgorithms.isCCW(coord) ? CGAlgorithms.COUNTERCLOCKWISE
			: CGAlgorithms.CLOCKWISE;

	if (orientation != desiredOrientation) {
		final Coordinate[] reverse = (Coordinate[]) coord.clone();
		reverse(reverse);

		return reverse;
	}

	return coord;
}
 
Example #2
Source File: DistanceLineLineStressTest.java    From jts with GNU Lesser General Public License v2.1 6 votes vote down vote up
public void testRandomDisjointCollinearSegments() throws Exception
{
  int n = 1000000;
  int failCount = 0;
  for (int i = 0; i < n; i++) {
    //System.out.println(i);
    Coordinate[] seg = randomDisjointCollinearSegments();
    if (0 == CGAlgorithms.distanceLineLine(seg[0], seg[1], seg[2], seg[3])) {
      /*
      System.out.println("FAILED! - "
          + WKTWriter.toLineString(seg[0], seg[1]) + "  -  "
          + WKTWriter.toLineString(seg[2], seg[3]));
          */
      failCount++;
    }
  }
  System.out.println("# failed = " + failCount + " out of " + n);
}
 
Example #3
Source File: MinimumClearance.java    From jts with GNU Lesser General Public License v2.1 6 votes vote down vote up
private double segmentDistance(FacetSequence fs1, FacetSequence fs2) {
 for (int i1 = 0; i1 < fs1.size(); i1++) {
   for (int i2 = 1; i2 < fs2.size(); i2++) {
     
     Coordinate p = fs1.getCoordinate(i1);
     
     Coordinate seg0 = fs2.getCoordinate(i2-1);
     Coordinate seg1 = fs2.getCoordinate(i2);
     
     if (! (p.equals2D(seg0) || p.equals2D(seg1))) {
       double d = CGAlgorithms.distancePointLine(p, seg0, seg1);
       if (d < minDist) {
         minDist = d;
         updatePts(p, seg0, seg1);
         if (d == 0.0)
           return d;
       }
     }
   }
 }
 return minDist;
}
 
Example #4
Source File: FacetSequence.java    From jts with GNU Lesser General Public License v2.1 6 votes vote down vote up
private double computeLineLineDistance(FacetSequence facetSeq)
{
  // both linear - compute minimum segment-segment distance
  double minDistance = Double.MAX_VALUE;

  for (int i = start; i < end - 1; i++) {
    for (int j = facetSeq.start; j < facetSeq.end - 1; j++) {
      pts.getCoordinate(i, p0);
      pts.getCoordinate(i + 1, p1);
      facetSeq.pts.getCoordinate(j, q0);
      facetSeq.pts.getCoordinate(j + 1, q1);
      
      double dist = CGAlgorithms.distanceLineLine(p0, p1, q0, q1);
      if (dist == 0.0) 
        return 0.0;
      if (dist < minDistance) {
        minDistance = dist;
      }
    }
  }
  return minDistance;
}
 
Example #5
Source File: OffsetSegmentGenerator.java    From jts with GNU Lesser General Public License v2.1 6 votes vote down vote up
/**
 * Adds points for a circular fillet arc
 * between two specified angles.  
 * The start and end point for the fillet are not added -
 * the caller must add them if required.
 *
 * @param direction is -1 for a CW angle, 1 for a CCW angle
 * @param radius the radius of the fillet
 */
private void addFillet(Coordinate p, double startAngle, double endAngle, int direction, double radius)
{
  int directionFactor = direction == CGAlgorithms.CLOCKWISE ? -1 : 1;

  double totalAngle = Math.abs(startAngle - endAngle);
  int nSegs = (int) (totalAngle / filletAngleQuantum + 0.5);

  if (nSegs < 1) return;    // no segments because angle is less than increment - nothing to do!

  double initAngle, currAngleInc;

  // choose angle increment so that each segment has equal length
  initAngle = 0.0;
  currAngleInc = totalAngle / nSegs;

  double currAngle = initAngle;
  Coordinate pt = new Coordinate();
  while (currAngle < totalAngle) {
    double angle = startAngle + directionFactor * currAngle;
    pt.x = p.x + radius * Math.cos(angle);
    pt.y = p.y + radius * Math.sin(angle);
    segList.addPt(pt);
    currAngle += currAngleInc;
  }
}
 
Example #6
Source File: OffsetSegmentGenerator.java    From jts with GNU Lesser General Public License v2.1 6 votes vote down vote up
/**
 * Add points for a circular fillet around a reflex corner.
 * Adds the start and end points
 * 
 * @param p base point of curve
 * @param p0 start point of fillet curve
 * @param p1 endpoint of fillet curve
 * @param direction the orientation of the fillet
 * @param radius the radius of the fillet
 */
private void addFillet(Coordinate p, Coordinate p0, Coordinate p1, int direction, double radius)
{
  double dx0 = p0.x - p.x;
  double dy0 = p0.y - p.y;
  double startAngle = Math.atan2(dy0, dx0);
  double dx1 = p1.x - p.x;
  double dy1 = p1.y - p.y;
  double endAngle = Math.atan2(dy1, dx1);

  if (direction == CGAlgorithms.CLOCKWISE) {
    if (startAngle <= endAngle) startAngle += 2.0 * Math.PI;
  }
  else {    // direction == COUNTERCLOCKWISE
    if (startAngle >= endAngle) startAngle -= 2.0 * Math.PI;
  }
  segList.addPt(p0);
  addFillet(p, startAngle, endAngle, direction, radius);
  segList.addPt(p1);
}
 
Example #7
Source File: BufferInputLineSimplifier.java    From jts with GNU Lesser General Public License v2.1 6 votes vote down vote up
/**
 * Simplify the input coordinate list.
 * If the distance tolerance is positive, 
 * concavities on the LEFT side of the line are simplified.
 * If the supplied distance tolerance is negative,
 * concavities on the RIGHT side of the line are simplified.
 * 
 * @param distanceTol simplification distance tolerance to use
 * @return the simplified coordinate list
 */
public Coordinate[] simplify(double distanceTol)
{
  this.distanceTol = Math.abs(distanceTol);
  if (distanceTol < 0)
    angleOrientation = CGAlgorithms.CLOCKWISE;
  
  // rely on fact that boolean array is filled with false value
  isDeleted = new byte[inputLine.length];
  
  boolean isChanged = false;
  do {
    isChanged = deleteShallowConcavities();
  } while (isChanged);
  
  return collapseLine();
}
 
Example #8
Source File: RoadSkill.java    From gama with GNU General Public License v3.0 6 votes vote down vote up
public static int getSegmentIndex(final IAgent road, final IAgent driver) {
	final GamaPoint[] coords = GeometryUtils.getPointsOf(road);
	if (coords.length == 2) { return 0; }

	final GamaPoint loc = driver.getLocation().toGamaPoint();
	for (int i = 0; i < coords.length - 1; i++) {
		if (coords[i].equals(loc)) { return i; }
	}
	double distanceS = Double.MAX_VALUE;
	int indexSegment = 0;
	final int nbSp = coords.length;
	for (int i = 0; i < nbSp - 1; i++) {
		final double distS = CGAlgorithms.distancePointLine(loc, coords[i], coords[i + 1]);
		if (distS < distanceS) {
			distanceS = distS;
			indexSegment = i;
		}
	}
	return indexSegment;

}
 
Example #9
Source File: GeometryLocationsWriter.java    From jts with GNU Lesser General Public License v2.1 6 votes vote down vote up
private String componentType(GeometryLocation loc) {
  String compType = "";
  if (loc.getComponent() instanceof LinearRing) {
    boolean isCCW = CGAlgorithms.isCCW(loc.getComponent().getCoordinates());
    compType = "Ring" 
      + (isCCW ? "-CCW" : "-CW ")
        + " ";
  }
  else if (loc.getComponent() instanceof LineString) { 
    compType = "Line  ";
  }
  else if (loc.getComponent() instanceof Point) { 
    compType = "Point ";
  }
  return compType;
}
 
Example #10
Source File: CGAlgorithmFunctions.java    From jts with GNU Lesser General Public License v2.1 5 votes vote down vote up
public static int orientationIndex(Geometry segment, Geometry ptGeom) {
  if (segment.getNumPoints() != 2 || ptGeom.getNumPoints() != 1) {
    throw new IllegalArgumentException("A must have two points and B must have one");
  }
  Coordinate[] segPt = segment.getCoordinates();
  
  Coordinate p = ptGeom.getCoordinate();
  int index = CGAlgorithms.orientationIndex(segPt[0], segPt[1], p);
  return index;
}
 
Example #11
Source File: LinearRingImpl.java    From mrgeo with Apache License 2.0 5 votes vote down vote up
@Override
public boolean isCCW()
{
  Coordinate[] coordinates = new Coordinate[getNumPoints()];
  for (int i = 0; i < getNumPoints(); i++)
  {
    Point pt = getPoint(i);
    coordinates[i] = new Coordinate(pt.getX(), pt.getY());
  }

  return CGAlgorithms.isCCW(coordinates);
}
 
Example #12
Source File: CoordinateUtil.java    From geowe-core with GNU General Public License v3.0 5 votes vote down vote up
public void addCoordinateArrays(final Geometry geometry, final boolean orientPolygons,
		final List<Coordinate[]> coordArrayList) {
	if (geometry.getDimension() <= 0) {
		return;
	} else if (geometry instanceof LineString) {
		final LineString l = (LineString) geometry;
		coordArrayList.add(l.getCoordinates());
	} else if (geometry instanceof Polygon) {
		final Polygon poly = (Polygon) geometry;
		Coordinate[] shell = poly.getExteriorRing().getCoordinates();

		if (orientPolygons) {
			shell = ensureOrientation(CGAlgorithms.CLOCKWISE, shell);
		}

		coordArrayList.add(shell);

		for (int numRing = 0; numRing < poly.getNumInteriorRing(); numRing++) {
			Coordinate[] hole = poly.getInteriorRingN(numRing).getCoordinates();

			if (orientPolygons) {
				hole = ensureOrientation(
						CGAlgorithms.COUNTERCLOCKWISE, hole);
			}

			coordArrayList.add(hole);
		}
	} else if (geometry instanceof GeometryCollection) {
		final GeometryCollection gc = (GeometryCollection) geometry;

		for (int numGeom = 0; numGeom < gc.getNumGeometries(); numGeom++) {
			addCoordinateArrays(gc.getGeometryN(numGeom), orientPolygons,
					coordArrayList);
		}
	}
}
 
Example #13
Source File: RobustLineIntersectorTest.java    From jts with GNU Lesser General Public License v2.1 5 votes vote down vote up
public void testA() {
  Coordinate p1 = new Coordinate(-123456789, -40);
  Coordinate p2 = new Coordinate(381039468754763d, 123456789);
  Coordinate q  = new Coordinate(0, 0);
  LineString l = new GeometryFactory().createLineString(new Coordinate[] {p1, p2});
  Point p = new GeometryFactory().createPoint(q);
  assertEquals(false, l.intersects(p));
  assertEquals(false, CGAlgorithms.isOnLine(q, new Coordinate[] {p1, p2}));
  assertEquals(-1, CGAlgorithms.computeOrientation(p1, p2, q));
}
 
Example #14
Source File: RobustLineIntersectorTest.java    From jts with GNU Lesser General Public License v2.1 5 votes vote down vote up
public void testIsCCW2() {
  assertEquals(0, CGAlgorithms.computeOrientation(
      new Coordinate(10, 10),
      new Coordinate(20, 20),
      new Coordinate(0, 0)));
  assertEquals(0, NonRobustCGAlgorithms.computeOrientation(
      new Coordinate(10, 10),
      new Coordinate(20, 20),
      new Coordinate(0, 0)));
}
 
Example #15
Source File: EdgeRing.java    From jts with GNU Lesser General Public License v2.1 5 votes vote down vote up
/**
 * 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 = getLinearRing();
  Envelope env = shell.getEnvelopeInternal();
  if (! env.contains(p)) return false;
  if (! CGAlgorithms.isPointInRing(p, shell.getCoordinates()) ) return false;

  for (Iterator i = holes.iterator(); i.hasNext(); ) {
    EdgeRing hole = (EdgeRing) i.next();
    if (hole.containsPoint(p) )
      return false;
  }
  return true;
}
 
Example #16
Source File: EdgeRing.java    From jts with GNU Lesser General Public License v2.1 5 votes vote down vote up
/**
   * Compute a LinearRing from the point list previously collected.
   * Test if the ring is a hole (i.e. if it is CCW) and set the hole flag
   * accordingly.
   */
  public void computeRing()
  {
    if (ring != null) return;   // don't compute more than once
    Coordinate[] coord = new Coordinate[pts.size()];
    for (int i = 0; i < pts.size(); i++) {
      coord[i] = (Coordinate) pts.get(i);
    }
    ring = geometryFactory.createLinearRing(coord);
    isHole = CGAlgorithms.isCCW(ring.getCoordinates());
//Debug.println( (isHole ? "hole - " : "shell - ") + WKTWriter.toLineString(new CoordinateArraySequence(ring.getCoordinates())));
  }
 
Example #17
Source File: SimpleMinimumClearance.java    From jts with GNU Lesser General Public License v2.1 5 votes vote down vote up
private void checkSegmentDistance(Coordinate seg0, Coordinate seg1)
{
    if (queryPt.equals2D(seg0) || queryPt.equals2D(seg1))
      return;
    double segDist = CGAlgorithms.distancePointLine(queryPt, seg1, seg0);
    if (segDist > 0) 
      updateClearance(segDist, queryPt, seg1, seg0);
}
 
Example #18
Source File: FacetSequence.java    From jts with GNU Lesser General Public License v2.1 5 votes vote down vote up
private double computePointLineDistance(Coordinate pt, FacetSequence facetSeq) 
{
  double minDistance = Double.MAX_VALUE;

  for (int i = facetSeq.start; i < facetSeq.end - 1; i++) {
    facetSeq.pts.getCoordinate(i, q0);
    facetSeq.pts.getCoordinate(i + 1, q1);
    double dist = CGAlgorithms.distancePointLine(pt, q0, q1);
    if (dist == 0.0) return 0.0;
    if (dist < minDistance) {
      minDistance = dist;
    }
  }
  return minDistance;
}
 
Example #19
Source File: OffsetSegmentGenerator.java    From jts with GNU Lesser General Public License v2.1 5 votes vote down vote up
private void addCollinear(boolean addStartPoint)
{
  /**
   * This test could probably be done more efficiently,
   * but the situation of exact collinearity should be fairly rare.
   */
  li.computeIntersection(s0, s1, s1, s2);
  int numInt = li.getIntersectionNum();
  /**
   * if numInt is < 2, the lines are parallel and in the same direction. In
   * this case the point can be ignored, since the offset lines will also be
   * parallel.
   */
  if (numInt >= 2) {
    /**
     * segments are collinear but reversing. 
     * Add an "end-cap" fillet
     * all the way around to other direction This case should ONLY happen
     * for LineStrings, so the orientation is always CW. (Polygons can never
     * have two consecutive segments which are parallel but reversed,
     * because that would be a self intersection.
     * 
     */
    if (bufParams.getJoinStyle() == BufferParameters.JOIN_BEVEL 
        || bufParams.getJoinStyle() == BufferParameters.JOIN_MITRE) {
      if (addStartPoint) segList.addPt(offset0.p1);
      segList.addPt(offset1.p0);
    }
    else {
      addFillet(s1, offset0.p1, offset1.p0, CGAlgorithms.CLOCKWISE, distance);
    }
  }
}
 
Example #20
Source File: OffsetSegmentGenerator.java    From jts with GNU Lesser General Public License v2.1 5 votes vote down vote up
public void addNextSegment(Coordinate p, boolean addStartPoint)
{
  // s0-s1-s2 are the coordinates of the previous segment and the current one
  s0 = s1;
  s1 = s2;
  s2 = p;
  seg0.setCoordinates(s0, s1);
  computeOffsetSegment(seg0, side, distance, offset0);
  seg1.setCoordinates(s1, s2);
  computeOffsetSegment(seg1, side, distance, offset1);

  // do nothing if points are equal
  if (s1.equals(s2)) return;

  int orientation = CGAlgorithms.computeOrientation(s0, s1, s2);
  boolean outsideTurn =
        (orientation == CGAlgorithms.CLOCKWISE        && side == Position.LEFT)
    ||  (orientation == CGAlgorithms.COUNTERCLOCKWISE && side == Position.RIGHT);

  if (orientation == 0) { // lines are collinear
    addCollinear(addStartPoint);
  }
  else if (outsideTurn) 
  {
    addOutsideTurn(orientation, addStartPoint);
  }
  else { // inside turn
    addInsideTurn(orientation, addStartPoint);
  }
}
 
Example #21
Source File: GeometryFunctions.java    From jts with GNU Lesser General Public License v2.1 5 votes vote down vote up
public static boolean isCCW(Geometry g)
{
  Coordinate[] pts = null;
  if (g instanceof Polygon) {
    pts = ((Polygon) g).getExteriorRing().getCoordinates();
  } 
  else if (g instanceof LineString
      && ((LineString) g).isClosed()) {
    pts = g.getCoordinates();
  }
  if (pts == null) return false;
  return CGAlgorithms.isCCW(pts);
}
 
Example #22
Source File: BufferInputLineSimplifier.java    From jts with GNU Lesser General Public License v2.1 5 votes vote down vote up
private boolean isShallowConcavity(Coordinate p0, Coordinate p1, Coordinate p2, double distanceTol)
{
  int orientation = CGAlgorithms.computeOrientation(p0, p1, p2);
  boolean isAngleToSimplify = (orientation == angleOrientation);
  if (! isAngleToSimplify)
    return false;
  
  double dist = CGAlgorithms.distancePointLine(p1, p0, p2);
  return dist < distanceTol;
}
 
Example #23
Source File: SmallHoleRemover.java    From jts with GNU Lesser General Public License v2.1 4 votes vote down vote up
public boolean value(Geometry geom) {
  double holeArea = Math.abs(CGAlgorithms.signedArea(geom.getCoordinates()));
  return holeArea <= area;
}
 
Example #24
Source File: GeometryValidator.java    From geowe-core with GNU General Public License v3.0 4 votes vote down vote up
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. Coordenadas");
		result.setErrorsPoints(errorCoordinates);
	}


	if(!messages.isEmpty()) {
		result.setMessages(messages);
		validationErrors.add(result);
	}		
}
 
Example #25
Source File: BufferInputLineSimplifier.java    From jts with GNU Lesser General Public License v2.1 4 votes vote down vote up
private boolean isShallow(Coordinate p0, Coordinate p1, Coordinate p2, double distanceTol)
{
  double dist = CGAlgorithms.distancePointLine(p1, p0, p2);
  return dist < distanceTol;
}
 
Example #26
Source File: OffsetSegmentGenerator.java    From jts with GNU Lesser General Public License v2.1 4 votes vote down vote up
/**
 * Add an end cap around point p1, terminating a line segment coming from p0
 */
public void addLineEndCap(Coordinate p0, Coordinate p1)
{
  LineSegment seg = new LineSegment(p0, p1);

  LineSegment offsetL = new LineSegment();
  computeOffsetSegment(seg, Position.LEFT, distance, offsetL);
  LineSegment offsetR = new LineSegment();
  computeOffsetSegment(seg, Position.RIGHT, distance, offsetR);

  double dx = p1.x - p0.x;
  double dy = p1.y - p0.y;
  double angle = Math.atan2(dy, dx);

  switch (bufParams.getEndCapStyle()) {
    case BufferParameters.CAP_ROUND:
      // add offset seg points with a fillet between them
      segList.addPt(offsetL.p1);
      addFillet(p1, angle + Math.PI / 2, angle - Math.PI / 2, CGAlgorithms.CLOCKWISE, distance);
      segList.addPt(offsetR.p1);
      break;
    case BufferParameters.CAP_FLAT:
      // only offset segment points are added
      segList.addPt(offsetL.p1);
      segList.addPt(offsetR.p1);
      break;
    case BufferParameters.CAP_SQUARE:
      // add a square defined by extensions of the offset segment endpoints
      Coordinate squareCapSideOffset = new Coordinate();
      squareCapSideOffset.x = Math.abs(distance) * Math.cos(angle);
      squareCapSideOffset.y = Math.abs(distance) * Math.sin(angle);

      Coordinate squareCapLOffset = new Coordinate(
          offsetL.p1.x + squareCapSideOffset.x,
          offsetL.p1.y + squareCapSideOffset.y);
      Coordinate squareCapROffset = new Coordinate(
          offsetR.p1.x + squareCapSideOffset.x,
          offsetR.p1.y + squareCapSideOffset.y);
      segList.addPt(squareCapLOffset);
      segList.addPt(squareCapROffset);
      break;

  }
}
 
Example #27
Source File: QuadEdgeTriangle.java    From jts with GNU Lesser General Public License v2.1 4 votes vote down vote up
public boolean contains(Coordinate pt) {
	Coordinate[] ring = getCoordinates();
	return CGAlgorithms.isPointInRing(pt, ring);
}
 
Example #28
Source File: PolygonHandler.java    From jts with GNU Lesser General Public License v2.1 4 votes vote down vote up
private ArrayList assignHolesToShells(ArrayList shells, ArrayList holes)
{
  // now we have a list of all shells and all holes
  ArrayList holesForShells = new ArrayList(shells.size());
  for (int i = 0; i < shells.size(); i++) {
    holesForShells.add(new ArrayList());
  }

  // find homes
  for (int i = 0; i < holes.size(); i++) {
    LinearRing testHole = (LinearRing) holes.get(i);
    LinearRing minShell = null;
    Envelope minEnv = null;
    Envelope testHoleEnv = testHole.getEnvelopeInternal();
    Coordinate testHolePt = testHole.getCoordinateN(0);
    LinearRing tryShell;
    int nShells = shells.size();
    for (int j = 0; j < nShells; j++) {
      tryShell = (LinearRing) shells.get(j);
      Envelope tryShellEnv = tryShell.getEnvelopeInternal();
      if (! tryShellEnv.contains(testHoleEnv)) continue;
      
      boolean isContained = false;
      Coordinate[] coordList = tryShell.getCoordinates();

      if (nShells <= 1 
          || CGAlgorithms.isPointInRing(testHolePt, coordList) 
          || pointInList(testHolePt, coordList))
        isContained = true;
      
      // check if new containing ring is smaller than the current minimum ring
      if (minShell != null)
        minEnv = minShell.getEnvelopeInternal();
      if (isContained) {
        if (minShell == null || minEnv.contains(tryShellEnv)) {
          minShell = tryShell;
        }
      }
    }

    if (minShell == null) {
      System.err.println("Found polygon with a hole not inside a shell");
    }
    else {
      // ((ArrayList)holesForShells.get(shells.indexOf(minShell))).add(testRing);
      ((ArrayList) holesForShells.get(findIndex(shells, minShell)))
          .add(testHole);
    }
  }
  return holesForShells;
}
 
Example #29
Source File: OraReader.java    From jts with GNU Lesser General Public License v2.1 4 votes vote down vote up
/**
 * Read {@link Polygon) from encoded geometry.
 *
 * @param oraGeom SDO_GEOMETRY attributes being read
 * @param elemIndex the element being read
 * @param coords the coordinates of the entire geometry
 * @return Polygon as encoded by elemInfo, or null when faced with and
 *         encoding that can not be captured by JTS
 * @throws IllegalArgumentException When faced with an invalid SDO encoding
 */
private Polygon readPolygon(OraGeom oraGeom, int elemIndex) 
{
  int etype = oraGeom.eType(elemIndex);
  int interpretation = oraGeom.interpretation(elemIndex);

	checkOrdinates(oraGeom, elemIndex, "Polygon");
	checkETYPE(etype,OraGeom.ETYPE.POLYGON, OraGeom.ETYPE.POLYGON_EXTERIOR, "Polygon");
	checkInterpretation(interpretation, OraGeom.INTERP.POLYGON, OraGeom.INTERP.RECTANGLE, "Polygon");

  int nElem = oraGeom.numElements();
	// ETYPE is either POLYGON or POLYGON_EXTERIOR
  LinearRing exteriorRing = readLinearRing(oraGeom, elemIndex);

  /**
   * Holes are read as long as ETYPE = POLYGON_INTERIOR
   * or ETYPE = POLYGON && orient = CW (Hole)
   */
  List holeRings = new ArrayList();
  for (int i = elemIndex + 1; i < nElem; i++) {
    etype = oraGeom.eType(i);
    if (etype == OraGeom.ETYPE.POLYGON_INTERIOR) {
      holeRings.add(readLinearRing(oraGeom, i));
    } 
    else if (etype == OraGeom.ETYPE.POLYGON) { 
      // test orientation of Ring to see if it is
      // an interior (hole) ring
      LinearRing ring = readLinearRing(oraGeom, i);
      // TODO: use the coordSeq directly (requires new CGAlgorithms method)
      boolean isHole = ! CGAlgorithms.isCCW(ring.getCoordinates());
      // if not a hole, exit
      if (! isHole)
        break;
      // it is an Interior Hole
      holeRings.add(ring);
    } 
    else { // not a LinearRing - get out of here
        break;
    }
  }
  Polygon poly = geometryFactory.createPolygon(exteriorRing, 
      GeometryFactory.toLinearRingArray(holeRings));
  return poly;
}
 
Example #30
Source File: HalfEdge.java    From jts with GNU Lesser General Public License v2.1 4 votes vote down vote up
/**
 * Implements the total order relation:
 * <p>
 *    The angle of edge a is greater than the angle of edge b,
 *    where the angle of an edge is the angle made by 
 *    the first segment of the edge with the positive x-axis
 * <p>
 * When applied to a list of edges originating at the same point,
 * this produces a CCW ordering of the edges around the point.
 * <p>
 * Using the obvious algorithm of computing the angle is not robust,
 * since the angle calculation is susceptible to roundoff error.
 * A robust algorithm is:
 * <ul>
 * <li>First, compare the quadrants the edge vectors lie in.  
 * If the quadrants are different, 
 * it is trivial to determine which edge has a greater angle.
 * 
 * <li>if the vectors lie in the same quadrant, the 
 * {@link CGAlgorithms#computeOrientation(Coordinate, Coordinate, Coordinate)} function
 * can be used to determine the relative orientation of the vectors.
 * </ul>
 */
public int compareAngularDirection(HalfEdge e)
{
  double dx = deltaX();
  double dy = deltaY();
  double dx2 = e.deltaX();
  double dy2 = e.deltaY();
  
  // same vector
  if (dx == dx2 && dy == dy2)
    return 0;
  
  double quadrant = Quadrant.quadrant(dx, dy);
  double quadrant2 = Quadrant.quadrant(dx2, dy2);
  
  // if the vectors are in different quadrants, determining the ordering is trivial
  if (quadrant > quadrant2) return 1;
  if (quadrant < quadrant2) return -1;
  // vectors are in the same quadrant
  // Check relative orientation of direction vectors
  // this is > e if it is CCW of e
  return CGAlgorithms.computeOrientation(e.orig, e.dest(), dest());
}