كيفية عرض البيانات باستخدام OpenLayers مع OpenStreetMap في Geodjango؟
-
05-09-2019 - |
سؤال
لقد حصلت على Geodjango قيد التشغيل باستخدام openlayers. و openstreetmaps. مع تطبيق المسؤول.
الآن أريد أن أكتب بعض وجهات النظر لعرض البيانات. في الأساس، أريد فقط إضافة قائمة من النقاط (ينظر إليها في المسؤول) على الخريطة.
يظهر Geodjango لاستخدام خاص openlayers.js. ملف للقيام به سحر في المسؤول. هل هناك طريقة جيدة للواجهة مع هذا؟
كيف يمكنني كتابة عرض / قالب لعرض بيانات Geodjango على نافذة خريطة مفتوحة في الشارع، كما هو موضح في المشرف؟
في الوقت الحالي، أنا حفر في openlayers.js. ملف و API يبحث عن حل "سهل". (ليس لدي تجربة JS حتى يستغرق هذا بعض الوقت.)
الطريقة الحالية التي يمكنني رؤيتها للقيام بذلك هي إضافة ما يلي كقالب، واستخدم Django لإضافة الرمز المطلوب لعرض النقاط. (بناء على المثال هنا)
<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>
هل هذه هي الطريقة التي يتم بها، أم أنها هناك طريقة أفضل؟
المحلول
أعتقد أن الحل الخاص بك هو قابل للتطبيق وربما أسهل النهج. فقط قم بتذوق جافا سكريبت واستخدم Django لحقن نقاط البيانات الخاصة بك كما يتم تقديم القالب.
إذا كنت ترغب في الحصول على Fancier، فقد يكون لديك طريقة عرض Django التي تخدم نقاط البيانات ك JSON (التطبيق / JSON) ثم استخدم AJAX للاتصال مرة أخرى واسترجاع البيانات بناء على الأحداث التي تحدث في المتصفح. إذا كنت ترغب في أن يكون طلبك تفاعليا للغاية فوق وما بعده الذي يوفره OpenLayers، فقد يكون هذا يستحق التعقيد الإضافي، ولكن بالطبع يعتمد كل ذلك على احتياجات طلبك.
نصائح أخرى
حل آخر هو إنشاء نموذج يستخدم القطعة Geodjango Admin.
للقيام بذلك، أنا:
إعداد GeneratePolygonadminclass:
class GeneratePolygonAdmin(admin.GeoModelAdmin):
list_filter=('polygon',)
list_display=('object', 'polygon')
حيث تم بناء النموذج:
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
ملء القطعة من النموذج:
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
بناء على الرمز في:http://code.djangoproject.com/browser/django/branches/gis/django/contrib/gis/admin/options.py؟rev=7980.
يبدو أنه يمكنك استخدام خيار extre_js لتضمين OpenStreetMap (لم أختبر هذا).
هذا قديم جدا، ولن أتجول حول إنشاء اختراق القالب كما كنت أفكر في الأصل. الآن أود استخدام Leachlet.js. مع طلب AJAX لعرض DJANGO الذي يعود Geojson إلى طبقة Geojson Leaflet.
هذا يجعل الجانب django سوبر سهلة.
عرض عينة 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')
يمكنك التفكير في استخدام floppyforms.. وبعد في النهاية، عادة ما ينتهي عادة بتخصيص الحل لاحتياجاتي الخاصة، لكنها طريقة لطيفة للبدء.
الخروج من هذا البرنامج التعليمي من مشروع Geodjango-Basic-Apps:
http://code.google.com/p/geodjango-basic-apps/wiki/foss4gworkshop.
ربما لا تضطر إلى اختراق جافا سكريبت الخاصة بك