2014-11-08 16:08:12 +00:00
|
|
|
from __future__ import unicode_literals
|
|
|
|
|
|
|
|
import json
|
|
|
|
|
2015-04-24 15:24:07 +00:00
|
|
|
from django.contrib.gis.geos import LinearRing, Point, Polygon
|
2014-11-08 16:08:12 +00:00
|
|
|
from django.core import serializers
|
2015-07-18 12:50:08 +00:00
|
|
|
from django.test import TestCase, mock, skipUnlessDBFeature
|
|
|
|
from django.utils import six
|
2014-11-08 16:08:12 +00:00
|
|
|
|
2015-04-24 15:24:07 +00:00
|
|
|
from .models import City, MultiFields, PennsylvaniaCity
|
2014-11-08 16:08:12 +00:00
|
|
|
|
|
|
|
|
|
|
|
@skipUnlessDBFeature("gis_enabled")
|
|
|
|
class GeoJSONSerializerTests(TestCase):
|
|
|
|
fixtures = ['initial']
|
|
|
|
|
|
|
|
def test_builtin_serializers(self):
|
|
|
|
"""
|
|
|
|
'geojson' should be listed in available serializers.
|
|
|
|
"""
|
|
|
|
all_formats = set(serializers.get_serializer_formats())
|
|
|
|
public_formats = set(serializers.get_public_serializer_formats())
|
|
|
|
|
|
|
|
self.assertIn('geojson', all_formats),
|
|
|
|
self.assertIn('geojson', public_formats)
|
|
|
|
|
|
|
|
def test_serialization_base(self):
|
|
|
|
geojson = serializers.serialize('geojson', City.objects.all().order_by('name'))
|
|
|
|
try:
|
|
|
|
geodata = json.loads(geojson)
|
|
|
|
except Exception:
|
|
|
|
self.fail("Serialized output is not valid JSON")
|
|
|
|
self.assertEqual(len(geodata['features']), len(City.objects.all()))
|
|
|
|
self.assertEqual(geodata['features'][0]['geometry']['type'], 'Point')
|
|
|
|
self.assertEqual(geodata['features'][0]['properties']['name'], 'Chicago')
|
2016-02-23 18:57:53 +00:00
|
|
|
first_city = City.objects.all().order_by('name').first()
|
|
|
|
self.assertEqual(geodata['features'][0]['properties']['pk'], str(first_city.pk))
|
2014-11-08 16:08:12 +00:00
|
|
|
|
|
|
|
def test_geometry_field_option(self):
|
|
|
|
"""
|
|
|
|
When a model has several geometry fields, the 'geometry_field' option
|
|
|
|
can be used to specify the field to use as the 'geometry' key.
|
|
|
|
"""
|
|
|
|
MultiFields.objects.create(
|
|
|
|
city=City.objects.first(), name='Name', point=Point(5, 23),
|
|
|
|
poly=Polygon(LinearRing((0, 0), (0, 5), (5, 5), (5, 0), (0, 0))))
|
|
|
|
|
|
|
|
geojson = serializers.serialize('geojson', MultiFields.objects.all())
|
|
|
|
geodata = json.loads(geojson)
|
|
|
|
self.assertEqual(geodata['features'][0]['geometry']['type'], 'Point')
|
|
|
|
|
2016-01-26 10:06:29 +00:00
|
|
|
geojson = serializers.serialize(
|
|
|
|
'geojson',
|
|
|
|
MultiFields.objects.all(),
|
|
|
|
geometry_field='poly'
|
|
|
|
)
|
|
|
|
geodata = json.loads(geojson)
|
|
|
|
self.assertEqual(geodata['features'][0]['geometry']['type'], 'Polygon')
|
|
|
|
|
|
|
|
# geometry_field is considered even if not in fields (#26138).
|
|
|
|
geojson = serializers.serialize(
|
|
|
|
'geojson',
|
|
|
|
MultiFields.objects.all(),
|
|
|
|
geometry_field='poly',
|
|
|
|
fields=('city',)
|
|
|
|
)
|
2014-11-08 16:08:12 +00:00
|
|
|
geodata = json.loads(geojson)
|
|
|
|
self.assertEqual(geodata['features'][0]['geometry']['type'], 'Polygon')
|
|
|
|
|
|
|
|
def test_fields_option(self):
|
|
|
|
"""
|
|
|
|
The fields option allows to define a subset of fields to be present in
|
|
|
|
the 'properties' of the generated output.
|
|
|
|
"""
|
|
|
|
PennsylvaniaCity.objects.create(name='Mansfield', county='Tioga', point='POINT(-77.071445 41.823881)')
|
2016-04-08 02:04:45 +00:00
|
|
|
geojson = serializers.serialize(
|
|
|
|
'geojson', PennsylvaniaCity.objects.all(), fields=('county', 'point'),
|
|
|
|
)
|
2014-11-08 16:08:12 +00:00
|
|
|
geodata = json.loads(geojson)
|
|
|
|
self.assertIn('county', geodata['features'][0]['properties'])
|
|
|
|
self.assertNotIn('founded', geodata['features'][0]['properties'])
|
2016-02-23 18:57:53 +00:00
|
|
|
self.assertNotIn('pk', geodata['features'][0]['properties'])
|
2014-11-08 16:08:12 +00:00
|
|
|
|
|
|
|
def test_srid_option(self):
|
|
|
|
geojson = serializers.serialize('geojson', City.objects.all().order_by('name'), srid=2847)
|
|
|
|
geodata = json.loads(geojson)
|
|
|
|
self.assertEqual(
|
|
|
|
[int(c) for c in geodata['features'][0]['geometry']['coordinates']],
|
2016-04-08 02:04:45 +00:00
|
|
|
[1564802, 5613214]
|
|
|
|
)
|
2014-11-08 16:08:12 +00:00
|
|
|
|
2015-07-18 12:50:08 +00:00
|
|
|
@mock.patch('django.contrib.gis.serializers.geojson.HAS_GDAL', False)
|
|
|
|
def test_without_gdal(self):
|
|
|
|
# Without coordinate transformation, the serialization should succeed:
|
|
|
|
serializers.serialize('geojson', City.objects.all())
|
|
|
|
with six.assertRaisesRegex(self, serializers.base.SerializationError, '.*GDAL is not installed'):
|
|
|
|
# Coordinate transformations need GDAL
|
|
|
|
serializers.serialize('geojson', City.objects.all(), srid=2847)
|
|
|
|
|
2014-11-08 16:08:12 +00:00
|
|
|
def test_deserialization_exception(self):
|
|
|
|
"""
|
|
|
|
GeoJSON cannot be deserialized.
|
|
|
|
"""
|
|
|
|
with self.assertRaises(serializers.base.SerializerDoesNotExist):
|
|
|
|
serializers.deserialize('geojson', '{}')
|