Pages

Wednesday 24 September 2008

Applying the Secrets of JTS

FOSS4G is next week - let me share a little gem from last years FOSS4G conference - Martin's Secrets of JTS presentation.

Talks like this cover material you can revisit, and revisit and revisit. Although Martin does his best to make JTS numercially stable; his presentations can sometimes induce a little recursion.

I revisited this set of slides today as I went over how to "snap" points onto a line - as fast you possibly can. The general set up is some laxidasical source of data that you wish to "auto correct" with the wild assumption that cars stay on roads (or the even better assumption that you have data for all the roads).

The general approach here is to take a peek at behind the API; in this case we can explore the technology that makes a method call like geometry.getDistance( point ) possible.

Here is the heart of the code example - for details see the GeoTools user guide:

Envelope search = new Envelope(pt);
search.expandBy(distance);

List hits = index.query( search );
double d = Double.MAX_VALUE;
Coordinate best = null;
for( LocationIndexedLine line : hits ){
LinearLocation here = line.project( pt );
Coordinate point = line.extractPoint( here );
double currentD = point.distance( pt );
if( currentD <k d ){
best = point;
}
}
if( best == null ){
// we did not manage to snap to a line?
// with real data sets this happens all the time...
System.out.println( pt + "-X");
}
else {
System.out.println( pt + "->" + best );
}



Documentation harmed in the making of this example: Using SpatialIndex and LocationIndexLine to Snap points.