|
1 from django.conf import settings |
|
2 from django.contrib.admin import ModelAdmin |
|
3 from django.contrib.gis.admin.widgets import OpenLayersWidget |
|
4 from django.contrib.gis.gdal import OGRGeomType |
|
5 from django.contrib.gis.db import models |
|
6 |
|
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 admin_media_prefix = settings.ADMIN_MEDIA_PREFIX |
|
32 map_width = 600 |
|
33 map_height = 400 |
|
34 map_srid = 4326 |
|
35 map_template = 'gis/admin/openlayers.html' |
|
36 openlayers_url = 'http://openlayers.org/api/2.6/OpenLayers.js' |
|
37 wms_url = 'http://labs.metacarta.com/wms/vmap0' |
|
38 wms_layer = 'basic' |
|
39 wms_name = 'OpenLayers WMS' |
|
40 debug = False |
|
41 widget = OpenLayersWidget |
|
42 |
|
43 def _media(self): |
|
44 "Injects OpenLayers JavaScript into the admin." |
|
45 media = super(GeoModelAdmin, self)._media() |
|
46 media.add_js([self.openlayers_url]) |
|
47 media.add_js(self.extra_js) |
|
48 return media |
|
49 media = property(_media) |
|
50 |
|
51 def formfield_for_dbfield(self, db_field, **kwargs): |
|
52 """ |
|
53 Overloaded from ModelAdmin so that an OpenLayersWidget is used |
|
54 for viewing/editing GeometryFields. |
|
55 """ |
|
56 if isinstance(db_field, models.GeometryField): |
|
57 # Setting the widget with the newly defined widget. |
|
58 kwargs['widget'] = self.get_map_widget(db_field) |
|
59 return db_field.formfield(**kwargs) |
|
60 else: |
|
61 return super(GeoModelAdmin, self).formfield_for_dbfield(db_field, **kwargs) |
|
62 |
|
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 in ('MULTIPOINT', 'MULTILINESTRING', 'MULTIPOLYGON', 'GEOMETRYCOLLECTION') |
|
70 if is_collection: |
|
71 if db_field._geom == 'GEOMETRYCOLLECTION': collection_type = 'Any' |
|
72 else: collection_type = OGRGeomType(db_field._geom.replace('MULTI', '')) |
|
73 else: |
|
74 collection_type = 'None' |
|
75 |
|
76 class OLMap(self.widget): |
|
77 template = self.map_template |
|
78 geom_type = db_field._geom |
|
79 params = {'admin_media_prefix' : self.admin_media_prefix, |
|
80 'default_lon' : self.default_lon, |
|
81 'default_lat' : self.default_lat, |
|
82 'default_zoom' : self.default_zoom, |
|
83 'display_wkt' : self.debug or self.display_wkt, |
|
84 'geom_type' : OGRGeomType(db_field._geom), |
|
85 'field_name' : db_field.name, |
|
86 'is_collection' : is_collection, |
|
87 'scrollable' : self.scrollable, |
|
88 'layerswitcher' : self.layerswitcher, |
|
89 'collection_type' : collection_type, |
|
90 'is_linestring' : db_field._geom in ('LINESTRING', 'MULTILINESTRING'), |
|
91 'is_polygon' : db_field._geom in ('POLYGON', 'MULTIPOLYGON'), |
|
92 'is_point' : db_field._geom in ('POINT', 'MULTIPOINT'), |
|
93 'num_zoom' : self.num_zoom, |
|
94 'max_zoom' : self.max_zoom, |
|
95 'min_zoom' : self.min_zoom, |
|
96 'units' : self.units, #likely shoud get from object |
|
97 'max_resolution' : self.max_resolution, |
|
98 'max_extent' : self.max_extent, |
|
99 'modifiable' : self.modifiable, |
|
100 'mouse_position' : self.mouse_position, |
|
101 'scale_text' : self.scale_text, |
|
102 'map_width' : self.map_width, |
|
103 'map_height' : self.map_height, |
|
104 'srid' : self.map_srid, |
|
105 'display_srid' : self.display_srid, |
|
106 'wms_url' : self.wms_url, |
|
107 'wms_layer' : self.wms_layer, |
|
108 'wms_name' : self.wms_name, |
|
109 'debug' : self.debug, |
|
110 } |
|
111 return OLMap |
|
112 |
|
113 # Using the Beta OSM in the admin requires the following: |
|
114 # (1) The Google Maps Mercator projection needs to be added |
|
115 # to your `spatial_ref_sys` table. You'll need at least GDAL 1.5: |
|
116 # >>> from django.contrib.gis.gdal import SpatialReference |
|
117 # >>> from django.contrib.gis.utils import add_postgis_srs |
|
118 # >>> add_postgis_srs(SpatialReference(900913)) # Adding the Google Projection |
|
119 from django.contrib.gis import gdal |
|
120 if gdal.HAS_GDAL: |
|
121 class OSMGeoAdmin(GeoModelAdmin): |
|
122 map_template = 'gis/admin/osm.html' |
|
123 extra_js = ['http://openstreetmap.org/openlayers/OpenStreetMap.js'] |
|
124 num_zoom = 20 |
|
125 map_srid = 900913 |
|
126 max_extent = '-20037508,-20037508,20037508,20037508' |
|
127 max_resolution = 156543.0339 |
|
128 units = 'm' |