1
|
|
|
import unittest |
2
|
|
|
from pyramid import testing |
3
|
|
|
import colander |
4
|
|
|
from oe_geoutils.validation.validators_contour import GeometrieSchemaNode, PointGeometrieSchemaNode, GeometryValidator,\ |
5
|
|
|
GeoJson |
6
|
|
|
|
7
|
|
|
import collections |
8
|
|
|
|
9
|
|
|
Node = collections.namedtuple('Node', ['name']) |
10
|
|
|
|
11
|
|
|
|
12
|
|
|
class GeoJsonTests(unittest.TestCase): |
13
|
|
|
def setUp(self): |
14
|
|
|
self.config = testing.setUp() |
15
|
|
|
self.max_area = 5 |
16
|
|
|
|
17
|
|
|
self.geometrie = GeometrieSchemaNode(max_area=5) |
18
|
|
|
|
19
|
|
|
self.geojson_valid = { |
20
|
|
|
"type": "MultiPolygon", |
21
|
|
|
"coordinates": [[[[152184.01399999947, 212331.8648750011], [152185.94512499947, 212318.6137500011], |
22
|
|
|
[152186.13837499946, 212318.6326250011], [152186.86699999947, 212313.9570000011], |
23
|
|
|
[152186.91462499945, 212313.65187500112], [152192.45099999948, 212314.2943750011], |
24
|
|
|
[152190.69212499948, 212319.2656250011], [152199.58799999946, 212319.5248750011], |
25
|
|
|
[152197.85312499947, 212327.9388750011], [152197.57199999946, 212327.8978750011], |
26
|
|
|
[152197.08099999945, 212333.2668750011], [152184.01399999947, 212331.8648750011]]]], |
27
|
|
|
"crs": { |
28
|
|
|
"type": "name", |
29
|
|
|
"properties": { |
30
|
|
|
"name": "urn:ogc:def:crs:EPSG::31370" |
31
|
|
|
} |
32
|
|
|
} |
33
|
|
|
} |
34
|
|
|
self.geojson_invalid_type = { |
35
|
|
|
"type": "InvalidType", |
36
|
|
|
"coordinates": [ |
37
|
|
|
[[[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]]], |
38
|
|
|
[[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]], |
39
|
|
|
[[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]]] |
40
|
|
|
], |
41
|
|
|
"crs": { |
42
|
|
|
"type": "name", |
43
|
|
|
"properties": { |
44
|
|
|
"name": "urn:ogc:def:crs:EPSG::31370" |
45
|
|
|
} |
46
|
|
|
} |
47
|
|
|
} |
48
|
|
|
self.geojson_geom_not_in_flanders = { |
49
|
|
|
"type": "MultiPolygon", |
50
|
|
|
"coordinates": [ |
51
|
|
|
[[[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]]], |
52
|
|
|
[[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]], |
53
|
|
|
[[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]]] |
54
|
|
|
], |
55
|
|
|
"crs": { |
56
|
|
|
"type": "name", |
57
|
|
|
"properties": { |
58
|
|
|
"name": "urn:ogc:def:crs:EPSG::31370" |
59
|
|
|
} |
60
|
|
|
} |
61
|
|
|
} |
62
|
|
|
self.geojson_point = { |
63
|
|
|
"type": "Point", |
64
|
|
|
"coordinates": [102.0, 2.0], |
65
|
|
|
"crs": { |
66
|
|
|
"type": "name", |
67
|
|
|
"properties": { |
68
|
|
|
"name": "urn:ogc:def:crs:EPSG::31370" |
69
|
|
|
} |
70
|
|
|
} |
71
|
|
|
} |
72
|
|
|
self.geojson_srid_4326 = { |
73
|
|
|
"type": "MultiPolygon", |
74
|
|
|
"coordinates": [[[[152184.01399999947, 212331.8648750011], [152185.94512499947, 212318.6137500011], |
75
|
|
|
[152186.13837499946, 212318.6326250011], [152186.86699999947, 212313.9570000011], |
76
|
|
|
[152186.91462499945, 212313.65187500112], [152192.45099999948, 212314.2943750011], |
77
|
|
|
[152190.69212499948, 212319.2656250011], [152199.58799999946, 212319.5248750011], |
78
|
|
|
[152197.85312499947, 212327.9388750011], [152197.57199999946, 212327.8978750011], |
79
|
|
|
[152197.08099999945, 212333.2668750011], [152184.01399999947, 212331.8648750011]]]], |
80
|
|
|
"crs": { |
81
|
|
|
"type": "name", |
82
|
|
|
"properties": { |
83
|
|
|
"name": "urn:ogc:def:crs:EPSG::4326" |
84
|
|
|
} |
85
|
|
|
} |
86
|
|
|
} |
87
|
|
|
self.geojson_invalid_geom = { |
88
|
|
|
"type": "MultiPolygon", |
89
|
|
|
"coordinates": [[[[152184.01399999947, 212331.8648750011],[152184.01399999947, 212331.8648750010], |
90
|
|
|
[152184.01399999947, 212331.8648750010]]]], |
91
|
|
|
"crs": { |
92
|
|
|
"type": "name", |
93
|
|
|
"properties": { |
94
|
|
|
"name": "urn:ogc:def:crs:EPSG::31370" |
95
|
|
|
} |
96
|
|
|
} |
97
|
|
|
} |
98
|
|
|
self.geojson_invalid_type_no_crs = { |
99
|
|
|
"type": "MultiPolygon", |
100
|
|
|
"coordinates": [[[[152184.01399999947, 212331.8648750011], [152185.94512499947, 212318.6137500011], |
101
|
|
|
[152186.13837499946, 212318.6326250011], [152186.86699999947, 212313.9570000011], |
102
|
|
|
[152186.91462499945, 212313.65187500112], [152192.45099999948, 212314.2943750011], |
103
|
|
|
[152190.69212499948, 212319.2656250011], [152199.58799999946, 212319.5248750011], |
104
|
|
|
[152197.85312499947, 212327.9388750011], [152197.57199999946, 212327.8978750011], |
105
|
|
|
[152197.08099999945, 212333.2668750011], [152184.01399999947, 212331.8648750010]]]], |
106
|
|
|
} |
107
|
|
|
self.geojson_intersecting_geom = { |
108
|
|
|
"type": "MultiPolygon", |
109
|
|
|
"coordinates": [[[[136311.36331804123, 189479.80567278434], [136330.70361803696, 189482.001472787], |
110
|
|
|
[136330.25991803684, 189485.51207278483], [136312.9926180562, 189622.26197274867], |
111
|
|
|
[136309.1386180551, 189621.94727274682], [136287.7971180621, 189620.205472745], |
112
|
|
|
[136299.8650180514, 189546.03157276567], [136303.254718051, 189525.19737276994], |
113
|
|
|
[136303.72911804935, 189522.28157277592], [136303.86311804503, 189521.45807277132], |
114
|
|
|
[136304.32241804857, 189518.63487277366], [136305.1149180444, 189513.7637727782], |
115
|
|
|
[136305.38571804608, 189512.09917277843], [136310.10041803963, 189483.12087278347], |
116
|
|
|
[136310.65291804122, 189479.72507278528], [136311.36331804123, 189479.80567278434]]], |
117
|
|
|
[[[136337.15461803263, 189483.00437278394], [136336.6959180319, 189486.44747278653], |
118
|
|
|
[136328.27671804628, 189549.64527276624], [136390.48041802715, 189555.04837277252], |
119
|
|
|
[136380.7150180388, 189628.1505727535], [136349.4110180502, 189625.37497274857], |
120
|
|
|
[136329.42661805183, 189623.6030727476], [136312.9926180562, 189622.26197274867], |
121
|
|
|
[136330.25991803684, 189485.51207278483], [136330.70361803696, 189482.001472787], |
122
|
|
|
[136337.15461803263, 189483.00437278394]]]], |
123
|
|
|
"crs": { |
124
|
|
|
"type": "name", |
125
|
|
|
"properties": { |
126
|
|
|
"name": "urn:ogc:def:crs:EPSG::31370" |
127
|
|
|
} |
128
|
|
|
} |
129
|
|
|
} |
130
|
|
|
self.geojson_very_large = { |
131
|
|
|
"type": "MultiPolygon", |
132
|
|
|
"coordinates": [[[ |
133
|
|
|
[149287.72860779167967848, 218916.39169927779585123], |
134
|
|
|
[153788.90851591509999707, 182097.94758232310414314], |
135
|
|
|
[220400.85877580623491667, 180574.3110011201351881], |
136
|
|
|
[220400.85877580623491667, 180574.3110011201351881], |
137
|
|
|
[149287.72860779167967848, 218916.39169927779585123] |
138
|
|
|
]]], |
139
|
|
|
"crs": { |
140
|
|
|
"type": "name", |
141
|
|
|
"properties": { |
142
|
|
|
"name": "urn:ogc:def:crs:EPSG::31370" |
143
|
|
|
} |
144
|
|
|
} |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
def tearDown(self): |
148
|
|
|
testing.tearDown() |
149
|
|
|
|
150
|
|
|
def test_valid_max_area(self): |
151
|
|
|
geomschemanode = GeometrieSchemaNode(max_area="4") |
152
|
|
|
self.assertEqual(40000, geomschemanode.max_area) |
153
|
|
|
geomschemanode = GeometrieSchemaNode(max_area=5.2) |
154
|
|
|
self.assertEqual(52000, geomschemanode.max_area) |
155
|
|
|
|
156
|
|
|
def test_invalid_max_area(self): |
157
|
|
|
geomschemanode = GeometrieSchemaNode(max_area="test") |
158
|
|
|
self.assertEqual(80000000, geomschemanode.max_area) |
159
|
|
|
|
160
|
|
|
def test_validGeoJson(self): |
161
|
|
|
validated = self.geometrie.deserialize(self.geojson_valid) |
162
|
|
|
self.assertIsInstance(validated, dict) |
163
|
|
|
|
164
|
|
|
def test_geojson_serialize(self): |
165
|
|
|
self.assertRaises(NotImplementedError, GeoJson().serialize, None, None) |
166
|
|
|
|
167
|
|
|
def test_geojson_serializes_none(self): |
168
|
|
|
self.assertIsNone(GeoJson().build_shape(None)) |
169
|
|
|
self.assertEquals(colander.null, GeoJson().deserialize(None, {})) |
170
|
|
|
self.assertEquals(colander.null, GeoJson().deserialize(None, None)) |
171
|
|
|
|
172
|
|
|
def test_geojson_invalid_type(self): |
173
|
|
|
self.assertRaises( |
174
|
|
|
colander.Invalid, |
175
|
|
|
self.geometrie.deserialize, self.geojson_invalid_type) |
176
|
|
|
|
177
|
|
|
def test_geometrie_validator_none(self): |
178
|
|
|
self.assertRaises( |
179
|
|
|
colander.Invalid, GeometryValidator, None, {}) |
180
|
|
|
self.assertRaises( |
181
|
|
|
colander.Invalid, GeometryValidator, None, None) |
182
|
|
|
|
183
|
|
|
def test_geometrie_validator_no_multipolygon(self): |
184
|
|
|
self.assertRaises( |
185
|
|
|
colander.Invalid, GeometryValidator(None, self.geojson_point).validate_multipolygon, self.max_area) |
186
|
|
|
|
187
|
|
|
def test_geometrie_validator_invalid_srid(self): |
188
|
|
|
self.assertRaises( |
189
|
|
|
colander.Invalid, GeometryValidator(None, self.geojson_srid_4326).validate_multipolygon, self.max_area) |
190
|
|
|
|
191
|
|
|
def test_geometrie_validator_invalid_geometry(self): |
192
|
|
|
self.assertRaises( |
193
|
|
|
colander.Invalid, GeometryValidator(None, self.geojson_invalid_geom).validate_multipolygon, self.max_area) |
194
|
|
|
|
195
|
|
|
def test_geometrie_validator_geometry_not_in_flanders(self): |
196
|
|
|
self.assertRaises( |
197
|
|
|
colander.Invalid, GeometryValidator(None, self.geojson_geom_not_in_flanders).validate_multipolygon, |
198
|
|
|
self.max_area) |
199
|
|
|
|
200
|
|
|
def test_geometrie_validator_invalid_geojson(self): |
201
|
|
|
self.assertRaises( |
202
|
|
|
colander.Invalid, GeometryValidator, None, self.geojson_invalid_type) |
203
|
|
|
|
204
|
|
|
def test_geometrie_validator_invalid_geojson_no_crs(self): |
205
|
|
|
self.assertRaises( |
206
|
|
|
colander.Invalid, GeometryValidator(None, self.geojson_invalid_type_no_crs).validate_multipolygon, |
207
|
|
|
self.max_area) |
208
|
|
|
|
209
|
|
|
def test_geometrie_validator_intersecting_geometry(self): |
210
|
|
|
self.assertRaises( |
211
|
|
|
colander.Invalid, self.geometrie.deserialize, |
212
|
|
|
{"type": "Polygon", "coordinates": [[[0, 0], [0, 0], [0, 0], [0, 0]]], |
213
|
|
|
"crs": {"type": "name", "properties": {"name": "urn:ogc:def:crs:EPSG::31370"}}}) |
214
|
|
|
|
215
|
|
|
def test_geometrie_validator_empty_geometry(self): |
216
|
|
|
self.geometrie.deserialize(self.geojson_intersecting_geom) |
217
|
|
|
|
218
|
|
|
def test_geometrie_validator_very_large(self): |
219
|
|
|
self.assertRaises( |
220
|
|
|
colander.Invalid, self.geometrie.deserialize, self.geojson_very_large) |
221
|
|
|
|
222
|
|
|
def test_schema_node_with_none(self): |
223
|
|
|
self.assertRaises(colander.Invalid, self.geometrie.deserialize, None) |
224
|
|
|
|
225
|
|
|
def test_schema_node_with_max_area_kwarg(self): |
226
|
|
|
schema_node = GeometrieSchemaNode(max_area=6) |
227
|
|
|
self.assertEqual(6 * 10000, schema_node.max_area) |
228
|
|
|
|
229
|
|
|
def test_schema_node_with_max_area_arg(self): |
230
|
|
|
schema_node = GeometrieSchemaNode(6) |
231
|
|
|
self.assertEqual(6 * 10000, schema_node.max_area) |
232
|
|
|
|
233
|
|
|
def test_schema_node_default_missing(self): |
234
|
|
|
result = GeometrieSchemaNode(max_area=5, missing=None).deserialize(None) |
235
|
|
|
self.assertIsNone(result) |
236
|
|
|
|
237
|
|
|
def test_point_schema_node_default_missing(self): |
238
|
|
|
result = PointGeometrieSchemaNode(missing=None).deserialize(None) |
239
|
|
|
self.assertIsNone(result) |
240
|
|
|
|
241
|
|
|
def test_node_missing_in_schema(self): |
242
|
|
|
class TestClass(colander.MappingSchema): |
243
|
|
|
some = colander.SchemaNode(colander.String()) |
244
|
|
|
geometry = GeometrieSchemaNode(max_area=1000, missing=None) |
245
|
|
|
|
246
|
|
|
test_instance = TestClass().deserialize({'some': 'thing'}) |
247
|
|
|
self.assertEqual('thing', test_instance['some']) |
248
|
|
|
self.assertIsNone(test_instance['geometry']) |
249
|
|
|
|
250
|
|
|
def test_node_in_schema(self): |
251
|
|
|
class TestClass(colander.MappingSchema): |
252
|
|
|
some = colander.SchemaNode(colander.String()) |
253
|
|
|
geometry = GeometrieSchemaNode(max_area=1000, missing=None) |
254
|
|
|
|
255
|
|
|
test_instance = TestClass().deserialize({'some': 'thing', 'geometry': self.geojson_valid}) |
256
|
|
|
self.assertEqual('thing', test_instance['some']) |
257
|
|
|
self.assertIsNotNone(test_instance['geometry']) |
258
|
|
|
self.assertIsInstance(test_instance['geometry'], dict) |
259
|
|
|
|
260
|
|
|
def test_node_invalid_in_schema(self): |
261
|
|
|
class TestClass(colander.MappingSchema): |
262
|
|
|
some = colander.SchemaNode(colander.String()) |
263
|
|
|
geometry = GeometrieSchemaNode(max_area=1000, missing=None) |
264
|
|
|
self.assertRaises(colander.Invalid, TestClass().deserialize, |
265
|
|
|
{'some': 'thing', 'geometry': self.geojson_invalid_geom}) |
266
|
|
|
|
267
|
|
|
def test_point_schemanode(self): |
268
|
|
|
PointGeometrieSchemaNode().deserialize( |
269
|
|
|
{"type": "Point", "coordinates": [152185, 212318], |
270
|
|
|
"crs": {"type": "name", "properties": {"name": "urn:ogc:def:crs:EPSG::31370"}}}) |
271
|
|
|
self.assertRaises(colander.Invalid, PointGeometrieSchemaNode().deserialize, |
272
|
|
|
{"type": "MultiPoint", "coordinates": [152185, 212318], |
273
|
|
|
"crs": {"type": "name", "properties": {"name": "urn:ogc:def:crs:EPSG::31370"}}}) |
274
|
|
|
self.assertRaises(colander.Invalid, PointGeometrieSchemaNode().deserialize, |
275
|
|
|
{"type": "Point", "coordinates": [1521850, 2123180], |
276
|
|
|
"crs": {"type": "name", "properties": {"name": "urn:ogc:def:crs:EPSG::31370"}}}) |
277
|
|
|
self.assertRaises(colander.Invalid, PointGeometrieSchemaNode().deserialize, |
278
|
|
|
{"type": "Point", "coordinates": [152185, 212318], |
279
|
|
|
"crs": {"type": "name", "properties": {"name": "urn:ogc:def:crs:EPSG::4321"}}}) |
280
|
|
|
self.assertRaises(colander.Invalid, PointGeometrieSchemaNode().deserialize, |
281
|
|
|
{"type": "Point", "coordinates": [152185, 212318]}) |
282
|
|
|
|