jts

What influence has the JTS precision model on coordinates and topo functions?


How does the JTS Precision model work? I couldn't find a good explanation on the internet so far.

Intuitively I expected that any coordinate would be 'rounded' or 'snapped' to the grid according to the PrecisionModel. But this is not reality. Please help me understand it.

PrecisionModel pm = new PrecisionModel( 10D); // 10 d
GeometryFactory gfpm = new GeometryFactory(pm);
Coordinate coord = new Coordinate(0.0, 0.0);
Point point1 = gfpm.createPoint(coord);
Coordinate coord2 = new Coordinate(1.0, 1.0);
Point point2 = gfpm.createPoint(coord2);
System.out.printf("Distance: %.4f%n", point1.distance(point2));
// Gives: Distance: 1,4142

Coordinate coord3 = new Coordinate(0.1, 0.1);
Point point3 = gfpm.createPoint(coord3);
System.out.printf("Distance: %.4f%n", point1.distance(point3));
// Gives: Distance: 0,1414

Coordinate coord4 = new Coordinate(0.0001, 0.0001); // valid?
Point point4 = gfpm.createPoint(coord4);
System.out.printf("Distance: %.4f%n", point1.distance(point4));
// Gives: Distance: 0,0001 
System.out.printf( "Coord4: pm=%s coord=%.4f:%.4f%n", point4.getPrecisionModel().toString(), point4.getX(), point4.getY());
// Gives: Coord4: pm=Fixed (Scale=10.0) coord=0,0001:0,0001

I expected that coord4 should be snapped to the scale-10 grid. I would expect coord4 be snapped to the 0.0, 0.0 grid.


Solution

  • The precisionmodel should be APPLIED on the geometries. Nothing automatic here (of course). Via this JTS FAQ you find some background information.

    PrecisionModel pm = new PrecisionModel( 10D); // 10 d
    GeometryFactory gfpm = new GeometryFactory(pm);
    Coordinate coord = new Coordinate(0.0, 0.0);
    Point point1 = gfpm.createPoint(coord);
    Geometry point1Reduced = reducePrecision( point1, pm);
    
    Coordinate coord5 = new Coordinate(0.188, 0.188); // valid?
    Point point5 = gfpm.createPoint(coord5);
    Geometry point5Reduced = reducePrecision( point5, pm);
    System.out.printf("Distance-unreduced: %.4f%n", point1.distance(point5));
    System.out.printf( "Point1 reduced: %s. Point5 reduced: %s%n",
                       point1Reduced, point5Reduced);
    System.out.printf("Distance-reduced: %.4f%n", point1Reduced.distance(point5Reduced));
    

    The output is:

    Distance-unreduced: 0,2659
    Point1 reduced: POINT (0 0). Point5 reduced: POINT (0.2 0.2)
    Distance-reduced: 0,2828