Skip to content

Commit 5236d78

Browse files
committed
Added support for GeometryCollection #126
1 parent 1977767 commit 5236d78

File tree

4 files changed

+72
-9
lines changed

4 files changed

+72
-9
lines changed

requirements-test.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
six
12
psycopg2
23
djangorestframework>=3.3
34
coverage==3.7.1 # rq.filter: >=3,<4

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
six
12
djangorestframework>=3.3,<3.7

rest_framework_gis/fields.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import six # TODO Remove this along with GeoJsonDict when support for python 2.6/2.7 is dropped.
12
import json
23
from collections import OrderedDict
34

@@ -25,10 +26,7 @@ def to_representation(self, value):
2526
if isinstance(value, dict) or value is None:
2627
return value
2728
# we expect value to be a GEOSGeometry instance
28-
return GeoJsonDict((
29-
('type', value.geom_type),
30-
('coordinates', value.coords),
31-
))
29+
return GeoJsonDict(value.geojson)
3230

3331
def to_internal_value(self, value):
3432
if value == '' or value is None:
@@ -54,10 +52,7 @@ def to_representation(self, value):
5452
value = super(GeometrySerializerMethodField, self).to_representation(value)
5553
if value is not None:
5654
# we expect value to be a GEOSGeometry instance
57-
return GeoJsonDict((
58-
('type', value.geom_type),
59-
('coordinates', value.coords),
60-
))
55+
return GeoJsonDict(value.geojson)
6156
else:
6257
return None
6358

@@ -67,6 +62,18 @@ class GeoJsonDict(OrderedDict):
6762
Used for serializing GIS values to GeoJSON values
6863
TODO: remove this when support for python 2.6/2.7 will be dropped
6964
"""
65+
def __init__(self, *args, **kwargs):
66+
"""
67+
If a string is passed attempt to pass it through json.loads,
68+
because it should be a geojson formatted string.
69+
"""
70+
if args and isinstance(args[0], six.string_types):
71+
try:
72+
geojson = json.loads(args[0])
73+
args = (geojson,)
74+
except ValueError:
75+
pass
76+
super(GeoJsonDict, self).__init__(*args, **kwargs)
7077

7178
def __str__(self):
7279
"""

tests/django_restframework_gis_tests/tests.py

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ def test_geometry_serializer_method_field(self):
521521
self.assertEqual(response.status_code, 200)
522522
self.assertEqual(response.data['properties']['name'], 'hidden geometry')
523523
self.assertEqual(response.data['geometry']['type'], 'Point')
524-
self.assertEqual(response.data['geometry']['coordinates'], (0.0, 0.0))
524+
self.assertEqual(response.data['geometry']['coordinates'], [0.0, 0.0])
525525

526526
def test_geometry_serializer_method_field_none(self):
527527
location = Location.objects.create(name='None value', geometry='POINT (135.0 45.0)')
@@ -584,3 +584,57 @@ def test_pickle(self):
584584
pickled = pickle.dumps(geojsondict)
585585
restored = pickle.loads(pickled)
586586
self.assertEqual(restored, geojsondict)
587+
588+
def test_geometrycollection_geojson(self):
589+
""" test geometry collection geojson behaviour """
590+
location = Location.objects.create(name='geometry collection geojson test',
591+
geometry='GEOMETRYCOLLECTION ('
592+
'POINT (135.0 45.0),'
593+
'LINESTRING (135.0 45.0,140.0 50.0,145.0 55.0),'
594+
'POLYGON ((135.0 45.0,140.0 50.0,145.0 55.0,135.0 45.0)))')
595+
url = reverse('api_geojson_location_details', args=[location.id])
596+
expected = {
597+
'id': location.id,
598+
'type': 'Feature',
599+
'properties': {
600+
'details': "http://testserver/geojson/%s/" % location.id,
601+
'name': 'geometry collection geojson test',
602+
'fancy_name': 'Kool geometry collection geojson test',
603+
'timestamp': None,
604+
'slug': 'geometry-collection-geojson-test',
605+
},
606+
'geometry': {
607+
'type': 'GeometryCollection',
608+
'geometries': [
609+
{
610+
'type': 'Point',
611+
'coordinates': [135.0, 45.0]
612+
},
613+
{
614+
'type': 'LineString',
615+
'coordinates': [
616+
[135.0, 45.0],
617+
[140.0, 50.0],
618+
[145.0, 55.0]
619+
]
620+
},
621+
{
622+
'type': 'Polygon',
623+
'coordinates': [
624+
[
625+
[135.0, 45.0],
626+
[140.0, 50.0],
627+
[145.0, 55.0],
628+
[135.0, 45.0],
629+
]
630+
]
631+
},
632+
],
633+
}
634+
}
635+
response = self.client.get(url)
636+
if sys.version_info > (3, 0, 0):
637+
self.assertCountEqual(json.dumps(response.data), json.dumps(expected))
638+
else:
639+
self.assertItemsEqual(json.dumps(response.data), json.dumps(expected))
640+
self.assertContains(response, "Kool geometry collection geojson test")

0 commit comments

Comments
 (0)