2009-02-18 39 views
12

Tôi đã chạy geodjango bằng cách sử dụng openlayersOpenStreetMaps bằng ứng dụng quản trị.Làm thế nào để hiển thị dữ liệu bằng cách sử dụng openlayers với OpenStreetMap trong geodjango?

Bây giờ tôi muốn viết một số chế độ xem để hiển thị dữ liệu. Về cơ bản, tôi chỉ muốn thêm một danh sách các điểm (xem trong quản trị) vào bản đồ.

Geodjango dường như sử dụng đặc biệtopenlayers.js tệp để thực hiện điều đó trong quản trị viên. Có cách nào tốt để giao tiếp với điều này?

Làm cách nào để tôi có thể viết chế độ xem/mẫu để hiển thị dữ liệu geodjango trên cửa sổ bản đồ mở, như được thấy trong quản trị viên?

Hiện tại, tôi đang đào sâu vào tệp openlayers.js và api đang tìm kiếm giải pháp 'dễ dàng'. (Tôi không có kinh nghiệm js vì vậy việc này mất chút thời gian.)

Cách hiện tại tôi có thể xem để thực hiện việc này là thêm mẫu sau làm mẫu và sử dụng django để thêm mã cần thiết để hiển thị điểm. (Dựa trên ví dụ here)

<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> 

Đây có phải là cách thực hiện hoặc có cách nào tốt hơn không?

Trả lời

2

Tôi nghĩ giải pháp của bạn có thể thực hiện được và có lẽ là cách tiếp cận dễ nhất. Chỉ cần templatize javascript và sử dụng Django để tiêm điểm dữ liệu của bạn khi mẫu được hiển thị.

Nếu bạn muốn trở nên giàu có hơn, bạn có thể có chế độ xem Django đã phục vụ các điểm dữ liệu dưới dạng JSON (application/json) và sau đó sử dụng AJAX để gọi lại và truy xuất dữ liệu dựa trên các sự kiện đang diễn ra trong trình duyệt . Nếu bạn muốn ứng dụng của mình có tính tương tác cao ở trên và vượt ra ngoài những gì mà OpenLayers cung cấp, điều này có thể đáng được thêm vào, nhưng tất nhiên nó phụ thuộc vào nhu cầu của ứng dụng của bạn.

+0

Tôi nghĩ rằng phương pháp tốt nhất là tạo ra một cái nhìn django mà trả về đối tượng JSON cần thiết cho các dữ liệu cần thiết. – monkut

4

Một giải pháp khác là tạo biểu mẫu sử dụng tiện ích Quản trị GeoDjango.

Để làm điều này, tôi:

Thiết lập một GeneratePolygonAdminClass:

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

Trường hợp mẫu được xây dựng:

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 

Populating widget có dạng:

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 

Dựa trên mã tại: http://code.djangoproject.com/browser/django/branches/gis/django/contrib/gis/admin/options.py?rev=7980

Có vẻ như bạn có thể sử dụng tùy chọn extra_js để bao gồm OpenStreetMap (Tôi chưa thử nghiệm điều này).

1

Bạn có thể xem xét sử dụng FloppyForms. Cuối cùng, tôi thường kết thúc tùy chỉnh giải pháp theo nhu cầu của riêng mình, nhưng đó là một cách hay để bắt đầu.

2

này khá cũ, và tôi wouldn' Tôi đi xung quanh việc tạo ra một mẫu hack như tôi đã suy nghĩ ban đầu. Bây giờ tôi sẽ sử dụng leaflet.js với một yêu cầu ajax để xem django trả về geojson cho một lớp geojson tờ rơi.

Điều này làm cho bên django siêu dễ dàng.

mẫu Django Xem:

# -*- 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') 
Các vấn đề liên quan