Skip to content

Commit

Permalink
Merge pull request #294 from City-of-Turku/feature/count-service-unit…
Browse files Browse the repository at this point in the history
…-by-division

Feature/count service unit by division
  • Loading branch information
juuso-j committed Aug 4, 2023
2 parents 4cd0194 + 3f8a7bc commit 3c7bb97
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 27 deletions.
77 changes: 52 additions & 25 deletions services/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,32 @@ def root_service_nodes(services):
)


def resolve_divisions(divisions):
div_list = []
for division_path in divisions:
if division_path.startswith("ocd-division"):
muni_ocd_id = division_path
else:
ocd_id_base = r"[\w0-9~_.-]+"
match_re = r"(%s)/([\w_-]+):(%s)" % (ocd_id_base, ocd_id_base)
m = re.match(match_re, division_path, re.U)
if not m:
raise ParseError("'division' must be of form 'muni/type:id'")

arr = division_path.split("/")
muni_ocd_id = make_muni_ocd_id(arr.pop(0), "/".join(arr))
try:
div = AdministrativeDivision.objects.select_related("geometry").get(
ocd_id=muni_ocd_id
)
except AdministrativeDivision.DoesNotExist:
raise ParseError(
"administrative division with OCD ID '%s' not found" % muni_ocd_id
)
div_list.append(div)
return div_list


class JSONAPISerializer(serializers.ModelSerializer):
def __init__(self, *args, **kwargs):
super(JSONAPISerializer, self).__init__(*args, **kwargs)
Expand Down Expand Up @@ -290,7 +316,13 @@ def root_service_nodes(self, obj):

class Meta:
model = ServiceNode
fields = "__all__"
exclude = (
"search_column_fi",
"search_column_sv",
"search_column_en",
"syllables_fi",
"service_reference",
)


class ServiceSerializer(TranslatedModelSerializer, JSONAPISerializer):
Expand All @@ -305,6 +337,16 @@ def to_representation(self, obj):
total += unit_count.count
ret["unit_count"]["municipality"][div_name] = unit_count.count
ret["unit_count"]["total"] = total

divisions = self.context.get("divisions", [])
include_fields = self.context.get("include", [])
if "unit_count_per_division" in include_fields and divisions:
ret["unit_count_per_division"] = {}
div_list = resolve_divisions(divisions)
for div in div_list:
ret["unit_count_per_division"][div.name] = Unit.objects.filter(
services=obj.pk, location__within=div.geometry.boundary
).count()
return ret

class Meta:
Expand Down Expand Up @@ -520,6 +562,13 @@ class ServiceViewSet(JSONAPIViewSet, viewsets.ReadOnlyModelViewSet):
queryset = Service.objects.all()
serializer_class = ServiceSerializer

def get_serializer_context(self):
ret = super(ServiceViewSet, self).get_serializer_context()
query_params = self.request.query_params
division = query_params.get("division", "")
ret["divisions"] = [x.strip() for x in division.split(",") if x]
return ret

def get_queryset(self):
queryset = (
super(ServiceViewSet, self)
Expand Down Expand Up @@ -710,6 +759,7 @@ class Meta:
"accessibility_property_hash",
"identifier_hash",
"public",
"syllables_fi",
"search_column_fi",
"search_column_sv",
"search_column_en",
Expand Down Expand Up @@ -906,30 +956,7 @@ def validate_service_node_ids(service_node_ids):
# Divisions can be specified with form:
# division=helsinki/kaupunginosa:kallio,vantaa/äänestysalue:5
d_list = filters["division"].lower().split(",")
div_list = []
for division_path in d_list:
if division_path.startswith("ocd-division"):
muni_ocd_id = division_path
else:
ocd_id_base = r"[\w0-9~_.-]+"
match_re = r"(%s)/([\w_-]+):(%s)" % (ocd_id_base, ocd_id_base)
m = re.match(match_re, division_path, re.U)
if not m:
raise ParseError("'division' must be of form 'muni/type:id'")

arr = division_path.split("/")
muni_ocd_id = make_muni_ocd_id(arr.pop(0), "/".join(arr))
try:
div = AdministrativeDivision.objects.select_related("geometry").get(
ocd_id=muni_ocd_id
)
except AdministrativeDivision.DoesNotExist:
raise ParseError(
"administrative division with OCD ID '%s' not found"
% muni_ocd_id
)
div_list.append(div)

div_list = resolve_divisions(d_list)
if div_list:
mp = div_list.pop(0).geometry.boundary
for div in div_list:
Expand Down
23 changes: 21 additions & 2 deletions specification.swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,25 @@ paths:
schema:
type: integer
example: 811
- $ref: "#/components/parameters/include_param"
- name: include
in: query
style: form
explode: false
description: "Enable count service by division with: "include=unit_count_per_division""
type: string
- name: division
in: query
style: form
explode: false
description: A comma-separated list of administrative divisions to be used when unit
counting by service and division. Use either full division ids or shorthands of the form
muni/type\:id
required: false
schema:
type: array
items:
type: string
example: ocd-division/country:fi/kunta:raisio
- $ref: "#/components/parameters/only_param"
- $ref: "#/components/parameters/geometry_param"
/service/:
Expand All @@ -313,7 +331,7 @@ paths:
- service
parameters:
- $ref: "#/components/parameters/page_param"
- $ref: "#/components/parameters/pagesize_param"
- $ref: "#/components/parameters/pagesize_param"
- name: id
in: query
style: form
Expand All @@ -324,6 +342,7 @@ paths:
items:
type: integer
example: 811,663

responses:
"200":
description: List of services, paginated
Expand Down

0 comments on commit 3c7bb97

Please sign in to comment.