mirror of
https://github.com/umap-project/umap.git
synced 2025-04-29 03:42:37 +02:00
parent
d574abfc36
commit
00c384bf25
6 changed files with 195 additions and 77 deletions
|
@ -9,7 +9,12 @@ import * as Utils from '../utils.js'
|
||||||
import { SCHEMA } from '../schema.js'
|
import { SCHEMA } from '../schema.js'
|
||||||
import { translate } from '../i18n.js'
|
import { translate } from '../i18n.js'
|
||||||
import { uMapAlert as Alert } from '../../components/alerts/alert.js'
|
import { uMapAlert as Alert } from '../../components/alerts/alert.js'
|
||||||
import { LeafletMarker, LeafletPolyline, LeafletPolygon } from '../rendering/ui.js'
|
import {
|
||||||
|
LeafletMarker,
|
||||||
|
LeafletPolyline,
|
||||||
|
LeafletPolygon,
|
||||||
|
MaskPolygon,
|
||||||
|
} from '../rendering/ui.js'
|
||||||
import loadPopup from '../rendering/popup.js'
|
import loadPopup from '../rendering/popup.js'
|
||||||
|
|
||||||
class Feature {
|
class Feature {
|
||||||
|
@ -60,7 +65,7 @@ class Feature {
|
||||||
}
|
}
|
||||||
|
|
||||||
get ui() {
|
get ui() {
|
||||||
if (!this._ui) this._ui = this.makeUI()
|
if (!this._ui) this.makeUI()
|
||||||
return this._ui
|
return this._ui
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,13 +81,41 @@ class Feature {
|
||||||
return this.ui.getBounds()
|
return this.ui.getBounds()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get type() {
|
||||||
|
return this.geometry.type
|
||||||
|
}
|
||||||
|
|
||||||
|
get coordinates() {
|
||||||
|
return this.geometry.coordinates
|
||||||
|
}
|
||||||
|
|
||||||
get geometry() {
|
get geometry() {
|
||||||
return this._geometry
|
return this._geometry
|
||||||
}
|
}
|
||||||
|
|
||||||
set geometry(value) {
|
set geometry(value) {
|
||||||
this._geometry = value
|
this._geometry = value
|
||||||
this.geometryChanged()
|
this.pushGeometry()
|
||||||
|
}
|
||||||
|
|
||||||
|
pushGeometry() {
|
||||||
|
this.ui.setLatLngs(this.toLatLngs())
|
||||||
|
}
|
||||||
|
|
||||||
|
pullGeometry(sync = true) {
|
||||||
|
this.fromLatLngs(this.ui.getLatLngs())
|
||||||
|
if (sync) {
|
||||||
|
this.sync.update('geometry', this.geometry)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fromLatLngs(latlngs) {
|
||||||
|
this._geometry = this.convertLatLngs(latlngs)
|
||||||
|
}
|
||||||
|
|
||||||
|
makeUI() {
|
||||||
|
const klass = this.getUIClass()
|
||||||
|
this._ui = new klass(this, this.toLatLngs())
|
||||||
}
|
}
|
||||||
|
|
||||||
getClassName() {
|
getClassName() {
|
||||||
|
@ -536,7 +569,13 @@ class Feature {
|
||||||
|
|
||||||
redraw() {
|
redraw() {
|
||||||
if (this.datalayer?.isVisible()) {
|
if (this.datalayer?.isVisible()) {
|
||||||
this.ui._redraw()
|
if (this.getUIClass() !== this.ui.getClass()) {
|
||||||
|
this.datalayer.hideFeature(this)
|
||||||
|
this.makeUI()
|
||||||
|
this.datalayer.showFeature(this)
|
||||||
|
} else {
|
||||||
|
this.ui._redraw()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -550,20 +589,16 @@ export class Point extends Feature {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get coordinates() {
|
toLatLngs() {
|
||||||
return GeoJSON.coordsToLatLng(this.geometry.coordinates)
|
return GeoJSON.coordsToLatLng(this.coordinates)
|
||||||
}
|
}
|
||||||
|
|
||||||
set coordinates(latlng) {
|
convertLatLngs(latlng) {
|
||||||
this.geometry.coordinates = GeoJSON.latLngToCoords(latlng)
|
return { coordinates: GeoJSON.latLngToCoords(latlng), type: 'Point' }
|
||||||
}
|
}
|
||||||
|
|
||||||
geometryChanged() {
|
getUIClass() {
|
||||||
this.ui.setLatLng(this.coordinates)
|
return LeafletMarker
|
||||||
}
|
|
||||||
|
|
||||||
makeUI() {
|
|
||||||
return new LeafletMarker(this)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hasGeom() {
|
hasGeom() {
|
||||||
|
@ -620,7 +655,7 @@ export class Point extends Feature {
|
||||||
|
|
||||||
isOnScreen(bounds) {
|
isOnScreen(bounds) {
|
||||||
bounds = bounds || this.map.getBounds()
|
bounds = bounds || this.map.getBounds()
|
||||||
return bounds.contains(this.coordinates)
|
return bounds.contains(this.toLatLngs())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -629,20 +664,6 @@ class Path extends Feature {
|
||||||
return !this.isEmpty()
|
return !this.isEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
get coordinates() {
|
|
||||||
return this._toLatlngs(this.geometry)
|
|
||||||
}
|
|
||||||
|
|
||||||
set coordinates(latlngs) {
|
|
||||||
const { coordinates, type } = this._toGeometry(latlngs)
|
|
||||||
this.geometry.coordinates = coordinates
|
|
||||||
this.geometry.type = type
|
|
||||||
}
|
|
||||||
|
|
||||||
geometryChanged() {
|
|
||||||
this.ui.setLatLngs(this.coordinates)
|
|
||||||
}
|
|
||||||
|
|
||||||
connectToDataLayer(datalayer) {
|
connectToDataLayer(datalayer) {
|
||||||
super.connectToDataLayer(datalayer)
|
super.connectToDataLayer(datalayer)
|
||||||
// We keep markers on their own layer on top of the paths.
|
// We keep markers on their own layer on top of the paths.
|
||||||
|
@ -722,18 +743,18 @@ class Path extends Feature {
|
||||||
transferShape(at, to) {
|
transferShape(at, to) {
|
||||||
const shape = this.ui.enableEdit().deleteShapeAt(at)
|
const shape = this.ui.enableEdit().deleteShapeAt(at)
|
||||||
// FIXME: make Leaflet.Editable send an event instead
|
// FIXME: make Leaflet.Editable send an event instead
|
||||||
this.ui.geometryChanged()
|
this.pullGeometry()
|
||||||
this.ui.disableEdit()
|
this.ui.disableEdit()
|
||||||
if (!shape) return
|
if (!shape) return
|
||||||
to.ui.enableEdit().appendShape(shape)
|
to.ui.enableEdit().appendShape(shape)
|
||||||
to.ui.geometryChanged()
|
to.pullGeometry()
|
||||||
if (this.isEmpty()) this.del()
|
if (this.isEmpty()) this.del()
|
||||||
}
|
}
|
||||||
|
|
||||||
isolateShape(latlngs) {
|
isolateShape(latlngs) {
|
||||||
const properties = this.cloneProperties()
|
const properties = this.cloneProperties()
|
||||||
const type = this instanceof LineString ? 'LineString' : 'Polygon'
|
const type = this instanceof LineString ? 'LineString' : 'Polygon'
|
||||||
const geometry = this._toGeometry(latlngs)
|
const geometry = this.convertLatLngs(latlngs)
|
||||||
const other = this.datalayer.makeFeature({ type, geometry, properties })
|
const other = this.datalayer.makeFeature({ type, geometry, properties })
|
||||||
other.edit()
|
other.edit()
|
||||||
return other
|
return other
|
||||||
|
@ -776,14 +797,11 @@ export class LineString extends Path {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_toLatlngs(geometry) {
|
toLatLngs(geometry) {
|
||||||
return GeoJSON.coordsToLatLngs(
|
return GeoJSON.coordsToLatLngs(this.coordinates, this.type === 'LineString' ? 0 : 1)
|
||||||
geometry.coordinates,
|
|
||||||
geometry.type === 'LineString' ? 0 : 1
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_toGeometry(latlngs) {
|
convertLatLngs(latlngs) {
|
||||||
let multi = !LineUtil.isFlat(latlngs)
|
let multi = !LineUtil.isFlat(latlngs)
|
||||||
let coordinates = GeoJSON.latLngsToCoords(latlngs, multi ? 1 : 0, false)
|
let coordinates = GeoJSON.latLngsToCoords(latlngs, multi ? 1 : 0, false)
|
||||||
if (coordinates.length === 1 && typeof coordinates[0][0] !== 'number') {
|
if (coordinates.length === 1 && typeof coordinates[0][0] !== 'number') {
|
||||||
|
@ -798,8 +816,8 @@ export class LineString extends Path {
|
||||||
return !this.coordinates.length
|
return !this.coordinates.length
|
||||||
}
|
}
|
||||||
|
|
||||||
makeUI() {
|
getUIClass() {
|
||||||
return new LeafletPolyline(this)
|
return LeafletPolyline
|
||||||
}
|
}
|
||||||
|
|
||||||
isSameClass(other) {
|
isSameClass(other) {
|
||||||
|
@ -875,7 +893,7 @@ export class LineString extends Path {
|
||||||
while (latlngs.length > 1) {
|
while (latlngs.length > 1) {
|
||||||
latlngs.splice(0, 2, this._mergeShapes(latlngs[1], latlngs[0]))
|
latlngs.splice(0, 2, this._mergeShapes(latlngs[1], latlngs[0]))
|
||||||
}
|
}
|
||||||
this.setLatLngs(latlngs[0])
|
this.ui.setLatLngs(latlngs[0])
|
||||||
if (!this.editEnabled()) this.edit()
|
if (!this.editEnabled()) this.edit()
|
||||||
this.editor.reset()
|
this.editor.reset()
|
||||||
this.isDirty = true
|
this.isDirty = true
|
||||||
|
@ -895,14 +913,11 @@ export class Polygon extends Path {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_toLatlngs(geometry) {
|
toLatLngs() {
|
||||||
return GeoJSON.coordsToLatLngs(
|
return GeoJSON.coordsToLatLngs(this.coordinates, this.type === 'Polygon' ? 1 : 2)
|
||||||
geometry.coordinates,
|
|
||||||
geometry.type === 'Polygon' ? 1 : 2
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_toGeometry(latlngs) {
|
convertLatLngs(latlngs) {
|
||||||
const holes = !LineUtil.isFlat(latlngs)
|
const holes = !LineUtil.isFlat(latlngs)
|
||||||
let multi = holes && !LineUtil.isFlat(latlngs[0])
|
let multi = holes && !LineUtil.isFlat(latlngs[0])
|
||||||
let coordinates = GeoJSON.latLngsToCoords(latlngs, multi ? 2 : holes ? 1 : 0, true)
|
let coordinates = GeoJSON.latLngsToCoords(latlngs, multi ? 2 : holes ? 1 : 0, true)
|
||||||
|
@ -918,8 +933,9 @@ export class Polygon extends Path {
|
||||||
return !this.coordinates.length || !this.coordinates[0].length
|
return !this.coordinates.length || !this.coordinates[0].length
|
||||||
}
|
}
|
||||||
|
|
||||||
makeUI() {
|
getUIClass() {
|
||||||
return new LeafletPolygon(this)
|
if (this.getOption('mask')) return MaskPolygon
|
||||||
|
return LeafletPolygon
|
||||||
}
|
}
|
||||||
|
|
||||||
isSameClass(other) {
|
isSameClass(other) {
|
||||||
|
@ -969,6 +985,12 @@ export class Polygon extends Path {
|
||||||
this.del()
|
this.del()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getAdvancedOptions() {
|
||||||
|
const actions = super.getAdvancedOptions()
|
||||||
|
actions.push('properties._umap_options.mask')
|
||||||
|
return actions
|
||||||
|
}
|
||||||
|
|
||||||
getAdvancedEditActions(container) {
|
getAdvancedEditActions(container) {
|
||||||
super.getAdvancedEditActions(container)
|
super.getAdvancedEditActions(container)
|
||||||
const toLineString = DomUtil.createButton(
|
const toLineString = DomUtil.createButton(
|
||||||
|
|
|
@ -363,6 +363,10 @@ export class DataLayer {
|
||||||
this.layer.addLayer(feature.ui)
|
this.layer.addLayer(feature.ui)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hideFeature(feature) {
|
||||||
|
this.layer.removeLayer(feature.ui)
|
||||||
|
}
|
||||||
|
|
||||||
addFeature(feature) {
|
addFeature(feature) {
|
||||||
const id = stamp(feature)
|
const id = stamp(feature)
|
||||||
feature.connectToDataLayer(this)
|
feature.connectToDataLayer(this)
|
||||||
|
@ -377,7 +381,7 @@ export class DataLayer {
|
||||||
removeFeature(feature, sync) {
|
removeFeature(feature, sync) {
|
||||||
const id = stamp(feature)
|
const id = stamp(feature)
|
||||||
if (sync !== false) feature.sync.delete()
|
if (sync !== false) feature.sync.delete()
|
||||||
this.layer.removeLayer(feature.ui)
|
this.hideFeature(feature)
|
||||||
delete this.map.features_index[feature.getSlug()]
|
delete this.map.features_index[feature.getSlug()]
|
||||||
feature.disconnectFromDataLayer(this)
|
feature.disconnectFromDataLayer(this)
|
||||||
this._index.splice(this._index.indexOf(id), 1)
|
this._index.splice(this._index.indexOf(id), 1)
|
||||||
|
|
|
@ -5,15 +5,17 @@ import {
|
||||||
Polygon,
|
Polygon,
|
||||||
DomUtil,
|
DomUtil,
|
||||||
LineUtil,
|
LineUtil,
|
||||||
|
latLng,
|
||||||
|
LatLngBounds,
|
||||||
} from '../../../vendors/leaflet/leaflet-src.esm.js'
|
} from '../../../vendors/leaflet/leaflet-src.esm.js'
|
||||||
import { translate } from '../i18n.js'
|
import { translate } from '../i18n.js'
|
||||||
import { uMapAlert as Alert } from '../../components/alerts/alert.js'
|
import { uMapAlert as Alert } from '../../components/alerts/alert.js'
|
||||||
import * as Utils from '../utils.js'
|
import * as Utils from '../utils.js'
|
||||||
|
|
||||||
const FeatureMixin = {
|
const FeatureMixin = {
|
||||||
initialize: function (feature) {
|
initialize: function (feature, latlngs) {
|
||||||
this.feature = feature
|
this.feature = feature
|
||||||
this.parentClass.prototype.initialize.call(this, this.feature.coordinates)
|
this.parentClass.prototype.initialize.call(this, latlngs)
|
||||||
},
|
},
|
||||||
|
|
||||||
onAdd: function (map) {
|
onAdd: function (map) {
|
||||||
|
@ -134,7 +136,7 @@ const FeatureMixin = {
|
||||||
},
|
},
|
||||||
|
|
||||||
onCommit: function () {
|
onCommit: function () {
|
||||||
this.geometryChanged(false)
|
this.feature.pullGeometry(false)
|
||||||
this.feature.onCommit()
|
this.feature.onCommit()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -145,16 +147,20 @@ export const LeafletMarker = Marker.extend({
|
||||||
parentClass: Marker,
|
parentClass: Marker,
|
||||||
includes: [FeatureMixin],
|
includes: [FeatureMixin],
|
||||||
|
|
||||||
initialize: function (feature) {
|
initialize: function (feature, latlng) {
|
||||||
FeatureMixin.initialize.call(this, feature)
|
FeatureMixin.initialize.call(this, feature, latlng)
|
||||||
this.setIcon(this.getIcon())
|
this.setIcon(this.getIcon())
|
||||||
},
|
},
|
||||||
|
|
||||||
geometryChanged: function (sync = true) {
|
getClass: () => LeafletMarker,
|
||||||
this.feature.coordinates = this._latlng
|
|
||||||
if (sync) {
|
// Make API consistent with path
|
||||||
this.feature.sync.update('geometry', this.feature.geometry)
|
getLatLngs: function () {
|
||||||
}
|
return this.getLatLng()
|
||||||
|
},
|
||||||
|
|
||||||
|
setLatLngs: function (latlng) {
|
||||||
|
return this.setLatLng(latlng)
|
||||||
},
|
},
|
||||||
|
|
||||||
addInteractions() {
|
addInteractions() {
|
||||||
|
@ -162,7 +168,7 @@ export const LeafletMarker = Marker.extend({
|
||||||
this.on('dragend', (event) => {
|
this.on('dragend', (event) => {
|
||||||
this.isDirty = true
|
this.isDirty = true
|
||||||
this.feature.edit(event)
|
this.feature.edit(event)
|
||||||
this.geometryChanged()
|
this.feature.pullGeometry()
|
||||||
})
|
})
|
||||||
this.on('editable:drawing:commit', this.onCommit)
|
this.on('editable:drawing:commit', this.onCommit)
|
||||||
if (!this.feature.isReadOnly()) this.on('mouseover', this._enableDragging)
|
if (!this.feature.isReadOnly()) this.on('mouseover', this._enableDragging)
|
||||||
|
@ -265,10 +271,6 @@ const PathMixin = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
geometryChanged: function () {
|
|
||||||
this.feature.coordinates = this._latlngs
|
|
||||||
},
|
|
||||||
|
|
||||||
addInteractions: function () {
|
addInteractions: function () {
|
||||||
FeatureMixin.addInteractions.call(this)
|
FeatureMixin.addInteractions.call(this)
|
||||||
this.on('editable:disable', this.onCommit)
|
this.on('editable:disable', this.onCommit)
|
||||||
|
@ -385,20 +387,22 @@ const PathMixin = {
|
||||||
return items
|
return items
|
||||||
},
|
},
|
||||||
|
|
||||||
isolateShape: function(atLatLng) {
|
isolateShape: function (atLatLng) {
|
||||||
if (!this.feature.isMulti()) return
|
if (!this.feature.isMulti()) return
|
||||||
const shape = this.enableEdit().deleteShapeAt(atLatLng)
|
const shape = this.enableEdit().deleteShapeAt(atLatLng)
|
||||||
this.geometryChanged()
|
this.feature.pullGeometry()
|
||||||
this.disableEdit()
|
this.disableEdit()
|
||||||
if (!shape) return
|
if (!shape) return
|
||||||
return this.feature.isolateShape(shape)
|
return this.feature.isolateShape(shape)
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export const LeafletPolyline = Polyline.extend({
|
export const LeafletPolyline = Polyline.extend({
|
||||||
parentClass: Polyline,
|
parentClass: Polyline,
|
||||||
includes: [FeatureMixin, PathMixin],
|
includes: [FeatureMixin, PathMixin],
|
||||||
|
|
||||||
|
getClass: () => LeafletPolyline,
|
||||||
|
|
||||||
getVertexActions: function (event) {
|
getVertexActions: function (event) {
|
||||||
const actions = PathMixin.getVertexActions.call(this, event)
|
const actions = PathMixin.getVertexActions.call(this, event)
|
||||||
const index = event.vertex.getIndex()
|
const index = event.vertex.getIndex()
|
||||||
|
@ -455,6 +459,8 @@ export const LeafletPolygon = Polygon.extend({
|
||||||
parentClass: Polygon,
|
parentClass: Polygon,
|
||||||
includes: [FeatureMixin, PathMixin],
|
includes: [FeatureMixin, PathMixin],
|
||||||
|
|
||||||
|
getClass: () => LeafletPolygon,
|
||||||
|
|
||||||
getContextMenuEditItems: function (event) {
|
getContextMenuEditItems: function (event) {
|
||||||
const items = PathMixin.getContextMenuEditItems.call(this, event)
|
const items = PathMixin.getContextMenuEditItems.call(this, event)
|
||||||
const shape = this.shapeAt(event.latlng)
|
const shape = this.shapeAt(event.latlng)
|
||||||
|
@ -482,3 +488,37 @@ export const LeafletPolygon = Polygon.extend({
|
||||||
this.enableEdit().newHole(event.latlng)
|
this.enableEdit().newHole(event.latlng)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
const WORLD = [
|
||||||
|
latLng([90, 180]),
|
||||||
|
latLng([90, -180]),
|
||||||
|
latLng([-90, -180]),
|
||||||
|
latLng([-90, 180]),
|
||||||
|
]
|
||||||
|
|
||||||
|
export const MaskPolygon = LeafletPolygon.extend({
|
||||||
|
getClass: () => MaskPolygon,
|
||||||
|
|
||||||
|
getLatLngs: function () {
|
||||||
|
// Exclude World coordinates.
|
||||||
|
return LeafletPolygon.prototype.getLatLngs.call(this).slice(1)
|
||||||
|
},
|
||||||
|
|
||||||
|
_setLatLngs: function (latlngs) {
|
||||||
|
const newLatLngs = []
|
||||||
|
newLatLngs.push(WORLD)
|
||||||
|
|
||||||
|
if (!this.feature.isMulti()) {
|
||||||
|
latlngs = [latlngs]
|
||||||
|
}
|
||||||
|
for (const ring of latlngs) {
|
||||||
|
newLatLngs.push(ring)
|
||||||
|
}
|
||||||
|
LeafletPolygon.prototype._setLatLngs.call(this, newLatLngs)
|
||||||
|
this._bounds = new LatLngBounds(latlngs)
|
||||||
|
},
|
||||||
|
|
||||||
|
_defaultShape: function () {
|
||||||
|
// Do not compute with world coordinates (eg. for centering the popup).
|
||||||
|
return this._latlngs[1]
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
|
@ -287,6 +287,11 @@ export const SCHEMA = {
|
||||||
nullable: true,
|
nullable: true,
|
||||||
label: translate('Display the measure control'),
|
label: translate('Display the measure control'),
|
||||||
},
|
},
|
||||||
|
mask: {
|
||||||
|
type: Boolean,
|
||||||
|
impacts: ['data'],
|
||||||
|
label: translate('Display the polygon inverted'),
|
||||||
|
},
|
||||||
miniMap: {
|
miniMap: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
impacts: ['ui'],
|
impacts: ['ui'],
|
||||||
|
|
|
@ -1167,15 +1167,7 @@ U.Editable = L.Editable.extend({
|
||||||
this.on('editable:editing', (event) => {
|
this.on('editable:editing', (event) => {
|
||||||
const layer = event.layer
|
const layer = event.layer
|
||||||
layer.feature.isDirty = true
|
layer.feature.isDirty = true
|
||||||
if (layer instanceof L.Marker) {
|
layer.feature.fromLatLngs(layer.getLatLngs())
|
||||||
layer.feature.coordinates = layer._latlng
|
|
||||||
} else {
|
|
||||||
layer.feature.coordinates = layer._latlngs
|
|
||||||
}
|
|
||||||
// if (layer._tooltip && layer.isTooltipOpen()) {
|
|
||||||
// layer._tooltip.setLatLng(layer.getCenter())
|
|
||||||
// layer._tooltip.update()
|
|
||||||
// }
|
|
||||||
})
|
})
|
||||||
this.on('editable:vertex:ctrlclick', (event) => {
|
this.on('editable:vertex:ctrlclick', (event) => {
|
||||||
const index = event.vertex.getIndex()
|
const index = event.vertex.getIndex()
|
||||||
|
|
|
@ -420,3 +420,58 @@ def test_can_transform_polygon_to_line(live_server, page, tilelayer, settings):
|
||||||
data = save_and_get_json(page)
|
data = save_and_get_json(page)
|
||||||
assert len(data["features"]) == 1
|
assert len(data["features"]) == 1
|
||||||
assert data["features"][0]["geometry"]["type"] == "LineString"
|
assert data["features"][0]["geometry"]["type"] == "LineString"
|
||||||
|
|
||||||
|
|
||||||
|
def test_can_draw_a_polygon_and_invert_it(live_server, page, tilelayer, settings):
|
||||||
|
settings.UMAP_ALLOW_ANONYMOUS = True
|
||||||
|
page.goto(f"{live_server.url}/en/map/new/")
|
||||||
|
paths = page.locator(".leaflet-overlay-pane path")
|
||||||
|
expect(paths).to_have_count(0)
|
||||||
|
page.get_by_title("Draw a polygon").click()
|
||||||
|
map = page.locator("#map")
|
||||||
|
map.click(position={"x": 200, "y": 100})
|
||||||
|
map.click(position={"x": 200, "y": 200})
|
||||||
|
map.click(position={"x": 100, "y": 200})
|
||||||
|
map.click(position={"x": 100, "y": 100})
|
||||||
|
# Click again to finish
|
||||||
|
map.click(position={"x": 100, "y": 100})
|
||||||
|
expect(paths).to_have_count(1)
|
||||||
|
page.get_by_text("Advanced properties").click()
|
||||||
|
page.get_by_text("Display the polygon inverted").click()
|
||||||
|
data = save_and_get_json(page)
|
||||||
|
assert len(data["features"]) == 1
|
||||||
|
assert data["features"][0]["geometry"]["type"] == "Polygon"
|
||||||
|
assert data["features"][0]["geometry"]["coordinates"] == [
|
||||||
|
[
|
||||||
|
[
|
||||||
|
-7.668457,
|
||||||
|
54.457267,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
-7.668457,
|
||||||
|
53.159947,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
-9.865723,
|
||||||
|
53.159947,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
-9.865723,
|
||||||
|
54.457267,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
-7.668457,
|
||||||
|
54.457267,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]
|
||||||
|
|
||||||
|
page.get_by_role("button", name="View").click()
|
||||||
|
popup = page.locator(".leaflet-popup")
|
||||||
|
expect(popup).to_be_hidden()
|
||||||
|
# Now click on the middle of the polygon, it should not show the popup
|
||||||
|
map.click(position={"x": 150, "y": 150})
|
||||||
|
expect(popup).to_be_hidden()
|
||||||
|
# Click elsewhere on the map, it should now show the popup
|
||||||
|
map.click(position={"x": 250, "y": 250})
|
||||||
|
expect(popup).to_be_visible()
|
||||||
|
|
Loading…
Reference in a new issue