Pregunta

He conseguido geodjango ejecutan utilizando openlayers y OpenStreetMaps con la aplicación de administración.

Ahora quiero escribir algunos puntos de vista para mostrar los datos. Básicamente, sólo quiero añadir una lista de puntos (visto en el administrador) en el mapa.

Geodjango parece utilizar un especial archivo openlayers.js hacer su magia en el admin. ¿Hay una buena manera de interactuar con esto?

¿Cómo puedo escribir una vista / plantilla para mostrar los datos geodjango en una ventana de mapa de la calle abierta, como se ve en el administrador?

Por el momento, estoy cavando en el openlayers.js archivo y api en busca de una solución 'fácil' . (No tengo experiencia js así que esto está tomando algún tiempo.)

La forma actual que puedo ver de hacer esto es añadir lo siguiente como una plantilla, y el uso de Django para añadir el código necesario para mostrar los puntos. (Basado en el ejemplo aquí )

<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Draw Feature Example</title>

        <script src="http://www.openlayers.org/api/OpenLayers.js"></script>
      <script type="text/javascript">
            var map;

            function init(){
                map = new OpenLayers.Map('map');
                var layer = new OpenLayers.Layer.WMS( "OpenLayers WMS",
                        "http://labs.metacarta.com/wms/vmap0", {layers: 'basic'} );
                map.addLayer(layer);

                /*
                 * Layer style
                 */
                // we want opaque external graphics and non-opaque internal graphics
                var layer_style = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style['default']);
                layer_style.fillOpacity = 0.2;
                layer_style.graphicOpacity = 1;

                /*
                 * Blue style
                 */
                var style_blue = OpenLayers.Util.extend({}, layer_style);
                style_blue.strokeColor = "blue";
                style_blue.fillColor = "blue";
                style_blue.graphicName = "star";
                style_blue.pointRadius = 10;
                style_blue.strokeWidth = 3;
                style_blue.rotation = 45;
                style_blue.strokeLinecap = "butt";

                var vectorLayer = new OpenLayers.Layer.Vector("Simple Geometry", {style: layer_style});

                // create a point feature
                var point = new OpenLayers.Geometry.Point(-111.04, 45.68);
                var pointFeature = new OpenLayers.Feature.Vector(point,null,style_blue);
                // Add additional points/features here via django

                map.addLayer(vectorLayer);
                map.setCenter(new OpenLayers.LonLat(point.x, point.y), 5);
                vectorLayer.addFeatures([pointFeature]);
            }
        </script>
    </head>
    <body onload="init()">
        <div id="map" class="smallmap"></div>
    </body>
</html>

¿Es así como se hace, o hay una mejor manera?

¿Fue útil?

Solución

Creo que la solución es viable y, probablemente, el método más sencillo. Sólo crear plantillas de la javascript y usar Django para inyectar sus puntos de datos como la plantilla se representa.

Si desea obtener más elegante, usted podría tener una vista de Django que sirven los puntos de datos como JSON (application / json) y luego usar AJAX para devolver la llamada y recuperar los datos en función de los acontecimientos que están sucediendo en el navegador. Si desea que su aplicación sea muy interactiva más allá de lo OpenLayers ofrece, esto podría valer la pena la complejidad añadida, pero por supuesto que todo depende de las necesidades de su aplicación.

Otros consejos

Otra solución es crear un formulario que utiliza el widget GeoDjango de administración.

Para ello, I:

Configuración de un GeneratePolygonAdminClass:

class GeneratePolygonAdmin(admin.GeoModelAdmin):
    list_filter=('polygon',)
    list_display=('object', 'polygon')

Cuando el formulario se construyó:

geoAdmin=GeneratePolygonAdmin(ModelWithPolygonField, admin.site)
PolygonFormField=GeneratePolygon._meta.get_field('Polygon')
PolygonWidget=geoAdmin.get_map_widget(PolygonFormField)
Dict['Polygon']=forms.CharField(widget=PolygonWidget())  #In this case, I am creating a Dict to use for a dynamic form

Rellenar el widget de la forma:

def SetupPolygonWidget(form, LayerName, MapFileName, DefaultPolygon=''):
    form.setData({'Polygon':DefaultPolygon})
    form.fields['Polygon'].widget.params['wms_layer']=LayerName
    form.fields['Polygon'].widget.params['wms_url']='/cgi-bin/mapserv?MAP=' + MapFileName
    form.fields['Polygon'].widget.params['default_lon']=-80.9
    form.fields['Polygon'].widget.params['default_lat']=33.7
    form.fields['Polygon'].widget.params['default_zoom']=11
    form.fields['Polygon'].widget.params['wms_name']=YOURWMSLayerName
    form.fields['Polygon'].widget.params['map_width']=800
    form.fields['Polygon'].widget.params['map_height']=600
    form.fields['Polygon'].widget.params['map_srid']=YOUR_SRID
    form.fields['Polygon'].widget.params['modifiable']=True
    form.fields['Polygon'].widget.params['map_options']={}
    form.fields['Polygon'].widget.params['map_options']['buffer'] = 0   
    return form

Basado en el código en: http: // code.djangoproject.com/browser/django/branches/gis/django/contrib/gis/admin/options.py?rev=7980

Parece que se puede utilizar la opción de incluir extra_js OpenStreetMap (no he probado esto).

Esto es bastante antiguo, y yo no iría en torno a la creación de una plantilla de hackear como yo pensaba originalmente. Ahora me gustaría utilizar leaflet.js con una petición AJAX a una vista de Django que devuelve GeoJSON a un folleto capa GeoJSON.

Esto hace que el lado Django muy fácil.

Muestra Django Ver:

# -*- coding: utf-8 -*-
'''
'''
import json
from django.http import HttpResponse, HttpResponseBadRequest
from django.contrib.gis.geos import Polygon

from models import ResultLayer, MyModel

def get_layer_polygons(request, layer_id):
    """
    Return the polygons for the given bbox (bounding box)
    """
    layer = ResultLayer.objects.get(id=layer_id)    
    bbox_raw = request.GET.get("bbox", None)

    # Make sure the incoming bounding box is correctly formed!
    bbox = None
    if bbox_raw and bbox_raw.count(",") == 3:        
        bbox = [float(v) for v in bbox_raw.split(",")]     
    if not bbox:
        msg = "Improperly formed or not given 'bbox' querystring option, should be in the format '?bbox=minlon,minlat,maxlon,maxlat'"
        return HttpResponseBadRequest(msg)

    bbox_poly = Polygon.from_bbox(bbox)
    bbox_poly.srid = 900913 # google
    bbox_poly.transform(layer.srid) # transform to the layer's srid for querying  

    bin_size = int(bin_size)
    # build vector polygons from bin
    results = MyModel.objects.filter(layer=layer, poly__intersects=bbox_poly).transform(900913, field_name="poly")
    geojson_data = []
    for r in results:
        # loading json in order to dump json list later
        gjson = r.poly.geojson
        py_gjson = json.loads(gjson)
        geojson_data.append(py_gjson)
    return HttpResponse(json.dumps(geojson_data), mimetype='application/json')

Se podría considerar el uso FloppyForms . Al final, por lo general terminan la personalización de la solución a mis propias necesidades, pero es una buena manera de empezar.

Pedido este tutorial del proyecto geodjango-basic-aplicaciones:
http://code.google.com/p/geodjango-basic-apps / wiki / FOSS4GWorkshop

tal vez usted no tiene que cortar su propio Javascript todavía

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top