You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

geojson.py 2.8 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. from __future__ import unicode_literals
  2. from django.contrib.gis.gdal import HAS_GDAL
  3. from django.core.serializers.base import (
  4. SerializationError, SerializerDoesNotExist,
  5. )
  6. from django.core.serializers.json import Serializer as JSONSerializer
  7. if HAS_GDAL:
  8. from django.contrib.gis.gdal import CoordTransform, SpatialReference
  9. class Serializer(JSONSerializer):
  10. """
  11. Convert a queryset to GeoJSON, http://geojson.org/
  12. """
  13. def _init_options(self):
  14. super(Serializer, self)._init_options()
  15. self.geometry_field = self.json_kwargs.pop('geometry_field', None)
  16. self.srid = self.json_kwargs.pop('srid', 4326)
  17. if (self.selected_fields is not None and self.geometry_field is not None
  18. and self.geometry_field not in self.selected_fields):
  19. self.selected_fields = list(self.selected_fields) + [self.geometry_field]
  20. def start_serialization(self):
  21. self._init_options()
  22. self._cts = {} # cache of CoordTransform's
  23. self.stream.write(
  24. '{"type": "FeatureCollection", "crs": {"type": "name", "properties": {"name": "EPSG:%d"}},'
  25. ' "features": [' % self.srid)
  26. def end_serialization(self):
  27. self.stream.write(']}')
  28. def start_object(self, obj):
  29. super(Serializer, self).start_object(obj)
  30. self._geometry = None
  31. if self.geometry_field is None:
  32. # Find the first declared geometry field
  33. for field in obj._meta.fields:
  34. if hasattr(field, 'geom_type'):
  35. self.geometry_field = field.name
  36. break
  37. def get_dump_object(self, obj):
  38. data = {
  39. "type": "Feature",
  40. "properties": self._current,
  41. }
  42. if self._geometry:
  43. if self._geometry.srid != self.srid:
  44. # If needed, transform the geometry in the srid of the global geojson srid
  45. if not HAS_GDAL:
  46. raise SerializationError(
  47. 'Unable to convert geometry to SRID %s when GDAL is not installed.' % self.srid
  48. )
  49. if self._geometry.srid not in self._cts:
  50. srs = SpatialReference(self.srid)
  51. self._cts[self._geometry.srid] = CoordTransform(self._geometry.srs, srs)
  52. self._geometry.transform(self._cts[self._geometry.srid])
  53. data["geometry"] = eval(self._geometry.geojson)
  54. else:
  55. data["geometry"] = None
  56. return data
  57. def handle_field(self, obj, field):
  58. if field.name == self.geometry_field:
  59. self._geometry = field.value_from_object(obj)
  60. else:
  61. super(Serializer, self).handle_field(obj, field)
  62. class Deserializer(object):
  63. def __init__(self, *args, **kwargs):
  64. raise SerializerDoesNotExist("geojson is a serialization-only serializer")