GeoLatte / geolatte-geom

A geometry model that conforms to the OGC Simple Features for SQL specification.
Other
132 stars 63 forks source link

Excact equality test fails for geometry collections containing a single element only #133

Closed guischulz closed 3 years ago

guischulz commented 3 years ago

The helper method JTSUtils.equalsExact3D(Geometry g1, Geometry g2) fails when comparing MultiPoints, MultiLines or MultiPolygons that only have a single element.

StackTrace: java.lang.IllegalStateException: Only simple geometries should be used at org.geolatte.geom.jts.JTSUtils.equals3DPrimitiveGeometries(JTSUtils.java:100) at org.geolatte.geom.jts.JTSUtils.equalsExact3D(JTSUtils.java:41)

   @Test
    public void testMultiPointsWithOneGeom() {
        MultiPoint mp1 = (MultiPoint) JTS.to(multipoint(WGS84, g(3.1, 50.2)));
        MultiPoint mp2 = (MultiPoint) JTS.to(multipoint(WGS84, g(3.1, 50.2)));
        MultiPoint mp3 = (MultiPoint) JTS.to(multipoint(WGS84, g(3.1, 51.2)));
        assertTrue(equalsExact3D(mp1, mp2));
        assertFalse(equalsExact3D(mp1, mp3));
    }

    @Test
    public void testMultiLineStringWithOneGeom() {
        MultiLineString ml1 = (MultiLineString) JTS.to(multilinestring(WGS84,
                linestring(g(3, 50), g(3.1, 50.2))
        ));
        MultiLineString ml2 = (MultiLineString) JTS.to(multilinestring(WGS84,
                linestring(g(3, 50), g(3.1, 50.2))
        ));
        MultiLineString ml3 = (MultiLineString) JTS.to(multilinestring(WGS84,
                linestring(g(3, 50), g(3.2, 50.2))
        ));
        assertTrue(equalsExact3D(ml1, ml2));
        assertFalse(equalsExact3D(ml1, ml3));
    }

    @Test
    public void testMultiPolygonsWithOneGeom() {
        MultiPolygon mpg1 = (MultiPolygon) JTS.to(multipolygon(polygon(WGS84,
                ring(g(3, 40), g(3.2, 40.1), g(3, 40)),
                ring(g(3.01, 40.01), g(3.02, 40.09), g(3.01, 40.01))
        )));
        MultiPolygon mpg2 = (MultiPolygon) JTS.to(multipolygon(polygon(WGS84,
                ring(g(3, 40), g(3.2, 40.1), g(3, 40)),
                ring(g(3.01, 40.01), g(3.02, 40.09), g(3.01, 40.01))
        )));
        MultiPolygon mpg3 = (MultiPolygon) JTS.to(multipolygon(polygon(WGS84,
                ring(g(3, 40), g(3.2, 40.1), g(3, 40)),
                ring(g(3.01, 40.01), g(3.03, 40.09), g(3.01, 40.01))
        )));
        assertTrue(equalsExact3D(mpg1, mpg2));
        assertFalse(equalsExact3D(mpg1, mpg3));
    }

Extending the comparision in JTSUtils.equalsExact3D(Geometry g1, Geometry g2) would probably be sufficient, like

        if (ng1 == 1 && !(g1 instanceof GeometryCollection)) {
            return equals3DPrimitiveGeometries(g1, g2);
        }
maesenka commented 3 years ago

Thanks for catching this. I'll be using your suggestion to fix this.