forked from City-of-Helsinki/parkkihubi
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request City-of-Helsinki#104 from amanpdyadav/geojson-impo…
…rters Geojson importers
- Loading branch information
Showing
11 changed files
with
359 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from .geojson_payment_zones import PaymentZoneImporter | ||
from .geojson_permit_areas import PermitAreaImporter | ||
|
||
__all__ = [ | ||
'PermitAreaImporter', | ||
'PaymentZoneImporter', | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import abc | ||
import json | ||
|
||
from django.contrib.gis.geos import GEOSGeometry | ||
|
||
|
||
class GeoJsonImporter(metaclass=abc.ABCMeta): | ||
|
||
def read_and_parse(self, geojson_file_path): | ||
with open(geojson_file_path, "rt") as file: | ||
root = json.load(file) | ||
for member in root['features']: | ||
yield self._parse_member(member) | ||
|
||
@abc.abstractmethod | ||
def _parse_member(self, member): | ||
pass | ||
|
||
def get_polygons(self, geom): | ||
return GEOSGeometry(json.dumps(geom)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import logging | ||
import os | ||
|
||
from django.db import transaction | ||
|
||
from parkings.models import PaymentZone | ||
|
||
from .geojson_importer import GeoJsonImporter | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
mydir = os.path.dirname(__file__) | ||
|
||
|
||
class PaymentZoneImporter(GeoJsonImporter): | ||
""" | ||
Imports paymentzones data | ||
""" | ||
|
||
def import_payment_zones(self, geojson_file_path): | ||
payment_zone_dicts = self.read_and_parse(geojson_file_path) | ||
count = self._save_payment_zones(payment_zone_dicts) | ||
logger.info('Created or updated {} payment zones'.format(count)) | ||
|
||
@transaction.atomic | ||
def _save_payment_zones(self, payment_zone_dicts): | ||
logger.info('Saving payment zones.') | ||
count = 0 | ||
payment_zone_ids = [] | ||
for payment_dict in payment_zone_dicts: | ||
payment_zone, _ = PaymentZone.objects.update_or_create( | ||
number=payment_dict['number'], | ||
defaults=payment_dict) | ||
payment_zone_ids.append(payment_zone.pk) | ||
count += 1 | ||
PaymentZone.objects.exclude(pk__in=payment_zone_ids).delete() | ||
return count | ||
|
||
def _parse_member(self, member): | ||
name = member['properties']['name'] | ||
number = member['properties']['number'] | ||
geom = self.get_polygons(member['geometry']) | ||
|
||
return { | ||
'name': name, | ||
'number': number, | ||
'geom': geom, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import logging | ||
import os | ||
|
||
from django.db import transaction | ||
|
||
from parkings.models import PermitArea | ||
|
||
from .geojson_importer import GeoJsonImporter | ||
|
||
logger = logging.getLogger(__name__) | ||
mydir = os.path.dirname(__file__) | ||
|
||
|
||
class PermitAreaImporter(GeoJsonImporter): | ||
""" | ||
Imports permit area data | ||
""" | ||
|
||
def import_permit_areas(self, geojson_file_path): | ||
permit_area_dicts = self.read_and_parse(geojson_file_path) | ||
count = self._save_permit_areas(permit_area_dicts) | ||
logger.info('Created or updated {} permit areas'.format(count)) | ||
|
||
@transaction.atomic | ||
def _save_permit_areas(self, permit_areas_dict): | ||
logger.info('Saving permit areas.') | ||
count = 0 | ||
permit_area_ids = [] | ||
for area_dict in permit_areas_dict: | ||
permit_area, _ = PermitArea.objects.update_or_create( | ||
identifier=area_dict['identifier'], | ||
defaults=area_dict) | ||
permit_area_ids.append(permit_area.pk) | ||
count += 1 | ||
PermitArea.objects.exclude(pk__in=permit_area_ids).delete() | ||
return count | ||
|
||
def _parse_member(self, member): | ||
identifier = member['properties']['identifier'] | ||
name = member['properties']['name'] | ||
geom = self.get_polygons(member['geometry']) | ||
|
||
return { | ||
'name': name, | ||
'identifier': identifier, | ||
'geom': geom, | ||
} |
14 changes: 14 additions & 0 deletions
14
parkings/management/commands/import_geojson_payment_zones.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
from django.core.management.base import BaseCommand | ||
|
||
from parkings.importers import PaymentZoneImporter | ||
|
||
|
||
class Command(BaseCommand): | ||
help = 'Uses the PaymentZoneImporter to import payment zones.' | ||
|
||
def add_arguments(self, parser): | ||
parser.add_argument('geojson_file_path') | ||
|
||
def handle(self, *args, **options): | ||
file_path = options.get('geojson_file_path', None) | ||
PaymentZoneImporter().import_payment_zones(file_path) |
14 changes: 14 additions & 0 deletions
14
parkings/management/commands/import_geojson_permit_areas.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
from django.core.management.base import BaseCommand | ||
|
||
from parkings.importers import PermitAreaImporter | ||
|
||
|
||
class Command(BaseCommand): | ||
help = 'Uses the PermitAreaImporter to create permit areas' | ||
|
||
def add_arguments(self, parser): | ||
parser.add_argument('geojson_file_path') | ||
|
||
def handle(self, *args, **options): | ||
file_path = options.get('geojson_file_path', None) | ||
PermitAreaImporter().import_permit_areas(file_path) |
90 changes: 90 additions & 0 deletions
90
parkings/tests/geojson_payment_zones_importer_data.geojson
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
{ | ||
"type": "FeatureCollection", | ||
"name": "maksut_wgs84", | ||
"crs": { | ||
"type": "name", | ||
"properties": { | ||
"name": "urn:ogc:def:crs:OGC:1.3:CRS84" | ||
} | ||
}, | ||
"features": [{ | ||
"type": "Feature", | ||
"properties": { | ||
"number": 0, | ||
"name": "Zone 1" | ||
}, | ||
"geometry": { | ||
"type": "MultiPolygon", | ||
"coordinates": [ | ||
[ | ||
[ | ||
[ | ||
-47.900390625, | ||
-14.944784875088372 | ||
], | ||
[ | ||
-51.591796875, | ||
-19.91138351415555 | ||
], | ||
[ | ||
-41.11083984375, | ||
-21.309846141087192 | ||
], | ||
[ | ||
-43.39599609375, | ||
-15.390135715305204 | ||
], | ||
[ | ||
-47.900390625, | ||
-14.944784875088372 | ||
] | ||
], | ||
[ | ||
[ | ||
-46.6259765625, | ||
-17.14079039331664 | ||
], | ||
[ | ||
-47.548828125, | ||
-16.804541076383455 | ||
], | ||
[ | ||
-46.23046874999999, | ||
-16.699340234594537 | ||
], | ||
[ | ||
-45.3515625, | ||
-19.31114335506464 | ||
], | ||
[ | ||
-46.6259765625, | ||
-17.14079039331664 | ||
] | ||
], | ||
[ | ||
[ | ||
-44.40673828125, | ||
-18.375379094031825 | ||
], | ||
[ | ||
-44.4287109375, | ||
-20.097206227083888 | ||
], | ||
[ | ||
-42.9345703125, | ||
-18.979025953255267 | ||
], | ||
[ | ||
-43.52783203125, | ||
-17.602139123350838 | ||
], | ||
[ | ||
-44.40673828125, | ||
-18.375379094031825 | ||
] | ||
] | ||
] | ||
] | ||
} | ||
}] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
{ | ||
"type": "FeatureCollection", | ||
"name": "asukaspysakointi_wgs84", | ||
"crs": { | ||
"type": "name", | ||
"properties": { | ||
"name": "urn:ogc:def:crs:OGC:1.3:CRS84" | ||
} | ||
}, | ||
"features": [{ | ||
"type": "Feature", | ||
"properties": { | ||
"identifier": 1, | ||
"name": "Asukaspysäköintialue A" | ||
}, | ||
"geometry": { | ||
"type": "MultiPolygon", | ||
"coordinates": [ | ||
[ | ||
[ | ||
[102.0, 2.0], | ||
[103.0, 2.0], | ||
[103.0, 3.0], | ||
[102.0, 3.0], | ||
[102.0, 2.0] | ||
] | ||
], | ||
[ | ||
[ | ||
[100.0, 0.0], | ||
[101.0, 0.0], | ||
[101.0, 1.0], | ||
[100.0, 1.0], | ||
[100.0, 0.0] | ||
], | ||
[ | ||
[100.2, 0.2], | ||
[100.8, 0.2], | ||
[100.8, 0.8], | ||
[100.2, 0.8], | ||
[100.2, 0.2] | ||
] | ||
] | ||
] | ||
} | ||
}] | ||
} |
27 changes: 27 additions & 0 deletions
27
parkings/tests/test_geojson_importing_management_commands.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import os | ||
|
||
import pytest | ||
from django.core.management import call_command | ||
|
||
from parkings.models import PaymentZone, PermitArea | ||
|
||
from ..management.commands import ( | ||
import_geojson_payment_zones, import_geojson_permit_areas) | ||
|
||
mydir = os.path.dirname(__file__) | ||
permit_areas = os.path.join(mydir, 'geojson_permit_areas_importer_data.geojson') | ||
payment_zones = os.path.join(mydir, 'geojson_payment_zones_importer_data.geojson') | ||
|
||
|
||
@pytest.mark.django_db | ||
def test_import_payment_zones(): | ||
call_command(import_geojson_payment_zones.Command(), payment_zones) | ||
|
||
assert PaymentZone.objects.count() == 1 | ||
|
||
|
||
@pytest.mark.django_db | ||
def test_permit_area_importer(): | ||
call_command(import_geojson_permit_areas.Command(), permit_areas) | ||
|
||
assert PermitArea.objects.count() == 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import os | ||
|
||
from parkings.importers import PaymentZoneImporter | ||
|
||
mydir = os.path.dirname(__file__) | ||
|
||
|
||
def test_payment_zone_importer(): | ||
filename = os.path.join(mydir, 'geojson_payment_zones_importer_data.geojson') | ||
importer = PaymentZoneImporter() | ||
data = importer.read_and_parse(filename) | ||
payment_zone = next(iter(data)) | ||
|
||
assert payment_zone['name'] == "Zone 1" | ||
assert payment_zone['number'] == 0 | ||
assert payment_zone['geom'].wkt == ( | ||
'MULTIPOLYGON ((' | ||
'(-47.900390625 -14.94478487508837, -51.591796875 -19.91138351415555, -41.11083984375' | ||
' -21.30984614108719, -43.39599609375 -15.3901357153052, -47.900390625 -14.94478487508837), ' | ||
'(-46.6259765625 -17.14079039331664, -47.548828125 -16.80454107638345, -46.23046874999999' | ||
' -16.69934023459454, -45.3515625 -19.31114335506464, -46.6259765625 -17.14079039331664), ' | ||
'(-44.40673828125 -18.37537909403182, -44.4287109375 -20.09720622708389, -42.9345703125' | ||
' -18.97902595325527, -43.52783203125 -17.60213912335084, -44.40673828125 -18.37537909403182)))' | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import os | ||
|
||
from parkings.importers import PermitAreaImporter | ||
|
||
mydir = os.path.dirname(__file__) | ||
|
||
|
||
def test_permit_area_importer(): | ||
filename = os.path.join(mydir, 'geojson_permit_areas_importer_data.geojson') | ||
importer = PermitAreaImporter() | ||
data = importer.read_and_parse(filename) | ||
permit_area = next(iter(data)) | ||
|
||
assert permit_area['name'] == 'Asukaspysäköintialue A' | ||
assert permit_area['identifier'] == 1 | ||
assert permit_area['geom'].wkt == ( | ||
'MULTIPOLYGON ((' | ||
'(102 2, 103 2, 103 3, 102 3, 102 2)),' | ||
' ((100 0, 101 0, 101 1, 100 1, 100 0),' | ||
' (100.2 0.2, 100.8 0.2, 100.8 0.8, 100.2 0.8, 100.2 0.2)))' | ||
) |