diff options
| author | David Smith <39445562+smithdc1@users.noreply.github.com> | 2024-10-22 21:24:36 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-10-22 17:24:36 -0300 |
| commit | 04adff9f98a93a546d7b4d7453b80965233d22a3 (patch) | |
| tree | ad2b2eec7489a7dc548807c3b6fb237938049ecb /tests/gis_tests | |
| parent | dd0a116b93c40f9febf0e09614ad666af1191744 (diff) | |
Refs #34406 -- Added support for GDAL curved geometries.
Co-authored-by: Fabien Le Frapper <contact@fabienlefrapper.me>
Diffstat (limited to 'tests/gis_tests')
| -rw-r--r-- | tests/gis_tests/data/geometries.json | 82 | ||||
| -rw-r--r-- | tests/gis_tests/gdal_tests/test_geom.py | 137 |
2 files changed, 199 insertions, 20 deletions
diff --git a/tests/gis_tests/data/geometries.json b/tests/gis_tests/data/geometries.json index 7786f26e9b..eb6c64b6d9 100644 --- a/tests/gis_tests/data/geometries.json +++ b/tests/gis_tests/data/geometries.json @@ -137,5 +137,87 @@ "union_geoms": [ {"wkt": "POLYGON ((-5 0,-5 10,5 10,5 5,10 5,10 -5,0 -5,0 0,-5 0))"}, {"wkt": "POLYGON ((2 0, 2 15, 18 15, 18 0, 2 0))"} + ], +"curved_geoms": [ + {"wkt": "CIRCULARSTRING(1 5, 6 2, 7 3)", + "name": "CircularString", + "num": 8 + }, + {"wkt": "COMPOUNDCURVE((5 3, 5 13), CIRCULARSTRING(5 13, 7 15, 9 13), (9 13, 9 3), CIRCULARSTRING(9 3, 7 1, 5 3))", + "name": "CompoundCurve", + "num": 9 + }, + {"wkt": "CURVEPOLYGON(CIRCULARSTRING(0 0, 4 0, 4 4, 0 4, 0 0),(1 1, 3 3, 3 1, 1 1))", + "name": "CurvePolygon", + "num": 10 + }, + {"wkt": "MULTICURVE((0 0, 5 5), CIRCULARSTRING(4 0, 4 4, 8 4))", + "name": "MultiCurve", + "num": 11 + }, + {"wkt": "MULTISURFACE(((0 0, 0 1, 1 1, 1 0, 0 0)), ((1 1, 1 2, 2 2, 2 1, 1 1)))", + "name": "MultiSurface", + "num": 12 + }, + {"wkt": "CIRCULARSTRING Z (1 5 1, 6 2 2, 7 3 3)", + "name": "CircularStringZ", + "num": 1008 + }, + {"wkt": "COMPOUNDCURVE Z ((5 3 0, 5 13 0), CIRCULARSTRING Z (5 13 0, 7 15 0, 9 13 0), (9 13 0 , 9 3 0), CIRCULARSTRING(9 3 0, 7 1 0, 5 3 0))", + "name": "CompoundCurveZ", + "num": 1009 + }, + {"wkt": "CURVEPOLYGON Z(CIRCULARSTRING Z (0 0 0, 4 0 0, 4 4 0, 0 4 0, 0 0 0),(1 1 0, 3 3 0, 3 1 0, 1 1 0))", + "name": "CurvePolygonZ", + "num": 1010 + }, + {"wkt": "MULTICURVE Z ((0 0 1, 5 5 2), CIRCULARSTRING Z (4 0 0, 4 4 0, 8 4 0))", + "name": "MultiCurveZ", + "num": 1011 + }, + {"wkt": "MULTISURFACE Z (((0 0 1, 0 1 2, 1 1 3, 1 0 4, 0 0 5)), ((1 1 0, 1 2 0, 2 2 0, 2 1 0, 1 1 0)))", + "name": "MultiSurfaceZ", + "num": 1012 + }, + {"wkt": "CIRCULARSTRING M (1 5 1, 6 2 2, 7 3 3)", + "name": "CircularStringM", + "num": 2008 + }, + {"wkt": "COMPOUNDCURVE M ((5 3 0, 5 13 0), CIRCULARSTRING M (5 13 0, 7 15 0, 9 13 0), (9 13 0 , 9 3 0), CIRCULARSTRING M (9 3 0, 7 1 0, 5 3 0))", + "name": "CompoundCurveM", + "num": 2009 + }, + {"wkt": "CURVEPOLYGON M (CIRCULARSTRING M (0 0 0, 4 0 0, 4 4 0, 0 4 0, 0 0 0),(1 1 0, 3 3 1, 3 1 1, 1 1 2))", + "name": "CurvePolygonM", + "num": 2010 + }, + {"wkt": "MULTICURVE M ((0 0 1, 5 5 2), CIRCULARSTRING M (4 0 0, 4 4 0, 8 4 0))", + "name": "MultiCurveM", + "num": 2011 + }, + {"wkt": "MULTISURFACE M (((0 0 1, 0 1 2, 1 1 3, 1 0 4, 0 0 5)), ((1 1 0, 1 2 0, 2 2 0, 2 1 0, 1 1 0)))", + "name": "MultiSurfaceM", + "num": 2012 + }, + {"wkt": "CIRCULARSTRING ZM (1 5 0 1, 6 2 0 2, 7 3 0 3)", + "name": "CircularStringZM", + "num": 3008 + }, + {"wkt": "COMPOUNDCURVE ZM ((5 3 0 0, 5 13 0 0), CIRCULARSTRING ZM (5 13 0 0, 7 15 0 0, 9 13 0 0), (9 13 0 0, 9 3 0 0), CIRCULARSTRING ZM (9 3 0 0, 7 1 0 0, 5 3 0 0))", + "name": "CompoundCurveZM", + "num": 3009 + }, + {"wkt": "CURVEPOLYGON ZM (CIRCULARSTRING ZM (0 0 0 0, 4 0 0 0, 4 4 0 0, 0 4 0 0, 0 0 0 0), (1 1 0 0, 3 3 0 0, 3 1 0 0, 1 1 0 0))", + "name": "CurvePolygonZM", + "num": 3010 + }, + {"wkt": "MULTICURVE ZM ((0 0 0 1, 5 5 0 2), CIRCULARSTRING ZM (4 0 0 0, 4 4 0 0, 8 4 0 0))", + "name": "MultiCurveZM", + "num": 3011 + }, + {"wkt": "MULTISURFACE ZM (((0 0 0 1, 0 1 0 2, 1 1 0 3, 1 0 0 4, 0 0 0 5)), ((1 1 0 0, 1 2 0 0, 2 2 0 0, 2 1 0 0, 1 1 0 0)))", + "name": "MultiSurfaceZM", + "num": 3012 + } ] } diff --git a/tests/gis_tests/gdal_tests/test_geom.py b/tests/gis_tests/gdal_tests/test_geom.py index 5c23a6f2cf..6c551d0804 100644 --- a/tests/gis_tests/gdal_tests/test_geom.py +++ b/tests/gis_tests/gdal_tests/test_geom.py @@ -8,6 +8,8 @@ from django.contrib.gis.gdal import ( OGRGeomType, SpatialReference, ) +from django.contrib.gis.gdal.geometries import CircularString, CurvePolygon +from django.contrib.gis.geos import GEOSException from django.template import Context from django.template.engine import Engine from django.test import SimpleTestCase @@ -646,11 +648,11 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin): ("Multilinestring", 5, True), ("MultiPolygon", 6, True), ("GeometryCollection", 7, True), - ("CircularString", 8, False), - ("CompoundCurve", 9, False), - ("CurvePolygon", 10, False), - ("MultiCurve", 11, False), - ("MultiSurface", 12, False), + ("CircularString", 8, True), + ("CompoundCurve", 9, True), + ("CurvePolygon", 10, True), + ("MultiCurve", 11, True), + ("MultiSurface", 12, True), # 13 (Curve) and 14 (Surface) are abstract types. ("PolyhedralSurface", 15, False), ("TIN", 16, False), @@ -664,11 +666,11 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin): ("Multilinestring Z", -2147483643, True), # 1005 ("MultiPolygon Z", -2147483642, True), # 1006 ("GeometryCollection Z", -2147483641, True), # 1007 - ("CircularString Z", 1008, False), - ("CompoundCurve Z", 1009, False), - ("CurvePolygon Z", 1010, False), - ("MultiCurve Z", 1011, False), - ("MultiSurface Z", 1012, False), + ("CircularString Z", 1008, True), + ("CompoundCurve Z", 1009, True), + ("CurvePolygon Z", 1010, True), + ("MultiCurve Z", 1011, True), + ("MultiSurface Z", 1012, True), ("PolyhedralSurface Z", 1015, False), ("TIN Z", 1016, False), ("Triangle Z", 1017, False), @@ -679,11 +681,11 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin): ("MultiLineString M", 2005, True), ("MultiPolygon M", 2006, True), ("GeometryCollection M", 2007, True), - ("CircularString M", 2008, False), - ("CompoundCurve M", 2009, False), - ("CurvePolygon M", 2010, False), - ("MultiCurve M", 2011, False), - ("MultiSurface M", 2012, False), + ("CircularString M", 2008, True), + ("CompoundCurve M", 2009, True), + ("CurvePolygon M", 2010, True), + ("MultiCurve M", 2011, True), + ("MultiSurface M", 2012, True), ("PolyhedralSurface M", 2015, False), ("TIN M", 2016, False), ("Triangle M", 2017, False), @@ -694,11 +696,11 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin): ("MultiLineString ZM", 3005, True), ("MultiPolygon ZM", 3006, True), ("GeometryCollection ZM", 3007, True), - ("CircularString ZM", 3008, False), - ("CompoundCurve ZM", 3009, False), - ("CurvePolygon ZM", 3010, False), - ("MultiCurve ZM", 3011, False), - ("MultiSurface ZM", 3012, False), + ("CircularString ZM", 3008, True), + ("CompoundCurve ZM", 3009, True), + ("CurvePolygon ZM", 3010, True), + ("MultiCurve ZM", 3011, True), + ("MultiSurface ZM", 3012, True), ("PolyhedralSurface ZM", 3015, False), ("TIN ZM", 3016, False), ("Triangle ZM", 3017, False), @@ -967,6 +969,101 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin): geom = OGRGeometry(geom_input) self.assertIs(geom.is_measured, True) + def test_has_curve(self): + for geom in self.geometries.curved_geoms: + with self.subTest(wkt=geom.wkt): + geom = OGRGeometry(geom.wkt) + self.assertIs(geom.has_curve, True) + msg = f"GEOS does not support {geom.__class__.__qualname__}." + with self.assertRaisesMessage(GEOSException, msg): + geom.geos + geom = OGRGeometry("POINT (0 1)") + self.assertIs(geom.has_curve, False) + + def test_get_linear_geometry(self): + geom = OGRGeometry("CIRCULARSTRING (-0.797 0.466,-0.481 0.62,-0.419 0.473)") + linear = geom.get_linear_geometry() + self.assertEqual(linear.geom_name, "LINESTRING") + self.assertIs(linear.has_curve, False) + + def test_get_linear_geometry_no_conversion_possible(self): + wkt = "POINT (0 0)" + geom = OGRGeometry(wkt) + geom2 = geom.get_linear_geometry() + self.assertEqual(geom2.wkt, wkt) + + def test_get_curve_geometry(self): + linear_string = OGRGeometry( + "LINESTRING (-0.797 0.466,-0.797500910583869 0.479079607685707," + "-0.797096828208069 0.49216256476959,-0.795789684575482 0.505186328593822," + "-0.793585728444384 0.518088639471983,-0.79049549575663 0.530807818319715," + "-0.786533759270668 0.543283061509385,-0.781719457941079 0.555454731539925," + "-0.776075606381369 0.567264642132187,-0.769629184843353 0.578656336386302," + "-0.76241101023902 0.589575356672327,-0.754455588821145 0.599969504963013," + "-0.745800951227352 0.609789092364991,-0.736488470675795 0.618987176654798," + "-0.726562665181888 0.627519786684672,-0.716070984741265 0.635346132585369," + "-0.705063584496685 0.642428800760598,-0.693593084972889 0.648733932741749," + "-0.681714320525941 0.654231387047048,-0.669484077209319 0.658894883272069," + "-0.656960821309923 0.662702127722269,-0.644204419852031 0.665634919987354," + "-0.631275854404748 0.667679239947688,-0.618236929561618 0.668825314797118," + "-0.60514997748578 0.669067665761503,-0.592077559933017 0.66840513428977," + "-0.579082169177269 0.666840887592428,-0.566225929268313 0.664382403500809," + "-0.553570299049824 0.661041434719465,-0.541175778357228 0.656833952642756," + "-0.529101618800212 0.651780071004197,-0.5174055405123 0.645903949723276," + "-0.506143456221622 0.639233679409784,-0.495369203961872 0.631801147077652," + "-0.485134289701335 0.623641883709865,-0.475487641120239 0.614794894404014," + "-0.46647537371355 0.605302471909454,-0.458140570337321 0.595209994448282," + "-0.450523075252448 0.58456570878613,-0.443659303650563 0.573420499590156," + "-0.437582067572208 0.561827646176397,-0.432320419050072 0.549842567809747," + "-0.427899511226613 0.537522558773986,-0.424340478110267 0.524926514478182," + "-0.421660333544978 0.512114649909193,-0.419871889876113 0.499148211775737," + "-0.418983696701434 0.486089185720561,-0.419 0.473)" + ) + curve = linear_string.get_curve_geometry() + self.assertEqual(curve.geom_name, "CIRCULARSTRING") + self.assertEqual( + curve.wkt, + "CIRCULARSTRING (-0.797 0.466,-0.618236929561618 " + "0.668825314797118,-0.419 0.473)", + ) + + def test_get_curve_geometry_no_conversion_possible(self): + geom = OGRGeometry("LINESTRING (0 0, 1 0, 2 0)") + geom2 = geom.get_curve_geometry() + self.assertEqual(geom2.wkt, geom.wkt) + + def test_curved_geometries(self): + for geom in self.geometries.curved_geoms: + with self.subTest(wkt=geom.wkt, geom_name=geom.name): + g = OGRGeometry(geom.wkt) + self.assertEqual(geom.name, g.geom_type.name) + self.assertEqual(geom.num, g.geom_type.num) + msg = f"GEOS does not support {g.__class__.__qualname__}." + with self.assertRaisesMessage(GEOSException, msg): + g.geos + + def test_circularstring_has_linestring_features(self): + geom = OGRGeometry("CIRCULARSTRING ZM (1 5 0 1, 6 2 0 2, 7 3 0 3)") + self.assertIsInstance(geom, CircularString) + self.assertEqual(geom.x, [1, 6, 7]) + self.assertEqual(geom.y, [5, 2, 3]) + self.assertEqual(geom.z, [0, 0, 0]) + self.assertEqual(geom.m, [1, 2, 3]) + self.assertEqual( + geom.tuple, + ((1.0, 5.0, 0.0, 1.0), (6.0, 2.0, 0.0, 2.0), (7.0, 3.0, 0.0, 3.0)), + ) + self.assertEqual(geom[0], (1, 5, 0, 1)) + self.assertEqual(len(geom), 3) + + def test_curvepolygon_has_polygon_features(self): + geom = OGRGeometry( + "CURVEPOLYGON ZM (CIRCULARSTRING ZM (0 0 0 0, 4 0 0 0, 4 4 0 0, 0 4 0 0, " + "0 0 0 0), (1 1 0 0, 3 3 0 0, 3 1 0 0, 1 1 0 0))" + ) + self.assertIsInstance(geom, CurvePolygon) + self.assertIsInstance(geom.shell, CircularString) + class DeprecationTests(SimpleTestCase): def test_coord_setter_deprecation(self): |
