summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Smith <smithdc@gmail.com>2023-12-22 17:21:08 +0000
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2023-12-27 11:40:28 +0100
commit21b0b23a67ee1aa1a35f7f64cd8fe997e4de89d7 (patch)
tree00f7bc43cefb4127fc8bd9d85c174d6707c92935
parent7c26dbf6ef9415f873ae43f12e6ab3742857c898 (diff)
Refs #35058 -- Made OGRGeomType aware of additional WKB geometry types.
This commit increases OGRGeomType's knowledge of WKB types and allows for improved error messages when Django doesn't yet have a corresponding class to wrap a given type.
-rw-r--r--django/contrib/gis/gdal/geometries.py4
-rw-r--r--django/contrib/gis/gdal/geomtype.py48
-rw-r--r--django/contrib/gis/geometry.py4
-rw-r--r--tests/gis_tests/gdal_tests/test_geom.py81
4 files changed, 134 insertions, 3 deletions
diff --git a/django/contrib/gis/gdal/geometries.py b/django/contrib/gis/gdal/geometries.py
index f74dc688b3..5094413642 100644
--- a/django/contrib/gis/gdal/geometries.py
+++ b/django/contrib/gis/gdal/geometries.py
@@ -123,7 +123,9 @@ class OGRGeometry(GDALBase):
self.srs = srs
# Setting the class depending upon the OGR Geometry Type
- self.__class__ = GEO_CLASSES[self.geom_type.num]
+ if (geo_class := GEO_CLASSES.get(self.geom_type.num)) is None:
+ raise TypeError(f"Unsupported geometry type: {self.geom_type}")
+ self.__class__ = geo_class
# Pickle routines
def __getstate__(self):
diff --git a/django/contrib/gis/gdal/geomtype.py b/django/contrib/gis/gdal/geomtype.py
index 6f342b3c96..c8c4703a82 100644
--- a/django/contrib/gis/gdal/geomtype.py
+++ b/django/contrib/gis/gdal/geomtype.py
@@ -16,9 +16,57 @@ class OGRGeomType:
5: "MultiLineString",
6: "MultiPolygon",
7: "GeometryCollection",
+ 8: "CircularString",
+ 9: "CompoundCurve",
+ 10: "CurvePolygon",
+ 11: "MultiCurve",
+ 12: "MultiSurface",
+ 15: "PolyhedralSurface",
+ 16: "TIN",
+ 17: "Triangle",
100: "None",
101: "LinearRing",
102: "PointZ",
+ 1008: "CircularStringZ",
+ 1009: "CompoundCurveZ",
+ 1010: "CurvePolygonZ",
+ 1011: "MultiCurveZ",
+ 1012: "MultiSurfaceZ",
+ 1013: "CurveZ",
+ 1014: "SurfaceZ",
+ 1015: "PolyhedralSurfaceZ",
+ 1016: "TINZ",
+ 1017: "TriangleZ",
+ 2001: "PointM",
+ 2002: "LineStringM",
+ 2003: "PolygonM",
+ 2004: "MultiPointM",
+ 2005: "MultiLineStringM",
+ 2006: "MultiPolygonM",
+ 2007: "GeometryCollectionM",
+ 2008: "CircularStringM",
+ 2009: "CompoundCurveM",
+ 2010: "CurvePolygonM",
+ 2011: "MultiCurveM",
+ 2012: "MultiSurfaceM",
+ 2015: "PolyhedralSurfaceM",
+ 2016: "TINM",
+ 2017: "TriangleM",
+ 3001: "PointZM",
+ 3002: "LineStringZM",
+ 3003: "PolygonZM",
+ 3004: "MultiPointZM",
+ 3005: "MultiLineStringZM",
+ 3006: "MultiPolygonZM",
+ 3007: "GeometryCollectionZM",
+ 3008: "CircularStringZM",
+ 3009: "CompoundCurveZM",
+ 3010: "CurvePolygonZM",
+ 3011: "MultiCurveZM",
+ 3012: "MultiSurfaceZM",
+ 3015: "PolyhedralSurfaceZM",
+ 3016: "TINZM",
+ 3017: "TriangleZM",
1 + wkb25bit: "Point25D",
2 + wkb25bit: "LineString25D",
3 + wkb25bit: "Polygon25D",
diff --git a/django/contrib/gis/geometry.py b/django/contrib/gis/geometry.py
index b5caf04be4..7aac8644ee 100644
--- a/django/contrib/gis/geometry.py
+++ b/django/contrib/gis/geometry.py
@@ -10,7 +10,9 @@ wkt_regex = _lazy_re_compile(
r"^(SRID=(?P<srid>\-?[0-9]+);)?"
r"(?P<wkt>"
r"(?P<type>POINT|LINESTRING|LINEARRING|POLYGON|MULTIPOINT|"
- r"MULTILINESTRING|MULTIPOLYGON|GEOMETRYCOLLECTION)"
+ r"MULTILINESTRING|MULTIPOLYGON|GEOMETRYCOLLECTION|CIRCULARSTRING|COMPOUNDCURVE|"
+ r"CURVEPOLYGON|MULTICURVE|MULTISURFACE|CURVE|SURFACE|POLYHEDRALSURFACE|TIN|"
+ r"TRIANGLE)"
r"[ACEGIMLONPSRUTYZ0-9,.+() -]+)$",
re.I,
)
diff --git a/tests/gis_tests/gdal_tests/test_geom.py b/tests/gis_tests/gdal_tests/test_geom.py
index 913e465ef1..372a385443 100644
--- a/tests/gis_tests/gdal_tests/test_geom.py
+++ b/tests/gis_tests/gdal_tests/test_geom.py
@@ -35,7 +35,7 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin):
with self.assertRaises(GDALException):
OGRGeomType("fooD")
with self.assertRaises(GDALException):
- OGRGeomType(9)
+ OGRGeomType(4001)
# Equivalence can take strings, ints, and other OGRGeomTypes
self.assertEqual(OGRGeomType(1), OGRGeomType(1))
@@ -635,3 +635,82 @@ class OGRGeomTest(SimpleTestCase, TestDataMixin):
def test_empty_point_to_geos(self):
p = OGRGeometry("POINT EMPTY", srs=4326)
self.assertEqual(p.geos.ewkt, p.ewkt)
+
+ def test_geometry_types(self):
+ tests = [
+ ("Point", 1, True),
+ ("LineString", 2, True),
+ ("Polygon", 3, True),
+ ("MultiPoint", 4, True),
+ ("Multilinestring", 5, True),
+ ("MultiPolygon", 6, True),
+ ("GeometryCollection", 7, True),
+ ("CircularString", 8, False),
+ ("CompoundCurve", 9, False),
+ ("CurvePolygon", 10, False),
+ ("MultiCurve", 11, False),
+ ("MultiSurface", 12, False),
+ # 13 (Curve) and 14 (Surface) are abstract types.
+ ("PolyhedralSurface", 15, False),
+ ("TIN", 16, False),
+ ("Triangle", 17, False),
+ ("Linearring", 2, True),
+ # Types 1 - 7 with Z dimension have 2.5D enums.
+ ("Point Z", -2147483647, True), # 1001
+ ("LineString Z", -2147483646, True), # 1002
+ ("Polygon Z", -2147483645, True), # 1003
+ ("MultiPoint Z", -2147483644, True), # 1004
+ ("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),
+ ("PolyhedralSurface Z", 1015, False),
+ ("TIN Z", 1016, False),
+ ("Triangle Z", 1017, False),
+ ("Point M", 2001, False),
+ ("LineString M", 2002, False),
+ ("Polygon M", 2003, False),
+ ("MultiPoint M", 2004, False),
+ ("MultiLineString M", 2005, False),
+ ("MultiPolygon M", 2006, False),
+ ("GeometryCollection M", 2007, False),
+ ("CircularString M", 2008, False),
+ ("CompoundCurve M", 2009, False),
+ ("CurvePolygon M", 2010, False),
+ ("MultiCurve M", 2011, False),
+ ("MultiSurface M", 2012, False),
+ ("PolyhedralSurface M", 2015, False),
+ ("TIN M", 2016, False),
+ ("Triangle M", 2017, False),
+ ("Point ZM", 3001, False),
+ ("LineString ZM", 3002, False),
+ ("Polygon ZM", 3003, False),
+ ("MultiPoint ZM", 3004, False),
+ ("MultiLineString ZM", 3005, False),
+ ("MultiPolygon ZM", 3006, False),
+ ("GeometryCollection ZM", 3007, False),
+ ("CircularString ZM", 3008, False),
+ ("CompoundCurve ZM", 3009, False),
+ ("CurvePolygon ZM", 3010, False),
+ ("MultiCurve ZM", 3011, False),
+ ("MultiSurface ZM", 3012, False),
+ ("PolyhedralSurface ZM", 3015, False),
+ ("TIN ZM", 3016, False),
+ ("Triangle ZM", 3017, False),
+ ]
+
+ for test in tests:
+ geom_type, num, supported = test
+ with self.subTest(geom_type=geom_type, num=num, supported=supported):
+ if supported:
+ g = OGRGeometry(f"{geom_type} EMPTY")
+ self.assertEqual(g.geom_type.num, num)
+ else:
+ type_ = geom_type.replace(" ", "")
+ msg = f"Unsupported geometry type: {type_}"
+ with self.assertRaisesMessage(TypeError, msg):
+ OGRGeometry(f"{geom_type} EMPTY")