16
16
import tempfile
17
17
import shutil
18
18
19
- from qgis .PyQt .QtCore import QCoreApplication , Qt , QObject , QDate
19
+ from qgis .PyQt .QtCore import QCoreApplication , Qt , QObject , QDate , QDateTime
20
20
21
21
from qgis .core import (NULL ,
22
22
QgsVectorLayer ,
29
29
QgsCategorizedSymbolRenderer ,
30
30
QgsProviderRegistry ,
31
31
QgsWkbTypes ,
32
- QgsDataSourceUri
32
+ QgsDataSourceUri ,
33
+ QgsVectorDataProviderTemporalCapabilities
33
34
)
34
35
from qgis .testing import (start_app ,
35
36
unittest
@@ -47,7 +48,9 @@ def sanitize(endpoint, x):
47
48
# print('Before: ' + endpoint + x)
48
49
# print('After: ' + ret)
49
50
return ret
50
- return endpoint + x .replace ('?' , '_' ).replace ('&' , '_' ).replace ('<' , '_' ).replace ('>' , '_' ).replace ('"' , '_' ).replace ("'" , '_' ).replace (' ' , '_' ).replace (':' , '_' ).replace ('/' , '_' ).replace ('\n ' , '_' )
51
+ return endpoint + x .replace ('?' , '_' ).replace ('&' , '_' ).replace ('<' , '_' ).replace ('>' , '_' ).replace ('"' ,
52
+ '_' ).replace (
53
+ "'" , '_' ).replace (' ' , '_' ).replace (':' , '_' ).replace ('/' , '_' ).replace ('\n ' , '_' )
51
54
52
55
53
56
class MessageLogger (QObject ):
@@ -221,7 +224,9 @@ def setUpClass(cls):
221
224
]
222
225
}""" .encode ('UTF-8' ))
223
226
224
- with open (sanitize (endpoint , '/query?f=json&objectIds=5,3,1,2,4&inSR=4326&outSR=4326&returnGeometry=true&outFields=*&returnM=false&returnZ=false&geometry=-71.123000,66.330000,-65.320000,78.300000&geometryType=esriGeometryEnvelope&spatialRel=esriSpatialRelEnvelopeIntersects' ), 'wb' ) as f :
227
+ with open (sanitize (endpoint ,
228
+ '/query?f=json&objectIds=5,3,1,2,4&inSR=4326&outSR=4326&returnGeometry=true&outFields=*&returnM=false&returnZ=false&geometry=-71.123000,66.330000,-65.320000,78.300000&geometryType=esriGeometryEnvelope&spatialRel=esriSpatialRelEnvelopeIntersects' ),
229
+ 'wb' ) as f :
225
230
f .write ("""
226
231
{
227
232
"displayFieldName": "name",
@@ -364,7 +369,9 @@ def setUpClass(cls):
364
369
]
365
370
}""" .encode ('UTF-8' ))
366
371
367
- with open (sanitize (endpoint , '/query?f=json&where=1=1&returnIdsOnly=true&geometry=-70.000000,67.000000,-60.000000,80.000000&geometryType=esriGeometryEnvelope&spatialRel=esriSpatialRelEnvelopeIntersects' ), 'wb' ) as f :
372
+ with open (sanitize (endpoint ,
373
+ '/query?f=json&where=1=1&returnIdsOnly=true&geometry=-70.000000,67.000000,-60.000000,80.000000&geometryType=esriGeometryEnvelope&spatialRel=esriSpatialRelEnvelopeIntersects' ),
374
+ 'wb' ) as f :
368
375
f .write ("""
369
376
{
370
377
"objectIdFieldName": "OBJECTID",
@@ -375,7 +382,9 @@ def setUpClass(cls):
375
382
}
376
383
""" .encode ('UTF-8' ))
377
384
378
- with open (sanitize (endpoint , '/query?f=json&where==1=&returnIdsOnly=true&geometry=-73.000000,70.000000,-63.000000,80.000000&geometryType=esriGeometryEnvelope&spatialRel=esriSpatialRelEnvelopeIntersects' ), 'wb' ) as f :
385
+ with open (sanitize (endpoint ,
386
+ '/query?f=json&where==1=&returnIdsOnly=true&geometry=-73.000000,70.000000,-63.000000,80.000000&geometryType=esriGeometryEnvelope&spatialRel=esriSpatialRelEnvelopeIntersects' ),
387
+ 'wb' ) as f :
379
388
f .write ("""
380
389
{
381
390
"objectIdFieldName": "OBJECTID",
@@ -386,7 +395,9 @@ def setUpClass(cls):
386
395
}
387
396
""" .encode ('UTF-8' ))
388
397
389
- with open (sanitize (endpoint , '/query?f=json&where=1=1&returnIdsOnly=true&geometry=-68.721119,68.177676,-64.678700,79.123755&geometryType=esriGeometryEnvelope&spatialRel=esriSpatialRelEnvelopeIntersects' ), 'wb' ) as f :
398
+ with open (sanitize (endpoint ,
399
+ '/query?f=json&where=1=1&returnIdsOnly=true&geometry=-68.721119,68.177676,-64.678700,79.123755&geometryType=esriGeometryEnvelope&spatialRel=esriSpatialRelEnvelopeIntersects' ),
400
+ 'wb' ) as f :
390
401
f .write ("""
391
402
{
392
403
"objectIdFieldName": "OBJECTID",
@@ -401,7 +412,7 @@ def setUpClass(cls):
401
412
def tearDownClass (cls ):
402
413
"""Run after all tests"""
403
414
QgsSettings ().clear ()
404
- #shutil.rmtree(cls.basetestpath, True)
415
+ # shutil.rmtree(cls.basetestpath, True)
405
416
cls .vl = None # so as to properly close the provider and remove any temporary file
406
417
407
418
def testGetFeaturesSubsetAttributes2 (self ):
@@ -471,7 +482,9 @@ def testObjectIdDifferentName(self):
471
482
}
472
483
""" .encode ('UTF-8' ))
473
484
474
- with open (sanitize (endpoint , '/query?f=json&objectIds=5,3,1,2,4&inSR=4326&outSR=4326&returnGeometry=true&outFields=*&returnM=false&returnZ=false' ), 'wb' ) as f :
485
+ with open (sanitize (endpoint ,
486
+ '/query?f=json&objectIds=5,3,1,2,4&inSR=4326&outSR=4326&returnGeometry=true&outFields=*&returnM=false&returnZ=false' ),
487
+ 'wb' ) as f :
475
488
f .write ("""
476
489
{
477
490
"displayFieldName": "LABEL",
@@ -545,8 +558,12 @@ def testDateTime(self):
545
558
vl = QgsVectorLayer ("url='http://" + endpoint + "' crs='epsg:4326'" , 'test' , 'arcgisfeatureserver' )
546
559
547
560
self .assertTrue (vl .isValid ())
561
+
562
+ self .assertFalse (vl .dataProvider ().temporalCapabilities ().hasTemporalCapabilities ())
563
+
548
564
with open (sanitize (endpoint ,
549
- '/query?f=json&objectIds=1,2&inSR=4326&outSR=4326&returnGeometry=true&outFields=*&returnM=false&returnZ=false' ), 'wb' ) as f :
565
+ '/query?f=json&objectIds=1,2&inSR=4326&outSR=4326&returnGeometry=true&outFields=*&returnM=false&returnZ=false' ),
566
+ 'wb' ) as f :
550
567
f .write ("""
551
568
{
552
569
"displayFieldName": "name",
@@ -754,7 +771,9 @@ def testBboxRestriction(self):
754
771
Test limiting provider to features within a preset bounding box
755
772
"""
756
773
endpoint = self .basetestpath + '/fake_qgis_http_endpoint'
757
- vl = QgsVectorLayer ("url='http://" + endpoint + "' crs='epsg:4326' bbox='-70.000000,67.000000,-60.000000,80.000000'" , 'test' , 'arcgisfeatureserver' )
774
+ vl = QgsVectorLayer (
775
+ "url='http://" + endpoint + "' crs='epsg:4326' bbox='-70.000000,67.000000,-60.000000,80.000000'" , 'test' ,
776
+ 'arcgisfeatureserver' )
758
777
self .assertTrue (vl .isValid ())
759
778
self .assertEqual (vl .featureCount (), 2 )
760
779
self .assertEqual ([f ['pk' ] for f in vl .getFeatures ()], [2 , 4 ])
@@ -799,7 +818,8 @@ def testBadMultiPoints(self):
799
818
800
819
self .assertTrue (vl .isValid ())
801
820
with open (sanitize (endpoint ,
802
- '/query?f=json&objectIds=1,2,3&inSR=4326&outSR=4326&returnGeometry=true&outFields=*&returnM=false&returnZ=false' ), 'wb' ) as f :
821
+ '/query?f=json&objectIds=1,2,3&inSR=4326&outSR=4326&returnGeometry=true&outFields=*&returnM=false&returnZ=false' ),
822
+ 'wb' ) as f :
803
823
f .write ("""
804
824
{
805
825
"displayFieldName": "name",
@@ -843,7 +863,8 @@ def testBadMultiPoints(self):
843
863
844
864
features = [f for f in vl .getFeatures ()]
845
865
self .assertEqual (len (features ), 3 )
846
- self .assertEqual ([f .geometry ().asWkt () for f in features ], ['MultiPoint ((-70 66))' , '' , 'MultiPoint ((-68 70),(-22 21))' ])
866
+ self .assertEqual ([f .geometry ().asWkt () for f in features ],
867
+ ['MultiPoint ((-70 66))' , '' , 'MultiPoint ((-68 70),(-22 21))' ])
847
868
848
869
def testDomain (self ):
849
870
"""
@@ -908,7 +929,118 @@ def testDomain(self):
908
929
self .assertTrue (vl .isValid ())
909
930
self .assertFalse (vl .fields ()[0 ].editorWidgetSetup ().type ())
910
931
self .assertEqual (vl .fields ()[1 ].editorWidgetSetup ().type (), 'ValueMap' )
911
- self .assertEqual (vl .fields ()[1 ].editorWidgetSetup ().config (), {'map' : [{'Value 1' : 1.0 }, {'Value 2' : 2.0 }, {'Value 3' : 3.0 }]})
932
+ self .assertEqual (vl .fields ()[1 ].editorWidgetSetup ().config (),
933
+ {'map' : [{'Value 1' : 1.0 }, {'Value 2' : 2.0 }, {'Value 3' : 3.0 }]})
934
+
935
+ def testTemporal1 (self ):
936
+ """
937
+ Test timeinfo parsing
938
+ """
939
+ endpoint = self .basetestpath + '/temporal1_fake_qgis_http_endpoint'
940
+ with open (sanitize (endpoint , '?f=json' ), 'wb' ) as f :
941
+ f .write ("""
942
+ {"currentVersion":10.22,"id":1,"name":"QGIS Test","type":"Feature Layer","description":
943
+ "QGIS Provider Test Layer.\n ","geometryType":"esriGeometryPoint","copyrightText":"","parentLayer":{"id":0,"name":"QGIS Tests"},"subLayers":[],
944
+ "minScale":72225,"maxScale":0,
945
+ "defaultVisibility":true,
946
+ "extent":{"xmin":-71.123,"ymin":66.33,"xmax":-65.32,"ymax":78.3,
947
+ "spatialReference":{"wkid":4326,"latestWkid":4326}},
948
+ "hasAttachments":false,"htmlPopupType":"esriServerHTMLPopupTypeAsHTMLText",
949
+ "displayField":"LABEL","typeIdField":null,
950
+ "fields":[{"name":"OBJECTID","type":"esriFieldTypeOID","alias":"OBJECTID","domain":null}
951
+ ],
952
+ "timeInfo": {
953
+ "startTimeField": "date_start",
954
+ "endTimeField": null,
955
+ "trackIdField": null,
956
+ "timeExtent": [
957
+ 1142000000000,
958
+ 1487000000000
959
+ ]
960
+ },
961
+ "relationships":[],"canModifyLayer":false,"canScaleSymbols":false,"hasLabels":false,
962
+ "capabilities":"Map,Query,Data","maxRecordCount":1000,"supportsStatistics":true,
963
+ "supportsAdvancedQueries":true,"supportedQueryFormats":"JSON, AMF",
964
+ "ownershipBasedAccessControlForFeatures":{"allowOthersToQuery":true},"useStandardizedQueries":true}""" .encode (
965
+ 'UTF-8' ))
966
+
967
+ with open (sanitize (endpoint , '/query?f=json_where=1=1&returnIdsOnly=true' ), 'wb' ) as f :
968
+ f .write ("""
969
+ {
970
+ "objectIdFieldName": "OBJECTID",
971
+ "objectIds": [
972
+ 1,
973
+ 2,
974
+ 3
975
+ ]
976
+ }
977
+ """ .encode ('UTF-8' ))
978
+
979
+ # Create test layer
980
+ vl = QgsVectorLayer ("url='http://" + endpoint + "' crs='epsg:4326'" , 'test' , 'arcgisfeatureserver' )
981
+
982
+ self .assertTrue (vl .isValid ())
983
+ self .assertTrue (vl .dataProvider ().temporalCapabilities ().hasTemporalCapabilities ())
984
+ self .assertEqual (vl .dataProvider ().temporalCapabilities ().startField (), 'date_start' )
985
+ self .assertFalse (vl .dataProvider ().temporalCapabilities ().endField ())
986
+ self .assertEqual (vl .dataProvider ().temporalCapabilities ().mode (), QgsVectorDataProviderTemporalCapabilities .ProviderStoresFeatureDateTimeInstantInField )
987
+ self .assertEqual (vl .dataProvider ().temporalCapabilities ().availableTemporalRange ().begin (), QDateTime (2006 , 3 , 11 , 0 , 13 , 20 ))
988
+ self .assertEqual (vl .dataProvider ().temporalCapabilities ().availableTemporalRange ().end (), QDateTime (2017 , 2 , 14 , 1 , 33 , 20 ))
989
+
990
+ def testTemporal2 (self ):
991
+ """
992
+ Test timeinfo parsing
993
+ """
994
+ endpoint = self .basetestpath + '/temporal2_fake_qgis_http_endpoint'
995
+ with open (sanitize (endpoint , '?f=json' ), 'wb' ) as f :
996
+ f .write ("""
997
+ {"currentVersion":10.22,"id":1,"name":"QGIS Test","type":"Feature Layer","description":
998
+ "QGIS Provider Test Layer.\n ","geometryType":"esriGeometryPoint","copyrightText":"","parentLayer":{"id":0,"name":"QGIS Tests"},"subLayers":[],
999
+ "minScale":72225,"maxScale":0,
1000
+ "defaultVisibility":true,
1001
+ "extent":{"xmin":-71.123,"ymin":66.33,"xmax":-65.32,"ymax":78.3,
1002
+ "spatialReference":{"wkid":4326,"latestWkid":4326}},
1003
+ "hasAttachments":false,"htmlPopupType":"esriServerHTMLPopupTypeAsHTMLText",
1004
+ "displayField":"LABEL","typeIdField":null,
1005
+ "fields":[{"name":"OBJECTID","type":"esriFieldTypeOID","alias":"OBJECTID","domain":null}
1006
+ ],
1007
+ "timeInfo": {
1008
+ "startTimeField": "date_start",
1009
+ "endTimeField": "date_end",
1010
+ "trackIdField": null,
1011
+ "timeExtent": [
1012
+ 1142000000000,
1013
+ 1487000000000
1014
+ ]
1015
+ },
1016
+ "relationships":[],"canModifyLayer":false,"canScaleSymbols":false,"hasLabels":false,
1017
+ "capabilities":"Map,Query,Data","maxRecordCount":1000,"supportsStatistics":true,
1018
+ "supportsAdvancedQueries":true,"supportedQueryFormats":"JSON, AMF",
1019
+ "ownershipBasedAccessControlForFeatures":{"allowOthersToQuery":true},"useStandardizedQueries":true}""" .encode (
1020
+ 'UTF-8' ))
1021
+
1022
+ with open (sanitize (endpoint , '/query?f=json_where=1=1&returnIdsOnly=true' ), 'wb' ) as f :
1023
+ f .write ("""
1024
+ {
1025
+ "objectIdFieldName": "OBJECTID",
1026
+ "objectIds": [
1027
+ 1,
1028
+ 2,
1029
+ 3
1030
+ ]
1031
+ }
1032
+ """ .encode ('UTF-8' ))
1033
+
1034
+ # Create test layer
1035
+ vl = QgsVectorLayer ("url='http://" + endpoint + "' crs='epsg:4326'" , 'test' , 'arcgisfeatureserver' )
1036
+
1037
+ self .assertTrue (vl .isValid ())
1038
+ self .assertTrue (vl .dataProvider ().temporalCapabilities ().hasTemporalCapabilities ())
1039
+ self .assertEqual (vl .dataProvider ().temporalCapabilities ().startField (), 'date_start' )
1040
+ self .assertEqual (vl .dataProvider ().temporalCapabilities ().endField (), 'date_end' )
1041
+ self .assertEqual (vl .dataProvider ().temporalCapabilities ().mode (), QgsVectorDataProviderTemporalCapabilities .ProviderStoresFeatureDateTimeStartAndEndInSeparateFields )
1042
+ self .assertEqual (vl .dataProvider ().temporalCapabilities ().availableTemporalRange ().begin (), QDateTime (2006 , 3 , 11 , 0 , 13 , 20 ))
1043
+ self .assertEqual (vl .dataProvider ().temporalCapabilities ().availableTemporalRange ().end (), QDateTime (2017 , 2 , 14 , 1 , 33 , 20 ))
912
1044
913
1045
def testImageServer (self ):
914
1046
"""
0 commit comments