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.
 
 
 
 

143 lines
5.5 KiB

  1. from django.contrib.admin import ModelAdmin
  2. from django.contrib.gis.admin.widgets import OpenLayersWidget
  3. from django.contrib.gis.db import models
  4. from django.contrib.gis.gdal import HAS_GDAL, OGRGeomType
  5. from django.core.exceptions import ImproperlyConfigured
  6. spherical_mercator_srid = 3857
  7. class GeoModelAdmin(ModelAdmin):
  8. """
  9. The administration options class for Geographic models. Map settings
  10. may be overloaded from their defaults to create custom maps.
  11. """
  12. # The default map settings that may be overloaded -- still subject
  13. # to API changes.
  14. default_lon = 0
  15. default_lat = 0
  16. default_zoom = 4
  17. display_wkt = False
  18. display_srid = False
  19. extra_js = []
  20. num_zoom = 18
  21. max_zoom = False
  22. min_zoom = False
  23. units = False
  24. max_resolution = False
  25. max_extent = False
  26. modifiable = True
  27. mouse_position = True
  28. scale_text = True
  29. layerswitcher = True
  30. scrollable = True
  31. map_width = 600
  32. map_height = 400
  33. map_srid = 4326
  34. map_template = 'gis/admin/openlayers.html'
  35. openlayers_url = 'http://openlayers.org/api/2.13/OpenLayers.js'
  36. point_zoom = num_zoom - 6
  37. wms_url = 'http://vmap0.tiles.osgeo.org/wms/vmap0'
  38. wms_layer = 'basic'
  39. wms_name = 'OpenLayers WMS'
  40. wms_options = {'format': 'image/jpeg'}
  41. debug = False
  42. widget = OpenLayersWidget
  43. @property
  44. def media(self):
  45. "Injects OpenLayers JavaScript into the admin."
  46. media = super(GeoModelAdmin, self).media
  47. media.add_js([self.openlayers_url])
  48. media.add_js(self.extra_js)
  49. return media
  50. def formfield_for_dbfield(self, db_field, **kwargs):
  51. """
  52. Overloaded from ModelAdmin so that an OpenLayersWidget is used
  53. for viewing/editing 2D GeometryFields (OpenLayers 2 does not support
  54. 3D editing).
  55. """
  56. if isinstance(db_field, models.GeometryField) and db_field.dim < 3:
  57. kwargs.pop('request', None)
  58. # Setting the widget with the newly defined widget.
  59. kwargs['widget'] = self.get_map_widget(db_field)
  60. return db_field.formfield(**kwargs)
  61. else:
  62. return super(GeoModelAdmin, self).formfield_for_dbfield(db_field, **kwargs)
  63. def get_map_widget(self, db_field):
  64. """
  65. Returns a subclass of the OpenLayersWidget (or whatever was specified
  66. in the `widget` attribute) using the settings from the attributes set
  67. in this class.
  68. """
  69. is_collection = db_field.geom_type in ('MULTIPOINT', 'MULTILINESTRING', 'MULTIPOLYGON', 'GEOMETRYCOLLECTION')
  70. if is_collection:
  71. if db_field.geom_type == 'GEOMETRYCOLLECTION':
  72. collection_type = 'Any'
  73. else:
  74. collection_type = OGRGeomType(db_field.geom_type.replace('MULTI', ''))
  75. else:
  76. collection_type = 'None'
  77. class OLMap(self.widget):
  78. template = self.map_template
  79. geom_type = db_field.geom_type
  80. wms_options = ''
  81. if self.wms_options:
  82. wms_options = ["%s: '%s'" % pair for pair in self.wms_options.items()]
  83. wms_options = ', %s' % ', '.join(wms_options)
  84. params = {'default_lon': self.default_lon,
  85. 'default_lat': self.default_lat,
  86. 'default_zoom': self.default_zoom,
  87. 'display_wkt': self.debug or self.display_wkt,
  88. 'geom_type': OGRGeomType(db_field.geom_type),
  89. 'field_name': db_field.name,
  90. 'is_collection': is_collection,
  91. 'scrollable': self.scrollable,
  92. 'layerswitcher': self.layerswitcher,
  93. 'collection_type': collection_type,
  94. 'is_generic': db_field.geom_type == 'GEOMETRY',
  95. 'is_linestring': db_field.geom_type in ('LINESTRING', 'MULTILINESTRING'),
  96. 'is_polygon': db_field.geom_type in ('POLYGON', 'MULTIPOLYGON'),
  97. 'is_point': db_field.geom_type in ('POINT', 'MULTIPOINT'),
  98. 'num_zoom': self.num_zoom,
  99. 'max_zoom': self.max_zoom,
  100. 'min_zoom': self.min_zoom,
  101. 'units': self.units, # likely should get from object
  102. 'max_resolution': self.max_resolution,
  103. 'max_extent': self.max_extent,
  104. 'modifiable': self.modifiable,
  105. 'mouse_position': self.mouse_position,
  106. 'scale_text': self.scale_text,
  107. 'map_width': self.map_width,
  108. 'map_height': self.map_height,
  109. 'point_zoom': self.point_zoom,
  110. 'srid': self.map_srid,
  111. 'display_srid': self.display_srid,
  112. 'wms_url': self.wms_url,
  113. 'wms_layer': self.wms_layer,
  114. 'wms_name': self.wms_name,
  115. 'wms_options': wms_options,
  116. 'debug': self.debug,
  117. }
  118. return OLMap
  119. class OSMGeoAdmin(GeoModelAdmin):
  120. map_template = 'gis/admin/osm.html'
  121. num_zoom = 20
  122. map_srid = spherical_mercator_srid
  123. max_extent = '-20037508,-20037508,20037508,20037508'
  124. max_resolution = '156543.0339'
  125. point_zoom = num_zoom - 6
  126. units = 'm'
  127. def __init__(self, *args):
  128. if not HAS_GDAL:
  129. raise ImproperlyConfigured("OSMGeoAdmin is not usable without GDAL libs installed")
  130. super(OSMGeoAdmin, self).__init__(*args)