GeoLatte / geolatte-geom

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

Oracle Polygon Encoder may use wrong orientation of the rings #51

Closed stephanps closed 7 years ago

stephanps commented 7 years ago

AbstractSDOEncoder.addPolygon uses NumericalMethods.isCounterClockwise(PositionSequence) to decide if the order of the postions has to be reversed. As this method only takes the first angel into consideration the result is wrong if this angle is oriented contrary to the orientation of the geometry itself.

Variation of the existing Tests in org.geolatte.geom.codec.db.oracle.TestSdoPolygonEncoder with only the first vertex of the hole changed:

@Test
public void test2DPolygonWithHole2() {
    // changed Polygon of "test2DPolygonWithHole" so orientation of the first 3 vertices,
    // of the hole in the polygon to be encoded, differs from the orientation of the hole itself
    // POLYGON ((2 4, 4 3, 10 3, 13 5, 13 9, 11 13, 5 13, 2 11, 2 4), (7 5, 9 6, 10 10, 10 5, 7 5))
    SDOGeometry expected = SDOGeometryHelper.sdoGeometry(2003, wgs84.getCrsId().getCode(), null,
            new int[] { 1, 1003, 1, 19, 2003, 1 },
            new Double[] { 2d, 4d, 4d, 3d, 10d, 3d, 13d, 5d, 13d, 9d, 11d, 13d, 5d, 13d, 2d,
                    11d, 2d, 4d, 7d, 5d, 9d, 6d, 10d, 10d, 10d, 5d, 7d, 5d });
    Polygon<G2D> poly = polygon(wgs84,
            ring(g(2, 4), g(4, 3), g(10, 3), g(13, 5), g(13, 9), g(11, 13), g(5, 13), g(2, 11),
                    g(2, 4)), ring(g(7, 5), g(9, 6), g(10, 10), g(10, 5), g(7, 5)));

    assertEquals(expected, Encoders.encode(poly));
}

@Test
public void test2DPolygonWithReversedOrientationRings2() {
    // changed Polygon of "test2DPolygonWithHole" so orientation of the first 3 vertices,
    // of the hole in the polygon to be encoded, differs from the orientation of the hole itself
    // POLYGON ((2 4, 2 11, 5 13, 11 13, 13 9, 13 5, 10 3, 4 3, 2 4), (7 5, 8 9, 10 10, 7 10, 7 5))
    SDOGeometry expected = SDOGeometryHelper.sdoGeometry(2003, wgs84.getCrsId().getCode(), null,
            new int[] { 1, 1003, 1, 19, 2003, 1 },
            new Double[] { 2d, 4d, 4d, 3d, 10d, 3d, 13d, 5d, 13d, 9d, 11d, 13d, 5d, 13d, 2d,
                    11d, 2d, 4d, 7d, 5d, 7d, 10d, 10d, 10d, 8d, 9d, 7d, 5d });
    Polygon<G2D> poly = polygon(wgs84,
            ring(g(2, 4), g(2, 11), g(5, 13), g(11, 13), g(13, 9), g(13, 5), g(10, 3), g(4, 3),
                    g(2, 4)), ring(g(7, 5), g(8, 9), g(10, 10), g(7, 10), g(7, 5)));

    assertEquals(expected, Encoders.encode(poly));
}
maesenka commented 7 years ago

This is fixed by 3b44b0b277031edd8e1fd5e7d195dbce1ba361c8