L.LineUtil._reducePoints = function (points, sqTolerance) { var reducedPoints = [points[0]]; for (var i = 1, prev = 0, len = points.length; i < len; i++) { if (this._sqDist(points[i], points[prev]) > sqTolerance) { reducedPoints.push(points[i]); prev = i; } } if (prev < len - 1) { reducedPoints.push(points[len - 1]); } return reducedPoints; }; L.Edit.Poly = L.Edit.Poly.extend({ options: { icon: new L.DivIcon({ iconSize: new L.Point(15, 15), className: 'abs-trackpoint-icon' }), iconMid: new L.DivIcon({ iconSize: new L.Point(15, 15), className: 'abs-trackpoint-icon mid' }), minZoom: 14, lastZoom: null, isInit: false }, initialize: function (poly, options) { var that = this; that._poly = poly; L.setOptions(this, options); application.controller.map.map.on('zoomend', that._checkZoom, that); that.lastZoom = application.controller.map.map.getZoom(); }, _checkZoom: function() { var zoom = application.controller.map.map.getZoom(); if (zoom >= this.options.minZoom && !this.options.isInit) { this.addHooks(); } else if (zoom < this.options.minZoom && this.options.isInit) { this.removeHooks(); this.options.isInit = false; } }, addHooks: function () { if (this._poly._map && this._poly.edit) { if (!this._markerGroup) { this._initMarkers(); } if (this._markerGroup) { this._poly._map.addLayer(this._markerGroup); } } }, removeHooks: function () { if (this._poly._map) { if (this._markerGroup) { this._poly._map.removeLayer(this._markerGroup); delete this._markerGroup; var track = this._poly.experience.track; this._poly.experience.track.isEditing = false; $(track.startMarker._icon).show(); $(track.endMarker._icon).show(); this._poly._map.fire('zoomend'); } delete this._markers; } }, updateMarkers: function () { this._markerGroup.clearLayers(); this._initMarkers(); }, _initMarkers: function() { if (application.controller.map.map.getZoom() >= this.options.minZoom) { var track = this._poly.experience.track; this._poly.experience.track.isEditing = true; $(track.startMarker._icon).hide(); $(track.endMarker._icon).hide(); if (!this._markerGroup) { this._markerGroup = new L.LayerGroup(); } this._markers = []; var latlngs = this._poly._latlngs, i, j, len, marker; // TODO refactor holes implementation in Polygon to support it here for (i = 0, len = latlngs.length; i < len; i++) { marker = this._createMarker(latlngs[i], i); if (!latlngs[i].ugChange) { marker.on('click', this._onMarkerClick, this); } else { marker.on('click', function() { var mText = 'Dieser Punkt kann wegen des Untergrundwechsels nicht gelöscht werden!'; var m = application.controller.message.addMessage('map', mText, 'warning', 3000); }); } this._markers.push(marker); } var markerLeft, markerRight; for (i = 0, j = len - 1; i < len; j = i++) { if (i === 0 && !(L.Polygon && (this._poly instanceof L.Polygon))) { continue; } markerLeft = this._markers[j]; markerRight = this._markers[i]; this._createMiddleMarker(markerLeft, markerRight); this._updatePrevNext(markerLeft, markerRight); } this.options.isInit = true; } }, _createMarker: function (latlng, index, type) { var icon = null; if (type !== undefined && type == 'mid') { icon = this.options.iconMid; } else { icon = this.options.icon; } var marker = new L.Marker(latlng, { draggable: true, icon: icon }); marker.getLatLng().ug = latlng.ug; marker.getLatLng().ele = latlng.ele; marker._origLatLng = latlng; marker._index = index; marker.on('drag', this._onMarkerDrag, this); marker.on('dragend', this._fireEdit, this); this._markerGroup.addLayer(marker); return marker; }, _fireEdit: function () { this._poly.fire('edit'); }, _onMarkerDrag: function (e) { var marker = e.target; L.extend(marker._origLatLng, marker._latlng); if (marker._middleLeft) { var latlng = this._getMiddleLatLng(marker._prev, marker); marker._middleLeft.setLatLng(latlng); } if (marker._middleRight) { var latlng = this._getMiddleLatLng(marker, marker._next); marker._middleRight.setLatLng(latlng); } this._poly.redraw(); if (this._poly.polyIn) { $.each(this._poly.polyIn, function(i, poly) { poly.redraw(); }); } }, _onMarkerClick: function (e) { // we want to remove the marker on click, but if latlng count < 3, polyline would be invalid if (this._poly._latlngs.length < 3) { return; } var marker = e.target, i = marker._index; var polyIn = null; var polyIndex = 0; $.each(this._poly.polyIn, function(ii, poly) { if (polyIn !== null) { return; } if (polyIndex <= i && i < polyIndex + poly.getLatLngs().length) { polyIn = poly; polyIn.startIndex = polyIndex; } polyIndex += poly.getLatLngs().length - 1; }); // remove the marker this._markerGroup.removeLayer(marker); this._markers.splice(i, 1); this._poly.spliceLatLngs(i, 1); if (polyIn) { polyIn.spliceLatLngs(i - polyIn.startIndex, 1); } this._updateIndexes(i, -1); // update prev/next links of adjacent markers this._updatePrevNext(marker._prev, marker._next); // remove ghost markers near the removed marker if (marker._middleLeft) { this._markerGroup.removeLayer(marker._middleLeft); } if (marker._middleRight) { this._markerGroup.removeLayer(marker._middleRight); } // create a ghost marker in place of the removed one if (marker._prev && marker._next) { this._createMiddleMarker(marker._prev, marker._next); } else if (!marker._prev) { marker._next._middleLeft = null; } else if (!marker._next) { marker._prev._middleRight = null; } this._poly.fire('edit'); }, _updateIndexes: function (index, delta) { this._markerGroup.eachLayer(function (marker) { if (marker._index > index) { marker._index += delta; } }); }, _createMiddleMarker: function (marker1, marker2) { var latlng = this._getMiddleLatLng(marker1, marker2), marker = this._createMarker(latlng, undefined, 'mid'), onClick, onDragStart, onDragEnd; marker1._middleRight = marker2._middleLeft = marker; onDragStart = function () { var i = marker2._index; marker._index = i; marker .off('click', onClick) .on('click', this._onMarkerClick, this); var polyIn = null; var polyIndex = 0; $.each(this._poly.polyIn, function(ii, poly) { if (polyIn !== null) { return; } if (polyIndex <= i && i < polyIndex + poly.getLatLngs().length) { polyIn = poly; polyIn.startIndex = polyIndex; } polyIndex += poly.getLatLngs().length - 1; }); latlng.lat = marker.getLatLng().lat; latlng.lng = marker.getLatLng().lng; this._poly.spliceLatLngs(i, 0, latlng); if (polyIn) { polyIn.spliceLatLngs(i - polyIn.startIndex, 0, latlng) } this._markers.splice(i, 0, marker); $(marker._icon).removeClass('mid'); this._updateIndexes(i, 1); marker2._index++; this._updatePrevNext(marker1, marker); this._updatePrevNext(marker, marker2); }; onDragEnd = function () { marker.off('dragstart', onDragStart, this); marker.off('dragend', onDragEnd, this); this._createMiddleMarker(marker1, marker); this._createMiddleMarker(marker, marker2); }; onClick = function () { onDragStart.call(this); onDragEnd.call(this); this._poly.fire('edit'); }; marker .on('click', onClick, this) .on('dragstart', onDragStart, this) .on('dragend', onDragEnd, this); this._markerGroup.addLayer(marker); }, _updatePrevNext: function (marker1, marker2) { if (marker1) { marker1._next = marker2; } if (marker2) { marker2._prev = marker1; } }, _getMiddleLatLng: function (marker1, marker2) { var map = this._poly._map; var latlng = new L.LatLng((marker1.getLatLng().lat + marker2.getLatLng().lat) / 2 , (marker1.getLatLng().lng + marker2.getLatLng().lng) / 2 ); latlng.ele = (marker1._origLatLng.ele + marker2._origLatLng.ele) / 2; latlng.ug = marker1._origLatLng.ug; return latlng; } })