从LineStringField

时间:2019-11-08 12:43:01

标签: python django geojson geodjango

我有一个来自GeoDjango的简单模型,用于线向量:

    from django.contrib.gis.db import models
    class LineBuffer(models.Model):
        geom = models.LineStringField()

        def __int__(self):
            return self.pk

        @property
        def coordinates(self):
            return str(self.geom.x) + ', ' + str(self.geom.y)

我需要使用Turf.js创建一个缓冲区;结果将使用MapBox重新显示。

使用此视图,我可以创建地图:

def line_mapbox_turf_buffer(request):
    geometry = LineBuffer.objects.all()
    context = {
        'geometry': geometry,
    }
    template = 'buffer/reading/line_mapbox_turf_buffer.html'
    return render(request, template, context)

我尝试生成GeoJSON

var data_source = {
    "type": "FeatureCollection",
    "features": [{% for d in geometry %}
        {
        "type": "Feature",
        "properties": {
            "pk": "{{ d.pk }}"
        },
        "geometry": {
            "type": "LineString",
            "coordinates": [{{ d.coordinates }}]
        }
        {% if forloop.last %}} {% else %}}, {% endif %}{% endfor %}
    ]
}

但是我看到了:

{
            "type": "Feature",
            "properties": {
                "pk": "1"
            },
            "geometry": {
                "type": "LineString",
                "coordinates": [
          [14.364295, 14.3662612, 14.3681209, 14.3702697, 14.3730481, 14.3742791, 14.3763224], 
          [40.8086793, 40.8101317, 40.8118721, 40.8139257, 40.8165981, 40.8177693, 40.8206666]
          ]
            }
            }

代替此:

{
      "type": "Feature",
      "properties": {
        "pk": "1"
      },
      "geometry": {
        "type": "LineString",
        "coordinates": [
          [14.364295,40.8086793],
          [14.3662612,40.8101317],
          [14.3681209,40.8118721],
          [14.3702697,40.8139257],
          [14.3730481,40.8165981],
          [14.3742791,40.8177693],
          [14.3763224,40.8206666]
        ]
      }
    }

我认为我的问题是财产 coordinates。如何正确提取线向量的坐标?

1 个答案:

答案 0 :(得分:0)

在错误中进行简单的事后检验,我们可以清楚地看到coordinates属性的响应需要进行重构以适应您的需求。

我建议使用geom.coords属性访问和操纵LineString的坐标。
Django的LineString坐标看起来像这样:((x_0, y_0), (x_1, y_1), ...),所以很清楚我们需要做什么:

@property
def coordinates(self):
    return [list(coord_pair) for coords_pair in self.geom.coords]

并且在模板中,当我们使用list属性时,我们需要省略coordinates强制转换:

var data_source = {
    "type": "FeatureCollection",
    "features": [{% for d in geometry %}
        {
        "type": "Feature",
        "properties": {
            "pk": "{{ d.pk }}"
        },
        "geometry": {
            "type": "LineString",
            "coordinates": {{ d.coordinates }}
        }
        {% if forloop.last %}} {% else %}}, {% endif %}{% endfor %}
    ]
}

在这种特定情况下进行自己的序列化没有任何好处,我建议您完全重构您的过程以利用GeoJson Serializer

from django.core.serializers import serialize

def line_mapbox_turf_buffer(request):
    context = {
        'geometry': serialize(
            'geojson', 
            LineBuffer.objects.all(),
            geometry_field='geom',
        )
    }
    template = 'buffer/reading/line_mapbox_turf_buffer.html'
    return render(request, template, context)

,并在模板中只需访问geometry上下文字段:

var data_source = {{ geometry }}