1. import json
    
  2. import pickle
    
  3. 
    
  4. from django.contrib.gis.gdal import (
    
  5.     CoordTransform,
    
  6.     GDALException,
    
  7.     OGRGeometry,
    
  8.     OGRGeomType,
    
  9.     SpatialReference,
    
  10. )
    
  11. from django.template import Context
    
  12. from django.template.engine import Engine
    
  13. from django.test import SimpleTestCase
    
  14. 
    
  15. from ..test_data import TestDataMixin
    
  16. 
    
  17. 
    
  18. class OGRGeomTest(SimpleTestCase, TestDataMixin):
    
  19.     "This tests the OGR Geometry."
    
  20. 
    
  21.     def test_geomtype(self):
    
  22.         "Testing OGRGeomType object."
    
  23. 
    
  24.         # OGRGeomType should initialize on all these inputs.
    
  25.         OGRGeomType(1)
    
  26.         OGRGeomType(7)
    
  27.         OGRGeomType("point")
    
  28.         OGRGeomType("GeometrycollectioN")
    
  29.         OGRGeomType("LINearrING")
    
  30.         OGRGeomType("Unknown")
    
  31. 
    
  32.         # Should throw TypeError on this input
    
  33.         with self.assertRaises(GDALException):
    
  34.             OGRGeomType(23)
    
  35.         with self.assertRaises(GDALException):
    
  36.             OGRGeomType("fooD")
    
  37.         with self.assertRaises(GDALException):
    
  38.             OGRGeomType(9)
    
  39. 
    
  40.         # Equivalence can take strings, ints, and other OGRGeomTypes
    
  41.         self.assertEqual(OGRGeomType(1), OGRGeomType(1))
    
  42.         self.assertEqual(OGRGeomType(7), "GeometryCollection")
    
  43.         self.assertEqual(OGRGeomType("point"), "POINT")
    
  44.         self.assertNotEqual(OGRGeomType("point"), 2)
    
  45.         self.assertEqual(OGRGeomType("unknown"), 0)
    
  46.         self.assertEqual(OGRGeomType(6), "MULtiPolyGON")
    
  47.         self.assertEqual(OGRGeomType(1), OGRGeomType("point"))
    
  48.         self.assertNotEqual(OGRGeomType("POINT"), OGRGeomType(6))
    
  49. 
    
  50.         # Testing the Django field name equivalent property.
    
  51.         self.assertEqual("PointField", OGRGeomType("Point").django)
    
  52.         self.assertEqual("GeometryField", OGRGeomType("Geometry").django)
    
  53.         self.assertEqual("GeometryField", OGRGeomType("Unknown").django)
    
  54.         self.assertIsNone(OGRGeomType("none").django)
    
  55. 
    
  56.         # 'Geometry' initialization implies an unknown geometry type.
    
  57.         gt = OGRGeomType("Geometry")
    
  58.         self.assertEqual(0, gt.num)
    
  59.         self.assertEqual("Unknown", gt.name)
    
  60. 
    
  61.     def test_geomtype_25d(self):
    
  62.         "Testing OGRGeomType object with 25D types."
    
  63.         wkb25bit = OGRGeomType.wkb25bit
    
  64.         self.assertEqual(OGRGeomType(wkb25bit + 1), "Point25D")
    
  65.         self.assertEqual(OGRGeomType("MultiLineString25D"), (5 + wkb25bit))
    
  66.         self.assertEqual(
    
  67.             "GeometryCollectionField", OGRGeomType("GeometryCollection25D").django
    
  68.         )
    
  69. 
    
  70.     def test_wkt(self):
    
  71.         "Testing WKT output."
    
  72.         for g in self.geometries.wkt_out:
    
  73.             geom = OGRGeometry(g.wkt)
    
  74.             self.assertEqual(g.wkt, geom.wkt)
    
  75. 
    
  76.     def test_ewkt(self):
    
  77.         "Testing EWKT input/output."
    
  78.         for ewkt_val in ("POINT (1 2 3)", "LINEARRING (0 0,1 1,2 1,0 0)"):
    
  79.             # First with ewkt output when no SRID in EWKT
    
  80.             self.assertEqual(ewkt_val, OGRGeometry(ewkt_val).ewkt)
    
  81.             # No test consumption with an SRID specified.
    
  82.             ewkt_val = "SRID=4326;%s" % ewkt_val
    
  83.             geom = OGRGeometry(ewkt_val)
    
  84.             self.assertEqual(ewkt_val, geom.ewkt)
    
  85.             self.assertEqual(4326, geom.srs.srid)
    
  86. 
    
  87.     def test_gml(self):
    
  88.         "Testing GML output."
    
  89.         for g in self.geometries.wkt_out:
    
  90.             geom = OGRGeometry(g.wkt)
    
  91.             exp_gml = g.gml
    
  92.             self.assertEqual(exp_gml, geom.gml)
    
  93. 
    
  94.     def test_hex(self):
    
  95.         "Testing HEX input/output."
    
  96.         for g in self.geometries.hex_wkt:
    
  97.             geom1 = OGRGeometry(g.wkt)
    
  98.             self.assertEqual(g.hex.encode(), geom1.hex)
    
  99.             # Constructing w/HEX
    
  100.             geom2 = OGRGeometry(g.hex)
    
  101.             self.assertEqual(geom1, geom2)
    
  102. 
    
  103.     def test_wkb(self):
    
  104.         "Testing WKB input/output."
    
  105.         for g in self.geometries.hex_wkt:
    
  106.             geom1 = OGRGeometry(g.wkt)
    
  107.             wkb = geom1.wkb
    
  108.             self.assertEqual(wkb.hex().upper(), g.hex)
    
  109.             # Constructing w/WKB.
    
  110.             geom2 = OGRGeometry(wkb)
    
  111.             self.assertEqual(geom1, geom2)
    
  112. 
    
  113.     def test_json(self):
    
  114.         "Testing GeoJSON input/output."
    
  115.         for g in self.geometries.json_geoms:
    
  116.             geom = OGRGeometry(g.wkt)
    
  117.             if not hasattr(g, "not_equal"):
    
  118.                 # Loading jsons to prevent decimal differences
    
  119.                 self.assertEqual(json.loads(g.json), json.loads(geom.json))
    
  120.                 self.assertEqual(json.loads(g.json), json.loads(geom.geojson))
    
  121.             self.assertEqual(OGRGeometry(g.wkt), OGRGeometry(geom.json))
    
  122.         # Test input with some garbage content (but valid json) (#15529)
    
  123.         geom = OGRGeometry(
    
  124.             '{"type": "Point", "coordinates": [ 100.0, 0.0 ], "other": "<test>"}'
    
  125.         )
    
  126.         self.assertIsInstance(geom, OGRGeometry)
    
  127. 
    
  128.     def test_points(self):
    
  129.         "Testing Point objects."
    
  130. 
    
  131.         OGRGeometry("POINT(0 0)")
    
  132.         for p in self.geometries.points:
    
  133.             if not hasattr(p, "z"):  # No 3D
    
  134.                 pnt = OGRGeometry(p.wkt)
    
  135.                 self.assertEqual(1, pnt.geom_type)
    
  136.                 self.assertEqual("POINT", pnt.geom_name)
    
  137.                 self.assertEqual(p.x, pnt.x)
    
  138.                 self.assertEqual(p.y, pnt.y)
    
  139.                 self.assertEqual((p.x, p.y), pnt.tuple)
    
  140. 
    
  141.     def test_multipoints(self):
    
  142.         "Testing MultiPoint objects."
    
  143.         for mp in self.geometries.multipoints:
    
  144.             mgeom1 = OGRGeometry(mp.wkt)  # First one from WKT
    
  145.             self.assertEqual(4, mgeom1.geom_type)
    
  146.             self.assertEqual("MULTIPOINT", mgeom1.geom_name)
    
  147.             mgeom2 = OGRGeometry("MULTIPOINT")  # Creating empty multipoint
    
  148.             mgeom3 = OGRGeometry("MULTIPOINT")
    
  149.             for g in mgeom1:
    
  150.                 mgeom2.add(g)  # adding each point from the multipoints
    
  151.                 mgeom3.add(g.wkt)  # should take WKT as well
    
  152.             self.assertEqual(mgeom1, mgeom2)  # they should equal
    
  153.             self.assertEqual(mgeom1, mgeom3)
    
  154.             self.assertEqual(mp.coords, mgeom2.coords)
    
  155.             self.assertEqual(mp.n_p, mgeom2.point_count)
    
  156. 
    
  157.     def test_linestring(self):
    
  158.         "Testing LineString objects."
    
  159.         prev = OGRGeometry("POINT(0 0)")
    
  160.         for ls in self.geometries.linestrings:
    
  161.             linestr = OGRGeometry(ls.wkt)
    
  162.             self.assertEqual(2, linestr.geom_type)
    
  163.             self.assertEqual("LINESTRING", linestr.geom_name)
    
  164.             self.assertEqual(ls.n_p, linestr.point_count)
    
  165.             self.assertEqual(ls.coords, linestr.tuple)
    
  166.             self.assertEqual(linestr, OGRGeometry(ls.wkt))
    
  167.             self.assertNotEqual(linestr, prev)
    
  168.             msg = "Index out of range when accessing points of a line string: %s."
    
  169.             with self.assertRaisesMessage(IndexError, msg % len(linestr)):
    
  170.                 linestr.__getitem__(len(linestr))
    
  171.             prev = linestr
    
  172. 
    
  173.             # Testing the x, y properties.
    
  174.             x = [tmpx for tmpx, tmpy in ls.coords]
    
  175.             y = [tmpy for tmpx, tmpy in ls.coords]
    
  176.             self.assertEqual(x, linestr.x)
    
  177.             self.assertEqual(y, linestr.y)
    
  178. 
    
  179.     def test_multilinestring(self):
    
  180.         "Testing MultiLineString objects."
    
  181.         prev = OGRGeometry("POINT(0 0)")
    
  182.         for mls in self.geometries.multilinestrings:
    
  183.             mlinestr = OGRGeometry(mls.wkt)
    
  184.             self.assertEqual(5, mlinestr.geom_type)
    
  185.             self.assertEqual("MULTILINESTRING", mlinestr.geom_name)
    
  186.             self.assertEqual(mls.n_p, mlinestr.point_count)
    
  187.             self.assertEqual(mls.coords, mlinestr.tuple)
    
  188.             self.assertEqual(mlinestr, OGRGeometry(mls.wkt))
    
  189.             self.assertNotEqual(mlinestr, prev)
    
  190.             prev = mlinestr
    
  191.             for ls in mlinestr:
    
  192.                 self.assertEqual(2, ls.geom_type)
    
  193.                 self.assertEqual("LINESTRING", ls.geom_name)
    
  194.             msg = "Index out of range when accessing geometry in a collection: %s."
    
  195.             with self.assertRaisesMessage(IndexError, msg % len(mlinestr)):
    
  196.                 mlinestr.__getitem__(len(mlinestr))
    
  197. 
    
  198.     def test_linearring(self):
    
  199.         "Testing LinearRing objects."
    
  200.         prev = OGRGeometry("POINT(0 0)")
    
  201.         for rr in self.geometries.linearrings:
    
  202.             lr = OGRGeometry(rr.wkt)
    
  203.             # self.assertEqual(101, lr.geom_type.num)
    
  204.             self.assertEqual("LINEARRING", lr.geom_name)
    
  205.             self.assertEqual(rr.n_p, len(lr))
    
  206.             self.assertEqual(lr, OGRGeometry(rr.wkt))
    
  207.             self.assertNotEqual(lr, prev)
    
  208.             prev = lr
    
  209. 
    
  210.     def test_polygons(self):
    
  211.         "Testing Polygon objects."
    
  212. 
    
  213.         # Testing `from_bbox` class method
    
  214.         bbox = (-180, -90, 180, 90)
    
  215.         p = OGRGeometry.from_bbox(bbox)
    
  216.         self.assertEqual(bbox, p.extent)
    
  217. 
    
  218.         prev = OGRGeometry("POINT(0 0)")
    
  219.         for p in self.geometries.polygons:
    
  220.             poly = OGRGeometry(p.wkt)
    
  221.             self.assertEqual(3, poly.geom_type)
    
  222.             self.assertEqual("POLYGON", poly.geom_name)
    
  223.             self.assertEqual(p.n_p, poly.point_count)
    
  224.             self.assertEqual(p.n_i + 1, len(poly))
    
  225.             msg = "Index out of range when accessing rings of a polygon: %s."
    
  226.             with self.assertRaisesMessage(IndexError, msg % len(poly)):
    
  227.                 poly.__getitem__(len(poly))
    
  228. 
    
  229.             # Testing area & centroid.
    
  230.             self.assertAlmostEqual(p.area, poly.area, 9)
    
  231.             x, y = poly.centroid.tuple
    
  232.             self.assertAlmostEqual(p.centroid[0], x, 9)
    
  233.             self.assertAlmostEqual(p.centroid[1], y, 9)
    
  234. 
    
  235.             # Testing equivalence
    
  236.             self.assertEqual(poly, OGRGeometry(p.wkt))
    
  237.             self.assertNotEqual(poly, prev)
    
  238. 
    
  239.             if p.ext_ring_cs:
    
  240.                 ring = poly[0]
    
  241.                 self.assertEqual(p.ext_ring_cs, ring.tuple)
    
  242.                 self.assertEqual(p.ext_ring_cs, poly[0].tuple)
    
  243.                 self.assertEqual(len(p.ext_ring_cs), ring.point_count)
    
  244. 
    
  245.             for r in poly:
    
  246.                 self.assertEqual("LINEARRING", r.geom_name)
    
  247. 
    
  248.     def test_polygons_templates(self):
    
  249.         # Accessing Polygon attributes in templates should work.
    
  250.         engine = Engine()
    
  251.         template = engine.from_string("{{ polygons.0.wkt }}")
    
  252.         polygons = [OGRGeometry(p.wkt) for p in self.geometries.multipolygons[:2]]
    
  253.         content = template.render(Context({"polygons": polygons}))
    
  254.         self.assertIn("MULTIPOLYGON (((100", content)
    
  255. 
    
  256.     def test_closepolygons(self):
    
  257.         "Testing closing Polygon objects."
    
  258.         # Both rings in this geometry are not closed.
    
  259.         poly = OGRGeometry("POLYGON((0 0, 5 0, 5 5, 0 5), (1 1, 2 1, 2 2, 2 1))")
    
  260.         self.assertEqual(8, poly.point_count)
    
  261.         with self.assertRaises(GDALException):
    
  262.             poly.centroid
    
  263. 
    
  264.         poly.close_rings()
    
  265.         self.assertEqual(
    
  266.             10, poly.point_count
    
  267.         )  # Two closing points should've been added
    
  268.         self.assertEqual(OGRGeometry("POINT(2.5 2.5)"), poly.centroid)
    
  269. 
    
  270.     def test_multipolygons(self):
    
  271.         "Testing MultiPolygon objects."
    
  272.         OGRGeometry("POINT(0 0)")
    
  273.         for mp in self.geometries.multipolygons:
    
  274.             mpoly = OGRGeometry(mp.wkt)
    
  275.             self.assertEqual(6, mpoly.geom_type)
    
  276.             self.assertEqual("MULTIPOLYGON", mpoly.geom_name)
    
  277.             if mp.valid:
    
  278.                 self.assertEqual(mp.n_p, mpoly.point_count)
    
  279.                 self.assertEqual(mp.num_geom, len(mpoly))
    
  280.                 msg = "Index out of range when accessing geometry in a collection: %s."
    
  281.                 with self.assertRaisesMessage(IndexError, msg % len(mpoly)):
    
  282.                     mpoly.__getitem__(len(mpoly))
    
  283.                 for p in mpoly:
    
  284.                     self.assertEqual("POLYGON", p.geom_name)
    
  285.                     self.assertEqual(3, p.geom_type)
    
  286.             self.assertEqual(mpoly.wkt, OGRGeometry(mp.wkt).wkt)
    
  287. 
    
  288.     def test_srs(self):
    
  289.         "Testing OGR Geometries with Spatial Reference objects."
    
  290.         for mp in self.geometries.multipolygons:
    
  291.             # Creating a geometry w/spatial reference
    
  292.             sr = SpatialReference("WGS84")
    
  293.             mpoly = OGRGeometry(mp.wkt, sr)
    
  294.             self.assertEqual(sr.wkt, mpoly.srs.wkt)
    
  295. 
    
  296.             # Ensuring that SRS is propagated to clones.
    
  297.             klone = mpoly.clone()
    
  298.             self.assertEqual(sr.wkt, klone.srs.wkt)
    
  299. 
    
  300.             # Ensuring all children geometries (polygons and their rings) all
    
  301.             # return the assigned spatial reference as well.
    
  302.             for poly in mpoly:
    
  303.                 self.assertEqual(sr.wkt, poly.srs.wkt)
    
  304.                 for ring in poly:
    
  305.                     self.assertEqual(sr.wkt, ring.srs.wkt)
    
  306. 
    
  307.             # Ensuring SRS propagate in topological ops.
    
  308.             a = OGRGeometry(self.geometries.topology_geoms[0].wkt_a, sr)
    
  309.             b = OGRGeometry(self.geometries.topology_geoms[0].wkt_b, sr)
    
  310.             diff = a.difference(b)
    
  311.             union = a.union(b)
    
  312.             self.assertEqual(sr.wkt, diff.srs.wkt)
    
  313.             self.assertEqual(sr.srid, union.srs.srid)
    
  314. 
    
  315.             # Instantiating w/an integer SRID
    
  316.             mpoly = OGRGeometry(mp.wkt, 4326)
    
  317.             self.assertEqual(4326, mpoly.srid)
    
  318.             mpoly.srs = SpatialReference(4269)
    
  319.             self.assertEqual(4269, mpoly.srid)
    
  320.             self.assertEqual("NAD83", mpoly.srs.name)
    
  321. 
    
  322.             # Incrementing through the multipolygon after the spatial reference
    
  323.             # has been re-assigned.
    
  324.             for poly in mpoly:
    
  325.                 self.assertEqual(mpoly.srs.wkt, poly.srs.wkt)
    
  326.                 poly.srs = 32140
    
  327.                 for ring in poly:
    
  328.                     # Changing each ring in the polygon
    
  329.                     self.assertEqual(32140, ring.srs.srid)
    
  330.                     self.assertEqual("NAD83 / Texas South Central", ring.srs.name)
    
  331.                     ring.srs = str(SpatialReference(4326))  # back to WGS84
    
  332.                     self.assertEqual(4326, ring.srs.srid)
    
  333. 
    
  334.                     # Using the `srid` property.
    
  335.                     ring.srid = 4322
    
  336.                     self.assertEqual("WGS 72", ring.srs.name)
    
  337.                     self.assertEqual(4322, ring.srid)
    
  338. 
    
  339.             # srs/srid may be assigned their own values, even when srs is None.
    
  340.             mpoly = OGRGeometry(mp.wkt, srs=None)
    
  341.             mpoly.srs = mpoly.srs
    
  342.             mpoly.srid = mpoly.srid
    
  343. 
    
  344.     def test_srs_transform(self):
    
  345.         "Testing transform()."
    
  346.         orig = OGRGeometry("POINT (-104.609 38.255)", 4326)
    
  347.         trans = OGRGeometry("POINT (992385.4472045 481455.4944650)", 2774)
    
  348. 
    
  349.         # Using an srid, a SpatialReference object, and a CoordTransform object
    
  350.         # or transformations.
    
  351.         t1, t2, t3 = orig.clone(), orig.clone(), orig.clone()
    
  352.         t1.transform(trans.srid)
    
  353.         t2.transform(SpatialReference("EPSG:2774"))
    
  354.         ct = CoordTransform(SpatialReference("WGS84"), SpatialReference(2774))
    
  355.         t3.transform(ct)
    
  356. 
    
  357.         # Testing use of the `clone` keyword.
    
  358.         k1 = orig.clone()
    
  359.         k2 = k1.transform(trans.srid, clone=True)
    
  360.         self.assertEqual(k1, orig)
    
  361.         self.assertNotEqual(k1, k2)
    
  362. 
    
  363.         # Different PROJ versions use different transformations, all are
    
  364.         # correct as having a 1 meter accuracy.
    
  365.         prec = -1
    
  366.         for p in (t1, t2, t3, k2):
    
  367.             self.assertAlmostEqual(trans.x, p.x, prec)
    
  368.             self.assertAlmostEqual(trans.y, p.y, prec)
    
  369. 
    
  370.     def test_transform_dim(self):
    
  371.         "Testing coordinate dimension is the same on transformed geometries."
    
  372.         ls_orig = OGRGeometry("LINESTRING(-104.609 38.255)", 4326)
    
  373.         ls_trans = OGRGeometry("LINESTRING(992385.4472045 481455.4944650)", 2774)
    
  374. 
    
  375.         # Different PROJ versions use different transformations, all are
    
  376.         # correct as having a 1 meter accuracy.
    
  377.         prec = -1
    
  378.         ls_orig.transform(ls_trans.srs)
    
  379.         # Making sure the coordinate dimension is still 2D.
    
  380.         self.assertEqual(2, ls_orig.coord_dim)
    
  381.         self.assertAlmostEqual(ls_trans.x[0], ls_orig.x[0], prec)
    
  382.         self.assertAlmostEqual(ls_trans.y[0], ls_orig.y[0], prec)
    
  383. 
    
  384.     def test_difference(self):
    
  385.         "Testing difference()."
    
  386.         for i in range(len(self.geometries.topology_geoms)):
    
  387.             a = OGRGeometry(self.geometries.topology_geoms[i].wkt_a)
    
  388.             b = OGRGeometry(self.geometries.topology_geoms[i].wkt_b)
    
  389.             d1 = OGRGeometry(self.geometries.diff_geoms[i].wkt)
    
  390.             d2 = a.difference(b)
    
  391.             self.assertTrue(d1.geos.equals(d2.geos))
    
  392.             self.assertTrue(
    
  393.                 d1.geos.equals((a - b).geos)
    
  394.             )  # __sub__ is difference operator
    
  395.             a -= b  # testing __isub__
    
  396.             self.assertTrue(d1.geos.equals(a.geos))
    
  397. 
    
  398.     def test_intersection(self):
    
  399.         "Testing intersects() and intersection()."
    
  400.         for i in range(len(self.geometries.topology_geoms)):
    
  401.             a = OGRGeometry(self.geometries.topology_geoms[i].wkt_a)
    
  402.             b = OGRGeometry(self.geometries.topology_geoms[i].wkt_b)
    
  403.             i1 = OGRGeometry(self.geometries.intersect_geoms[i].wkt)
    
  404.             self.assertTrue(a.intersects(b))
    
  405.             i2 = a.intersection(b)
    
  406.             self.assertTrue(i1.geos.equals(i2.geos))
    
  407.             self.assertTrue(
    
  408.                 i1.geos.equals((a & b).geos)
    
  409.             )  # __and__ is intersection operator
    
  410.             a &= b  # testing __iand__
    
  411.             self.assertTrue(i1.geos.equals(a.geos))
    
  412. 
    
  413.     def test_symdifference(self):
    
  414.         "Testing sym_difference()."
    
  415.         for i in range(len(self.geometries.topology_geoms)):
    
  416.             a = OGRGeometry(self.geometries.topology_geoms[i].wkt_a)
    
  417.             b = OGRGeometry(self.geometries.topology_geoms[i].wkt_b)
    
  418.             d1 = OGRGeometry(self.geometries.sdiff_geoms[i].wkt)
    
  419.             d2 = a.sym_difference(b)
    
  420.             self.assertTrue(d1.geos.equals(d2.geos))
    
  421.             self.assertTrue(
    
  422.                 d1.geos.equals((a ^ b).geos)
    
  423.             )  # __xor__ is symmetric difference operator
    
  424.             a ^= b  # testing __ixor__
    
  425.             self.assertTrue(d1.geos.equals(a.geos))
    
  426. 
    
  427.     def test_union(self):
    
  428.         "Testing union()."
    
  429.         for i in range(len(self.geometries.topology_geoms)):
    
  430.             a = OGRGeometry(self.geometries.topology_geoms[i].wkt_a)
    
  431.             b = OGRGeometry(self.geometries.topology_geoms[i].wkt_b)
    
  432.             u1 = OGRGeometry(self.geometries.union_geoms[i].wkt)
    
  433.             u2 = a.union(b)
    
  434.             self.assertTrue(u1.geos.equals(u2.geos))
    
  435.             self.assertTrue(u1.geos.equals((a | b).geos))  # __or__ is union operator
    
  436.             a |= b  # testing __ior__
    
  437.             self.assertTrue(u1.geos.equals(a.geos))
    
  438. 
    
  439.     def test_add(self):
    
  440.         "Testing GeometryCollection.add()."
    
  441.         # Can't insert a Point into a MultiPolygon.
    
  442.         mp = OGRGeometry("MultiPolygon")
    
  443.         pnt = OGRGeometry("POINT(5 23)")
    
  444.         with self.assertRaises(GDALException):
    
  445.             mp.add(pnt)
    
  446. 
    
  447.         # GeometryCollection.add may take an OGRGeometry (if another collection
    
  448.         # of the same type all child geoms will be added individually) or WKT.
    
  449.         for mp in self.geometries.multipolygons:
    
  450.             mpoly = OGRGeometry(mp.wkt)
    
  451.             mp1 = OGRGeometry("MultiPolygon")
    
  452.             mp2 = OGRGeometry("MultiPolygon")
    
  453.             mp3 = OGRGeometry("MultiPolygon")
    
  454. 
    
  455.             for poly in mpoly:
    
  456.                 mp1.add(poly)  # Adding a geometry at a time
    
  457.                 mp2.add(poly.wkt)  # Adding WKT
    
  458.             mp3.add(mpoly)  # Adding a MultiPolygon's entire contents at once.
    
  459.             for tmp in (mp1, mp2, mp3):
    
  460.                 self.assertEqual(mpoly, tmp)
    
  461. 
    
  462.     def test_extent(self):
    
  463.         "Testing `extent` property."
    
  464.         # The xmin, ymin, xmax, ymax of the MultiPoint should be returned.
    
  465.         mp = OGRGeometry("MULTIPOINT(5 23, 0 0, 10 50)")
    
  466.         self.assertEqual((0.0, 0.0, 10.0, 50.0), mp.extent)
    
  467.         # Testing on the 'real world' Polygon.
    
  468.         poly = OGRGeometry(self.geometries.polygons[3].wkt)
    
  469.         ring = poly.shell
    
  470.         x, y = ring.x, ring.y
    
  471.         xmin, ymin = min(x), min(y)
    
  472.         xmax, ymax = max(x), max(y)
    
  473.         self.assertEqual((xmin, ymin, xmax, ymax), poly.extent)
    
  474. 
    
  475.     def test_25D(self):
    
  476.         "Testing 2.5D geometries."
    
  477.         pnt_25d = OGRGeometry("POINT(1 2 3)")
    
  478.         self.assertEqual("Point25D", pnt_25d.geom_type.name)
    
  479.         self.assertEqual(3.0, pnt_25d.z)
    
  480.         self.assertEqual(3, pnt_25d.coord_dim)
    
  481.         ls_25d = OGRGeometry("LINESTRING(1 1 1,2 2 2,3 3 3)")
    
  482.         self.assertEqual("LineString25D", ls_25d.geom_type.name)
    
  483.         self.assertEqual([1.0, 2.0, 3.0], ls_25d.z)
    
  484.         self.assertEqual(3, ls_25d.coord_dim)
    
  485. 
    
  486.     def test_pickle(self):
    
  487.         "Testing pickle support."
    
  488.         g1 = OGRGeometry("LINESTRING(1 1 1,2 2 2,3 3 3)", "WGS84")
    
  489.         g2 = pickle.loads(pickle.dumps(g1))
    
  490.         self.assertEqual(g1, g2)
    
  491.         self.assertEqual(4326, g2.srs.srid)
    
  492.         self.assertEqual(g1.srs.wkt, g2.srs.wkt)
    
  493. 
    
  494.     def test_ogrgeometry_transform_workaround(self):
    
  495.         "Testing coordinate dimensions on geometries after transformation."
    
  496.         # A bug in GDAL versions prior to 1.7 changes the coordinate
    
  497.         # dimension of a geometry after it has been transformed.
    
  498.         # This test ensures that the bug workarounds employed within
    
  499.         # `OGRGeometry.transform` indeed work.
    
  500.         wkt_2d = "MULTILINESTRING ((0 0,1 1,2 2))"
    
  501.         wkt_3d = "MULTILINESTRING ((0 0 0,1 1 1,2 2 2))"
    
  502.         srid = 4326
    
  503. 
    
  504.         # For both the 2D and 3D MultiLineString, ensure _both_ the dimension
    
  505.         # of the collection and the component LineString have the expected
    
  506.         # coordinate dimension after transform.
    
  507.         geom = OGRGeometry(wkt_2d, srid)
    
  508.         geom.transform(srid)
    
  509.         self.assertEqual(2, geom.coord_dim)
    
  510.         self.assertEqual(2, geom[0].coord_dim)
    
  511.         self.assertEqual(wkt_2d, geom.wkt)
    
  512. 
    
  513.         geom = OGRGeometry(wkt_3d, srid)
    
  514.         geom.transform(srid)
    
  515.         self.assertEqual(3, geom.coord_dim)
    
  516.         self.assertEqual(3, geom[0].coord_dim)
    
  517.         self.assertEqual(wkt_3d, geom.wkt)
    
  518. 
    
  519.     # Testing binary predicates, `assertIs` is used to check that bool is returned.
    
  520. 
    
  521.     def test_equivalence_regression(self):
    
  522.         "Testing equivalence methods with non-OGRGeometry instances."
    
  523.         self.assertIsNotNone(OGRGeometry("POINT(0 0)"))
    
  524.         self.assertNotEqual(OGRGeometry("LINESTRING(0 0, 1 1)"), 3)
    
  525. 
    
  526.     def test_contains(self):
    
  527.         self.assertIs(
    
  528.             OGRGeometry("POINT(0 0)").contains(OGRGeometry("POINT(0 0)")), True
    
  529.         )
    
  530.         self.assertIs(
    
  531.             OGRGeometry("POINT(0 0)").contains(OGRGeometry("POINT(0 1)")), False
    
  532.         )
    
  533. 
    
  534.     def test_crosses(self):
    
  535.         self.assertIs(
    
  536.             OGRGeometry("LINESTRING(0 0, 1 1)").crosses(
    
  537.                 OGRGeometry("LINESTRING(0 1, 1 0)")
    
  538.             ),
    
  539.             True,
    
  540.         )
    
  541.         self.assertIs(
    
  542.             OGRGeometry("LINESTRING(0 0, 0 1)").crosses(
    
  543.                 OGRGeometry("LINESTRING(1 0, 1 1)")
    
  544.             ),
    
  545.             False,
    
  546.         )
    
  547. 
    
  548.     def test_disjoint(self):
    
  549.         self.assertIs(
    
  550.             OGRGeometry("LINESTRING(0 0, 1 1)").disjoint(
    
  551.                 OGRGeometry("LINESTRING(0 1, 1 0)")
    
  552.             ),
    
  553.             False,
    
  554.         )
    
  555.         self.assertIs(
    
  556.             OGRGeometry("LINESTRING(0 0, 0 1)").disjoint(
    
  557.                 OGRGeometry("LINESTRING(1 0, 1 1)")
    
  558.             ),
    
  559.             True,
    
  560.         )
    
  561. 
    
  562.     def test_equals(self):
    
  563.         self.assertIs(
    
  564.             OGRGeometry("POINT(0 0)").contains(OGRGeometry("POINT(0 0)")), True
    
  565.         )
    
  566.         self.assertIs(
    
  567.             OGRGeometry("POINT(0 0)").contains(OGRGeometry("POINT(0 1)")), False
    
  568.         )
    
  569. 
    
  570.     def test_intersects(self):
    
  571.         self.assertIs(
    
  572.             OGRGeometry("LINESTRING(0 0, 1 1)").intersects(
    
  573.                 OGRGeometry("LINESTRING(0 1, 1 0)")
    
  574.             ),
    
  575.             True,
    
  576.         )
    
  577.         self.assertIs(
    
  578.             OGRGeometry("LINESTRING(0 0, 0 1)").intersects(
    
  579.                 OGRGeometry("LINESTRING(1 0, 1 1)")
    
  580.             ),
    
  581.             False,
    
  582.         )
    
  583. 
    
  584.     def test_overlaps(self):
    
  585.         self.assertIs(
    
  586.             OGRGeometry("POLYGON ((0 0, 0 2, 2 2, 2 0, 0 0))").overlaps(
    
  587.                 OGRGeometry("POLYGON ((1 1, 1 5, 5 5, 5 1, 1 1))")
    
  588.             ),
    
  589.             True,
    
  590.         )
    
  591.         self.assertIs(
    
  592.             OGRGeometry("POINT(0 0)").overlaps(OGRGeometry("POINT(0 1)")), False
    
  593.         )
    
  594. 
    
  595.     def test_touches(self):
    
  596.         self.assertIs(
    
  597.             OGRGeometry("POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))").touches(
    
  598.                 OGRGeometry("LINESTRING(0 2, 2 0)")
    
  599.             ),
    
  600.             True,
    
  601.         )
    
  602.         self.assertIs(
    
  603.             OGRGeometry("POINT(0 0)").touches(OGRGeometry("POINT(0 1)")), False
    
  604.         )
    
  605. 
    
  606.     def test_within(self):
    
  607.         self.assertIs(
    
  608.             OGRGeometry("POINT(0.5 0.5)").within(
    
  609.                 OGRGeometry("POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))")
    
  610.             ),
    
  611.             True,
    
  612.         )
    
  613.         self.assertIs(
    
  614.             OGRGeometry("POINT(0 0)").within(OGRGeometry("POINT(0 1)")), False
    
  615.         )
    
  616. 
    
  617.     def test_from_gml(self):
    
  618.         self.assertEqual(
    
  619.             OGRGeometry("POINT(0 0)"),
    
  620.             OGRGeometry.from_gml(
    
  621.                 '<gml:Point gml:id="p21" '
    
  622.                 'srsName="http://www.opengis.net/def/crs/EPSG/0/4326">'
    
  623.                 '    <gml:pos srsDimension="2">0 0</gml:pos>'
    
  624.                 "</gml:Point>"
    
  625.             ),
    
  626.         )
    
  627. 
    
  628.     def test_empty(self):
    
  629.         self.assertIs(OGRGeometry("POINT (0 0)").empty, False)
    
  630.         self.assertIs(OGRGeometry("POINT EMPTY").empty, True)
    
  631. 
    
  632.     def test_empty_point_to_geos(self):
    
  633.         p = OGRGeometry("POINT EMPTY", srs=4326)
    
  634.         self.assertEqual(p.geos.ewkt, p.ewkt)