1

我注意到 Geodjango 管理员中的地图在右侧有一个菜单。

我如何添加更多的图层,而不仅仅是一个代表地图在管理员中相关的模型字段?

这是我的模型(model.py):

class Foresta(models.Model):

    nome = models.CharField("Nome", blank = False, max_length = 255)
    descrizione = tinymce_models.HTMLField("Descrizione", blank = True, help_text='Inserire una descrizione del bosco')
    slug = models.SlugField("Slug", blank = True)
    published = models.BooleanField("Pubblicato")
    ...

    coord = models.PointField("Coordinata punto foresta", blank = False)
    # GeoDjango-specific: a geometry field (MultiPolygonField), and
    # overriding the default manager with a GeoManager instance.
    mpoly = models.MultiPolygonField("Mappa foresta (poligono)", blank = False)
    objects = models.GeoManager()

这是我的管理模型(admin.py):

class ForestaAdmin(admin.OSMGeoAdmin):
    default_lon= 1308296
    default_lat= 5714101
    default_zoom= 9
    overlays = ('coord', 'mpoly')

我尝试了“覆盖”选项,但没有成功!

4

3 回答 3

3

您可以在此处找到默认的 OSMGeoAdmin 设置。不幸的是,您似乎无法通过指定覆盖元组这样简单的事情来完成此操作。相反,您似乎应该创建一个自定义地图模板,然后使用模板的路径覆盖 ForestaAdmin 类中的 map_template 选项。首先复制默认的openlayers模板并自定义 javascript 以将其他图层添加为额外的OpenLayers 矢量图层。

于 2013-03-15T21:39:31.490 回答
0

您可以使用 olwidget http://docs.olwidget.org/en/latest/django-olwidget.html。它允许您编辑和显示不同的层(在 Django 管理员内部和外部)。但是,根据您运行的 Django 版本,您可能会发现使用起来很困难。

最后,我设法通过修改此处(我的案例)中找到的 openlayers.js 文件来按照@garnetb 所说的那样做到这一点:

/usr/local/lib/python2.7/dist-packages/django/contrib/gis/templates/gis/admin/openlayers.js

如果找不到它,只需在 osm.html 和/或 openlayers.html 中查找。所以,这就是我设法添加第二层的方式。我的目标是添加一个“视觉”唯一的图层,但如果你想编辑它,你可以轻松地修改控件。所以,让我们假设你有一个像这样的模型:

class Lines(gis_models.Model):
name = gis_models.CharField(max_length=10)
geom = gis_models.MultiLineStringField(srid=4326)
geom_points = gis_models.MultiPointField(srid=4326, null=True)
objects = gis_models.GeoManager()
def __unicode__(self):
    return self.name

所以你看,有两个元素正在加载,第一个是线,第二个是点。所以我的目标是添加线条作为我处理点时的视觉参考。为此,请转到 openlayers.js 并查找定义 Base Layer 的部分并添加类似的内容。

// Base Layer
    {% if field_name != "geom" %}

    geom_layer = new OpenLayers.Layer.Vector("visual");
    {{ module }}.map.addLayer(geom_layer);
    var wkt_vis = document.getElementById('id_geom').value;
    if (wkt_vis){
        var features = {{ module }}.read_wkt(wkt_vis);
        geom_layer.addFeatures(features);
    }
    else {
        alert("no wkt id field");
    }   

{% endif %}

if ({{ module }}.is_point) {
    var style = new OpenLayers.Style({
        pointRadius : 4,
        strokeColor : 'red',
        strokeWidth : 2,
        strokeOpacity : 1,
        fillColor : 'white',
        fillOpacity : 1
    });

    var layer_style = new OpenLayers.StyleMap({
        'default' : style,
    });
    {{ module }}.layers.vector = new OpenLayers.Layer.Vector(" {{ field_name }}", {styleMap : layer_style});
}
else {
    {{ module }}.layers.vector = new OpenLayers.Layer.Vector(" {{ field_name }}");
}

如您所见,整个想法是为每一层加载 openlayers.js,但您仍然可以访问其他对象。这种配置给我留下了一个方便的管理员,我在其中显示了两张地图。在第一个中,我展示了线条并且我可以修改它们。在第二个中,我将线条显示为参考,并且这些点是可编辑的。第二部分向您展示如何设置点样式(以防万一......)这只是一个简化的示例。如果您需要更多详细信息,请告诉我。我还设法添加了一个“删除功能”控件。我只在 Django 1.6 上使用 GeoDjango 进行了尝试,但只要它们以相同的方式使用 openlayers.js,它应该可以与其他版本一起使用。

于 2014-04-23T14:01:38.850 回答
0

我不得不在地图上添加额外的只读多面体。我重新定义了 osm.html (?只是更改了 osm.js 文件路径,因为 django 使用了默认的“gis/admin/osm.js”)

{% extends "gis/admin/openlayers.html" %}
{% block openlayers %}{% include "gis/osm.js" %}{% endblock %}

osm.js:

{% extends "gis/admin/osm.js" %}
{% block extra_layers %}
    {% if extra_wkt %}
        extraLayer = new OpenLayers.Layer.Vector("extra_layer");
        {{ module }}.map.addLayer(extraLayer);

        var extraLayerStyle = {
            fillColor: "#8a8a8a",
            fillOpacity: 0.5,
            strokeColor: "#000000",
            strokeOpacity: 1,
            strokeWidth: 1,
        };
        var extraGeometry = {{ module }}.read_wkt('{{ extra_wkt }}');
        for (var i = 0; i < extraGeometry.geometry.components.length; i++) {
            var feat = new OpenLayers.Feature.Vector(
                extraGeometry.geometry.components[i].clone(),
                {}, // attrs
                extraLayerStyle,
            )
            extraLayer.addFeatures([feat]);
        }
    {% endif %}
{% endblock %}

有我使用extra_wkt作为上下文传递的值。( mpoly- geodjango 多面域的名称)

from django.contrib.gis.admin import OSMGeoAdmin, OpenLayersWidget


class OSMLayersWidget(OpenLayersWidget):

    def get_context(self, name, value, attrs):
        context = super().get_context(name, value, attrs)

        if name == "mpoly":
            extra_mpoly = MultiPolygon([..., ...])
            if extra_mpoly:
                srid = self.params['srid']
                if extra_mpoly.srid != srid:
                    try:
                        extra_mpoly.transform(srid)
                        extra_wkt = extra_mpoly.wkt
                    except GDALException as err:
                        logger.error(
                            "Error creating geometry from value '%s' (%s)",
                            extra_mpoly,
                            err,
                        )
                        extra_wkt = ''
                else:
                    extra_wkt = extra_mpoly.wkt

                context["extra_wkt"] = extra_wkt

        return context

管理员.py:

class ServiceZoneAdmin(OSMGeoAdmin):

    map_template = 'gis/osm.html'
    widget = OSMLayersWidget

结果: 在此处输入图像描述

于 2022-02-15T12:45:53.330 回答