Skip to content

Commit

Permalink
Fixed #11810 -- Fixed typo and errors that prevented modifiable fro…
Browse files Browse the repository at this point in the history
…m working in the geographic admin. Thanks to Rob Coup for the bug report. Refs #12504.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@12995 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information
jbronn committed Apr 16, 2010
1 parent 2cd48ba commit 1ad9c36
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 23 deletions.
8 changes: 1 addition & 7 deletions django/contrib/gis/admin/options.py
Expand Up @@ -64,7 +64,7 @@ def formfield_for_dbfield(self, db_field, **kwargs):
def get_map_widget(self, db_field): def get_map_widget(self, db_field):
""" """
Returns a subclass of the OpenLayersWidget (or whatever was specified Returns a subclass of the OpenLayersWidget (or whatever was specified
in the `widget` attribute) using the settings from the attributes set in the `widget` attribute) using the settings from the attributes set
in this class. in this class.
""" """
is_collection = db_field.geom_type in ('MULTIPOINT', 'MULTILINESTRING', 'MULTIPOLYGON', 'GEOMETRYCOLLECTION') is_collection = db_field.geom_type in ('MULTIPOINT', 'MULTILINESTRING', 'MULTIPOLYGON', 'GEOMETRYCOLLECTION')
Expand Down Expand Up @@ -111,12 +111,6 @@ class OLMap(self.widget):
} }
return OLMap 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 from django.contrib.gis import gdal
if gdal.HAS_GDAL: if gdal.HAS_GDAL:
class OSMGeoAdmin(GeoModelAdmin): class OSMGeoAdmin(GeoModelAdmin):
Expand Down
37 changes: 22 additions & 15 deletions django/contrib/gis/templates/gis/admin/openlayers.js
@@ -1,6 +1,7 @@
{# Author: Justin Bronn, Travis Pinney & Dane Springmeyer #} {# Author: Justin Bronn, Travis Pinney & Dane Springmeyer #}
{% block vars %}var {{ module }} = {}; {% block vars %}var {{ module }} = {};
{{ module }}.map = null; {{ module }}.controls = null; {{ module }}.panel = null; {{ module }}.re = new RegExp("^SRID=\d+;(.+)", "i"); {{ module }}.layers = {}; {{ module }}.map = null; {{ module }}.controls = null; {{ module }}.panel = null; {{ module }}.re = new RegExp("^SRID=\d+;(.+)", "i"); {{ module }}.layers = {};
{{ module }}.modifiable = {{ modifiable|yesno:"true,false" }};
{{ module }}.wkt_f = new OpenLayers.Format.WKT(); {{ module }}.wkt_f = new OpenLayers.Format.WKT();
{{ module }}.is_collection = {{ is_collection|yesno:"true,false" }}; {{ module }}.is_collection = {{ is_collection|yesno:"true,false" }};
{{ module }}.collection_type = '{{ collection_type }}'; {{ module }}.collection_type = '{{ collection_type }}';
Expand Down Expand Up @@ -43,10 +44,10 @@
{{ module }}.modify_wkt = function(event){ {{ module }}.modify_wkt = function(event){
if ({{ module }}.is_collection){ if ({{ module }}.is_collection){
if ({{ module }}.is_point){ if ({{ module }}.is_point){
{{ module }}.add_wkt(event); {{ module }}.add_wkt(event);
return; return;
} else { } else {
// When modifying the selected components are added to the // When modifying the selected components are added to the
// vector layer so we only increment to the `num_geom` value. // vector layer so we only increment to the `num_geom` value.
var feat = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.{{ geom_type }}()); var feat = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.{{ geom_type }}());
for (var i = 0; i < {{ module }}.num_geom; i++){ for (var i = 0; i < {{ module }}.num_geom; i++){
Expand All @@ -69,7 +70,7 @@
{{ module }}.map.setCenter(new OpenLayers.LonLat({{ default_lon }}, {{ default_lat }}), {{ default_zoom }}); {{ module }}.map.setCenter(new OpenLayers.LonLat({{ default_lon }}, {{ default_lat }}), {{ default_zoom }});
} }
// Add Select control // Add Select control
{{ module }}.addSelectControl = function(){ {{ module }}.addSelectControl = function(){
var select = new OpenLayers.Control.SelectFeature({{ module }}.layers.vector, {'toggle' : true, 'clickout' : true}); var select = new OpenLayers.Control.SelectFeature({{ module }}.layers.vector, {'toggle' : true, 'clickout' : true});
{{ module }}.map.addControl(select); {{ module }}.map.addControl(select);
select.activate(); select.activate();
Expand All @@ -88,16 +89,20 @@
} else if ({{ module }}.is_point){ } else if ({{ module }}.is_point){
draw_ctl = new OpenLayers.Control.DrawFeature(lyr, OpenLayers.Handler.Point, {'displayClass': 'olControlDrawFeaturePoint'}); draw_ctl = new OpenLayers.Control.DrawFeature(lyr, OpenLayers.Handler.Point, {'displayClass': 'olControlDrawFeaturePoint'});
} }
{% if modifiable %} if ({{ module }}.modifiable){
var mod = new OpenLayers.Control.ModifyFeature(lyr, {'displayClass': 'olControlModifyFeature'}); var mod = new OpenLayers.Control.ModifyFeature(lyr, {'displayClass': 'olControlModifyFeature'});
{{ module }}.controls = [nav, draw_ctl, mod]; {{ module }}.controls = [nav, draw_ctl, mod];
{% else %} } else {
{{ module }}.controls = [nav, darw_ctl]; if(!lyr.features.length){
{% endif %} {{ module }}.controls = [nav, draw_ctl];
} else {
{{ module }}.controls = [nav];
}
}
} }
{{ module }}.init = function(){ {{ module }}.init = function(){
{% block map_options %}// The options hash, w/ zoom, resolution, and projection settings. {% block map_options %}// The options hash, w/ zoom, resolution, and projection settings.
var options = { var options = {
{% autoescape off %}{% for item in map_options.items %} '{{ item.0 }}' : {{ item.1 }}{% if not forloop.last %},{% endif %} {% autoescape off %}{% for item in map_options.items %} '{{ item.0 }}' : {{ item.1 }}{% if not forloop.last %},{% endif %}
{% endfor %}{% endautoescape %} };{% endblock %} {% endfor %}{% endautoescape %} };{% endblock %}
// The admin map for this geometry field. // The admin map for this geometry field.
Expand All @@ -112,7 +117,7 @@
// Read WKT from the text field. // Read WKT from the text field.
var wkt = document.getElementById('{{ id }}').value; var wkt = document.getElementById('{{ id }}').value;
if (wkt){ if (wkt){
// After reading into geometry, immediately write back to // After reading into geometry, immediately write back to
// WKT <textarea> as EWKT (so that SRID is included). // WKT <textarea> as EWKT (so that SRID is included).
var admin_geom = {{ module }}.read_wkt(wkt); var admin_geom = {{ module }}.read_wkt(wkt);
{{ module }}.write_wkt(admin_geom); {{ module }}.write_wkt(admin_geom);
Expand All @@ -128,14 +133,14 @@
// Zooming to the bounds. // Zooming to the bounds.
{{ module }}.map.zoomToExtent(admin_geom.geometry.getBounds()); {{ module }}.map.zoomToExtent(admin_geom.geometry.getBounds());
if ({{ module }}.is_point){ if ({{ module }}.is_point){
{{ module }}.map.zoomTo({{ point_zoom }}); {{ module }}.map.zoomTo({{ point_zoom }});
} }
} else { } else {
{{ module }}.map.setCenter(new OpenLayers.LonLat({{ default_lon }}, {{ default_lat }}), {{ default_zoom }}); {{ module }}.map.setCenter(new OpenLayers.LonLat({{ default_lon }}, {{ default_lat }}), {{ default_zoom }});
} }
// This allows editing of the geographic fields -- the modified WKT is // This allows editing of the geographic fields -- the modified WKT is
// written back to the content field (as EWKT, so that the ORM will know // written back to the content field (as EWKT, so that the ORM will know
// to transform back to original SRID). // to transform back to original SRID).
{{ module }}.layers.vector.events.on({"featuremodified" : {{ module }}.modify_wkt}); {{ module }}.layers.vector.events.on({"featuremodified" : {{ module }}.modify_wkt});
{{ module }}.layers.vector.events.on({"featureadded" : {{ module }}.add_wkt}); {{ module }}.layers.vector.events.on({"featureadded" : {{ module }}.add_wkt});
{% block controls %} {% block controls %}
Expand All @@ -153,7 +158,9 @@
{% if not scrollable %}{{ module }}.map.getControlsByClass('OpenLayers.Control.Navigation')[0].disableZoomWheel();{% endif %} {% if not scrollable %}{{ module }}.map.getControlsByClass('OpenLayers.Control.Navigation')[0].disableZoomWheel();{% endif %}
{% endblock %} {% endblock %}
if (wkt){ if (wkt){
{{ module }}.enableEditing(); if ({{ module }}.modifiable){
{{ module }}.enableEditing();
}
} else { } else {
{{ module }}.enableDrawing(); {{ module }}.enableDrawing();
} }
Expand Down
17 changes: 16 additions & 1 deletion docs/ref/contrib/gis/admin.txt
Expand Up @@ -47,11 +47,26 @@ GeoDjango's admin site
Link to the URL of the OpenLayers JavaScript. Defaults to Link to the URL of the OpenLayers JavaScript. Defaults to
``'http://openlayers.org/api/2.8/OpenLayers.js'``. ``'http://openlayers.org/api/2.8/OpenLayers.js'``.



.. attribute:: modifiable

Defaults to ``False``. When set to to ``True``, disables editing of
existing geometry fields in the admin.

.. note::

This is different from adding the geometry field to
:attr:`~django.contrib.admin.ModelAdmin.readonly_fields`,
which will only display the WKT of the geometry. Setting
``modifiable=False``, actually displays the geometry in a map,
but disables the ability to edit its vertices.

``OSMGeoAdmin`` ``OSMGeoAdmin``
=============== ===============


.. class:: OSMGeoAdmin .. class:: OSMGeoAdmin


A subclass of :class:`GeoModelAdmin` that uses a spherical mercator projection A subclass of :class:`GeoModelAdmin` that uses a spherical mercator projection
with OpenStreetMap street data tiles. See the :ref:`OSMGeoAdmin introduction <osmgeoadmin-intro>` with `OpenStreetMap <http://openstreetmap.org/>`_ street data tiles.
See the :ref:`OSMGeoAdmin introduction <osmgeoadmin-intro>`
in the tutorial for a usage example. in the tutorial for a usage example.

0 comments on commit 1ad9c36

Please sign in to comment.