osm openlayer lib examples example ejemplos python mapping openlayers geodjango

python - lib - ¿Cómo mostrar datos usando Openlayers con OpenStreetMap en geodjango?



openlayers lib openlayers js (5)

Creo que su solución es viable y, probablemente, el enfoque más fácil. Simplemente personalice el javascript y use Django para inyectar sus puntos de datos a medida que se procesa la plantilla.

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

Tengo geodjango corriendo usando openlayers y OpenStreetMaps con la aplicación de administración.

Ahora quiero escribir algunas vistas para mostrar los datos. Básicamente, solo quiero agregar una lista de puntos (vistos en el administrador) al mapa.

Geodjango parece usar un archivo especial de openlayers.js para hacer magia en el administrador. ¿Hay una buena manera de interactuar con esto?

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

Por el momento, estoy investigando el archivo openlayers.js y la API que buscan una solución ''fácil''. (No tengo experiencia js así que esto toma algo de tiempo).

La forma actual en que puedo ver esto es agregar lo siguiente como plantilla y usar django para agregar 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?


Otra solución es crear un formulario que utilice el widget GeoDjango Admin.

Para hacer esto, yo:

Configurar un GeneratePolygonAdminClass:

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

Donde se construye la forma:

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

Poblar el widget del formulario:

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 puede usar la opción extra_js para incluir OpenStreetMap (no lo he probado).


Podría considerar usar FloppyForms . Al final, generalmente termino personalizando la solución para mis propias necesidades, pero es una buena forma de comenzar.



Esto es bastante viejo, y yo no iría creando un hack de plantilla como estaba originalmente pensando. Ahora utilizaría leaflet.js con una solicitud de ajax a una vista django que devuelva geojson a una capa geojson de folleto.

Esto hace que el lado django sea muy fácil.

Muestra de la vista de Django:

# -*- 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'')