Merge pull request #1266 from umap-project/zoom-from-to-at-load
Store DataLayer's settings in DB
This commit is contained in:
commit
8095c5721d
6 changed files with 83 additions and 41 deletions
|
@ -59,7 +59,7 @@ class DataLayerForm(forms.ModelForm):
|
|||
|
||||
class Meta:
|
||||
model = DataLayer
|
||||
fields = ('geojson', 'name', 'display_on_load', 'rank')
|
||||
fields = ('geojson', 'name', 'display_on_load', 'rank', 'settings')
|
||||
|
||||
|
||||
class MapSettingsForm(forms.ModelForm):
|
||||
|
|
19
umap/migrations/0012_datalayer_settings.py
Normal file
19
umap/migrations/0012_datalayer_settings.py
Normal file
|
@ -0,0 +1,19 @@
|
|||
# Generated by Django 4.2.2 on 2023-08-16 05:24
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("umap", "0011_alter_map_edit_status_alter_map_share_status"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="datalayer",
|
||||
name="settings",
|
||||
field=models.JSONField(
|
||||
blank=True, default=dict, null=True, verbose_name="settings"
|
||||
),
|
||||
),
|
||||
]
|
|
@ -176,10 +176,14 @@ class Map(NamedModel):
|
|||
settings.AUTH_USER_MODEL, blank=True, verbose_name=_("editors")
|
||||
)
|
||||
edit_status = models.SmallIntegerField(
|
||||
choices=EDIT_STATUS, default=get_default_edit_status, verbose_name=_("edit status")
|
||||
choices=EDIT_STATUS,
|
||||
default=get_default_edit_status,
|
||||
verbose_name=_("edit status"),
|
||||
)
|
||||
share_status = models.SmallIntegerField(
|
||||
choices=SHARE_STATUS, default=get_default_share_status, verbose_name=_("share status")
|
||||
choices=SHARE_STATUS,
|
||||
default=get_default_share_status,
|
||||
verbose_name=_("share status"),
|
||||
)
|
||||
settings = models.JSONField(
|
||||
blank=True, null=True, verbose_name=_("settings"), default=dict
|
||||
|
@ -308,6 +312,9 @@ class DataLayer(NamedModel):
|
|||
help_text=_("Display this layer on load."),
|
||||
)
|
||||
rank = models.SmallIntegerField(default=0)
|
||||
settings = models.JSONField(
|
||||
blank=True, null=True, verbose_name=_("settings"), default=dict
|
||||
)
|
||||
|
||||
class Meta:
|
||||
ordering = ("rank",)
|
||||
|
@ -340,7 +347,14 @@ class DataLayer(NamedModel):
|
|||
|
||||
@property
|
||||
def metadata(self):
|
||||
return {"name": self.name, "id": self.pk, "displayOnLoad": self.display_on_load}
|
||||
# Retrocompat: minimal settings for maps not saved after settings property
|
||||
# has been introduced
|
||||
obj = self.settings or {
|
||||
"name": self.name,
|
||||
"displayOnLoad": self.display_on_load,
|
||||
}
|
||||
obj["id"] = self.pk
|
||||
return obj
|
||||
|
||||
def clone(self, map_inst=None):
|
||||
new = self.__class__.objects.get(pk=self.pk)
|
||||
|
|
|
@ -248,11 +248,6 @@ L.U.DataLayer = L.Evented.extend({
|
|||
}
|
||||
this.setUmapId(data.id)
|
||||
this.setOptions(data)
|
||||
this.backupOptions()
|
||||
this.connectToMap()
|
||||
if (this.displayedOnLoad()) this.show()
|
||||
if (!this.umap_id) this.isDirty = true
|
||||
|
||||
// Retrocompat
|
||||
if (this.options.remoteData && this.options.remoteData.from) {
|
||||
this.options.fromZoom = this.options.remoteData.from
|
||||
|
@ -260,11 +255,15 @@ L.U.DataLayer = L.Evented.extend({
|
|||
if (this.options.remoteData && this.options.remoteData.to) {
|
||||
this.options.toZoom = this.options.remoteData.to
|
||||
}
|
||||
this.backupOptions()
|
||||
this.connectToMap()
|
||||
if (this.displayedOnLoad() && this.showAtZoom()) this.show()
|
||||
if (!this.umap_id) this.isDirty = true
|
||||
|
||||
this.onceLoaded(function () {
|
||||
this.map.on('moveend', this.onMoveEnd, this)
|
||||
this.map.on('zoomend', this.onZoomEnd, this)
|
||||
})
|
||||
this.map.on('zoomend', this.onZoomEnd, this)
|
||||
},
|
||||
|
||||
onMoveEnd: function (e) {
|
||||
|
@ -313,7 +312,7 @@ L.U.DataLayer = L.Evented.extend({
|
|||
const Class = L.U.Layer[this.options.type] || L.U.Layer.Default
|
||||
this.layer = new Class(this)
|
||||
this.eachLayer((feature) => this.showFeature(feature))
|
||||
if (visible) this.map.addLayer(this.layer)
|
||||
if (visible) this.show()
|
||||
this.propagateRemote()
|
||||
},
|
||||
|
||||
|
@ -335,12 +334,15 @@ L.U.DataLayer = L.Evented.extend({
|
|||
|
||||
fetchData: function () {
|
||||
if (!this.umap_id) return
|
||||
if (this._loading) return
|
||||
this._loading = true
|
||||
this.map.get(this._dataUrl(), {
|
||||
callback: function (geojson, response) {
|
||||
this._last_modified = response.getResponseHeader('Last-Modified')
|
||||
this.fromUmapGeoJSON(geojson)
|
||||
this.backupOptions()
|
||||
this.fire('loaded')
|
||||
this._loading = false
|
||||
},
|
||||
context: this,
|
||||
})
|
||||
|
@ -1182,6 +1184,7 @@ L.U.DataLayer = L.Evented.extend({
|
|||
formData.append('name', this.options.name)
|
||||
formData.append('display_on_load', !!this.options.displayOnLoad)
|
||||
formData.append('rank', this.getRank())
|
||||
formData.append('settings', JSON.stringify(this.options))
|
||||
// Filename support is shaky, don't do it for now.
|
||||
const blob = new Blob([JSON.stringify(geojson)], { type: 'application/json' })
|
||||
formData.append('geojson', blob)
|
||||
|
|
|
@ -27,10 +27,11 @@ class TileLayerFactory(factory.django.DjangoModelFactory):
|
|||
|
||||
|
||||
class UserFactory(factory.django.DjangoModelFactory):
|
||||
username = 'Joe'
|
||||
username = "Joe"
|
||||
email = factory.LazyAttribute(
|
||||
lambda a: '{0}@example.com'.format(a.username).lower())
|
||||
password = factory.PostGenerationMethodCall('set_password', '123123')
|
||||
lambda a: "{0}@example.com".format(a.username).lower()
|
||||
)
|
||||
password = factory.PostGenerationMethodCall("set_password", "123123")
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
|
@ -41,32 +42,32 @@ class MapFactory(factory.django.DjangoModelFactory):
|
|||
slug = "test-map"
|
||||
center = DEFAULT_CENTER
|
||||
settings = {
|
||||
'geometry': {
|
||||
'coordinates': [13.447265624999998, 48.94415123418794],
|
||||
'type': 'Point'
|
||||
"geometry": {
|
||||
"coordinates": [13.447265624999998, 48.94415123418794],
|
||||
"type": "Point",
|
||||
},
|
||||
'properties': {
|
||||
'datalayersControl': True,
|
||||
'description': 'Which is just the Danube, at the end',
|
||||
'displayCaptionOnLoad': False,
|
||||
'displayDataBrowserOnLoad': False,
|
||||
'displayPopupFooter': False,
|
||||
'licence': '',
|
||||
'miniMap': False,
|
||||
'moreControl': True,
|
||||
'name': 'Cruising on the Donau',
|
||||
'scaleControl': True,
|
||||
'tilelayer': {
|
||||
'attribution': u'\xa9 OSM Contributors',
|
||||
'maxZoom': 18,
|
||||
'minZoom': 0,
|
||||
'url_template': 'http://{s}.osm.fr/{z}/{x}/{y}.png'
|
||||
"properties": {
|
||||
"datalayersControl": True,
|
||||
"description": "Which is just the Danube, at the end",
|
||||
"displayCaptionOnLoad": False,
|
||||
"displayDataBrowserOnLoad": False,
|
||||
"displayPopupFooter": False,
|
||||
"licence": "",
|
||||
"miniMap": False,
|
||||
"moreControl": True,
|
||||
"name": "Cruising on the Donau",
|
||||
"scaleControl": True,
|
||||
"tilelayer": {
|
||||
"attribution": "\xa9 OSM Contributors",
|
||||
"maxZoom": 18,
|
||||
"minZoom": 0,
|
||||
"url_template": "http://{s}.osm.fr/{z}/{x}/{y}.png",
|
||||
},
|
||||
'tilelayersControl': True,
|
||||
'zoom': 7,
|
||||
'zoomControl': True
|
||||
"tilelayersControl": True,
|
||||
"zoom": 7,
|
||||
"zoomControl": True,
|
||||
},
|
||||
'type': 'Feature'
|
||||
"type": "Feature",
|
||||
}
|
||||
|
||||
licence = factory.SubFactory(LicenceFactory)
|
||||
|
@ -81,7 +82,10 @@ class DataLayerFactory(factory.django.DjangoModelFactory):
|
|||
name = "test datalayer"
|
||||
description = "test description"
|
||||
display_on_load = True
|
||||
geojson = factory.django.FileField(data="""{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[13.68896484375,48.55297816440071]},"properties":{"_umap_options":{"color":"DarkCyan","iconClass":"Ball"},"name":"Here","description":"Da place anonymous again 755"}}],"_umap_options":{"displayOnLoad":true,"name":"Donau","id":926}}""") # noqa
|
||||
settings = {"displayOnLoad": True, "browsable": True, name: "test datalayer"}
|
||||
geojson = factory.django.FileField(
|
||||
data="""{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[13.68896484375,48.55297816440071]},"properties":{"_umap_options":{"color":"DarkCyan","iconClass":"Ball"},"name":"Here","description":"Da place anonymous again 755"}}],"_umap_options":{"displayOnLoad":true,"name":"Donau","id":926}}"""
|
||||
) # noqa
|
||||
|
||||
class Meta:
|
||||
model = DataLayer
|
||||
|
@ -90,7 +94,7 @@ class DataLayerFactory(factory.django.DjangoModelFactory):
|
|||
def login_required(response):
|
||||
assert response.status_code == 200
|
||||
j = json.loads(response.content.decode())
|
||||
assert 'login_required' in j
|
||||
redirect_url = reverse('login')
|
||||
assert j['login_required'] == redirect_url
|
||||
assert "login_required" in j
|
||||
redirect_url = reverse("login")
|
||||
assert j["login_required"] == redirect_url
|
||||
return True
|
||||
|
|
|
@ -17,6 +17,7 @@ def post_data():
|
|||
return {
|
||||
"name": "name",
|
||||
"display_on_load": True,
|
||||
"settings": '{"displayOnLoad": true, "browsable": true, "name": "name"}',
|
||||
"rank": 0,
|
||||
"geojson": '{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-3.1640625,53.014783245859235],[-3.1640625,51.86292391360244],[-0.50537109375,51.385495069223204],[1.16455078125,52.38901106223456],[-0.41748046875,53.91728101547621],[-2.109375,53.85252660044951],[-3.1640625,53.014783245859235]]]},"properties":{"_umap_options":{},"name":"Ho god, sounds like a polygouine"}},{"type":"Feature","geometry":{"type":"LineString","coordinates":[[1.8017578124999998,51.16556659836182],[-0.48339843749999994,49.710272582105695],[-3.1640625,50.0923932109388],[-5.60302734375,51.998410382390325]]},"properties":{"_umap_options":{},"name":"Light line"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[0.63720703125,51.15178610143037]},"properties":{"_umap_options":{},"name":"marker he"}}],"_umap_options":{"displayOnLoad":true,"name":"new name","id":1668,"remoteData":{},"color":"LightSeaGreen","description":"test"}}',
|
||||
}
|
||||
|
@ -61,6 +62,7 @@ def test_update(client, datalayer, map, post_data):
|
|||
j = json.loads(response.content.decode())
|
||||
assert "id" in j
|
||||
assert datalayer.pk == j["id"]
|
||||
assert j["browsable"] is True
|
||||
assert Path(modified_datalayer.geojson.path).exists()
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue