33
33
from providertestbase import ProviderTestCase
34
34
35
35
36
- def sanitize (endpoint , x ):
37
- if len (endpoint + x ) > 256 :
38
- ret = endpoint + hashlib .md5 (x .replace ('/' , '_' ).encode ()).hexdigest ()
39
- # print('Before: ' + endpoint + x)
36
+ def sanitize (endpoint , query_params ):
37
+ # Implement the logic of QgsBaseNetworkRequest::sendGET()
38
+ # Note query_params can actually contain subpaths, so create the full url
39
+ # by concatenating boths, and then figure out things...
40
+
41
+ url = endpoint + query_params
42
+ # For REST API using URL subpaths, normalize the subpaths
43
+ afterEndpointStartPos = url .find ("fake_qgis_http_endpoint" ) + len ("fake_qgis_http_endpoint" )
44
+ afterEndpointStart = url [afterEndpointStartPos :]
45
+ afterEndpointStart = afterEndpointStart .replace ('/' , '_' )
46
+ url = url [0 :afterEndpointStartPos ] + afterEndpointStart
47
+ posQuotationMark = url .find ('?' )
48
+ endpoint = url [0 :posQuotationMark ]
49
+ query_params = url [posQuotationMark :]
50
+
51
+ if len (endpoint + query_params ) > 256 :
52
+ ret = endpoint + hashlib .md5 (query_params .encode ()).hexdigest ()
53
+ # print('Before: ' + endpoint + query_params)
40
54
# print('After: ' + ret)
41
55
return ret
42
- ret = endpoint + x .replace ('?' , '_' ).replace ('&' , '_' ).replace ('<' , '_' ).replace ('>' , '_' ).replace ('"' ,
43
- '_' ).replace ("'" ,
44
- '_' ).replace (
56
+ ret = endpoint + query_params .replace ('?' , '_' ).replace ('&' , '_' ).replace ('<' , '_' ).replace ('>' , '_' ).replace ('"' ,
57
+ '_' ).replace ("'" ,
58
+ '_' ).replace (
45
59
' ' , '_' ).replace (':' , '_' ).replace ('/' , '_' ).replace ('\n ' , '_' )
46
60
return ret
47
61
@@ -58,7 +72,8 @@ def GDAL_COMPUTE_VERSION(maj, min, rev):
58
72
59
73
def create_landing_page_api_collection (endpoint ,
60
74
extraparam = '' ,
61
- crs_url = "http://www.opengis.net/def/crs/EPSG/0/4326" ,
75
+ storageCrs = None ,
76
+ crsList = None ,
62
77
bbox = [- 71.123 , 66.33 , - 65.32 , 78.3 ]):
63
78
64
79
questionmark_extraparam = '?' + extraparam if extraparam else ''
@@ -104,9 +119,10 @@ def add_params(x, y):
104
119
}
105
120
}
106
121
}
107
- if crs_url :
108
- collection ["crs" ] = [crs_url ]
109
- collection ["extent" ]["spatial" ]["crs" ] = crs_url
122
+ if storageCrs :
123
+ collection ["storageCrs" ] = storageCrs
124
+ if crsList :
125
+ collection ["crs" ] = crsList
110
126
111
127
with open (sanitize (endpoint , '/collections/mycollection?' + add_params (extraparam , ACCEPT_COLLECTION )), 'wb' ) as f :
112
128
f .write (json .dumps (collection ).encode ('UTF-8' ))
@@ -172,6 +188,9 @@ def tearDownClass(cls):
172
188
shutil .rmtree (cls .basetestpath , True )
173
189
cls .vl = None # so as to properly close the provider and remove any temporary file
174
190
191
+ def testCrs (self ):
192
+ self .assertEqual (self .source .sourceCrs ().authid (), 'OGC:CRS84' )
193
+
175
194
def testExtentSubsetString (self ):
176
195
# can't run the base provider test suite here - WFS/OAPIF extent handling is different
177
196
# to other providers
@@ -250,14 +269,14 @@ def testFeaturePaging(self):
250
269
def testBbox (self ):
251
270
252
271
endpoint = self .__class__ .basetestpath + '/fake_qgis_http_endpoint_testBbox'
253
- create_landing_page_api_collection (endpoint )
272
+ create_landing_page_api_collection (endpoint , storageCrs = "http://www.opengis.net/def/crs/EPSG/0/4326" )
254
273
255
274
# first items
256
275
first_items = {
257
276
"type" : "FeatureCollection" ,
258
277
"features" : [
259
278
{"type" : "Feature" , "id" : "feat.1" , "properties" : {"pk" : 1 , "cnt" : 100 },
260
- "geometry" : {"type" : "Point" , "coordinates" : [- 70.332 , 66.33 ]}}
279
+ "geometry" : {"type" : "Point" , "coordinates" : [66.33 , - 70.332 ]}}
261
280
]
262
281
}
263
282
with open (sanitize (endpoint , '/collections/mycollection/items?limit=10&' + ACCEPT_ITEMS ), 'wb' ) as f :
@@ -271,12 +290,12 @@ def testBbox(self):
271
290
"type" : "FeatureCollection" ,
272
291
"features" : [
273
292
{"type" : "Feature" , "id" : "feat.1" , "properties" : {"pk" : 1 , "cnt" : 100 },
274
- "geometry" : {"type" : "Point" , "coordinates" : [- 70.332 , 66.33 ]}},
293
+ "geometry" : {"type" : "Point" , "coordinates" : [66.33 , - 70.332 ]}},
275
294
{"type" : "Feature" , "id" : "feat.2" , "properties" : {"pk" : 2 , "cnt" : 200 },
276
- "geometry" : {"type" : "Point" , "coordinates" : [- 68.2 , 70.8 ]}}
295
+ "geometry" : {"type" : "Point" , "coordinates" : [70.8 , - 68.2 ]}}
277
296
]
278
297
}
279
- with open (sanitize (endpoint , '/collections/mycollection/items?limit=1000&bbox=65.5,-71,78,-65&bbox-crs=http://www.opengis.net/def/crs/EPSG/0/4326&' + ACCEPT_ITEMS ),
298
+ with open (sanitize (endpoint , '/collections/mycollection/items?limit=1000&bbox=65.5,-71,78,-65&bbox-crs=http://www.opengis.net/def/crs/EPSG/0/4326&crs=http://www.opengis.net/def/crs/EPSG/0/4326& ' + ACCEPT_ITEMS ),
280
299
'wb' ) as f :
281
300
f .write (json .dumps (items ).encode ('UTF-8' ))
282
301
@@ -294,7 +313,7 @@ def testBbox(self):
294
313
295
314
# Test clamping of bbox
296
315
with open (
297
- sanitize (endpoint , '/collections/mycollection/items?limit=1000&bbox=64.5,-180,78,-65&bbox-crs=http://www.opengis.net/def/crs/EPSG/0/4326&' + ACCEPT_ITEMS ),
316
+ sanitize (endpoint , '/collections/mycollection/items?limit=1000&bbox=64.5,-180,78,-65&bbox-crs=http://www.opengis.net/def/crs/EPSG/0/4326&crs=http://www.opengis.net/def/crs/EPSG/0/4326& ' + ACCEPT_ITEMS ),
298
317
'wb' ) as f :
299
318
f .write (json .dumps (items ).encode ('UTF-8' ))
300
319
@@ -314,14 +333,14 @@ def testBbox(self):
314
333
"type" : "FeatureCollection" ,
315
334
"features" : [
316
335
{"type" : "Feature" , "id" : "feat.1" , "properties" : {"pk" : 1 , "cnt" : 100 },
317
- "geometry" : {"type" : "Point" , "coordinates" : [- 70.332 , 66.33 ]}},
336
+ "geometry" : {"type" : "Point" , "coordinates" : [66.33 , - 70.332 ]}},
318
337
{"type" : "Feature" , "id" : "feat.2" , "properties" : {"pk" : 2 , "cnt" : 200 },
319
- "geometry" : {"type" : "Point" , "coordinates" : [- 68.2 , 70.8 ]}},
338
+ "geometry" : {"type" : "Point" , "coordinates" : [70.8 , - 68.2 ]}},
320
339
{"type" : "Feature" , "id" : "feat.3" , "properties" : {"pk" : 4 , "cnt" : 400 },
321
- "geometry" : {"type" : "Point" , "coordinates" : [- 65.32 , 78.3 ]}}
340
+ "geometry" : {"type" : "Point" , "coordinates" : [78.3 , - 65.32 ]}}
322
341
]
323
342
}
324
- with open (sanitize (endpoint , '/collections/mycollection/items?limit=1000&bbox=-90,-180,90,180&bbox-crs=http://www.opengis.net/def/crs/EPSG/0/4326&' + ACCEPT_ITEMS ), 'wb' ) as f :
343
+ with open (sanitize (endpoint , '/collections/mycollection/items?limit=1000&bbox=-90,-180,90,180&bbox-crs=http://www.opengis.net/def/crs/EPSG/0/4326&crs=http://www.opengis.net/def/crs/EPSG/0/4326& ' + ACCEPT_ITEMS ), 'wb' ) as f :
325
344
f .write (json .dumps (items ).encode ('UTF-8' ))
326
345
327
346
extent = QgsRectangle (- 181 , - 91 , 181 , 91 )
@@ -394,8 +413,7 @@ def testLayerMetadata(self):
394
413
["1980-01-01T12:34:56.789Z" , None ],
395
414
[None , "2020-01-01T00:00:00Z" ]
396
415
]
397
- },
398
- "crs" : ["http://www.opengis.net/def/crs/EPSG/0/4326" ]
416
+ }
399
417
},
400
418
"links" : [
401
419
{"href" : "href_self" , "rel" : "self" , "type" : "application/json" , "title" : "my self link" },
@@ -453,6 +471,7 @@ def testLayerMetadata(self):
453
471
assert md .keywords ()['keywords' ] == ["keyword_a" , "keyword_b" ]
454
472
455
473
assert md .crs ().isValid ()
474
+ assert md .crs ().authid () == "OGC:CRS84"
456
475
assert md .crs ().isGeographic ()
457
476
assert not md .crs ().hasAxisInverted ()
458
477
@@ -551,6 +570,40 @@ def testLayerMetadata(self):
551
570
assert len (md .licenses ()) == 1
552
571
assert md .licenses ()[0 ] == 'proprietary'
553
572
573
+ # Variant with storageCrs
574
+ collection = copy .deepcopy (base_collection )
575
+ collection ['storageCrs' ] = "http://www.opengis.net/def/crs/EPSG/0/4258"
576
+ collection ['storageCrsCoordinateEpoch' ] = 2020.0
577
+ with open (sanitize (endpoint , '/collections/mycollection?' + ACCEPT_COLLECTION ), 'wb' ) as f :
578
+ f .write (json .dumps (collection ).encode ('UTF-8' ))
579
+
580
+ vl = QgsVectorLayer ("url='http://" + endpoint + "' typename='mycollection' restrictToRequestBBOX=1" , 'test' ,
581
+ 'OAPIF' )
582
+ self .assertTrue (vl .isValid ())
583
+
584
+ md = vl .metadata ()
585
+ assert vl .sourceCrs ().isValid ()
586
+ assert vl .sourceCrs ().authid () == "EPSG:4258"
587
+ assert vl .sourceCrs ().isGeographic ()
588
+ assert vl .sourceCrs ().coordinateEpoch () == 2020.0
589
+ assert vl .sourceCrs ().hasAxisInverted ()
590
+
591
+ # Variant with a list of crs
592
+ collection = copy .deepcopy (base_collection )
593
+ collection ['crs' ] = ["http://www.opengis.net/def/crs/EPSG/0/4258" , "http://www.opengis.net/def/crs/EPSG/0/4326" ]
594
+ with open (sanitize (endpoint , '/collections/mycollection?' + ACCEPT_COLLECTION ), 'wb' ) as f :
595
+ f .write (json .dumps (collection ).encode ('UTF-8' ))
596
+
597
+ vl = QgsVectorLayer ("url='http://" + endpoint + "' typename='mycollection' restrictToRequestBBOX=1" , 'test' ,
598
+ 'OAPIF' )
599
+ self .assertTrue (vl .isValid ())
600
+
601
+ md = vl .metadata ()
602
+ assert vl .sourceCrs ().isValid ()
603
+ assert vl .sourceCrs ().authid () == "EPSG:4258"
604
+ assert vl .sourceCrs ().isGeographic ()
605
+ assert vl .sourceCrs ().hasAxisInverted ()
606
+
554
607
def testDateTimeFiltering (self ):
555
608
556
609
endpoint = self .__class__ .basetestpath + '/fake_qgis_http_endpoint_testDateTimeFiltering'
@@ -719,7 +772,6 @@ def testDefaultCRS(self):
719
772
endpoint = basetestpath + '/fake_qgis_http_endpoint_ogc84'
720
773
721
774
create_landing_page_api_collection (endpoint ,
722
- crs_url = "" , # OGC norm says that if crs is not explicitly defined it is OGC:CRS84
723
775
bbox = [66.33 , - 71.123 , 78.3 , - 65.32 ])
724
776
725
777
items = {
@@ -766,8 +818,8 @@ def testCRS2056(self):
766
818
endpoint = basetestpath + '/fake_qgis_http_endpoint_epsg_2056'
767
819
768
820
create_landing_page_api_collection (endpoint ,
769
- crs_url = "http://www.opengis.net/def/crs/EPSG/0/2056" ,
770
- bbox = [ 2508500 , 1152000 , 2513450 , 1156950 ])
821
+ storageCrs = "http://www.opengis.net/def/crs/EPSG/0/2056" ,
822
+ crsList = [ "http://www.opengis.net/def/crs/OGC/0/CRS84" , "http://www.opengis.net/def/crs/EPSG/0/2056" ])
771
823
772
824
items = {
773
825
"type" : "FeatureCollection" ,
0 commit comments