Skip to content

Commit b7e8464

Browse files
authored
Merge pull request #96 from neo-garaix/add-limit-&-order
Add limit & order for requests
2 parents 313d99b + b47cead commit b7e8464

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed

lizmap_server/expression_service.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -782,6 +782,9 @@ def virtualFields(params: Dict[str, str], response: QgsServerResponse, project:
782782
FILTER=An expression to filter layer
783783
FIELDS=list of requested field separated by comma
784784
WITH_GEOMETRY=False
785+
LIMIT=number of features to return or nothing to return all
786+
SORTING_ORDER=asc or desc, default = asc
787+
SORTING_FIELD=field name to sort by
785788
"""
786789
logger = Logger()
787790
layer_name = params.get('LAYER', '')
@@ -865,6 +868,30 @@ def virtualFields(params: Dict[str, str], response: QgsServerResponse, project:
865868

866869
req = QgsFeatureRequest()
867870

871+
# set limit
872+
req_limit = params.get('LIMIT', '-1')
873+
try:
874+
req.setLimit(int(req_limit))
875+
except ValueError:
876+
raise ExpressionServiceError(
877+
"Bad request error",
878+
f"Invalid LIMIT for 'VirtualFields': \"{req_limit}\"",
879+
400)
880+
881+
# set orderby
882+
req_sorting_order_param = params.get('SORTING_ORDER', '')
883+
884+
if req_sorting_order_param in ('asc', 'desc'):
885+
# QGIS expects a boolean to know how to sort
886+
req_sorting_field = params.get('SORTING_FIELD', '')
887+
order_by_clause = QgsFeatureRequest.OrderByClause(req_sorting_field, req_sorting_order_param == 'asc')
888+
req.setOrderBy(QgsFeatureRequest.OrderBy([order_by_clause]))
889+
elif req_sorting_order_param != '' :
890+
raise ExpressionServiceError(
891+
"Bad request error",
892+
f"Invalid SORTING_ORDER for 'VirtualFields': \"{req_sorting_order_param}\"",
893+
400)
894+
868895
# get filter
869896
req_filter = params.get('FILTER', '')
870897
if req_filter:

test/test_expression_service_virtualfields.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import json
22

33
from urllib.parse import quote
4+
from test.utils import _build_query_string, _check_request
45

56
__copyright__ = 'Copyright 2019, 3Liz'
67
__license__ = 'GPL version 3'
@@ -204,3 +205,88 @@ def test_request_with_filter_fields_geometry(client):
204205
assert b['features'][0]['properties']['a'] == 1
205206
assert 'b' in b['features'][0]['properties']
206207
assert b['features'][0]['properties']['b'] == 2
208+
209+
def test_request_limit(client):
210+
""" Test Expression VirtualFields request
211+
"""
212+
projectfile = "france_parts.qgs"
213+
214+
# Make a request
215+
qs = {
216+
"SERVICE": "EXPRESSION",
217+
"REQUEST": "VirtualFields",
218+
"MAP": "france_parts.qgs",
219+
"LAYER": "france_parts",
220+
"VIRTUALS": "{\"a\":\"%s\", \"b\":\"%s\"}" % (
221+
quote('1', safe=''), quote('1 + 1', safe='')),
222+
"LIMIT": "2",
223+
}
224+
225+
rv = client.get(_build_query_string(qs), projectfile)
226+
b = _check_request(rv, http_code=200)
227+
228+
assert 'type' in b
229+
assert b['type'] == 'FeatureCollection'
230+
231+
assert 'features' in b
232+
assert len(b['features']) == 2
233+
234+
assert 'type' in b['features'][0]
235+
assert b['features'][0]['type'] == 'Feature'
236+
237+
assert 'geometry' in b['features'][0]
238+
assert b['features'][0]['geometry'] is None
239+
240+
assert 'properties' in b['features'][0]
241+
assert 'NAME_1' in b['features'][0]['properties']
242+
assert 'Region' in b['features'][0]['properties']
243+
244+
assert 'a' in b['features'][0]['properties']
245+
assert b['features'][0]['properties']['a'] == 1
246+
assert 'b' in b['features'][0]['properties']
247+
assert b['features'][0]['properties']['b'] == 2
248+
249+
250+
def test_request_order(client):
251+
""" Test Expression VirtualFields request
252+
"""
253+
projectfile = "france_parts.qgs"
254+
255+
# Make a request
256+
qs = {
257+
"SERVICE": "EXPRESSION",
258+
"REQUEST": "VirtualFields",
259+
"MAP": "france_parts.qgs",
260+
"LAYER": "france_parts",
261+
"VIRTUALS": "{\"a\":\"%s\", \"b\":\"%s\"}" % (
262+
quote('1', safe=''), quote('1 + 1', safe='')),
263+
"SORTING_ORDER": "desc",
264+
"SORTING_FIELD": "NAME_1",
265+
}
266+
267+
rv = client.get(_build_query_string(qs), projectfile)
268+
b = _check_request(rv, http_code=200)
269+
270+
assert 'type' in b
271+
assert b['type'] == 'FeatureCollection'
272+
273+
assert 'features' in b
274+
assert len(b['features']) == 4
275+
276+
assert 'type' in b['features'][0]
277+
assert b['features'][0]['type'] == 'Feature'
278+
279+
assert 'geometry' in b['features'][0]
280+
assert b['features'][0]['geometry'] is None
281+
282+
assert 'properties' in b['features'][0]
283+
assert 'NAME_1' in b['features'][0]['properties']
284+
assert 'Region' in b['features'][0]['properties']
285+
286+
assert 'a' in b['features'][0]['properties']
287+
assert b['features'][0]['properties']['a'] == 1
288+
assert 'b' in b['features'][0]['properties']
289+
assert b['features'][0]['properties']['b'] == 2
290+
291+
assert b['features'][0]['id'] == 'france_parts.2'
292+
assert b['features'][3]['id'] == 'france_parts.0'

0 commit comments

Comments
 (0)