Skip to content

Commit f26623b

Browse files
authored
Merge pull request mozboz#9 from webisteme/master
New API endpoint
2 parents 04abab6 + 3c4f346 commit f26623b

File tree

5 files changed

+121
-25
lines changed

5 files changed

+121
-25
lines changed

README.md

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,30 @@ several operations for querying data inside JSONB fields.
1818

1919
See: https://docs.djangoproject.com/en/1.10/ref/contrib/postgres/fields/#containment-and-key-operations
2020

21-
## Usage
22-
23-
python manage.py transformap -i jobs/jobfile.json
24-
25-
Admin interface: /admin
26-
API URL: /places-api/
27-
New jobs should be created as .YAML files in jobs/
28-
2921
## Misc
3022

3123
ETL business logic: places/management/commands
3224
REST API configuration: places/api.py
3325

26+
## Deployment
27+
28+
For development, testing or demo purposes, use the Django development server:
29+
30+
python manage.py runserver 0.0.0.0:9000
31+
32+
Navigate to http://localhost:9000 ...
33+
34+
- /admin for the Admin area
35+
- /places-api for the REST API interface
36+
- /map-instance/MAP-INSTANCE-ID for the GEOJSON API
37+
38+
For production use, deploy Django using WSGI. See:
39+
https://docs.djangoproject.com/en/1.10/howto/deployment/wsgi/
40+
41+
## Usage
42+
43+
To run a job, create a YAML job file in /jobs, then:
3444

45+
python manage.py transformap -i jobs/jobfile.yaml
3546

47+
This fetch and save the partner's data to the database.

places/api.py

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,34 @@ class MapOwnerViewSet(viewsets.ModelViewSet):
1515
queryset = MapOwner.objects.all()
1616
serializer_class = MapOwnerSerializer
1717

18-
# Map Instance
1918

20-
class MapInstanceSerializer(serializers.HyperlinkedModelSerializer):
19+
20+
# Map Data
21+
22+
class MapDataSerializer(serializers.HyperlinkedModelSerializer):
23+
class Meta:
24+
model = MapData
25+
fields = ('map_instance', 'map_object', 'schema_field', 'field_value', 'date_created', 'date_modified')
26+
27+
class MapDataViewSet(viewsets.ModelViewSet):
28+
queryset = MapData.objects.all()
29+
serializer_class = MapDataSerializer
30+
31+
32+
33+
# Map Instance (lite)
34+
35+
class MapInstanceSerializer(serializers.ModelSerializer):
36+
2137
class Meta:
2238
model = MapInstance
23-
fields = ('schema', 'map_definition', 'date_created', 'date_modified')
39+
fields = ('id', 'schema', 'map_definition', 'date_created', 'date_modified',)
2440

2541
class MapInstanceViewSet(viewsets.ModelViewSet):
2642
queryset = MapInstance.objects.all()
2743
serializer_class = MapInstanceSerializer
28-
44+
45+
2946
# Map Object
3047

3148
class MapObjectSerializer(serializers.HyperlinkedModelSerializer):
@@ -36,17 +53,6 @@ class Meta:
3653
class MapObjectViewSet(viewsets.ModelViewSet):
3754
queryset = MapObject.objects.all()
3855
serializer_class = MapObjectSerializer
39-
40-
# Map Data
41-
42-
class MapDataSerializer(serializers.HyperlinkedModelSerializer):
43-
class Meta:
44-
model = MapData
45-
fields = ('map_instance', 'map_object', 'schema_field', 'field_value', 'date_created', 'date_modified')
46-
47-
class MapDataViewSet(viewsets.ModelViewSet):
48-
queryset = MapData.objects.all()
49-
serializer_class = MapDataSerializer
5056

5157
# Map Definition
5258

places/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class MapInstance(models.Model):
4949
date_modified = models.DateTimeField(auto_now=True)
5050

5151
def __unicode__(self):
52-
return u'%s' % self.map_definition
52+
return u'%s %s' % (self.map_definition, self.id)
5353

5454
class Meta:
5555
db_table = 'map_instances'

places/views.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,80 @@
1+
from urlparse import urlparse
2+
13
from django.shortcuts import render
4+
from django.http import HttpResponse, JsonResponse
5+
from django.core.exceptions import ObjectDoesNotExist
6+
7+
from places.models import MapInstance, MapData, MapObject
28

39
# Create your views here.
10+
11+
def map_instance_geojson(request, map_instance_id):
12+
13+
'''
14+
Fetched all objects (and properties) for a given map instance,
15+
returns a GEOJSON feature collection.
16+
'''
17+
18+
# Fetch the map instance
19+
20+
try:
21+
map_instance = MapInstance.objects.get(id=map_instance_id)
22+
except ObjectDoesNotExist:
23+
return JsonResponse({"Error" : "Map Instance with ID %s does not exist!" % map_instance_id})
24+
25+
# Deduce URL from request
26+
27+
request_url = urlparse(request.build_absolute_uri())
28+
base_url = 'http://%s%s' % (request_url.netloc, request_url.path)
29+
30+
# Set pagination params
31+
32+
page = int(request.GET.get('page', 1))
33+
x = (page - 1) * 25
34+
y = page * 25
35+
36+
# Prepare GEOJSON response
37+
38+
response = {
39+
"type" : "Feature Collection",
40+
"count" : 25,
41+
"next" : "%s?page=%s" % (base_url, page + 1),
42+
}
43+
44+
if page <= 1:
45+
response['previous'] = None
46+
else:
47+
response['previous'] = "%s?page=%s" % (base_url, page - 1)
48+
49+
# Fetch and serialise map objects
50+
51+
map_objects = MapObject.objects.filter(map_instance=map_instance).order_by('id')[x:y]
52+
53+
features = []
54+
for map_object in map_objects:
55+
feature = {
56+
"type" : "Feature",
57+
"geometry" : {
58+
"type" : "Point",
59+
"coordinates": [
60+
float(map_object.longitude),
61+
float(map_object.latitude),
62+
]
63+
},
64+
"properties" : {}
65+
}
66+
67+
object_data = MapData.objects.filter(map_object=map_object)
68+
69+
for field in object_data:
70+
field_name = field.schema_field
71+
feature["properties"][field.schema_field.field_name] = field.field_value
72+
73+
features.append(feature)
74+
75+
response['features'] = features
76+
77+
return JsonResponse(response, safe=False)
78+
79+
80+

tfm/urls.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
from django.conf.urls import url, include
22
from django.contrib import admin
33

4-
import places.api
4+
import places.api, places.views
55

66

77
urlpatterns = [
88
url(r'^admin/', admin.site.urls),
99
url(r'^places-api/', include(places.api.router.urls)),
10+
url(r'^map-instance/(?P<map_instance_id>\d+)/$', places.views.map_instance_geojson)
1011
]

0 commit comments

Comments
 (0)