editor/overlay multipoint support (might still be a bit broken)
This commit is contained in:
parent
d231dec726
commit
0df0580f1b
6 changed files with 6026 additions and 5660 deletions
|
@ -1327,6 +1327,7 @@ editor = {
|
|||
editor.map.doubleClickZoom.disable();
|
||||
},
|
||||
|
||||
_current_editing_shape: [],
|
||||
// edit and create geometries
|
||||
_check_start_editing: function () {
|
||||
// called on sidebar load. start editing or creating depending on how the sidebar may require it
|
||||
|
@ -1356,6 +1357,7 @@ editor = {
|
|||
return options;
|
||||
},
|
||||
pointToLayer: editor._point_to_layer,
|
||||
multipoint: true,
|
||||
}).getLayers()[0].addTo(editor._geometries_layer);
|
||||
editor._editing_layer.enableEdit();
|
||||
if (editor._editing_layer.editor._resizeLatLng !== undefined) {
|
||||
|
@ -1384,7 +1386,9 @@ editor = {
|
|||
options = editor._line_draw_geometry_style(options);
|
||||
editor._current_editing_shape = editor.map.editTools.startPolyline(null, options);
|
||||
} else if (geomtype === 'point') {
|
||||
editor._current_editing_shape = editor.map.editTools.startMarker(null, options);
|
||||
editor._current_editing_shape = editor.map.editTools.startCircleMarker(null, options);
|
||||
} else if (geomtype === 'multipoint') {
|
||||
editor._current_editing_shape = editor.map.editTools.startMultipoint(null, options);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1395,7 +1399,8 @@ editor = {
|
|||
const geomtypeNames = {
|
||||
polygon: 'Polygon',
|
||||
linestring: 'Line string',
|
||||
point: 'Point'
|
||||
multipoint: 'Multipoint',
|
||||
point: 'Point',
|
||||
}; // TODO: translations
|
||||
for(const geomtype of geomtypes) {
|
||||
const option = $(`<option value="${geomtype}">${geomtypeNames[geomtype]}</option>`);
|
||||
|
@ -1435,23 +1440,29 @@ editor = {
|
|||
_done_creating: function (e) {
|
||||
// called when creating is completed (by clicking on the last point). fills in the form and switches to editing.
|
||||
if (editor._creating) {
|
||||
editor._creating = false;
|
||||
// return L.circle(latlng, {radius: 0.5});
|
||||
if (editor._creating_type !== 'multipoint') {
|
||||
// multipoints can always accept more points so they are always in "creating" mode
|
||||
editor._creating = false;
|
||||
}
|
||||
var layer = e.layer;
|
||||
if (e.layer._latlng !== undefined) {
|
||||
layer = L.circle(e.layer._latlng, e.layer.options);
|
||||
if (editor._creating_type === 'point' && layer._latlng !== undefined) {
|
||||
layer = L.circle(layer._latlng, layer.options);
|
||||
layer.setRadius(0.15);
|
||||
e.layer.remove();
|
||||
editor._current_editing_shapes = [layer];
|
||||
}
|
||||
editor._editing_layer = layer;
|
||||
editor._editing_layer.addTo(editor._geometries_layer);
|
||||
if (e.layer._latlng !== undefined) {
|
||||
if (editor._creating_type === 'point' && e.layer._latlng !== undefined) {
|
||||
layer.enableEdit();
|
||||
layer.editor._resizeLatLng.__vertex._icon.style.display = 'none';
|
||||
}
|
||||
editor._update_editing();
|
||||
$('#sidebar').find('.content').find('form.creation-lock').removeClass('creation-lock')
|
||||
.find('input:not([type=hidden], .btn)').first().focus();
|
||||
const form = $('#sidebar').find('.content').find('form.creation-lock');
|
||||
form.removeClass('creation-lock')
|
||||
if (editor._creating_type !== 'multipoint') {
|
||||
form.find('input:not([type=hidden], .btn)').first().focus();
|
||||
}
|
||||
}
|
||||
},
|
||||
_update_editing: function () {
|
||||
|
|
|
@ -129,7 +129,7 @@ def overlay_feature_edit(request, level=None, overlay=None, pk=None):
|
|||
'new': new,
|
||||
'title': obj.title if obj else None,
|
||||
'geometry_url': geometry_url,
|
||||
'geomtype': 'polygon,linestring,point',
|
||||
'geomtype': 'polygon,linestring,multipoint,point',
|
||||
'default_geomtype': overlay.default_geomtype,
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ from django.utils.translation import gettext_lazy as _
|
|||
from shapely import validation
|
||||
from shapely.geometry import LineString, MultiPolygon, Point, Polygon, mapping, shape
|
||||
from shapely.geometry.base import BaseGeometry
|
||||
from shapely.geometry.multipoint import MultiPoint
|
||||
|
||||
from c3nav.mapdata.utils.geometry import WrappedGeometry, clean_geometry
|
||||
from c3nav.mapdata.utils.json import format_geojson
|
||||
|
@ -64,9 +65,9 @@ class GeometryField(models.JSONField):
|
|||
def __init__(self, geomtype=None, default=None, null=False, blank=False, help_text=None):
|
||||
if geomtype == 'polyline':
|
||||
geomtype = 'linestring'
|
||||
if geomtype not in (None, 'polygon', 'multipolygon', 'linestring', 'point'):
|
||||
if geomtype not in (None, 'polygon', 'multipolygon', 'linestring', 'multipoint', 'point'):
|
||||
raise ValueError('GeometryField.geomtype has to be '
|
||||
'None, "polygon", "multipolygon", "linestring" or "point"')
|
||||
'None, "polygon", "multipolygon", "linestring", "multipoint" or "point"')
|
||||
self.geomtype = geomtype
|
||||
super().__init__(default=default, null=null, blank=blank, help_text=help_text)
|
||||
|
||||
|
@ -108,6 +109,7 @@ class GeometryField(models.JSONField):
|
|||
'polygon': (Polygon, ),
|
||||
'multipolygon': (Polygon, MultiPolygon),
|
||||
'linestring': (LineString, ),
|
||||
'multipoint': (MultiPoint, ),
|
||||
'point': (Point, )
|
||||
}.get(self.geomtype, None)
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ def format_geojson(data, rounded=True):
|
|||
if coordinates is not None:
|
||||
if data['type'] == 'Point':
|
||||
coordinates = tuple(round(i, 2) for i in coordinates)
|
||||
elif data['type'] == 'LineString':
|
||||
elif data['type'] == 'LineString' or data['type'] == 'MultiPoint':
|
||||
coordinates = round_coordinates(coordinates)
|
||||
elif data['type'] == 'MultiLineString':
|
||||
coordinates = tuple(round_coordinates(linestring) for linestring in coordinates)
|
||||
|
|
76
src/c3nav/static/leaflet/leaflet.editable.js
vendored
76
src/c3nav/static/leaflet/leaflet.editable.js
vendored
|
@ -64,6 +64,8 @@
|
|||
// Class to be used when creating a new Polyline.
|
||||
polylineClass: L.Polyline,
|
||||
|
||||
multipointClass: L.MultiPoint,
|
||||
|
||||
// 🍂option markerClass: class = L.Marker
|
||||
// Class to be used when creating a new Marker.
|
||||
markerClass: L.Marker,
|
||||
|
@ -108,6 +110,8 @@
|
|||
// Class to be used as Marker editor.
|
||||
markerEditorClass: undefined,
|
||||
|
||||
multipointEditorClass: undefined,
|
||||
|
||||
// 🍂option circleMarkerEditorClass: class = CircleMarkerEditor
|
||||
// Class to be used as CircleMarker editor.
|
||||
circleMarkerEditorClass: undefined,
|
||||
|
@ -320,6 +324,15 @@
|
|||
return line
|
||||
},
|
||||
|
||||
// 🍂method startMultipoint(latlng: L.LatLng, options: hash): L.Polyline
|
||||
// Start drawing a startMultipoint. If `latlng` is given, a first point will be added. In any case, continuing on user click.
|
||||
// If `options` is given, it will be passed to the Polyline class constructor.
|
||||
startMultipoint: function (latlng, options) {
|
||||
const multipoint = this.createMultipoint([], options)
|
||||
multipoint.enableEdit(this.map)
|
||||
return multipoint
|
||||
},
|
||||
|
||||
// 🍂method startPolygon(latlng: L.LatLng, options: hash): L.Polygon
|
||||
// Start drawing a Polygon. If `latlng` is given, a first point will be added. In any case, continuing on user click.
|
||||
// If `options` is given, it will be passed to the Polygon class constructor.
|
||||
|
@ -394,6 +407,14 @@
|
|||
)
|
||||
},
|
||||
|
||||
createMultipoint: function (latlngs, options) {
|
||||
return this.createLayer(
|
||||
options?.multipointClass || this.options.multipointClass,
|
||||
latlngs,
|
||||
options
|
||||
)
|
||||
},
|
||||
|
||||
createPolygon: function (latlngs, options) {
|
||||
return this.createLayer(
|
||||
options?.polygonClass || this.options.polygonClass,
|
||||
|
@ -1868,6 +1889,50 @@
|
|||
},
|
||||
})
|
||||
|
||||
L.Editable.MultipointEditor = L.Editable.PathEditor.extend({
|
||||
|
||||
addHooks: function () {
|
||||
L.Editable.PathEditor.prototype.addHooks.call(this)
|
||||
this.startDrawing();
|
||||
return this
|
||||
},
|
||||
|
||||
processDrawingClick: function (e) {
|
||||
if (e.vertex && e.vertex.editor === this) return;
|
||||
this.addLatLng(e.latlng);
|
||||
this.fireAndForward('editable:drawing:clicked', e)
|
||||
this.onCommitDrawing({
|
||||
...e,
|
||||
layer: this.feature,
|
||||
});
|
||||
},
|
||||
|
||||
addLatLng: function (latlng) {
|
||||
this._drawnLatLngs.push(latlng)
|
||||
this.feature._bounds.extend(latlng)
|
||||
const vertex = this.addVertexMarker(latlng, this._drawnLatLngs)
|
||||
this.onNewVertex(vertex)
|
||||
this.refresh()
|
||||
},
|
||||
|
||||
refresh: function () {
|
||||
// this.feature.redraw() // TODO: L.MultiPoint needs to support redraw
|
||||
this.onEditing()
|
||||
},
|
||||
|
||||
getLatLngs: function() {
|
||||
return this.feature._latlngs;
|
||||
},
|
||||
|
||||
getDefaultLatLngs: function() {
|
||||
return this.feature._latlngs;
|
||||
},
|
||||
|
||||
hasMiddleMarkers: function () {
|
||||
return false;
|
||||
},
|
||||
})
|
||||
|
||||
// 🍂namespace Editable; 🍂class EditableMixin
|
||||
// `EditableMixin` is included to `L.Polyline`, `L.Polygon`, `L.Rectangle`, `L.Circle`
|
||||
// and `L.Marker`. It adds some methods to them.
|
||||
|
@ -2027,6 +2092,12 @@
|
|||
},
|
||||
}
|
||||
|
||||
const MultipointMixin = {
|
||||
getEditorClass: (tools) => {
|
||||
return tools?.options?.multipointEditorClass || L.Editable.MultipointEditor
|
||||
},
|
||||
}
|
||||
|
||||
const CircleMarkerMixin = {
|
||||
getEditorClass: (tools) => {
|
||||
return tools?.options?.circleMarkerEditorClass || L.Editable.CircleMarkerEditor
|
||||
|
@ -2079,6 +2150,11 @@
|
|||
L.Circle.include(EditableMixin)
|
||||
L.Circle.include(CircleMixin)
|
||||
}
|
||||
if (L.MultiPoint) {
|
||||
L.MultiPoint.include(EditableMixin)
|
||||
L.MultiPoint.include(MultipointMixin)
|
||||
L.MultiPoint.addInitHook(keepEditable)
|
||||
}
|
||||
|
||||
L.LatLng.prototype.update = function (latlng) {
|
||||
latlng = L.latLng(latlng)
|
||||
|
|
11571
src/c3nav/static/leaflet/leaflet.js
vendored
11571
src/c3nav/static/leaflet/leaflet.js
vendored
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue