1- from django .contrib .gis .geos import LineString
1+ import math
2+ from unittest import skipIf
3+ from unittest .mock import patch
4+
5+ from django .contrib .gis .geos import GEOSGeometry , LineString
6+ from django .contrib .gis .geos import prototypes as capi
7+ from django .contrib .gis .geos .coordseq import GEOSCoordSeq
8+ from django .contrib .gis .geos .libgeos import geos_version_tuple
29from django .test import SimpleTestCase
310
411
@@ -13,3 +20,130 @@ def test_getitem(self):
1320 with self .subTest (i ):
1421 with self .assertRaisesMessage (IndexError , msg ):
1522 coord_seq [i ]
23+
24+ @skipIf (geos_version_tuple () < (3 , 14 ), "GEOS M support requires 3.14+" )
25+ def test_has_m (self ):
26+ geom = GEOSGeometry ("POINT ZM (1 2 3 4)" )
27+ coord_seq = GEOSCoordSeq (capi .get_cs (geom .ptr ), z = True )
28+ self .assertIs (coord_seq .hasm , True )
29+
30+ geom = GEOSGeometry ("POINT Z (1 2 3)" )
31+ coord_seq = GEOSCoordSeq (capi .get_cs (geom .ptr ), z = True )
32+ self .assertIs (coord_seq .hasm , False )
33+
34+ geom = GEOSGeometry ("POINT M (1 2 3)" )
35+ coord_seq = GEOSCoordSeq (capi .get_cs (geom .ptr ), z = False )
36+ self .assertIs (coord_seq .hasm , True )
37+
38+ @skipIf (geos_version_tuple () < (3 , 14 ), "GEOS M support requires 3.14+" )
39+ def test_get_set_m (self ):
40+ geom = GEOSGeometry ("POINT ZM (1 2 3 4)" )
41+ coord_seq = GEOSCoordSeq (capi .get_cs (geom .ptr ), z = True )
42+ self .assertEqual (coord_seq .tuple , (1 , 2 , 3 , 4 ))
43+ self .assertEqual (coord_seq .getM (0 ), 4 )
44+ coord_seq .setM (0 , 10 )
45+ self .assertEqual (coord_seq .tuple , (1 , 2 , 3 , 10 ))
46+ self .assertEqual (coord_seq .getM (0 ), 10 )
47+
48+ geom = GEOSGeometry ("POINT M (1 2 4)" )
49+ coord_seq = GEOSCoordSeq (capi .get_cs (geom .ptr ), z = False )
50+ self .assertEqual (coord_seq .tuple , (1 , 2 , 4 ))
51+ self .assertEqual (coord_seq .getM (0 ), 4 )
52+ coord_seq .setM (0 , 10 )
53+ self .assertEqual (coord_seq .tuple , (1 , 2 , 10 ))
54+ self .assertEqual (coord_seq .getM (0 ), 10 )
55+ self .assertIs (math .isnan (coord_seq .getZ (0 )), True )
56+
57+ @skipIf (geos_version_tuple () < (3 , 14 ), "GEOS M support requires 3.14+" )
58+ def test_setitem (self ):
59+ geom = GEOSGeometry ("POINT ZM (1 2 3 4)" )
60+ coord_seq = GEOSCoordSeq (capi .get_cs (geom .ptr ), z = True )
61+ coord_seq [0 ] = (10 , 20 , 30 , 40 )
62+ self .assertEqual (coord_seq .tuple , (10 , 20 , 30 , 40 ))
63+
64+ geom = GEOSGeometry ("POINT M (1 2 4)" )
65+ coord_seq = GEOSCoordSeq (capi .get_cs (geom .ptr ), z = False )
66+ coord_seq [0 ] = (10 , 20 , 40 )
67+ self .assertEqual (coord_seq .tuple , (10 , 20 , 40 ))
68+ self .assertEqual (coord_seq .getM (0 ), 40 )
69+ self .assertIs (math .isnan (coord_seq .getZ (0 )), True )
70+
71+ @skipIf (geos_version_tuple () < (3 , 14 ), "GEOS M support requires 3.14+" )
72+ def test_kml_m_dimension (self ):
73+ geom = GEOSGeometry ("POINT ZM (1 2 3 4)" )
74+ coord_seq = GEOSCoordSeq (capi .get_cs (geom .ptr ), z = True )
75+ self .assertEqual (coord_seq .kml , "<coordinates>1.0,2.0,3.0</coordinates>" )
76+ geom = GEOSGeometry ("POINT M (1 2 4)" )
77+ coord_seq = GEOSCoordSeq (capi .get_cs (geom .ptr ), z = False )
78+ self .assertEqual (coord_seq .kml , "<coordinates>1.0,2.0,0</coordinates>" )
79+
80+ @skipIf (geos_version_tuple () < (3 , 14 ), "GEOS M support requires 3.14+" )
81+ def test_clone_m_dimension (self ):
82+ geom = GEOSGeometry ("POINT ZM (1 2 3 4)" )
83+ coord_seq = GEOSCoordSeq (capi .get_cs (geom .ptr ), z = True )
84+ clone = coord_seq .clone ()
85+ self .assertEqual (clone .tuple , (1 , 2 , 3 , 4 ))
86+ self .assertIs (clone .hasz , True )
87+ self .assertIs (clone .hasm , True )
88+
89+ geom = GEOSGeometry ("POINT M (1 2 4)" )
90+ coord_seq = GEOSCoordSeq (capi .get_cs (geom .ptr ), z = False )
91+ clone = coord_seq .clone ()
92+ self .assertEqual (clone .tuple , (1 , 2 , 4 ))
93+ self .assertIs (clone .hasz , False )
94+ self .assertIs (clone .hasm , True )
95+
96+ @skipIf (geos_version_tuple () < (3 , 14 ), "GEOS M support requires 3.14+" )
97+ def test_dims (self ):
98+ geom = GEOSGeometry ("POINT ZM (1 2 3 4)" )
99+ coord_seq = GEOSCoordSeq (capi .get_cs (geom .ptr ), z = True )
100+ self .assertEqual (coord_seq .dims , 4 )
101+
102+ geom = GEOSGeometry ("POINT M (1 2 4)" )
103+ coord_seq = GEOSCoordSeq (capi .get_cs (geom .ptr ), z = False )
104+ self .assertEqual (coord_seq .dims , 3 )
105+
106+ geom = GEOSGeometry ("POINT Z (1 2 3)" )
107+ coord_seq = GEOSCoordSeq (capi .get_cs (geom .ptr ), z = True )
108+ self .assertEqual (coord_seq .dims , 3 )
109+
110+ geom = GEOSGeometry ("POINT (1 2)" )
111+ coord_seq = GEOSCoordSeq (capi .get_cs (geom .ptr ), z = False )
112+ self .assertEqual (coord_seq .dims , 2 )
113+
114+ def test_size (self ):
115+ geom = GEOSGeometry ("POINT (1 2)" )
116+ coord_seq = GEOSCoordSeq (capi .get_cs (geom .ptr ), z = False )
117+ self .assertEqual (coord_seq .size , 1 )
118+
119+ geom = GEOSGeometry ("POINT M (1 2 4)" )
120+ coord_seq = GEOSCoordSeq (capi .get_cs (geom .ptr ), z = False )
121+ self .assertEqual (coord_seq .size , 1 )
122+
123+ @skipIf (geos_version_tuple () < (3 , 14 ), "GEOS M support requires 3.14+" )
124+ def test_iscounterclockwise (self ):
125+ geom = GEOSGeometry ("LINEARRING ZM (0 0 3 0, 1 0 0 2, 0 1 1 3, 0 0 3 4)" )
126+ coord_seq = GEOSCoordSeq (capi .get_cs (geom .ptr ), z = True )
127+ self .assertEqual (
128+ coord_seq .tuple ,
129+ (
130+ (0.0 , 0.0 , 3.0 , 0.0 ),
131+ (1.0 , 0.0 , 0.0 , 2.0 ),
132+ (0.0 , 1.0 , 1.0 , 3.0 ),
133+ (0.0 , 0.0 , 3.0 , 4.0 ),
134+ ),
135+ )
136+ self .assertIs (coord_seq .is_counterclockwise , True )
137+
138+ def test_m_support_error (self ):
139+ geom = GEOSGeometry ("POINT M (1 2 4)" )
140+ coord_seq = GEOSCoordSeq (capi .get_cs (geom .ptr ), z = True )
141+ msg = "GEOSCoordSeq with an M dimension requires GEOS 3.14+."
142+
143+ # mock geos_version_tuple to be 3.13.13
144+ with patch (
145+ "django.contrib.gis.geos.coordseq.geos_version_tuple" ,
146+ return_value = (3 , 13 , 13 ),
147+ ):
148+ with self .assertRaisesMessage (NotImplementedError , msg ):
149+ coord_seq .hasm
0 commit comments