Re: [Jts-topo-suite-user] IllegalArgumentException: Comparison method violates its general contract
Brought to you by:
dr_jts
From: Janda M. <ja...@cr...> - 2014-06-30 12:17:37
|
Hi, I isolated the problem with small test case: The problem is in calling "LineSegment:orientationIndex" from "SubgraphDepthLocater$DepthSegment:compareTo". Test case: public class TestBuffer { public static void main(String[] args) { LineSegment segment1 = new LineSegment(13.4411564327, 51.8421162769, 13.4428710938, 51.8422851563); LineSegment segment2 = new LineSegment(13.4428710938, 51.8422851563, 13.4427022144, 51.8439998173); int index1 = segment1.orientationIndex(segment2); int index2 = segment2.orientationIndex(segment1); System.out.printf("Index: %d, %d%n", index1, index2); } } This test prints "Index: 1, 1". Method "compareTo" requires output "Index: 1, -1". I think that "LineSegment:orientationIndex" works correctly but it is not suitable for "DepthSegment:compareTo" Proposed solution: 1) Keep "LineSegment:orientationIndex" without change 2) make SubgraphDepthLocater$DepthSegment STATIC class - to reduce allocated memory 3) introduce static method "orientationIndex" to SubgraphDepthLocater$DepthSegment - this is modified version of "LineSegment:orientationIndex" private static int orientationIndex(LineSegment s1, LineSegment seg) { int orient0 = CGAlgorithms.orientationIndex(s1.p0, s1.p1, seg.p0); int orient1 = CGAlgorithms.orientationIndex(s1.p0, s1.p1, seg.p1); if (orient0 == orient1) return orient0; return 0; } 4) modify compareTo method in DepthSegment private int compare(final DepthSegment other) { /** * try and compute a determinate orientation for the segments. * Test returns 1 if other is left of this (i.e. this > other) */ int orientIndex = orientationIndex(upwardSeg, other.upwardSeg); // MODIFIED call local method /** * If comparison between this and other is indeterminate, * try the opposite call order. * orientationIndex value is 1 if this is left of other, * so have to flip sign to get proper comparison value of * -1 if this is leftmost */ if (orientIndex == 0) orientIndex = -1 * orientationIndex(other.upwardSeg, upwardSeg); // MODIFIED call local method // if orientation is determinate, return it if (orientIndex != 0) return orientIndex; // otherwise, segs must be collinear - sort based on minimum X value return compareX(this.upwardSeg, other.upwardSeg); } ----------- I don't know whether this is correct modification without introducing regression. I hope that this help fix this issue. Thank you Martin ----- Original Message ----- From: "Janda Martin" <ja...@cr...> To: jts...@li..., "jts-devel" <jts...@li...> Sent: Monday, June 30, 2014 12:17:32 PM Subject: [Jts-topo-suite-user] IllegalArgumentException: Comparison method violates its general contract! Hi, I got "IllegalArgumentException: Comparison method violates its general contract!" in BufferOp. This issue was introduced by changes in Java 7 sorting algorithm. It was already discussed on this mailing list (2012-11-05 - http://ehc.ac/p/jts-topo-suite/mailman/message/30057535/ ) . I'm using JTS 1.13. And I don't see fix in trunk (I didn't test trunk version). This is showstopper for me. Will this issue be fixed soon? Or should I try to fix it and send patch to JTS? Thank you Martin Stack trace from older post: Exception in thread "pool-357-thread-8" java.lang.IllegalArgumentException: Comparison method violates its general contract! at java.util.ComparableTimSort.mergeLo(ComparableTimSort.java:714) at java.util.ComparableTimSort.mergeAt(ComparableTimSort.java:451) at java.util.ComparableTimSort.mergeCollapse(ComparableTimSort.java:376) at java.util.ComparableTimSort.sort(ComparableTimSort.java:182) at java.util.ComparableTimSort.sort(ComparableTimSort.java:146) at java.util.Arrays.sort(Arrays.java:472) at java.util.Collections.sort(Collections.java:155) at com.vividsolutions.jts.operation.buffer.SubgraphDepthLocater.getDepth(SubgraphDepthLocater.java:66) at com.vividsolutions.jts.operation.buffer.BufferBuilder.buildSubgraphs(BufferBuilder.java:289) at com.vividsolutions.jts.operation.buffer.BufferBuilder.buffer(BufferBuilder.java:156) at com.vividsolutions.jts.operation.buffer.BufferOp.bufferFixedPrecision(BufferOp.java:368) at com.vividsolutions.jts.operation.buffer.BufferOp.bufferReducedPrecision(BufferOp.java:356) at com.vividsolutions.jts.operation.buffer.BufferOp.bufferReducedPrecision(BufferOp.java:320) at com.vividsolutions.jts.operation.buffer.BufferOp.computeGeometry(BufferOp.java:312) at com.vividsolutions.jts.operation.buffer.BufferOp.getResultGeometry(BufferOp.java:299) at com.vividsolutions.jts.operation.buffer.BufferOp.bufferOp(BufferOp.java:175) at com.vividsolutions.jts.geom.Geometry.buffer(Geometry.java:1180) at ch.valnova.ontracktiler.simplify.TileGeometrySimplifier.simplifyGeometry(TileGeometrySimplifier.java:110) at ch.valnova.ontracktiler.DatabaseTiler$ProcessingRunnable.doProcessing(DatabaseTiler.java:134) at ch.valnova.ontracktiler.DatabaseTiler$ProcessingRunnable.run(DatabaseTiler.java:117) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) at java.lang.Thread.run(Thread.java:722) ------------------------------------------------------------------------------ Open source business process management suite built on Java and Eclipse Turn processes into business applications with Bonita BPM Community Edition Quickly connect people, data, and systems into organized workflows Winner of BOSSIE, CODIE, OW2 and Gartner awards http://p.sf.net/sfu/Bonitasoft _______________________________________________ Jts-topo-suite-user mailing list Jts...@li... https://lists.sourceforge.net/lists/listinfo/jts-topo-suite-user |