app/django/contrib/gis/admin/options.py
author Sverre Rabbelier <srabbelier@gmail.com>
Fri, 23 Jan 2009 21:20:33 +0000 (2009-01-23)
changeset 935 09f47e08f805
parent 323 ff1a9aa48cfd
permissions -rw-r--r--
Adust the as_table tag to render a pick link if appropriate The templates are adjusted to pass on a 'reference' value, which is the url_name of the view from which the entity should be picked. The as_table (and related) function(s) construct and then pass on this argument and enable takes_contex so that we have access to the context of the enclosing template. We only extract ReferenceProperties that end with '_link_id' since that is how all RP's are currently named. It is not possible to create a field with the same name as the RP, as GAE will try to interpret it's contents as the key of an entity before even calling any function we can override. Patch by: Sverre Rabbelier
from django.conf import settings
from django.contrib.admin import ModelAdmin
from django.contrib.gis.admin.widgets import OpenLayersWidget
from django.contrib.gis.gdal import OGRGeomType
from django.contrib.gis.db import models

class GeoModelAdmin(ModelAdmin):
    """
    The administration options class for Geographic models. Map settings
    may be overloaded from their defaults to create custom maps.
    """
    # The default map settings that may be overloaded -- still subject
    # to API changes.
    default_lon = 0
    default_lat = 0
    default_zoom = 4
    display_wkt = False
    display_srid = False
    extra_js = []
    num_zoom = 18
    max_zoom = False
    min_zoom = False
    units = False
    max_resolution = False
    max_extent = False
    modifiable = True
    mouse_position = True
    scale_text = True
    layerswitcher = True
    scrollable = True
    admin_media_prefix = settings.ADMIN_MEDIA_PREFIX
    map_width = 600
    map_height = 400
    map_srid = 4326
    map_template = 'gis/admin/openlayers.html'
    openlayers_url = 'http://openlayers.org/api/2.6/OpenLayers.js'
    wms_url = 'http://labs.metacarta.com/wms/vmap0'
    wms_layer = 'basic'
    wms_name = 'OpenLayers WMS'
    debug = False
    widget = OpenLayersWidget

    def _media(self):
        "Injects OpenLayers JavaScript into the admin."
        media = super(GeoModelAdmin, self)._media()
        media.add_js([self.openlayers_url])
        media.add_js(self.extra_js)
        return media
    media = property(_media)

    def formfield_for_dbfield(self, db_field, **kwargs):
        """
        Overloaded from ModelAdmin so that an OpenLayersWidget is used
        for viewing/editing GeometryFields.
        """
        if isinstance(db_field, models.GeometryField):
            # Setting the widget with the newly defined widget.
            kwargs['widget'] = self.get_map_widget(db_field)
            return db_field.formfield(**kwargs)
        else:
            return super(GeoModelAdmin, self).formfield_for_dbfield(db_field, **kwargs)

    def get_map_widget(self, db_field):
        """
        Returns a subclass of the OpenLayersWidget (or whatever was specified
        in the `widget` attribute) using the settings from the attributes set 
        in this class.
        """
        is_collection = db_field._geom in ('MULTIPOINT', 'MULTILINESTRING', 'MULTIPOLYGON', 'GEOMETRYCOLLECTION')
        if is_collection:
            if db_field._geom == 'GEOMETRYCOLLECTION': collection_type = 'Any'
            else: collection_type = OGRGeomType(db_field._geom.replace('MULTI', ''))
        else:
            collection_type = 'None'

        class OLMap(self.widget):
            template = self.map_template
            geom_type = db_field._geom
            params = {'admin_media_prefix' : self.admin_media_prefix,
                      'default_lon' : self.default_lon,
                      'default_lat' : self.default_lat,
                      'default_zoom' : self.default_zoom,
                      'display_wkt' : self.debug or self.display_wkt,
                      'geom_type' : OGRGeomType(db_field._geom),
                      'field_name' : db_field.name,
                      'is_collection' : is_collection,
                      'scrollable' : self.scrollable,
                      'layerswitcher' : self.layerswitcher,
                      'collection_type' : collection_type,
                      'is_linestring' : db_field._geom in ('LINESTRING', 'MULTILINESTRING'),
                      'is_polygon' : db_field._geom in ('POLYGON', 'MULTIPOLYGON'),
                      'is_point' : db_field._geom in ('POINT', 'MULTIPOINT'),
                      'num_zoom' : self.num_zoom,
                      'max_zoom' : self.max_zoom,
                      'min_zoom' : self.min_zoom,
                      'units' : self.units, #likely shoud get from object
                      'max_resolution' : self.max_resolution,
                      'max_extent' : self.max_extent,
                      'modifiable' : self.modifiable,
                      'mouse_position' : self.mouse_position,
                      'scale_text' : self.scale_text,
                      'map_width' : self.map_width,
                      'map_height' : self.map_height,
                      'srid' : self.map_srid,
                      'display_srid' : self.display_srid,
                      'wms_url' : self.wms_url,
                      'wms_layer' : self.wms_layer,
                      'wms_name' : self.wms_name,
                      'debug' : self.debug,
                      }
        return OLMap

# Using the Beta OSM in the admin requires the following:
#  (1) The Google Maps Mercator projection needs to be added
#      to your `spatial_ref_sys` table.  You'll need at least GDAL 1.5:
#      >>> from django.contrib.gis.gdal import SpatialReference
#      >>> from django.contrib.gis.utils import add_postgis_srs
#      >>> add_postgis_srs(SpatialReference(900913)) # Adding the Google Projection 
from django.contrib.gis import gdal
if gdal.HAS_GDAL:
    class OSMGeoAdmin(GeoModelAdmin):
        map_template = 'gis/admin/osm.html'
        extra_js = ['http://openstreetmap.org/openlayers/OpenStreetMap.js']
        num_zoom = 20
        map_srid = 900913
        max_extent = '-20037508,-20037508,20037508,20037508'
        max_resolution = 156543.0339
        units = 'm'