/*
* Copyright (c) 2016 Vivid Solutions.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v. 1.0 which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
*
* http://www.eclipse.org/org/documents/edl-v10.php.
*/
package test.jts.perf.algorithm;
import java.util.Iterator;
import java.util.List;
import org.locationtech.jts.algorithm.PointInRing;
import org.locationtech.jts.algorithm.RobustDeterminant;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Envelope;
import org.locationtech.jts.geom.LineSegment;
import org.locationtech.jts.geom.LinearRing;
import org.locationtech.jts.index.strtree.SIRtree;
/**
* Implements {@link PointInRing}
* using a {@link SIRtree} index to
* increase performance.
*
* @version 1.7
* @deprecated use MCPointInRing instead
*/
public class SIRtreePointInRing implements PointInRing {
private LinearRing ring;
private SIRtree sirTree;
private int crossings = 0; // number of segment/ray crossings
public SIRtreePointInRing(LinearRing ring)
{
this.ring = ring;
buildIndex();
}
private void buildIndex()
{
Envelope env = ring.getEnvelopeInternal();
sirTree = new SIRtree();
Coordinate[] pts = ring.getCoordinates();
for (int i = 1; i < pts.length; i++) {
if (pts[i-1].equals(pts[i])) { continue; } //Optimization suggested by MD. [Jon Aquino]
LineSegment seg = new LineSegment(pts[i - 1], pts[i]);
sirTree.insert(seg.p0.y, seg.p1.y, seg);
}
}
public boolean isInside(Coordinate pt)
{
crossings = 0;
// test all segments intersected by vertical ray at pt
List segs = sirTree.query(pt.y);
//System.out.println("query size = " + segs.size());
for (Iterator i = segs.iterator(); i.hasNext(); ) {
LineSegment seg = (LineSegment) i.next();
testLineSegment(pt, seg);
}
/*
* p is inside if number of crossings is odd.
*/
if ((crossings % 2) == 1) {
return true;
}
return false;
}
private void testLineSegment(Coordinate p, LineSegment seg) {
double xInt; // x intersection of segment with ray
double x1; // translated coordinates
double y1;
double x2;
double y2;
/*
* Test if segment crosses ray from test point in positive x direction.
*/
Coordinate p1 = seg.p0;
Coordinate p2 = seg.p1;
x1 = p1.x - p.x;
y1 = p1.y - p.y;
x2 = p2.x - p.x;
y2 = p2.y - p.y;
if (((y1 > 0) && (y2 <= 0)) ||
((y2 > 0) && (y1 <= 0))) {
/*
* segment straddles x axis, so compute intersection.
*/
xInt = RobustDeterminant.signOfDet2x2(x1, y1, x2, y2) / (y2 - y1);
//xsave = xInt;
/*
* crosses ray if strictly positive intersection.
*/
if (0.0 < xInt) {
crossings++;
}
}
}
}