return;
}
// load shapefile end (docs marker)
final SpatialIndex index = new STRtree();
FeatureCollection features = source.getFeatures();
System.out.println("Slurping in features ...");
features.accepts(new FeatureVisitor() {
@Override
public void visit(Feature feature) {
SimpleFeature simpleFeature = (SimpleFeature) feature;
Geometry geom = (MultiLineString) simpleFeature.getDefaultGeometry();
// Just in case: check for null or empty geometry
if (geom != null) {
Envelope env = geom.getEnvelopeInternal();
if (!env.isNull()) {
index.insert(env, new LocationIndexedLine(geom));
}
}
}
}, new NullProgressListener());
// cache features end (docs marker)
/*
* For test data, we generate a large number of points placed randomly
* within the bounding rectangle of the features.
*/
final int NUM_POINTS = 10000;
ReferencedEnvelope bounds = features.getBounds();
Coordinate[] points = new Coordinate[NUM_POINTS];
Random rand = new Random(file.hashCode());
for (int i = 0; i < NUM_POINTS; i++) {
points[i] = new Coordinate(
bounds.getMinX() + rand.nextDouble() * bounds.getWidth(),
bounds.getMinY() + rand.nextDouble() * bounds.getHeight());
}
// generate points end (docs marker)
/*
* We defined the maximum distance that a line can be from a point
* to be a candidate for snapping (1% of the width of the feature
* bounds for this example).
*/
final double MAX_SEARCH_DISTANCE = bounds.getSpan(0) / 100.0;
// Maximum time to spend running the snapping process (milliseconds)
final long DURATION = 5000;
int pointsProcessed = 0;
int pointsSnapped = 0;
long elapsedTime = 0;
long startTime = System.currentTimeMillis();
while (pointsProcessed < NUM_POINTS &&
(elapsedTime = System.currentTimeMillis() - startTime) < DURATION) {
// Get point and create search envelope
Coordinate pt = points[pointsProcessed++];
Envelope search = new Envelope(pt);
search.expandBy(MAX_SEARCH_DISTANCE);
/*
* Query the spatial index for objects within the search envelope.
* Note that this just compares the point envelope to the line envelopes
* so it is possible that the point is actually more distant than
* MAX_SEARCH_DISTANCE from a line.
*/
List<LocationIndexedLine> lines = index.query(search);
// Initialize the minimum distance found to our maximum acceptable
// distance plus a little bit
double minDist = MAX_SEARCH_DISTANCE + 1.0e-6;
Coordinate minDistPoint = null;