GeoDjango отображает одну и ту же геометрию несколько раз в карте листочков
У меня есть приложение GeoDjango, следующее этому учебнику, но заменяющее данные полигонов World Borders, включенные в стандартный учебник GeoDjango.
Я создал сериализаторы и django rest api, который отображает геометрию, пересекающую текущую ограничительную область, используя leaflet. Проблема, которую я заметил, заключается в том, что когда я панорамирую по карте, она отображает дубликаты полигонов друг на друге каждый раз, когда я задаю новый запрос на определение границ. Это приводит к замедлению работы карты при увеличении количества полигонов, а также к непрозрачной симбологии.
Как сделать так, чтобы каждый полигон рендерился только один раз, а не каждый раз при обновлении местоположения карты?
models.py
from django.contrib.gis.db import models
class WorldBorder(models.Model):
# Regular Django fields corresponding to the attributes in the
# world borders shapefile.
name = models.CharField(max_length=50)
area = models.IntegerField()
pop2005 = models.IntegerField('Population 2005')
fips = models.CharField('FIPS Code', max_length=2, null=True)
iso2 = models.CharField('2 Digit ISO', max_length=2)
iso3 = models.CharField('3 Digit ISO', max_length=3)
un = models.IntegerField('United Nations Code')
region = models.IntegerField('Region Code')
subregion = models.IntegerField('Sub-Region Code')
lon = models.FloatField()
lat = models.FloatField()
# GeoDjango-specific: a geometry field (MultiPolygonField)
mpoly = models.MultiPolygonField()
# Returns the string representation of the model.
def __str__(self):
return self.name
class Meta:
ordering = ['name']
verbose_name_plural = "World borders"
Набор представлений границ мира:
"""World borders API views."""
from rest_framework import viewsets
from rest_framework_gis import filters
from .models import WorldBorder
from .serializers import WorldBorderSerializer
class WorldBorderViewSet(viewsets.ReadOnlyModelViewSet):
"""World border view set."""
bbox_filter_field = "mpoly"
filter_backends = (filters.InBBoxFilter,)
queryset = WorldBorder.objects.all()
bbox_filter_include_overlapping = True
serializer_class = WorldBorderSerializer
serializers.py
from rest_framework_gis import serializers
from .models import WorldBorder
class WorldBorderSerializer(serializers.GeoFeatureModelSerializer):
"""world border GeoJSON serializer."""
class Meta:
"""World border serializer meta class."""
fields = ("id", "name")
geo_field = "mpoly"
model = WorldBorder
leaflet map js
const copy = "© <a href='https://www.openstreetmap.org/copyright'>OpenStreetMap</a> contributors";
const url = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png";
const osm = L.tileLayer(url, { attribution: copy });
const map = L.map("map", { layers: [osm] });
map.
locate()
.on("locationfound", (e) => map.setView(e.latlng, 8))
.on("locationerror", () => map.setView([0, 0], 5));
async function load_world_borders() {
const world_border_url = `/api/world/?in_bbox=${map.getBounds().toBBoxString()}`
const response = await fetch(world_border_url)
const geojson = await response.json()
return geojson
}
async function render_world_borders() {
const world_borders = await load_world_borders();
L.geoJSON(world_borders)
.bindPopup((layer) => layer.feature.properties.name)
.addTo(map);
}
map.on("moveend", render_world_borders);