jts
jts copied to clipboard
CoordinateXYM causes invalid ordinate exception
Hugh reported an issue with LineStringM on the GeoTools-user list. From the message:
"I can create a LinestringM object from an array of CoordinateXYM objects. But calling a function on the geom (e.g. line.getLength()) causes the following error. (I’m using Java 11).
Exception in thread "MyAppClient-StreamThread-1" java.lang.IllegalArgumentException: Invalid ordinate index: 3
at org.locationtech.jts.geom.Coordinate.setM(Coordinate.java:190)
at org.locationtech.jts.geom.impl.CoordinateArraySequence.getCoordinate(CoordinateArraySequence.java:234)
at org.locationtech.jts.algorithm.Length.ofLine(Length.java:41)
at org.locationtech.jts.geom.LineString.getLength(LineString.java:163)
at au.com.iag.transformation.local.setup.SJSummaryAggregation.lambda$main$1(SJSummaryAggregation.java:136)
at org.apache.kafka.streams.kstream.internals.KStreamAggregate$KStreamAggregateProcessor.process(KStreamAggregate.java:91)
at org.apache.kafka.streams.processor.internals.ProcessorNode.process(ProcessorNode.java:115)
....
Here’s my code:
CoordinateXYM[] coords = new CoordinateXYM[num_points];
int i = 0;
for (Waypoint waypoint : waypoints) {
CoordinateXYM coord = new CoordinateXYM(waypoint.getLon(), waypoint.getLat(), waypoint.getUnixTime());
coords[i] = coord;
i++;
}
LineString line = geometryFactory.createLineString(coords);
System.out.println(line.getLength());
"
Thanks for filing this, @jnh5y
The createLineString
method converts the arg coordinate array into a CoordinateSequence
using the CoordinateSequenceFactory
defined in the geometryFactory
. So that might be an important piece of information as well.
But I will try testing with the default CoordinateArraySequenceFactory
and see if the error can be reproduced.
Amazing how hard it is to get the new Coordinate dimension extensions right...
This error does not occur in master. I have added a unit test for it in #371.
I think there was some fixes to the Coordinate craziness post-release of 1.16? So maybe this is an issue with older code?
FYI - I was using the version of JTS in Geotools 21-RC
Can you indicate the exact JTS jar version?
jts-core version is 1.16.0.
Also, @jodygarnett made this point on the GeoTools-user list:
Can you confirm you have setup the geometryFactory with the correct dimensions?
I haven't done that in my code due to lack of Geotools experience. I'm simply using the default geometryFactory, i.e:
GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null);
Does this relate to the issue?
This is caused by a bug in 1.16. The bug was fixed in #333.
@jodygarnett Can this be closed?
Actually I was just about to open a new bug regarding this behavior... when I saw NTS's tests failing, I saw that the defect is actually in the code implicated by the stack trace itself: https://github.com/locationtech/jts/blob/a579291fbd1c1313652c701aa32e0d35e02e0030/modules/core/src/main/java/org/locationtech/jts/algorithm/Length.java#L40-L41
I feel like a fix that only touches CoordinateArraySequence
is naive, because the problem isn't specific to that implementation; it's actually that we should be using createCoordinate
instead of new Coordinate()
for any coordinates that we want to use as the target of getCoordinate(int, Coordinate)
.
- At least, assuming that I'm not completely wrong about this being the use case for
createCoordinate
...
Full disclosure, I've only ported the commits up to 1.16.0, so it's possible that a later fix might have addressed this... I've only looked at the code on master
to confirm that the issue is still present in the callers, and that it would likely be present when using packed sequences or other sequences that assume that the Coordinate
given to getCoordinate(int, Coordinate)
was created via createCoordinate()
(which should be a fair assumption because of this note in the javadoc).
My initial fixes were here: NetTopologySuite/NetTopologySuite@35fa4fc (note how RectangleIntersects
was solved, to keep heap allocations the same), and so these are the equivalent spots in JTS (edit: missed NetTopologySuite/NetTopologySuite@65bd052 which was masked by another NTS-specific problem):
- https://github.com/locationtech/jts/blob/a579291fbd1c1313652c701aa32e0d35e02e0030/modules/core/src/main/java/org/locationtech/jts/algorithm/Area.java#L96-L100
- https://github.com/locationtech/jts/blob/a579291fbd1c1313652c701aa32e0d35e02e0030/modules/core/src/main/java/org/locationtech/jts/algorithm/Length.java#L40-L41
- https://github.com/locationtech/jts/blob/a579291fbd1c1313652c701aa32e0d35e02e0030/modules/core/src/main/java/org/locationtech/jts/algorithm/PointLocation.java#L62-L67
- https://github.com/locationtech/jts/blob/a579291fbd1c1313652c701aa32e0d35e02e0030/modules/core/src/main/java/org/locationtech/jts/operation/distance3d/Distance3DOp.java#L412-L420
- https://github.com/locationtech/jts/blob/a579291fbd1c1313652c701aa32e0d35e02e0030/modules/core/src/main/java/org/locationtech/jts/operation/predicate/RectangleContains.java#L126-L130
- https://github.com/locationtech/jts/blob/a579291fbd1c1313652c701aa32e0d35e02e0030/modules/core/src/main/java/org/locationtech/jts/operation/predicate/RectangleIntersects.java#L233-L236
- Combination of
- https://github.com/locationtech/jts/blob/a579291fbd1c1313652c701aa32e0d35e02e0030/modules/core/src/main/java/org/locationtech/jts/operation/predicate/RectangleIntersects.java#L269-L270
- https://github.com/locationtech/jts/blob/a579291fbd1c1313652c701aa32e0d35e02e0030/modules/core/src/main/java/org/locationtech/jts/operation/predicate/RectangleIntersects.java#L327-L328
It's possible that there are more; these are just the ones that caused our tests to fail, because (at least for the time being) our base Coordinate
class changed to XY, so we started finding these kinds of errors even with plain ol' XYZ sequences.
Another edit: not sure if AxisPlaneCoordinateSequence.getDimension()
returning 2 is going to be a problem for you too if this gets fixed... it was for me, so I'm having ours override CreateCoordinate
to return a coordinate with the Z-ordinate.
Good analysis, @airbreather . I think this is the same as #375 (but more general) ?