diff --git a/src/js/Draw/L.PM.Draw.Circle.js b/src/js/Draw/L.PM.Draw.Circle.js index ebf626cc..2d47de75 100644 --- a/src/js/Draw/L.PM.Draw.Circle.js +++ b/src/js/Draw/L.PM.Draw.Circle.js @@ -1,6 +1,6 @@ import Draw from './L.PM.Draw'; -import { destinationOnLine, getTranslation } from '../helpers'; +import { destinationOnLine } from '../helpers'; Draw.Circle = Draw.extend({ initialize(map) { @@ -56,7 +56,7 @@ Draw.Circle = Draw.extend({ // add tooltip to hintmarker if (this.options.tooltips) { this._hintMarker - .bindTooltip(getTranslation('tooltips.startCircle'), { + .bindTooltip(L.PM.Translation.getTranslation('tooltips.startCircle'), { permanent: true, offset: L.point(0, 10), direction: 'bottom', @@ -211,7 +211,7 @@ Draw.Circle = Draw.extend({ this._hintMarker.on('move', this._syncCircleRadius, this); this._hintMarker.setTooltipContent( - getTranslation('tooltips.finishCircle') + L.PM.Translation.getTranslation('tooltips.finishCircle') ); this._fireCenterPlaced(); diff --git a/src/js/Draw/L.PM.Draw.CircleMarker.js b/src/js/Draw/L.PM.Draw.CircleMarker.js index 3b6b3bc9..1fe5fd9f 100644 --- a/src/js/Draw/L.PM.Draw.CircleMarker.js +++ b/src/js/Draw/L.PM.Draw.CircleMarker.js @@ -1,5 +1,5 @@ import Draw from './L.PM.Draw'; -import { destinationOnLine, getTranslation } from '../helpers'; +import { destinationOnLine } from '../helpers'; Draw.CircleMarker = Draw.Marker.extend({ initialize(map) { @@ -58,13 +58,16 @@ Draw.CircleMarker = Draw.Marker.extend({ // add tooltip to hintmarker if (this.options.tooltips) { this._hintMarker - .bindTooltip(getTranslation('tooltips.startCircle'), { - permanent: true, - offset: L.point(0, 10), - direction: 'bottom', - - opacity: 0.8, - }) + .bindTooltip( + L.PM.Translation.getTranslation('tooltips.startCircle'), + { + permanent: true, + offset: L.point(0, 10), + direction: 'bottom', + + opacity: 0.8, + } + ) .openTooltip(); } @@ -92,13 +95,16 @@ Draw.CircleMarker = Draw.Marker.extend({ // add tooltip to hintmarker if (this.options.tooltips) { this._hintMarker - .bindTooltip(getTranslation('tooltips.placeCircleMarker'), { - permanent: true, - offset: L.point(0, 10), - direction: 'bottom', - - opacity: 0.8, - }) + .bindTooltip( + L.PM.Translation.getTranslation('tooltips.placeCircleMarker'), + { + permanent: true, + offset: L.point(0, 10), + direction: 'bottom', + + opacity: 0.8, + } + ) .openTooltip(); } } @@ -201,7 +207,7 @@ Draw.CircleMarker = Draw.Marker.extend({ this._hintMarker.on('move', this._syncCircleRadius, this); this._hintMarker.setTooltipContent( - getTranslation('tooltips.finishCircle') + L.PM.Translation.getTranslation('tooltips.finishCircle') ); this._fireCenterPlaced(); diff --git a/src/js/Draw/L.PM.Draw.Line.js b/src/js/Draw/L.PM.Draw.Line.js index 0a940d36..a67f1166 100644 --- a/src/js/Draw/L.PM.Draw.Line.js +++ b/src/js/Draw/L.PM.Draw.Line.js @@ -1,8 +1,6 @@ import kinks from '@turf/kinks'; import Draw from './L.PM.Draw'; -import { getTranslation } from '../helpers'; - Draw.Line = Draw.extend({ initialize(map) { this._map = map; @@ -51,7 +49,7 @@ Draw.Line = Draw.extend({ // add tooltip to hintmarker if (this.options.tooltips) { this._hintMarker - .bindTooltip(getTranslation('tooltips.firstVertex'), { + .bindTooltip(L.PM.Translation.getTranslation('tooltips.firstVertex'), { permanent: true, offset: L.point(0, 10), direction: 'bottom', @@ -368,9 +366,9 @@ Draw.Line = Draw.extend({ // handle tooltip text if (length <= 1) { - text = getTranslation('tooltips.continueLine'); + text = L.PM.Translation.getTranslation('tooltips.continueLine'); } else { - text = getTranslation('tooltips.finishLine'); + text = L.PM.Translation.getTranslation('tooltips.finishLine'); } this._hintMarker.setTooltipContent(text); }, diff --git a/src/js/Draw/L.PM.Draw.Marker.js b/src/js/Draw/L.PM.Draw.Marker.js index e9980df1..e846e15a 100644 --- a/src/js/Draw/L.PM.Draw.Marker.js +++ b/src/js/Draw/L.PM.Draw.Marker.js @@ -1,5 +1,4 @@ import Draw from './L.PM.Draw'; -import { getTranslation } from '../helpers'; Draw.Marker = Draw.extend({ initialize(map) { @@ -30,7 +29,7 @@ Draw.Marker = Draw.extend({ // add tooltip to hintmarker if (this.options.tooltips) { this._hintMarker - .bindTooltip(getTranslation('tooltips.placeMarker'), { + .bindTooltip(L.PM.Translation.getTranslation('tooltips.placeMarker'), { permanent: true, offset: L.point(0, 10), direction: 'bottom', diff --git a/src/js/Draw/L.PM.Draw.Polygon.js b/src/js/Draw/L.PM.Draw.Polygon.js index 1310fd09..2dc0d95a 100644 --- a/src/js/Draw/L.PM.Draw.Polygon.js +++ b/src/js/Draw/L.PM.Draw.Polygon.js @@ -1,5 +1,4 @@ import Draw from './L.PM.Draw'; -import { getTranslation } from '../helpers'; Draw.Polygon = Draw.Line.extend({ initialize(map) { @@ -46,9 +45,9 @@ Draw.Polygon = Draw.Line.extend({ // handle tooltip text if (length <= 2) { - text = getTranslation('tooltips.continueLine'); + text = L.PM.Translation.getTranslation('tooltips.continueLine'); } else { - text = getTranslation('tooltips.finishPoly'); + text = L.PM.Translation.getTranslation('tooltips.finishPoly'); } this._hintMarker.setTooltipContent(text); }, diff --git a/src/js/Draw/L.PM.Draw.Rectangle.js b/src/js/Draw/L.PM.Draw.Rectangle.js index 0b862d30..6b7e150b 100644 --- a/src/js/Draw/L.PM.Draw.Rectangle.js +++ b/src/js/Draw/L.PM.Draw.Rectangle.js @@ -1,5 +1,5 @@ import Draw from './L.PM.Draw'; -import { fixLatOffset, getTranslation } from '../helpers'; +import { fixLatOffset } from '../helpers'; Draw.Rectangle = Draw.extend({ initialize(map) { @@ -55,7 +55,7 @@ Draw.Rectangle = Draw.extend({ // add tooltip to hintmarker if (this.options.tooltips) { this._hintMarker - .bindTooltip(getTranslation('tooltips.firstVertex'), { + .bindTooltip(L.PM.Translation.getTranslation('tooltips.firstVertex'), { permanent: true, offset: L.point(0, 10), direction: 'bottom', @@ -175,7 +175,9 @@ Draw.Rectangle = Draw.extend({ this._map.on('click', this._finishShape, this); // change tooltip text - this._hintMarker.setTooltipContent(getTranslation('tooltips.finishRect')); + this._hintMarker.setTooltipContent( + L.PM.Translation.getTranslation('tooltips.finishRect') + ); this._setRectangleOrigin(); }, diff --git a/src/js/Draw/L.PM.Draw.js b/src/js/Draw/L.PM.Draw.js index b2fc17b9..f72f6ca0 100644 --- a/src/js/Draw/L.PM.Draw.js +++ b/src/js/Draw/L.PM.Draw.js @@ -221,6 +221,10 @@ const Draw = L.Class.extend({ const map = this._map || this._layer._map; return map.pm.getGeomanLayers().length === 0; }, + addShape(name) { + this.shapes.push(name); + this[name] = new L.PM.Draw[name](this._map); + }, }); export default Draw; diff --git a/src/js/Edit/L.PM.Edit.Circle.js b/src/js/Edit/L.PM.Edit.Circle.js index 80416618..712ce1be 100644 --- a/src/js/Edit/L.PM.Edit.Circle.js +++ b/src/js/Edit/L.PM.Edit.Circle.js @@ -355,4 +355,12 @@ Edit.Circle = Edit.extend({ // calculate the new latlng of marker if radius is out of min/max this._outerMarker.setLatLng(this._getNewDestinationOfOuterMarker()); }, + _handleDrag(deltaLatLng) { + // create the new coordinates array + const newCoords = L.PM.Utils.moveCoordsByDelta(deltaLatLng, [ + this._layer.getLatLng(), + ]); + // set new coordinates and redraw + this._layer.setLatLng(newCoords[0]); + }, }); diff --git a/src/js/Edit/L.PM.Edit.CircleMarker.js b/src/js/Edit/L.PM.Edit.CircleMarker.js index a5971574..8ac4c6fb 100644 --- a/src/js/Edit/L.PM.Edit.CircleMarker.js +++ b/src/js/Edit/L.PM.Edit.CircleMarker.js @@ -429,4 +429,26 @@ Edit.CircleMarker = Edit.extend({ // calculate the new latlng of marker if radius is out of min/max this._outerMarker.setLatLng(this._getNewDestinationOfOuterMarker()); }, + _handleDrag(deltaLatLng) { + if (this._layer instanceof L.CircleMarker && this._layer.options.editable) { + // create the new coordinates array + const newCoords = L.PM.Utils.moveCoordsByDelta(deltaLatLng, [ + this._layer.getLatLng(), + ]); + // set new coordinates and redraw + this._layer.setLatLng(newCoords[0]); + } else { + let coordsRefernce = this._layer.getLatLng(); + if (this._layer._snapped) { + // if layer is snapped we use the original latlng for re-calculation, else the layer will not be "unsnappable" anymore + coordsRefernce = this._layer._orgLatLng; + } + // create the new coordinates array + const newCoords = L.PM.Utils.moveCoordsByDelta(deltaLatLng, [ + coordsRefernce, + ]); + // set new coordinates and redraw + this._layer.setLatLng(newCoords[0]); + } + }, }); diff --git a/src/js/Edit/L.PM.Edit.ImageOverlay.js b/src/js/Edit/L.PM.Edit.ImageOverlay.js index 387c2ab3..391e04f4 100644 --- a/src/js/Edit/L.PM.Edit.ImageOverlay.js +++ b/src/js/Edit/L.PM.Edit.ImageOverlay.js @@ -87,4 +87,13 @@ Edit.ImageOverlay = Edit.extend({ return [northwest, northeast, southeast, southwest]; }, + _handleDrag(deltaLatLng) { + // create the new coordinates array + const newCoords = L.PM.Utils.moveCoordsByDelta(deltaLatLng, [ + this._layer.getBounds().getNorthWest(), + this._layer.getBounds().getSouthEast(), + ]); + // set new coordinates and redraw + this._layer.setBounds(newCoords); + }, }); diff --git a/src/js/Edit/L.PM.Edit.Line.js b/src/js/Edit/L.PM.Edit.Line.js index bdfa01f3..c3822e2c 100644 --- a/src/js/Edit/L.PM.Edit.Line.js +++ b/src/js/Edit/L.PM.Edit.Line.js @@ -811,4 +811,14 @@ Edit.Line = Edit.extend({ this._fireVertexClick(e, indexPath); }, + _handleDrag(deltaLatLng) { + // create the new coordinates array + const newCoords = L.PM.Utils.moveCoordsByDelta( + deltaLatLng, + this._layer.getLatLngs() + ); + + // set new coordinates and redraw + this._layer.setLatLngs(newCoords); + }, }); diff --git a/src/js/Edit/L.PM.Edit.Marker.js b/src/js/Edit/L.PM.Edit.Marker.js index b6538e6a..63076876 100644 --- a/src/js/Edit/L.PM.Edit.Marker.js +++ b/src/js/Edit/L.PM.Edit.Marker.js @@ -116,4 +116,17 @@ Edit.Marker = Edit.extend({ marker.off('pm:dragend', this._cleanupSnapping, this); marker.off('pm:dragstart', this._unsnap, this); }, + _handleDrag(deltaLatLng) { + let coordsRefernce = this._layer.getLatLng(); + if (this._layer._snapped) { + // if layer is snapped we use the original latlng for re-calculation, else the layer will not be "unsnappable" anymore + coordsRefernce = this._layer._orgLatLng; + } + // create the new coordinates array + const newCoords = L.PM.Utils.moveCoordsByDelta(deltaLatLng, [ + coordsRefernce, + ]); + // set new coordinates and redraw + this._layer.setLatLng(newCoords[0]); + }, }); diff --git a/src/js/Edit/L.PM.Edit.js b/src/js/Edit/L.PM.Edit.js index 2e0cd7f4..5bddb5e7 100644 --- a/src/js/Edit/L.PM.Edit.js +++ b/src/js/Edit/L.PM.Edit.js @@ -107,6 +107,9 @@ const Edit = L.Class.extend({ } return true; }, + _handleRotate(latlngs) { + this._layer.setLatLngs(latlngs); + }, }); export default Edit; diff --git a/src/js/L.PM.Map.js b/src/js/L.PM.Map.js index ad68666d..f3182fb4 100644 --- a/src/js/L.PM.Map.js +++ b/src/js/L.PM.Map.js @@ -1,11 +1,11 @@ import merge from 'lodash/merge'; -import translations from '../assets/translations'; import GlobalEditMode from './Mixins/Modes/Mode.Edit'; import GlobalDragMode from './Mixins/Modes/Mode.Drag'; import GlobalRemovalMode from './Mixins/Modes/Mode.Removal'; import GlobalRotateMode from './Mixins/Modes/Mode.Rotate'; import EventMixin from './Mixins/Events'; import KeyboardMixins from './Mixins/Keyboard'; +import { isEmptyDeep } from './helpers'; const Map = L.Class.extend({ includes: [ @@ -41,16 +41,53 @@ const Map = L.Class.extend({ }; this.Keyboard._initKeyListener(map); + + this._allowedTypes = [ + L.Polyline, + L.Marker, + L.Circle, + L.CircleMarker, + L.ImageOverlay, + ]; + this._allowedSnappingTypes = [ + L.Polyline, + L.Marker, + L.Circle, + L.CircleMarker, + L.ImageOverlay, + ]; + this._allowedRotateTypes = [L.Polyline]; + this._latlngFunctions = [ + { type: L.Marker, fnc: L.Marker.prototype.getLatLng }, + { type: L.CircleMarker, fnc: L.CircleMarker.prototype.getLatLng }, + { type: L.Polyline, fnc: L.Polyline.prototype.getLatLngs }, + { type: L.ImageOverlay, fnc: L.ImageOverlay.prototype.getBounds }, + ]; + this._latlngRotationOverlayFunctions = []; + this._snappingDistanceFunctions = []; + + this._snappingFilters = [ + (layer) => layer._latlng, + (layer) => layer._latlngs && !isEmptyDeep(layer._latlngs), + ]; }, setLang(lang = 'en', t, fallback = 'en') { const oldLang = L.PM.activeLang; if (t) { - translations[lang] = merge(translations[fallback], t); + L.PM.Translation.translations[lang] = merge( + L.PM.Translation.translations[fallback], + t + ); } L.PM.activeLang = lang; this.map.pm.Toolbar.reinit(); - this._fireLangChange(oldLang, lang, fallback, translations[lang]); + this._fireLangChange( + oldLang, + lang, + fallback, + L.PM.Translation.translations + ); }, addControls(options) { this.Toolbar.addControls(options); diff --git a/src/js/L.PM.Translation.js b/src/js/L.PM.Translation.js new file mode 100644 index 00000000..085b7372 --- /dev/null +++ b/src/js/L.PM.Translation.js @@ -0,0 +1,18 @@ +import has from 'lodash/has'; +import get from 'lodash/get'; +import merge from 'lodash/merge'; +import translations from '../assets/translations/index'; + +export default { + translations, + getTranslation(path, lang = L.PM.activeLang) { + if (!has(this.translations, lang)) { + lang = 'en'; + } + + return get(this.translations[lang], path); + }, + addTranslation(lang, json) { + this.translations[lang] = merge(this.translations[lang], json); + }, +} diff --git a/src/js/L.PM.Utils.js b/src/js/L.PM.Utils.js index 6522532c..901532d8 100644 --- a/src/js/L.PM.Utils.js +++ b/src/js/L.PM.Utils.js @@ -1,4 +1,4 @@ -import { createGeodesicPolygon, getTranslation } from './helpers'; +import { createGeodesicPolygon } from './helpers'; import { _toLatLng, _toPoint } from './helpers/ModeHelper'; const Utils = { @@ -13,13 +13,7 @@ const Utils = { findLayers(map) { let layers = []; map.eachLayer((layer) => { - if ( - layer instanceof L.Polyline || - layer instanceof L.Marker || - layer instanceof L.Circle || - layer instanceof L.CircleMarker || - layer instanceof L.ImageOverlay - ) { + if (map.pm._allowedTypes.find((x) => layer instanceof x)) { layers.push(layer); } }); @@ -110,7 +104,7 @@ const Utils = { }; }, createGeodesicPolygon, - getTranslation, + getTranslation: (path) => L.PM.Translation.getTranslation(path), findDeepCoordIndex(arr, latlng) { // find latlng in arr and return its location as path // thanks for the function, Felix Heck @@ -215,6 +209,51 @@ const Utils = { const pointB = L.point(pointA.x + radiusInPx, pointA.y); return map.distance(map.unproject(pointB), center); }, + // move the coordinates by the delta + moveCoordsByDelta(deltaLatLng, coords) { + // alter the coordinates + return coords.map((currentLatLng) => { + if (Array.isArray(currentLatLng)) { + // do this recursively as coords might be nested + return L.PM.Utils.moveCoordsByDelta(deltaLatLng, currentLatLng); + } + + // move the coord and return it + return { + lat: currentLatLng.lat + deltaLatLng.lat, + lng: currentLatLng.lng + deltaLatLng.lng, + }; + }); + }, + _getCoords(map, layer, clone = false) { + const obj = map.pm._latlngFunctions.find((f) => layer instanceof f.type); + if (clone) { + return L.PM.Utils.cloneLatLngs(obj.fnc.call(layer, layer)); + } + return obj.fnc.call(layer, layer); + }, + _getRotationOverlayCoords(map, layer) { + const obj = map.pm._latlngRotationOverlayFunctions.find( + (f) => layer instanceof f.type + ); + if (!obj) { + return L.PM.Utils._getCoords(map, layer); + } + return obj.fnc.call(layer, layer); + }, + cloneLatLngs(latlngs) { + const result = []; + const flat = L.LineUtil.isFlat(latlngs); + + for (let i = 0, len = latlngs.length; i < len; i += 1) { + if (flat) { + result[i] = L.latLng(latlngs[i]).clone(); + } else { + result[i] = L.PM.Utils.cloneLatLngs(latlngs[i]); + } + } + return result; + }, }; export default Utils; diff --git a/src/js/L.PM.js b/src/js/L.PM.js index b6bd735c..f8d6479f 100644 --- a/src/js/L.PM.js +++ b/src/js/L.PM.js @@ -39,6 +39,8 @@ import '../css/controls.css'; import Matrix from './helpers/Matrix'; import Utils from './L.PM.Utils'; +import Translation from './L.PM.Translation'; +import Mixins from './Mixins/index'; L.PM = L.PM || { version: packageInfo.version, @@ -48,6 +50,8 @@ L.PM = L.PM || { Edit, Utils, Matrix, + Mixins, + Translation, activeLang: 'en', optIn: false, initialize(options) { diff --git a/src/js/Mixins/Dragging.js b/src/js/Mixins/Dragging.js index 1140471c..37f07337 100644 --- a/src/js/Mixins/Dragging.js +++ b/src/js/Mixins/Dragging.js @@ -332,57 +332,25 @@ const DragMixin = { lng: latlng.lng - this._tempDragCoord.lng, }; - // move the coordinates by the delta - const moveCoords = (coords) => - // alter the coordinates - coords.map((currentLatLng) => { - if (Array.isArray(currentLatLng)) { - // do this recursively as coords might be nested - return moveCoords(currentLatLng); + if(this._handleDrag){ + this._handleDrag(deltaLatLng); + } else { + if (this._layer.getLatLng) { + let coordsRefernce = this._layer.getLatLng(); + if (this._layer._snapped) { + // if layer is snapped we use the original latlng for re-calculation, else the layer will not be "unsnappable" anymore + coordsRefernce = this._layer._orgLatLng; } - - // move the coord and return it - return { - lat: currentLatLng.lat + deltaLatLng.lat, - lng: currentLatLng.lng + deltaLatLng.lng, - }; - }); - - if ( - this._layer instanceof L.Circle || - (this._layer instanceof L.CircleMarker && this._layer.options.editable) - ) { - // create the new coordinates array - const newCoords = moveCoords([this._layer.getLatLng()]); - // set new coordinates and redraw - this._layer.setLatLng(newCoords[0]); - } else if ( - this._layer instanceof L.CircleMarker || - this._layer instanceof L.Marker - ) { - let coordsRefernce = this._layer.getLatLng(); - if (this._layer._snapped) { - // if layer is snapped we use the original latlng for re-calculation, else the layer will not be "unsnappable" anymore - coordsRefernce = this._layer._orgLatLng; + // create the new coordinates array + const newCoords = L.PM.Utils.moveCoordsByDelta(deltaLatLng,[coordsRefernce]); + // set new coordinates and redraw + this._layer.setLatLng(newCoords[0]); + } else { + // create the new coordinates array + const newCoords = L.PM.Utils.moveCoordsByDelta(deltaLatLng, this._layer.getLatLngs()); + // set new coordinates and redraw + this._layer.setLatLngs(newCoords); } - // create the new coordinates array - const newCoords = moveCoords([coordsRefernce]); - // set new coordinates and redraw - this._layer.setLatLng(newCoords[0]); - } else if (this._layer instanceof L.ImageOverlay) { - // create the new coordinates array - const newCoords = moveCoords([ - this._layer.getBounds().getNorthWest(), - this._layer.getBounds().getSouthEast(), - ]); - // set new coordinates and redraw - this._layer.setBounds(newCoords); - } else { - // create the new coordinates array - const newCoords = moveCoords(this._layer.getLatLngs()); - - // set new coordinates and redraw - this._layer.setLatLngs(newCoords); } // save current latlng for next delta calculation diff --git a/src/js/Mixins/Modes/Mode.Rotate.js b/src/js/Mixins/Modes/Mode.Rotate.js index 4f03b8d3..a291c320 100644 --- a/src/js/Mixins/Modes/Mode.Rotate.js +++ b/src/js/Mixins/Modes/Mode.Rotate.js @@ -2,8 +2,8 @@ const GlobalRotateMode = { _globalRotateModeEnabled: false, enableGlobalRotateMode() { this._globalRotateModeEnabled = true; - const layers = L.PM.Utils.findLayers(this.map).filter( - (l) => l instanceof L.Polyline + const layers = L.PM.Utils.findLayers(this.map).filter((l) => + this.map.pm._allowedRotateTypes.find((x) => l instanceof x) ); layers.forEach((layer) => { if (this._isRelevantForRotate(layer)) { @@ -27,8 +27,8 @@ const GlobalRotateMode = { }, disableGlobalRotateMode() { this._globalRotateModeEnabled = false; - const layers = L.PM.Utils.findLayers(this.map).filter( - (l) => l instanceof L.Polyline + const layers = L.PM.Utils.findLayers(this.map).filter((l) => + this.map.pm._allowedRotateTypes.find((x) => l instanceof x) ); layers.forEach((layer) => { layer.pm.disableRotate(); diff --git a/src/js/Mixins/Rotating.js b/src/js/Mixins/Rotating.js index f7319191..ac5c8f87 100644 --- a/src/js/Mixins/Rotating.js +++ b/src/js/Mixins/Rotating.js @@ -1,6 +1,5 @@ import get from 'lodash/get'; import { _convertLatLngs, _toPoint } from '../helpers/ModeHelper'; -import { copyLatLngs } from '../helpers'; /** * We create a temporary polygon with the same latlngs as the layer that we want to rotate. @@ -17,11 +16,14 @@ const RotateMixin = { this._rotationOriginPoint = _toPoint(this._map, this._rotationOriginLatLng); this._rotationStartPoint = _toPoint(this._map, e.target.getLatLng()); // we need to store the initial latlngs so we can always re-calc from the origin latlngs - this._initialRotateLatLng = copyLatLngs(this._layer); + this._initialRotateLatLng = L.PM.Utils._getCoords( + this._layer._map, + this._layer, + true + ); this._startAngle = this.getAngle(); - const originLatLngs = copyLatLngs( - this._rotationLayer, + const originLatLngs = L.PM.Utils.cloneLatLngs( this._rotationLayer.pm._rotateOrgLatLng ); @@ -66,9 +68,13 @@ const RotateMixin = { } forEachLatLng(this._layer.getLatLngs()); - const oldLatLngs = copyLatLngs(this._rotationLayer); + const oldLatLngs = L.PM.Utils._getCoords( + this._rotationLayer._map, + this._rotationLayer, + true + ); // rotate the origin layer - this._rotationLayer.setLatLngs( + this._rotationLayer.pm._handleRotate( this._rotateLayer( angleDiffRadiant, this._rotationLayer.pm._rotateOrgLatLng, @@ -96,12 +102,15 @@ const RotateMixin = { delete this._initialRotateLatLng; delete this._startAngle; - const originLatLngs = copyLatLngs( - this._rotationLayer, + const originLatLngs = L.PM.Utils.cloneLatLngs( this._rotationLayer.pm._rotateOrgLatLng ); // store the new latlngs - this._rotationLayer.pm._rotateOrgLatLng = copyLatLngs(this._rotationLayer); + this._rotationLayer.pm._rotateOrgLatLng = L.PM.Utils._getCoords( + this._rotationLayer._map, + this._rotationLayer, + true + ); this._fireRotationEnd(this._rotationLayer, startAngle, originLatLngs); this._fireRotationEnd(this._map, startAngle, originLatLngs); @@ -149,9 +158,10 @@ const RotateMixin = { }; // we create a temp polygon for rotation - this._rotatePoly = L.polygon(this._layer.getLatLngs(), options).addTo( - this._layer._map - ); + this._rotatePoly = L.polygon( + L.PM.Utils._getRotationOverlayCoords(this._layer._map, this._layer), + options + ).addTo(this._layer._map); this._rotatePoly.pm._setAngle(this.getAngle()); this._rotatePoly.pm.setOptions(this._layer._map.pm.getGlobalOptions()); this._rotatePoly.pm.setOptions({ @@ -164,7 +174,11 @@ const RotateMixin = { this._rotatePoly.pm.enable(); // store the original latlngs - this._rotateOrgLatLng = copyLatLngs(this._layer); + this._rotateOrgLatLng = L.PM.Utils._getCoords( + this._layer._map, + this._layer, + true + ); this._rotateEnabled = true; @@ -201,14 +215,18 @@ const RotateMixin = { this._layer.setLatLngs( this._rotateLayer( rads, - this._layer.getLatLngs(), + L.PM.Utils._getCoords(this._layer._map, this._layer), this._getRotationCenter(), L.PM.Matrix.init(), this._layer._map ) ); // store the new latlngs - this._rotateOrgLatLng = L.polygon(this._layer.getLatLngs()).getLatLngs(); + this._rotateOrgLatLng = L.PM.Utils._getCoords( + this._layer._map, + this._layer, + true + ); this._setAngle(this.getAngle() + angle); if ( this.rotateEnabled() && diff --git a/src/js/Mixins/Snapping.js b/src/js/Mixins/Snapping.js index 19331914..bf347007 100644 --- a/src/js/Mixins/Snapping.js +++ b/src/js/Mixins/Snapping.js @@ -183,10 +183,7 @@ const SnapMixin = { // temporary markers of polygon-edits map.eachLayer((layer) => { if ( - (layer instanceof L.Polyline || - layer instanceof L.Marker || - layer instanceof L.CircleMarker || - layer instanceof L.ImageOverlay) && + map.pm._allowedSnappingTypes.find((x) => layer instanceof x) && layer.options.snapIgnore !== true ) { // if snapIgnore === false the layer will be always snappable @@ -227,9 +224,8 @@ const SnapMixin = { layers = layers.filter((layer) => this._layer !== layer); // also remove everything that has no coordinates yet - layers = layers.filter( - (layer) => - layer._latlng || (layer._latlngs && !isEmptyDeep(layer._latlngs)) + layers = layers.filter((layer) => + this._map.pm._snappingFilters.find((filter) => filter(layer)) ); // finally remove everything that's leaflet-geoman specific temporary stuff @@ -270,7 +266,15 @@ const SnapMixin = { return; } // find the closest latlng, segment and the distance of this layer to the dragged marker latlng - const results = this._calcLayerDistances(latlng, layer); + //const results = this._calcLayerDistances(latlng, layer); + + const snappingDistanceFnc = this._map.pm._snappingDistanceFunctions.find( + (x) => layer instanceof x.type + ); + + const results = snappingDistanceFnc + ? snappingDistanceFnc.fnc(this, latlng, layer) + : this._calcLayerDistances(latlng, layer); if (this.debugIndicatorLines[index]) { // show indicator lines, it's for debugging @@ -308,8 +312,17 @@ const SnapMixin = { // the point P which we want to snap (probpably the marker that is dragged) const P = latlng; + let tracedLatlngs; + if (layer instanceof L.Curve) { + const traceArray = []; + for (let i = 0; i < 1; i += 0.0001) { + traceArray.push(i); + } + tracedLatlngs = layer.trace(traceArray); + } + // the coords of the layer - const latlngs = isMarker ? layer.getLatLng() : layer.getLatLngs(); + const latlngs = tracedLatlngs || L.PM.Utils._getCoords(map, layer); if (isMarker) { // return the info for the marker, no more calculations needed @@ -430,11 +443,18 @@ const SnapMixin = { // receives priority over C as the snapping point. Let's check this here _checkPrioritiySnapping(closestLayer) { const map = this._map; + if (!closestLayer.segment) { + return { ...closestLayer.latlng }; + } // A and B are the points of the closest segment to P (the marker position we want to snap) const A = closestLayer.segment[0]; const B = closestLayer.segment[1]; + if (!A || !B) { + return { ...closestLayer.latlng }; + } + // C is the point we would snap to on the segment. // The closest point on the closest segment of the closest polygon to P. That's right. const C = closestLayer.latlng; diff --git a/src/js/Mixins/index.js b/src/js/Mixins/index.js new file mode 100644 index 00000000..49262736 --- /dev/null +++ b/src/js/Mixins/index.js @@ -0,0 +1,15 @@ +import DragMixin from './Dragging'; +import SnapMixin from './Snapping'; +import RotateMixin from './Rotating'; +import EventMixin from './Events'; +import Keyboard from './Keyboard'; +import MarkerLimits from './MarkerLimits'; + +export default { + DragMixin, + SnapMixin, + RotateMixin, + EventMixin, + Keyboard, + MarkerLimits, +}; diff --git a/src/js/Toolbar/L.Controls.js b/src/js/Toolbar/L.Controls.js index 009d176b..f361431f 100644 --- a/src/js/Toolbar/L.Controls.js +++ b/src/js/Toolbar/L.Controls.js @@ -1,4 +1,3 @@ -import { getTranslation } from '../helpers'; import EventMixin from '../Mixins/Events'; const PMButton = L.Control.extend({ @@ -105,25 +104,25 @@ const PMButton = L.Control.extend({ const actions = { cancel: { - text: getTranslation('actions.cancel'), + text: L.PM.Translation.getTranslation('actions.cancel'), onClick() { this._triggerClick(); }, }, finishMode: { - text: getTranslation('actions.finish'), + text: L.PM.Translation.getTranslation('actions.finish'), onClick() { this._triggerClick(); }, }, removeLastVertex: { - text: getTranslation('actions.removeLastVertex'), + text: L.PM.Translation.getTranslation('actions.removeLastVertex'), onClick() { this._map.pm.Draw[button.jsClass]._removeLastVertex(); }, }, finish: { - text: getTranslation('actions.finish'), + text: L.PM.Translation.getTranslation('actions.finish'), onClick(e) { this._map.pm.Draw[button.jsClass]._finishShape(e); }, diff --git a/src/js/Toolbar/L.PM.Toolbar.js b/src/js/Toolbar/L.PM.Toolbar.js index 515a407e..06daee0f 100644 --- a/src/js/Toolbar/L.PM.Toolbar.js +++ b/src/js/Toolbar/L.PM.Toolbar.js @@ -1,7 +1,5 @@ import PMButton from './L.Controls'; -import { getTranslation } from '../helpers'; - L.Control.PMButton = PMButton; const Toolbar = L.Class.extend({ @@ -203,7 +201,7 @@ const Toolbar = L.Class.extend({ // some buttons are still in their respective classes, like L.PM.Draw.Polygon const drawMarkerButton = { className: 'control-icon leaflet-pm-icon-marker', - title: getTranslation('buttonTitles.drawMarkerButton'), + title: L.PM.Translation.getTranslation('buttonTitles.drawMarkerButton'), jsClass: 'Marker', onClick: () => {}, afterClick: (e, ctx) => { @@ -218,7 +216,7 @@ const Toolbar = L.Class.extend({ }; const drawPolyButton = { - title: getTranslation('buttonTitles.drawPolyButton'), + title: L.PM.Translation.getTranslation('buttonTitles.drawPolyButton'), className: 'control-icon leaflet-pm-icon-polygon', jsClass: 'Polygon', onClick: () => {}, @@ -235,7 +233,7 @@ const Toolbar = L.Class.extend({ const drawLineButton = { className: 'control-icon leaflet-pm-icon-polyline', - title: getTranslation('buttonTitles.drawLineButton'), + title: L.PM.Translation.getTranslation('buttonTitles.drawLineButton'), jsClass: 'Line', onClick: () => {}, afterClick: (e, ctx) => { @@ -250,7 +248,7 @@ const Toolbar = L.Class.extend({ }; const drawCircleButton = { - title: getTranslation('buttonTitles.drawCircleButton'), + title: L.PM.Translation.getTranslation('buttonTitles.drawCircleButton'), className: 'control-icon leaflet-pm-icon-circle', jsClass: 'Circle', onClick: () => {}, @@ -266,7 +264,7 @@ const Toolbar = L.Class.extend({ }; const drawCircleMarkerButton = { - title: getTranslation('buttonTitles.drawCircleMarkerButton'), + title: L.PM.Translation.getTranslation('buttonTitles.drawCircleMarkerButton'), className: 'control-icon leaflet-pm-icon-circle-marker', jsClass: 'CircleMarker', onClick: () => {}, @@ -282,7 +280,7 @@ const Toolbar = L.Class.extend({ }; const drawRectButton = { - title: getTranslation('buttonTitles.drawRectButton'), + title: L.PM.Translation.getTranslation('buttonTitles.drawRectButton'), className: 'control-icon leaflet-pm-icon-rectangle', jsClass: 'Rectangle', onClick: () => {}, @@ -298,7 +296,7 @@ const Toolbar = L.Class.extend({ }; const editButton = { - title: getTranslation('buttonTitles.editButton'), + title: L.PM.Translation.getTranslation('buttonTitles.editButton'), className: 'control-icon leaflet-pm-icon-edit', onClick: () => {}, afterClick: () => { @@ -313,7 +311,7 @@ const Toolbar = L.Class.extend({ }; const dragButton = { - title: getTranslation('buttonTitles.dragButton'), + title: L.PM.Translation.getTranslation('buttonTitles.dragButton'), className: 'control-icon leaflet-pm-icon-drag', onClick: () => {}, afterClick: () => { @@ -328,7 +326,7 @@ const Toolbar = L.Class.extend({ }; const cutButton = { - title: getTranslation('buttonTitles.cutButton'), + title: L.PM.Translation.getTranslation('buttonTitles.cutButton'), className: 'control-icon leaflet-pm-icon-cut', jsClass: 'Cut', onClick: () => {}, @@ -349,7 +347,7 @@ const Toolbar = L.Class.extend({ }; const deleteButton = { - title: getTranslation('buttonTitles.deleteButton'), + title: L.PM.Translation.getTranslation('buttonTitles.deleteButton'), className: 'control-icon leaflet-pm-icon-delete', onClick: () => {}, afterClick: () => { @@ -364,7 +362,7 @@ const Toolbar = L.Class.extend({ }; const rotateButton = { - title: getTranslation('buttonTitles.rotateButton'), + title: L.PM.Translation.getTranslation('buttonTitles.rotateButton'), className: 'control-icon leaflet-pm-icon-rotate', onClick: () => {}, afterClick: () => { diff --git a/src/js/helpers/index.js b/src/js/helpers/index.js index 3bfb1b5d..c2f71d19 100644 --- a/src/js/helpers/index.js +++ b/src/js/helpers/index.js @@ -1,16 +1,6 @@ import get from 'lodash/get'; import has from 'lodash/has'; -import translations from '../../assets/translations'; - -export function getTranslation(path) { - let lang = L.PM.activeLang; - - if (!has(translations, lang)) { - lang = 'en'; - } - - return get(translations[lang], path); -} +import merge from 'lodash/merge'; export function isEmptyDeep(l) { // thanks for the function, Felix Heck @@ -219,6 +209,9 @@ export function prioritiseSort(key, _sortingOrder, order = 'asc') { if (layer instanceof L.Polyline) { return 'Line'; } + if (layer instanceof L.Curve) { + return 'Curve'; + } return undefined; } @@ -249,13 +242,6 @@ export function prioritiseSort(key, _sortingOrder, order = 'asc') { }; } -export function copyLatLngs(layer, latlngs = layer.getLatLngs()) { - if (layer instanceof L.Polygon) { - return L.polygon(latlngs).getLatLngs(); - } - return L.polyline(latlngs).getLatLngs(); -} - // Replaces the lat value with the MAX_LATITUDE of CRS if it is lower / higher export function fixLatOffset(latlng, map) { if (map.options.crs?.projection?.MAX_LATITUDE) {