Commit 80f25b4c authored by Santhanavanich's avatar Santhanavanich
Browse files

update

parent 63b0c450
Pipeline #6220 passed with stage
in 7 seconds
Showing with 2938 additions and 0 deletions
+2938 -0
L.SimpleShape = {};
/**
* @class L.Draw.SimpleShape
* @aka Draw.SimpleShape
* @inherits L.Draw.Feature
*/
L.Draw.SimpleShape = L.Draw.Feature.extend({
options: {
repeatMode: false
},
// @method initialize(): void
initialize: function (map, options) {
this._endLabelText = L.drawLocal.draw.handlers.simpleshape.tooltip.end;
L.Draw.Feature.prototype.initialize.call(this, map, options);
},
// @method addHooks(): void
// Add listener hooks to this handler.
addHooks: function () {
L.Draw.Feature.prototype.addHooks.call(this);
if (this._map) {
this._mapDraggable = this._map.dragging.enabled();
if (this._mapDraggable) {
this._map.dragging.disable();
}
//TODO refactor: move cursor to styles
this._container.style.cursor = 'crosshair';
this._tooltip.updateContent({text: this._initialLabelText});
this._map
.on('mousedown', this._onMouseDown, this)
.on('mousemove', this._onMouseMove, this)
.on('touchstart', this._onMouseDown, this)
.on('touchmove', this._onMouseMove, this);
// we should prevent default, otherwise default behavior (scrolling) will fire,
// and that will cause document.touchend to fire and will stop the drawing
// (circle, rectangle) in touch mode.
// (update): we have to send passive now to prevent scroll, because by default it is {passive: true} now, which means,
// handler can't event.preventDefault
// check the news https://developers.google.com/web/updates/2016/06/passive-event-listeners
document.addEventListener('touchstart', L.DomEvent.preventDefault, {passive: false});
}
},
// @method removeHooks(): void
// Remove listener hooks from this handler.
removeHooks: function () {
L.Draw.Feature.prototype.removeHooks.call(this);
if (this._map) {
if (this._mapDraggable) {
this._map.dragging.enable();
}
//TODO refactor: move cursor to styles
this._container.style.cursor = '';
this._map
.off('mousedown', this._onMouseDown, this)
.off('mousemove', this._onMouseMove, this)
.off('touchstart', this._onMouseDown, this)
.off('touchmove', this._onMouseMove, this);
L.DomEvent.off(document, 'mouseup', this._onMouseUp, this);
L.DomEvent.off(document, 'touchend', this._onMouseUp, this);
document.removeEventListener('touchstart', L.DomEvent.preventDefault);
// If the box element doesn't exist they must not have moved the mouse, so don't need to destroy/return
if (this._shape) {
this._map.removeLayer(this._shape);
delete this._shape;
}
}
this._isDrawing = false;
},
_getTooltipText: function () {
return {
text: this._endLabelText
};
},
_onMouseDown: function (e) {
this._isDrawing = true;
this._startLatLng = e.latlng;
L.DomEvent
.on(document, 'mouseup', this._onMouseUp, this)
.on(document, 'touchend', this._onMouseUp, this)
.preventDefault(e.originalEvent);
},
_onMouseMove: function (e) {
var latlng = e.latlng;
this._tooltip.updatePosition(latlng);
if (this._isDrawing) {
this._tooltip.updateContent(this._getTooltipText());
this._drawShape(latlng);
}
},
_onMouseUp: function () {
if (this._shape) {
this._fireCreatedEvent();
}
this.disable();
if (this.options.repeatMode) {
this.enable();
}
}
});
/*L.Map.mergeOptions({
editControl: true
});*/
/**
* @class L.EditToolbar
* @aka EditToolbar
*/
L.EditToolbar = L.Toolbar.extend({
statics: {
TYPE: 'edit'
},
options: {
edit: {
selectedPathOptions: {
dashArray: '10, 10',
fill: true,
fillColor: '#fe57a1',
fillOpacity: 0.1,
// Whether to user the existing layers color
maintainColor: false
}
},
remove: {},
poly: null,
featureGroup: null /* REQUIRED! TODO: perhaps if not set then all layers on the map are selectable? */
},
// @method intialize(): void
initialize: function (options) {
// Need to set this manually since null is an acceptable value here
if (options.edit) {
if (typeof options.edit.selectedPathOptions === 'undefined') {
options.edit.selectedPathOptions = this.options.edit.selectedPathOptions;
}
options.edit.selectedPathOptions = L.extend({}, this.options.edit.selectedPathOptions, options.edit.selectedPathOptions);
}
if (options.remove) {
options.remove = L.extend({}, this.options.remove, options.remove);
}
if (options.poly) {
options.poly = L.extend({}, this.options.poly, options.poly);
}
this._toolbarClass = 'leaflet-draw-edit';
L.Toolbar.prototype.initialize.call(this, options);
this._selectedFeatureCount = 0;
},
// @method getModeHandlers(): object
// Get mode handlers information
getModeHandlers: function (map) {
var featureGroup = this.options.featureGroup;
return [
{
enabled: this.options.edit,
handler: new L.EditToolbar.Edit(map, {
featureGroup: featureGroup,
selectedPathOptions: this.options.edit.selectedPathOptions,
poly: this.options.poly
}),
title: L.drawLocal.edit.toolbar.buttons.edit
},
{
enabled: this.options.remove,
handler: new L.EditToolbar.Delete(map, {
featureGroup: featureGroup
}),
title: L.drawLocal.edit.toolbar.buttons.remove
}
];
},
// @method getActions(): object
// Get actions information
getActions: function (handler) {
var actions = [
{
title: L.drawLocal.edit.toolbar.actions.save.title,
text: L.drawLocal.edit.toolbar.actions.save.text,
callback: this._save,
context: this
},
{
title: L.drawLocal.edit.toolbar.actions.cancel.title,
text: L.drawLocal.edit.toolbar.actions.cancel.text,
callback: this.disable,
context: this
}
];
if (handler.removeAllLayers) {
actions.push({
title: L.drawLocal.edit.toolbar.actions.clearAll.title,
text: L.drawLocal.edit.toolbar.actions.clearAll.text,
callback: this._clearAllLayers,
context: this
});
}
return actions;
},
// @method addToolbar(map): L.DomUtil
// Adds the toolbar to the map
addToolbar: function (map) {
var container = L.Toolbar.prototype.addToolbar.call(this, map);
this._checkDisabled();
this.options.featureGroup.on('layeradd layerremove', this._checkDisabled, this);
return container;
},
// @method removeToolbar(): void
// Removes the toolbar from the map
removeToolbar: function () {
this.options.featureGroup.off('layeradd layerremove', this._checkDisabled, this);
L.Toolbar.prototype.removeToolbar.call(this);
},
// @method disable(): void
// Disables the toolbar
disable: function () {
if (!this.enabled()) {
return;
}
this._activeMode.handler.revertLayers();
L.Toolbar.prototype.disable.call(this);
},
_save: function () {
this._activeMode.handler.save();
if (this._activeMode) {
this._activeMode.handler.disable();
}
},
_clearAllLayers: function () {
this._activeMode.handler.removeAllLayers();
if (this._activeMode) {
this._activeMode.handler.disable();
}
},
_checkDisabled: function () {
var featureGroup = this.options.featureGroup,
hasLayers = featureGroup.getLayers().length !== 0,
button;
if (this.options.edit) {
button = this._modes[L.EditToolbar.Edit.TYPE].button;
if (hasLayers) {
L.DomUtil.removeClass(button, 'leaflet-disabled');
} else {
L.DomUtil.addClass(button, 'leaflet-disabled');
}
button.setAttribute(
'title',
hasLayers ?
L.drawLocal.edit.toolbar.buttons.edit
: L.drawLocal.edit.toolbar.buttons.editDisabled
);
}
if (this.options.remove) {
button = this._modes[L.EditToolbar.Delete.TYPE].button;
if (hasLayers) {
L.DomUtil.removeClass(button, 'leaflet-disabled');
} else {
L.DomUtil.addClass(button, 'leaflet-disabled');
}
button.setAttribute(
'title',
hasLayers ?
L.drawLocal.edit.toolbar.buttons.remove
: L.drawLocal.edit.toolbar.buttons.removeDisabled
);
}
}
});
L.Edit = L.Edit || {};
/**
* @class L.Edit.Circle
* @aka Edit.Circle
* @inherits L.Edit.CircleMarker
*/
L.Edit.Circle = L.Edit.CircleMarker.extend({
_createResizeMarker: function () {
var center = this._shape.getLatLng(),
resizemarkerPoint = this._getResizeMarkerPoint(center);
this._resizeMarkers = [];
this._resizeMarkers.push(this._createMarker(resizemarkerPoint, this.options.resizeIcon));
},
_getResizeMarkerPoint: function (latlng) {
// From L.shape.getBounds()
var delta = this._shape._radius * Math.cos(Math.PI / 4),
point = this._map.project(latlng);
return this._map.unproject([point.x + delta, point.y - delta]);
},
_resize: function (latlng) {
var moveLatLng = this._moveMarker.getLatLng();
// Calculate the radius based on the version
if (L.GeometryUtil.isVersion07x()) {
radius = moveLatLng.distanceTo(latlng);
} else {
radius = this._map.distance(moveLatLng, latlng);
}
this._shape.setRadius(radius);
if (this._map.editTooltip) {
this._map._editTooltip.updateContent({
text: L.drawLocal.edit.handlers.edit.tooltip.subtext + '<br />' + L.drawLocal.edit.handlers.edit.tooltip.text,
subtext: L.drawLocal.draw.handlers.circle.radius + ': ' +
L.GeometryUtil.readableDistance(radius, true, this.options.feet, this.options.nautic)
});
}
this._shape.setRadius(radius);
this._map.fire(L.Draw.Event.EDITRESIZE, {layer: this._shape});
}
});
L.Circle.addInitHook(function () {
if (L.Edit.Circle) {
this.editing = new L.Edit.Circle(this);
if (this.options.editable) {
this.editing.enable();
}
}
});
L.Edit = L.Edit || {};
/**
* @class L.Edit.CircleMarker
* @aka Edit.Circle
* @inherits L.Edit.SimpleShape
*/
L.Edit.CircleMarker = L.Edit.SimpleShape.extend({
_createMoveMarker: function () {
var center = this._shape.getLatLng();
this._moveMarker = this._createMarker(center, this.options.moveIcon);
},
_createResizeMarker: function () {
// To avoid an undefined check in L.Edit.SimpleShape.removeHooks
this._resizeMarkers = [];
},
_move: function (latlng) {
if (this._resizeMarkers.length) {
var resizemarkerPoint = this._getResizeMarkerPoint(latlng);
// Move the resize marker
this._resizeMarkers[0].setLatLng(resizemarkerPoint);
}
// Move the circle
this._shape.setLatLng(latlng);
this._map.fire(L.Draw.Event.EDITMOVE, {layer: this._shape});
},
});
L.CircleMarker.addInitHook(function () {
if (L.Edit.CircleMarker) {
this.editing = new L.Edit.CircleMarker(this);
if (this.options.editable) {
this.editing.enable();
}
}
this.on('add', function () {
if (this.editing && this.editing.enabled()) {
this.editing.addHooks();
}
});
this.on('remove', function () {
if (this.editing && this.editing.enabled()) {
this.editing.removeHooks();
}
});
});
L.Edit = L.Edit || {};
/**
* @class L.Edit.Marker
* @aka Edit.Marker
*/
L.Edit.Marker = L.Handler.extend({
// @method initialize(): void
initialize: function (marker, options) {
this._marker = marker;
L.setOptions(this, options);
},
// @method addHooks(): void
// Add listener hooks to this handler
addHooks: function () {
var marker = this._marker;
marker.dragging.enable();
marker.on('dragend', this._onDragEnd, marker);
this._toggleMarkerHighlight();
},
// @method removeHooks(): void
// Remove listener hooks from this handler
removeHooks: function () {
var marker = this._marker;
marker.dragging.disable();
marker.off('dragend', this._onDragEnd, marker);
this._toggleMarkerHighlight();
},
_onDragEnd: function (e) {
var layer = e.target;
layer.edited = true;
this._map.fire(L.Draw.Event.EDITMOVE, {layer: layer});
},
_toggleMarkerHighlight: function () {
var icon = this._marker._icon;
// Don't do anything if this layer is a marker but doesn't have an icon. Markers
// should usually have icons. If using Leaflet.draw with Leaflet.markercluster there
// is a chance that a marker doesn't.
if (!icon) {
return;
}
// This is quite naughty, but I don't see another way of doing it. (short of setting a new icon)
icon.style.display = 'none';
if (L.DomUtil.hasClass(icon, 'leaflet-edit-marker-selected')) {
L.DomUtil.removeClass(icon, 'leaflet-edit-marker-selected');
// Offset as the border will make the icon move.
this._offsetMarker(icon, -4);
} else {
L.DomUtil.addClass(icon, 'leaflet-edit-marker-selected');
// Offset as the border will make the icon move.
this._offsetMarker(icon, 4);
}
icon.style.display = '';
},
_offsetMarker: function (icon, offset) {
var iconMarginTop = parseInt(icon.style.marginTop, 10) - offset,
iconMarginLeft = parseInt(icon.style.marginLeft, 10) - offset;
icon.style.marginTop = iconMarginTop + 'px';
icon.style.marginLeft = iconMarginLeft + 'px';
}
});
L.Marker.addInitHook(function () {
if (L.Edit.Marker) {
this.editing = new L.Edit.Marker(this);
if (this.options.editable) {
this.editing.enable();
}
}
});
L.Edit = L.Edit || {};
/**
* @class L.Edit.Polyline
* @aka L.Edit.Poly
* @aka Edit.Poly
*/
L.Edit.Poly = L.Handler.extend({
// @method initialize(): void
initialize: function (poly) {
this.latlngs = [poly._latlngs];
if (poly._holes) {
this.latlngs = this.latlngs.concat(poly._holes);
}
this._poly = poly;
this._poly.on('revert-edited', this._updateLatLngs, this);
},
// Compatibility method to normalize Poly* objects
// between 0.7.x and 1.0+
_defaultShape: function () {
if (!L.Polyline._flat) {
return this._poly._latlngs;
}
return L.Polyline._flat(this._poly._latlngs) ? this._poly._latlngs : this._poly._latlngs[0];
},
_eachVertexHandler: function (callback) {
for (var i = 0; i < this._verticesHandlers.length; i++) {
callback(this._verticesHandlers[i]);
}
},
// @method addHooks(): void
// Add listener hooks to this handler
addHooks: function () {
this._initHandlers();
this._eachVertexHandler(function (handler) {
handler.addHooks();
});
},
// @method removeHooks(): void
// Remove listener hooks from this handler
removeHooks: function () {
this._eachVertexHandler(function (handler) {
handler.removeHooks();
});
},
// @method updateMarkers(): void
// Fire an update for each vertex handler
updateMarkers: function () {
this._eachVertexHandler(function (handler) {
handler.updateMarkers();
});
},
_initHandlers: function () {
this._verticesHandlers = [];
for (var i = 0; i < this.latlngs.length; i++) {
this._verticesHandlers.push(new L.Edit.PolyVerticesEdit(this._poly, this.latlngs[i], this._poly.options.poly));
}
},
_updateLatLngs: function (e) {
this.latlngs = [e.layer._latlngs];
if (e.layer._holes) {
this.latlngs = this.latlngs.concat(e.layer._holes);
}
}
});
/**
* @class L.Edit.PolyVerticesEdit
* @aka Edit.PolyVerticesEdit
*/
L.Edit.PolyVerticesEdit = L.Handler.extend({
options: {
icon: new L.DivIcon({
iconSize: new L.Point(8, 8),
className: 'leaflet-div-icon leaflet-editing-icon'
}),
touchIcon: new L.DivIcon({
iconSize: new L.Point(20, 20),
className: 'leaflet-div-icon leaflet-editing-icon leaflet-touch-icon'
}),
drawError: {
color: '#b00b00',
timeout: 1000
}
},
// @method intialize(): void
initialize: function (poly, latlngs, options) {
// if touch, switch to touch icon
if (L.Browser.touch) {
this.options.icon = this.options.touchIcon;
}
this._poly = poly;
if (options && options.drawError) {
options.drawError = L.Util.extend({}, this.options.drawError, options.drawError);
}
this._latlngs = latlngs;
L.setOptions(this, options);
},
// Compatibility method to normalize Poly* objects
// between 0.7.x and 1.0+
_defaultShape: function () {
if (!L.Polyline._flat) {
return this._latlngs;
}
return L.Polyline._flat(this._latlngs) ? this._latlngs : this._latlngs[0];
},
// @method addHooks(): void
// Add listener hooks to this handler.
addHooks: function () {
var poly = this._poly;
var path = poly._path;
if (!(poly instanceof L.Polygon)) {
poly.options.fill = false;
if (poly.options.editing) {
poly.options.editing.fill = false;
}
}
if (path) {
if (poly.options.editing && poly.options.editing.className) {
if (poly.options.original.className) {
poly.options.original.className.split(' ').forEach(function (className) {
L.DomUtil.removeClass(path, className);
});
}
poly.options.editing.className.split(' ').forEach(function (className) {
L.DomUtil.addClass(path, className);
});
}
}
poly.setStyle(poly.options.editing);
if (this._poly._map) {
this._map = this._poly._map; // Set map
if (!this._markerGroup) {
this._initMarkers();
}
this._poly._map.addLayer(this._markerGroup);
}
},
// @method removeHooks(): void
// Remove listener hooks from this handler.
removeHooks: function () {
var poly = this._poly;
var path = poly._path;
if (path) {
if (poly.options.editing && poly.options.editing.className) {
poly.options.editing.className.split(' ').forEach(function (className) {
L.DomUtil.removeClass(path, className);
});
if (poly.options.original.className) {
poly.options.original.className.split(' ').forEach(function (className) {
L.DomUtil.addClass(path, className);
});
}
}
}
poly.setStyle(poly.options.original);
if (poly._map) {
poly._map.removeLayer(this._markerGroup);
delete this._markerGroup;
delete this._markers;
}
},
// @method updateMarkers(): void
// Clear markers and update their location
updateMarkers: function () {
this._markerGroup.clearLayers();
this._initMarkers();
},
_initMarkers: function () {
if (!this._markerGroup) {
this._markerGroup = new L.LayerGroup();
}
this._markers = [];
var latlngs = this._defaultShape(),
i, j, len, marker;
for (i = 0, len = latlngs.length; i < len; i++) {
marker = this._createMarker(latlngs[i], i);
marker.on('click', this._onMarkerClick, this);
marker.on('contextmenu', this._onContextMenu, this);
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);
}
},
_createMarker: function (latlng, index) {
// Extending L.Marker in TouchEvents.js to include touch.
var marker = new L.Marker.Touch(latlng, {
draggable: true,
icon: this.options.icon,
});
marker._origLatLng = latlng;
marker._index = index;
marker
.on('dragstart', this._onMarkerDragStart, this)
.on('drag', this._onMarkerDrag, this)
.on('dragend', this._fireEdit, this)
.on('touchmove', this._onTouchMove, this)
.on('touchend', this._fireEdit, this)
.on('MSPointerMove', this._onTouchMove, this)
.on('MSPointerUp', this._fireEdit, this);
this._markerGroup.addLayer(marker);
return marker;
},
_onMarkerDragStart: function () {
this._poly.fire('editstart');
},
_spliceLatLngs: function () {
var latlngs = this._defaultShape();
var removed = [].splice.apply(latlngs, arguments);
this._poly._convertLatLngs(latlngs, true);
this._poly.redraw();
return removed;
},
_removeMarker: function (marker) {
var i = marker._index;
this._markerGroup.removeLayer(marker);
this._markers.splice(i, 1);
this._spliceLatLngs(i, 1);
this._updateIndexes(i, -1);
marker
.off('dragstart', this._onMarkerDragStart, this)
.off('drag', this._onMarkerDrag, this)
.off('dragend', this._fireEdit, this)
.off('touchmove', this._onMarkerDrag, this)
.off('touchend', this._fireEdit, this)
.off('click', this._onMarkerClick, this)
.off('MSPointerMove', this._onTouchMove, this)
.off('MSPointerUp', this._fireEdit, this);
},
_fireEdit: function () {
this._poly.edited = true;
this._poly.fire('edit');
this._poly._map.fire(L.Draw.Event.EDITVERTEX, {layers: this._markerGroup, poly: this._poly});
},
_onMarkerDrag: function (e) {
var marker = e.target;
var poly = this._poly;
var oldOrigLatLng = L.LatLngUtil.cloneLatLng(marker._origLatLng);
L.extend(marker._origLatLng, marker._latlng);
if (poly.options.poly) {
var tooltip = poly._map._editTooltip; // Access the tooltip
// If we don't allow intersections and the polygon intersects
if (!poly.options.poly.allowIntersection && poly.intersects()) {
L.extend(marker._origLatLng, oldOrigLatLng);
marker.setLatLng(oldOrigLatLng);
var originalColor = poly.options.color;
poly.setStyle({color: this.options.drawError.color});
if (tooltip) {
tooltip.updateContent({
text: L.drawLocal.draw.handlers.polyline.error
});
}
// Reset everything back to normal after a second
setTimeout(function () {
poly.setStyle({color: originalColor});
if (tooltip) {
tooltip.updateContent({
text: L.drawLocal.edit.handlers.edit.tooltip.text,
subtext: L.drawLocal.edit.handlers.edit.tooltip.subtext
});
}
}, 1000);
}
}
if (marker._middleLeft) {
marker._middleLeft.setLatLng(this._getMiddleLatLng(marker._prev, marker));
}
if (marker._middleRight) {
marker._middleRight.setLatLng(this._getMiddleLatLng(marker, marker._next));
}
//refresh the bounds when draging
this._poly._bounds._southWest = L.latLng(Infinity, Infinity);
this._poly._bounds._northEast = L.latLng(-Infinity, -Infinity);
var latlngs = this._poly.getLatLngs();
this._poly._convertLatLngs(latlngs, true);
this._poly.redraw();
this._poly.fire('editdrag');
},
_onMarkerClick: function (e) {
var minPoints = L.Polygon && (this._poly instanceof L.Polygon) ? 4 : 3,
marker = e.target;
// If removing this point would create an invalid polyline/polygon don't remove
if (this._defaultShape().length < minPoints) {
return;
}
// remove the marker
this._removeMarker(marker);
// 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._fireEdit();
},
_onContextMenu: function (e) {
var marker = e.target;
var poly = this._poly;
this._poly._map.fire(L.Draw.Event.MARKERCONTEXT, {marker: marker, layers: this._markerGroup, poly: this._poly});
L.DomEvent.stopPropagation;
},
_onTouchMove: function (e) {
var layerPoint = this._map.mouseEventToLayerPoint(e.originalEvent.touches[0]),
latlng = this._map.layerPointToLatLng(layerPoint),
marker = e.target;
L.extend(marker._origLatLng, latlng);
if (marker._middleLeft) {
marker._middleLeft.setLatLng(this._getMiddleLatLng(marker._prev, marker));
}
if (marker._middleRight) {
marker._middleRight.setLatLng(this._getMiddleLatLng(marker, marker._next));
}
this._poly.redraw();
this.updateMarkers();
},
_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),
onClick,
onDragStart,
onDragEnd;
marker.setOpacity(0.6);
marker1._middleRight = marker2._middleLeft = marker;
onDragStart = function () {
marker.off('touchmove', onDragStart, this);
var i = marker2._index;
marker._index = i;
marker
.off('click', onClick, this)
.on('click', this._onMarkerClick, this);
latlng.lat = marker.getLatLng().lat;
latlng.lng = marker.getLatLng().lng;
this._spliceLatLngs(i, 0, latlng);
this._markers.splice(i, 0, marker);
marker.setOpacity(1);
this._updateIndexes(i, 1);
marker2._index++;
this._updatePrevNext(marker1, marker);
this._updatePrevNext(marker, marker2);
this._poly.fire('editstart');
};
onDragEnd = function () {
marker.off('dragstart', onDragStart, this);
marker.off('dragend', onDragEnd, this);
marker.off('touchmove', onDragStart, this);
this._createMiddleMarker(marker1, marker);
this._createMiddleMarker(marker, marker2);
};
onClick = function () {
onDragStart.call(this);
onDragEnd.call(this);
this._fireEdit();
};
marker
.on('click', onClick, this)
.on('dragstart', onDragStart, this)
.on('dragend', onDragEnd, this)
.on('touchmove', onDragStart, 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,
p1 = map.project(marker1.getLatLng()),
p2 = map.project(marker2.getLatLng());
return map.unproject(p1._add(p2)._divideBy(2));
}
});
L.Polyline.addInitHook(function () {
// Check to see if handler has already been initialized. This is to support versions of Leaflet that still have L.Handler.PolyEdit
if (this.editing) {
return;
}
if (L.Edit.Poly) {
this.editing = new L.Edit.Poly(this);
if (this.options.editable) {
this.editing.enable();
}
}
this.on('add', function () {
if (this.editing && this.editing.enabled()) {
this.editing.addHooks();
}
});
this.on('remove', function () {
if (this.editing && this.editing.enabled()) {
this.editing.removeHooks();
}
});
});
L.Edit = L.Edit || {};
/**
* @class L.Edit.Rectangle
* @aka Edit.Rectangle
* @inherits L.Edit.SimpleShape
*/
L.Edit.Rectangle = L.Edit.SimpleShape.extend({
_createMoveMarker: function () {
var bounds = this._shape.getBounds(),
center = bounds.getCenter();
this._moveMarker = this._createMarker(center, this.options.moveIcon);
},
_createResizeMarker: function () {
var corners = this._getCorners();
this._resizeMarkers = [];
for (var i = 0, l = corners.length; i < l; i++) {
this._resizeMarkers.push(this._createMarker(corners[i], this.options.resizeIcon));
// Monkey in the corner index as we will need to know this for dragging
this._resizeMarkers[i]._cornerIndex = i;
}
},
_onMarkerDragStart: function (e) {
L.Edit.SimpleShape.prototype._onMarkerDragStart.call(this, e);
// Save a reference to the opposite point
var corners = this._getCorners(),
marker = e.target,
currentCornerIndex = marker._cornerIndex;
this._oppositeCorner = corners[(currentCornerIndex + 2) % 4];
this._toggleCornerMarkers(0, currentCornerIndex);
},
_onMarkerDragEnd: function (e) {
var marker = e.target,
bounds, center;
// Reset move marker position to the center
if (marker === this._moveMarker) {
bounds = this._shape.getBounds();
center = bounds.getCenter();
marker.setLatLng(center);
}
this._toggleCornerMarkers(1);
this._repositionCornerMarkers();
L.Edit.SimpleShape.prototype._onMarkerDragEnd.call(this, e);
},
_move: function (newCenter) {
var latlngs = this._shape._defaultShape ? this._shape._defaultShape() : this._shape.getLatLngs(),
bounds = this._shape.getBounds(),
center = bounds.getCenter(),
offset, newLatLngs = [];
// Offset the latlngs to the new center
for (var i = 0, l = latlngs.length; i < l; i++) {
offset = [latlngs[i].lat - center.lat, latlngs[i].lng - center.lng];
newLatLngs.push([newCenter.lat + offset[0], newCenter.lng + offset[1]]);
}
this._shape.setLatLngs(newLatLngs);
// Reposition the resize markers
this._repositionCornerMarkers();
this._map.fire(L.Draw.Event.EDITMOVE, {layer: this._shape});
},
_resize: function (latlng) {
var bounds;
// Update the shape based on the current position of this corner and the opposite point
this._shape.setBounds(L.latLngBounds(latlng, this._oppositeCorner));
// Reposition the move marker
bounds = this._shape.getBounds();
this._moveMarker.setLatLng(bounds.getCenter());
this._map.fire(L.Draw.Event.EDITRESIZE, {layer: this._shape});
},
_getCorners: function () {
var bounds = this._shape.getBounds(),
nw = bounds.getNorthWest(),
ne = bounds.getNorthEast(),
se = bounds.getSouthEast(),
sw = bounds.getSouthWest();
return [nw, ne, se, sw];
},
_toggleCornerMarkers: function (opacity) {
for (var i = 0, l = this._resizeMarkers.length; i < l; i++) {
this._resizeMarkers[i].setOpacity(opacity);
}
},
_repositionCornerMarkers: function () {
var corners = this._getCorners();
for (var i = 0, l = this._resizeMarkers.length; i < l; i++) {
this._resizeMarkers[i].setLatLng(corners[i]);
}
}
});
L.Rectangle.addInitHook(function () {
if (L.Edit.Rectangle) {
this.editing = new L.Edit.Rectangle(this);
if (this.options.editable) {
this.editing.enable();
}
}
});
L.Edit = L.Edit || {};
/**
* @class L.Edit.SimpleShape
* @aka Edit.SimpleShape
*/
L.Edit.SimpleShape = L.Handler.extend({
options: {
moveIcon: new L.DivIcon({
iconSize: new L.Point(8, 8),
className: 'leaflet-div-icon leaflet-editing-icon leaflet-edit-move'
}),
resizeIcon: new L.DivIcon({
iconSize: new L.Point(8, 8),
className: 'leaflet-div-icon leaflet-editing-icon leaflet-edit-resize'
}),
touchMoveIcon: new L.DivIcon({
iconSize: new L.Point(20, 20),
className: 'leaflet-div-icon leaflet-editing-icon leaflet-edit-move leaflet-touch-icon'
}),
touchResizeIcon: new L.DivIcon({
iconSize: new L.Point(20, 20),
className: 'leaflet-div-icon leaflet-editing-icon leaflet-edit-resize leaflet-touch-icon'
}),
},
// @method intialize(): void
initialize: function (shape, options) {
// if touch, switch to touch icon
if (L.Browser.touch) {
this.options.moveIcon = this.options.touchMoveIcon;
this.options.resizeIcon = this.options.touchResizeIcon;
}
this._shape = shape;
L.Util.setOptions(this, options);
},
// @method addHooks(): void
// Add listener hooks to this handler
addHooks: function () {
var shape = this._shape;
if (this._shape._map) {
this._map = this._shape._map;
shape.setStyle(shape.options.editing);
if (shape._map) {
this._map = shape._map;
if (!this._markerGroup) {
this._initMarkers();
}
this._map.addLayer(this._markerGroup);
}
}
},
// @method removeHooks(): void
// Remove listener hooks from this handler
removeHooks: function () {
var shape = this._shape;
shape.setStyle(shape.options.original);
if (shape._map) {
this._unbindMarker(this._moveMarker);
for (var i = 0, l = this._resizeMarkers.length; i < l; i++) {
this._unbindMarker(this._resizeMarkers[i]);
}
this._resizeMarkers = null;
this._map.removeLayer(this._markerGroup);
delete this._markerGroup;
}
this._map = null;
},
// @method updateMarkers(): void
// Remove the edit markers from this layer
updateMarkers: function () {
this._markerGroup.clearLayers();
this._initMarkers();
},
_initMarkers: function () {
if (!this._markerGroup) {
this._markerGroup = new L.LayerGroup();
}
// Create center marker
this._createMoveMarker();
// Create edge marker
this._createResizeMarker();
},
_createMoveMarker: function () {
// Children override
},
_createResizeMarker: function () {
// Children override
},
_createMarker: function (latlng, icon) {
// Extending L.Marker in TouchEvents.js to include touch.
var marker = new L.Marker.Touch(latlng, {
draggable: true,
icon: icon,
zIndexOffset: 10
});
this._bindMarker(marker);
this._markerGroup.addLayer(marker);
return marker;
},
_bindMarker: function (marker) {
marker
.on('dragstart', this._onMarkerDragStart, this)
.on('drag', this._onMarkerDrag, this)
.on('dragend', this._onMarkerDragEnd, this)
.on('touchstart', this._onTouchStart, this)
.on('touchmove', this._onTouchMove, this)
.on('MSPointerMove', this._onTouchMove, this)
.on('touchend', this._onTouchEnd, this)
.on('MSPointerUp', this._onTouchEnd, this);
},
_unbindMarker: function (marker) {
marker
.off('dragstart', this._onMarkerDragStart, this)
.off('drag', this._onMarkerDrag, this)
.off('dragend', this._onMarkerDragEnd, this)
.off('touchstart', this._onTouchStart, this)
.off('touchmove', this._onTouchMove, this)
.off('MSPointerMove', this._onTouchMove, this)
.off('touchend', this._onTouchEnd, this)
.off('MSPointerUp', this._onTouchEnd, this);
},
_onMarkerDragStart: function (e) {
var marker = e.target;
marker.setOpacity(0);
this._shape.fire('editstart');
},
_fireEdit: function () {
this._shape.edited = true;
this._shape.fire('edit');
},
_onMarkerDrag: function (e) {
var marker = e.target,
latlng = marker.getLatLng();
if (marker === this._moveMarker) {
this._move(latlng);
} else {
this._resize(latlng);
}
this._shape.redraw();
this._shape.fire('editdrag');
},
_onMarkerDragEnd: function (e) {
var marker = e.target;
marker.setOpacity(1);
this._fireEdit();
},
_onTouchStart: function (e) {
L.Edit.SimpleShape.prototype._onMarkerDragStart.call(this, e);
if (typeof(this._getCorners) === 'function') {
// Save a reference to the opposite point
var corners = this._getCorners(),
marker = e.target,
currentCornerIndex = marker._cornerIndex;
marker.setOpacity(0);
// Copyed from Edit.Rectangle.js line 23 _onMarkerDragStart()
// Latlng is null otherwise.
this._oppositeCorner = corners[(currentCornerIndex + 2) % 4];
this._toggleCornerMarkers(0, currentCornerIndex);
}
this._shape.fire('editstart');
},
_onTouchMove: function (e) {
var layerPoint = this._map.mouseEventToLayerPoint(e.originalEvent.touches[0]),
latlng = this._map.layerPointToLatLng(layerPoint),
marker = e.target;
if (marker === this._moveMarker) {
this._move(latlng);
} else {
this._resize(latlng);
}
this._shape.redraw();
// prevent touchcancel in IOS
// e.preventDefault();
return false;
},
_onTouchEnd: function (e) {
var marker = e.target;
marker.setOpacity(1);
this.updateMarkers();
this._fireEdit();
},
_move: function () {
// Children override
},
_resize: function () {
// Children override
}
});
/**
* @class L.EditToolbar.Delete
* @aka EditToolbar.Delete
*/
L.EditToolbar.Delete = L.Handler.extend({
statics: {
TYPE: 'remove' // not delete as delete is reserved in js
},
// @method intialize(): void
initialize: function (map, options) {
L.Handler.prototype.initialize.call(this, map);
L.Util.setOptions(this, options);
// Store the selectable layer group for ease of access
this._deletableLayers = this.options.featureGroup;
if (!(this._deletableLayers instanceof L.FeatureGroup)) {
throw new Error('options.featureGroup must be a L.FeatureGroup');
}
// Save the type so super can fire, need to do this as cannot do this.TYPE :(
this.type = L.EditToolbar.Delete.TYPE;
var version = L.version.split('.');
//If Version is >= 1.2.0
if (parseInt(version[0], 10) === 1 && parseInt(version[1], 10) >= 2) {
L.EditToolbar.Delete.include(L.Evented.prototype);
} else {
L.EditToolbar.Delete.include(L.Mixin.Events);
}
},
// @method enable(): void
// Enable the delete toolbar
enable: function () {
if (this._enabled || !this._hasAvailableLayers()) {
return;
}
this.fire('enabled', {handler: this.type});
this._map.fire(L.Draw.Event.DELETESTART, {handler: this.type});
L.Handler.prototype.enable.call(this);
this._deletableLayers
.on('layeradd', this._enableLayerDelete, this)
.on('layerremove', this._disableLayerDelete, this);
},
// @method disable(): void
// Disable the delete toolbar
disable: function () {
if (!this._enabled) {
return;
}
this._deletableLayers
.off('layeradd', this._enableLayerDelete, this)
.off('layerremove', this._disableLayerDelete, this);
L.Handler.prototype.disable.call(this);
this._map.fire(L.Draw.Event.DELETESTOP, {handler: this.type});
this.fire('disabled', {handler: this.type});
},
// @method addHooks(): void
// Add listener hooks to this handler
addHooks: function () {
var map = this._map;
if (map) {
map.getContainer().focus();
this._deletableLayers.eachLayer(this._enableLayerDelete, this);
this._deletedLayers = new L.LayerGroup();
this._tooltip = new L.Draw.Tooltip(this._map);
this._tooltip.updateContent({text: L.drawLocal.edit.handlers.remove.tooltip.text});
this._map.on('mousemove', this._onMouseMove, this);
}
},
// @method removeHooks(): void
// Remove listener hooks from this handler
removeHooks: function () {
if (this._map) {
this._deletableLayers.eachLayer(this._disableLayerDelete, this);
this._deletedLayers = null;
this._tooltip.dispose();
this._tooltip = null;
this._map.off('mousemove', this._onMouseMove, this);
}
},
// @method revertLayers(): void
// Revert the deleted layers back to their prior state.
revertLayers: function () {
// Iterate of the deleted layers and add them back into the featureGroup
this._deletedLayers.eachLayer(function (layer) {
this._deletableLayers.addLayer(layer);
layer.fire('revert-deleted', {layer: layer});
}, this);
},
// @method save(): void
// Save deleted layers
save: function () {
this._map.fire(L.Draw.Event.DELETED, {layers: this._deletedLayers});
},
// @method removeAllLayers(): void
// Remove all delateable layers
removeAllLayers: function () {
// Iterate of the delateable layers and add remove them
this._deletableLayers.eachLayer(function (layer) {
this._removeLayer({layer: layer});
}, this);
this.save();
},
_enableLayerDelete: function (e) {
var layer = e.layer || e.target || e;
layer.on('click', this._removeLayer, this);
},
_disableLayerDelete: function (e) {
var layer = e.layer || e.target || e;
layer.off('click', this._removeLayer, this);
// Remove from the deleted layers so we can't accidentally revert if the user presses cancel
this._deletedLayers.removeLayer(layer);
},
_removeLayer: function (e) {
var layer = e.layer || e.target || e;
this._deletableLayers.removeLayer(layer);
this._deletedLayers.addLayer(layer);
layer.fire('deleted');
},
_onMouseMove: function (e) {
this._tooltip.updatePosition(e.latlng);
},
_hasAvailableLayers: function () {
return this._deletableLayers.getLayers().length !== 0;
}
});
/**
* @class L.EditToolbar.Edit
* @aka EditToolbar.Edit
*/
L.EditToolbar.Edit = L.Handler.extend({
statics: {
TYPE: 'edit'
},
// @method intialize(): void
initialize: function (map, options) {
L.Handler.prototype.initialize.call(this, map);
L.setOptions(this, options);
// Store the selectable layer group for ease of access
this._featureGroup = options.featureGroup;
if (!(this._featureGroup instanceof L.FeatureGroup)) {
throw new Error('options.featureGroup must be a L.FeatureGroup');
}
this._uneditedLayerProps = {};
// Save the type so super can fire, need to do this as cannot do this.TYPE :(
this.type = L.EditToolbar.Edit.TYPE;
var version = L.version.split('.');
//If Version is >= 1.2.0
if (parseInt(version[0], 10) === 1 && parseInt(version[1], 10) >= 2) {
L.EditToolbar.Edit.include(L.Evented.prototype);
} else {
L.EditToolbar.Edit.include(L.Mixin.Events);
}
},
// @method enable(): void
// Enable the edit toolbar
enable: function () {
if (this._enabled || !this._hasAvailableLayers()) {
return;
}
this.fire('enabled', {handler: this.type});
//this disable other handlers
this._map.fire(L.Draw.Event.EDITSTART, {handler: this.type});
//allow drawLayer to be updated before beginning edition.
L.Handler.prototype.enable.call(this);
this._featureGroup
.on('layeradd', this._enableLayerEdit, this)
.on('layerremove', this._disableLayerEdit, this);
},
// @method disable(): void
// Disable the edit toolbar
disable: function () {
if (!this._enabled) {
return;
}
this._featureGroup
.off('layeradd', this._enableLayerEdit, this)
.off('layerremove', this._disableLayerEdit, this);
L.Handler.prototype.disable.call(this);
this._map.fire(L.Draw.Event.EDITSTOP, {handler: this.type});
this.fire('disabled', {handler: this.type});
},
// @method addHooks(): void
// Add listener hooks for this handler
addHooks: function () {
var map = this._map;
if (map) {
map.getContainer().focus();
this._featureGroup.eachLayer(this._enableLayerEdit, this);
this._tooltip = new L.Draw.Tooltip(this._map);
this._tooltip.updateContent({
text: L.drawLocal.edit.handlers.edit.tooltip.text,
subtext: L.drawLocal.edit.handlers.edit.tooltip.subtext
});
// Quickly access the tooltip to update for intersection checking
map._editTooltip = this._tooltip;
this._updateTooltip();
this._map
.on('mousemove', this._onMouseMove, this)
.on('touchmove', this._onMouseMove, this)
.on('MSPointerMove', this._onMouseMove, this)
.on(L.Draw.Event.EDITVERTEX, this._updateTooltip, this);
}
},
// @method removeHooks(): void
// Remove listener hooks for this handler
removeHooks: function () {
if (this._map) {
// Clean up selected layers.
this._featureGroup.eachLayer(this._disableLayerEdit, this);
// Clear the backups of the original layers
this._uneditedLayerProps = {};
this._tooltip.dispose();
this._tooltip = null;
this._map
.off('mousemove', this._onMouseMove, this)
.off('touchmove', this._onMouseMove, this)
.off('MSPointerMove', this._onMouseMove, this)
.off(L.Draw.Event.EDITVERTEX, this._updateTooltip, this);
}
},
// @method revertLayers(): void
// Revert each layer's geometry changes
revertLayers: function () {
this._featureGroup.eachLayer(function (layer) {
this._revertLayer(layer);
}, this);
},
// @method save(): void
// Save the layer geometries
save: function () {
var editedLayers = new L.LayerGroup();
this._featureGroup.eachLayer(function (layer) {
if (layer.edited) {
editedLayers.addLayer(layer);
layer.edited = false;
}
});
this._map.fire(L.Draw.Event.EDITED, {layers: editedLayers});
},
_backupLayer: function (layer) {
var id = L.Util.stamp(layer);
if (!this._uneditedLayerProps[id]) {
// Polyline, Polygon or Rectangle
if (layer instanceof L.Polyline || layer instanceof L.Polygon || layer instanceof L.Rectangle) {
this._uneditedLayerProps[id] = {
latlngs: L.LatLngUtil.cloneLatLngs(layer.getLatLngs())
};
} else if (layer instanceof L.Circle) {
this._uneditedLayerProps[id] = {
latlng: L.LatLngUtil.cloneLatLng(layer.getLatLng()),
radius: layer.getRadius()
};
} else if (layer instanceof L.Marker || layer instanceof L.CircleMarker) { // Marker
this._uneditedLayerProps[id] = {
latlng: L.LatLngUtil.cloneLatLng(layer.getLatLng())
};
}
}
},
_getTooltipText: function () {
return ({
text: L.drawLocal.edit.handlers.edit.tooltip.text,
subtext: L.drawLocal.edit.handlers.edit.tooltip.subtext
});
},
_updateTooltip: function () {
this._tooltip.updateContent(this._getTooltipText());
},
_revertLayer: function (layer) {
var id = L.Util.stamp(layer);
layer.edited = false;
if (this._uneditedLayerProps.hasOwnProperty(id)) {
// Polyline, Polygon or Rectangle
if (layer instanceof L.Polyline || layer instanceof L.Polygon || layer instanceof L.Rectangle) {
layer.setLatLngs(this._uneditedLayerProps[id].latlngs);
} else if (layer instanceof L.Circle) {
layer.setLatLng(this._uneditedLayerProps[id].latlng);
layer.setRadius(this._uneditedLayerProps[id].radius);
} else if (layer instanceof L.Marker || layer instanceof L.CircleMarker) { // Marker or CircleMarker
layer.setLatLng(this._uneditedLayerProps[id].latlng);
}
layer.fire('revert-edited', {layer: layer});
}
},
_enableLayerEdit: function (e) {
var layer = e.layer || e.target || e,
pathOptions, poly;
// Back up this layer (if haven't before)
this._backupLayer(layer);
if (this.options.poly) {
poly = L.Util.extend({}, this.options.poly);
layer.options.poly = poly;
}
// Set different style for editing mode
if (this.options.selectedPathOptions) {
pathOptions = L.Util.extend({}, this.options.selectedPathOptions);
// Use the existing color of the layer
if (pathOptions.maintainColor) {
pathOptions.color = layer.options.color;
pathOptions.fillColor = layer.options.fillColor;
}
layer.options.original = L.extend({}, layer.options);
layer.options.editing = pathOptions;
}
if (layer instanceof L.Marker) {
if (layer.editing) {
layer.editing.enable();
}
layer.dragging.enable();
layer
.on('dragend', this._onMarkerDragEnd)
// #TODO: remove when leaflet finally fixes their draggable so it's touch friendly again.
.on('touchmove', this._onTouchMove, this)
.on('MSPointerMove', this._onTouchMove, this)
.on('touchend', this._onMarkerDragEnd, this)
.on('MSPointerUp', this._onMarkerDragEnd, this);
} else {
layer.editing.enable();
}
},
_disableLayerEdit: function (e) {
var layer = e.layer || e.target || e;
layer.edited = false;
if (layer.editing) {
layer.editing.disable();
}
delete layer.options.editing;
delete layer.options.original;
// Reset layer styles to that of before select
if (this._selectedPathOptions) {
if (layer instanceof L.Marker) {
this._toggleMarkerHighlight(layer);
} else {
// reset the layer style to what is was before being selected
layer.setStyle(layer.options.previousOptions);
// remove the cached options for the layer object
delete layer.options.previousOptions;
}
}
if (layer instanceof L.Marker) {
layer.dragging.disable();
layer
.off('dragend', this._onMarkerDragEnd, this)
.off('touchmove', this._onTouchMove, this)
.off('MSPointerMove', this._onTouchMove, this)
.off('touchend', this._onMarkerDragEnd, this)
.off('MSPointerUp', this._onMarkerDragEnd, this);
} else {
layer.editing.disable();
}
},
_onMouseMove: function (e) {
this._tooltip.updatePosition(e.latlng);
},
_onMarkerDragEnd: function (e) {
var layer = e.target;
layer.edited = true;
this._map.fire(L.Draw.Event.EDITMOVE, {layer: layer});
},
_onTouchMove: function (e) {
var touchEvent = e.originalEvent.changedTouches[0],
layerPoint = this._map.mouseEventToLayerPoint(touchEvent),
latlng = this._map.layerPointToLatLng(layerPoint);
e.target.setLatLng(latlng);
},
_hasAvailableLayers: function () {
return this._featureGroup.getLayers().length !== 0;
}
});
(function () {
var defaultPrecision = {
km: 2,
ha: 2,
m: 0,
mi: 2,
ac: 2,
yd: 0,
ft: 0,
nm: 2
};
/**
* @class L.GeometryUtil
* @aka GeometryUtil
*/
L.GeometryUtil = L.extend(L.GeometryUtil || {}, {
// Ported from the OpenLayers implementation. See https://github.com/openlayers/openlayers/blob/master/lib/OpenLayers/Geometry/LinearRing.js#L270
// @method geodesicArea(): number
geodesicArea: function (latLngs) {
var pointsCount = latLngs.length,
area = 0.0,
d2r = Math.PI / 180,
p1, p2;
if (pointsCount > 2) {
for (var i = 0; i < pointsCount; i++) {
p1 = latLngs[i];
p2 = latLngs[(i + 1) % pointsCount];
area += ((p2.lng - p1.lng) * d2r) *
(2 + Math.sin(p1.lat * d2r) + Math.sin(p2.lat * d2r));
}
area = area * 6378137.0 * 6378137.0 / 2.0;
}
return Math.abs(area);
},
// @method formattedNumber(n, precision): string
// Returns n in specified number format (if defined) and precision
formattedNumber: function (n, precision) {
var formatted = parseFloat(n).toFixed(precision),
format = L.drawLocal.format && L.drawLocal.format.numeric,
delimiters = format && format.delimiters,
thousands = delimiters && delimiters.thousands,
decimal = delimiters && delimiters.decimal;
if (thousands || decimal) {
var splitValue = formatted.split('.');
formatted = thousands ? splitValue[0].replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1' + thousands) : splitValue[0];
decimal = decimal || '.';
if (splitValue.length > 1) {
formatted = formatted + decimal + splitValue[1];
}
}
return formatted;
},
// @method readableArea(area, isMetric, precision): string
// Returns a readable area string in yards or metric.
// The value will be rounded as defined by the precision option object.
readableArea: function (area, isMetric, precision) {
var areaStr,
units,
precision = L.Util.extend({}, defaultPrecision, precision);
if (isMetric) {
units = ['ha', 'm'];
type = typeof isMetric;
if (type === 'string') {
units = [isMetric];
} else if (type !== 'boolean') {
units = isMetric;
}
if (area >= 1000000 && units.indexOf('km') !== -1) {
areaStr = L.GeometryUtil.formattedNumber(area * 0.000001, precision['km']) + ' km²';
} else if (area >= 10000 && units.indexOf('ha') !== -1) {
areaStr = L.GeometryUtil.formattedNumber(area * 0.0001, precision['ha']) + ' ha';
} else {
areaStr = L.GeometryUtil.formattedNumber(area, precision['m']) + '';
}
} else {
area /= 0.836127; // Square yards in 1 meter
if (area >= 3097600) { //3097600 square yards in 1 square mile
areaStr = L.GeometryUtil.formattedNumber(area / 3097600, precision['mi']) + ' mi²';
} else if (area >= 4840) { //4840 square yards in 1 acre
areaStr = L.GeometryUtil.formattedNumber(area / 4840, precision['ac']) + ' acres';
} else {
areaStr = L.GeometryUtil.formattedNumber(area, precision['yd']) + ' yd²';
}
}
return areaStr;
},
// @method readableDistance(distance, units): string
// Converts a metric distance to one of [ feet, nauticalMile, metric or yards ] string
//
// @alternative
// @method readableDistance(distance, isMetric, useFeet, isNauticalMile, precision): string
// Converts metric distance to distance string.
// The value will be rounded as defined by the precision option object.
readableDistance: function (distance, isMetric, isFeet, isNauticalMile, precision) {
var distanceStr,
units,
precision = L.Util.extend({}, defaultPrecision, precision);
if (isMetric) {
units = typeof isMetric == 'string' ? isMetric : 'metric';
} else if (isFeet) {
units = 'feet';
} else if (isNauticalMile) {
units = 'nauticalMile';
} else {
units = 'yards';
}
switch (units) {
case 'metric':
// show metres when distance is < 1km, then show km
if (distance > 1000) {
distanceStr = L.GeometryUtil.formattedNumber(distance / 1000, precision['km']) + ' km';
} else {
distanceStr = L.GeometryUtil.formattedNumber(distance, precision['m']) + ' m';
}
break;
case 'feet':
distance *= 1.09361 * 3;
distanceStr = L.GeometryUtil.formattedNumber(distance, precision['ft']) + ' ft';
break;
case 'nauticalMile':
distance *= 0.53996;
distanceStr = L.GeometryUtil.formattedNumber(distance / 1000, precision['nm']) + ' nm';
break;
case 'yards':
default:
distance *= 1.09361;
if (distance > 1760) {
distanceStr = L.GeometryUtil.formattedNumber(distance / 1760, precision['mi']) + ' miles';
} else {
distanceStr = L.GeometryUtil.formattedNumber(distance, precision['yd']) + ' yd';
}
break;
}
return distanceStr;
},
// @method isVersion07x(): boolean
// Returns true if the Leaflet version is 0.7.x, false otherwise.
isVersion07x: function () {
var version = L.version.split('.');
//If Version is == 0.7.*
return parseInt(version[0], 10) === 0 && parseInt(version[1], 10) === 7;
},
});
})();
/**
* @class L.LatLngUtil
* @aka LatLngUtil
*/
L.LatLngUtil = {
// Clones a LatLngs[], returns [][]
// @method cloneLatLngs(LatLngs[]): L.LatLngs[]
// Clone the latLng point or points or nested points and return an array with those points
cloneLatLngs: function (latlngs) {
var clone = [];
for (var i = 0, l = latlngs.length; i < l; i++) {
// Check for nested array (Polyline/Polygon)
if (Array.isArray(latlngs[i])) {
clone.push(L.LatLngUtil.cloneLatLngs(latlngs[i]));
} else {
clone.push(this.cloneLatLng(latlngs[i]));
}
}
return clone;
},
// @method cloneLatLng(LatLng): L.LatLng
// Clone the latLng and return a new LatLng object.
cloneLatLng: function (latlng) {
return L.latLng(latlng.lat, latlng.lng);
}
};
/**
* @class L.LineUtil
* @aka Util
* @aka L.Utils
*/
L.Util.extend(L.LineUtil, {
// @method segmentsIntersect(): boolean
// Checks to see if two line segments intersect. Does not handle degenerate cases.
// http://compgeom.cs.uiuc.edu/~jeffe/teaching/373/notes/x06-sweepline.pdf
segmentsIntersect: function (/*Point*/ p, /*Point*/ p1, /*Point*/ p2, /*Point*/ p3) {
return this._checkCounterclockwise(p, p2, p3) !==
this._checkCounterclockwise(p1, p2, p3) &&
this._checkCounterclockwise(p, p1, p2) !==
this._checkCounterclockwise(p, p1, p3);
},
// check to see if points are in counterclockwise order
_checkCounterclockwise: function (/*Point*/ p, /*Point*/ p1, /*Point*/ p2) {
return (p2.y - p.y) * (p1.x - p.x) > (p1.y - p.y) * (p2.x - p.x);
}
});
/**
* @class L.Polygon
* @aka Polygon
*/
L.Polygon.include({
// @method intersects(): boolean
// Checks a polygon for any intersecting line segments. Ignores holes.
intersects: function () {
var polylineIntersects,
points = this._getProjectedPoints(),
len, firstPoint, lastPoint, maxIndex;
if (this._tooFewPointsForIntersection()) {
return false;
}
polylineIntersects = L.Polyline.prototype.intersects.call(this);
// If already found an intersection don't need to check for any more.
if (polylineIntersects) {
return true;
}
len = points.length;
firstPoint = points[0];
lastPoint = points[len - 1];
maxIndex = len - 2;
// Check the line segment between last and first point. Don't need to check the first line segment (minIndex = 1)
return this._lineSegmentsIntersectsRange(lastPoint, firstPoint, maxIndex, 1);
}
});
/**
* @class L.Polyline
* @aka Polyline
*/
L.Polyline.include({
// @method intersects(): boolean
// Check to see if this polyline has any linesegments that intersect.
// NOTE: does not support detecting intersection for degenerate cases.
intersects: function () {
var points = this._getProjectedPoints(),
len = points ? points.length : 0,
i, p, p1;
if (this._tooFewPointsForIntersection()) {
return false;
}
for (i = len - 1; i >= 3; i--) {
p = points[i - 1];
p1 = points[i];
if (this._lineSegmentsIntersectsRange(p, p1, i - 2)) {
return true;
}
}
return false;
},
// @method newLatLngIntersects(): boolean
// Check for intersection if new latlng was added to this polyline.
// NOTE: does not support detecting intersection for degenerate cases.
newLatLngIntersects: function (latlng, skipFirst) {
// Cannot check a polyline for intersecting lats/lngs when not added to the map
if (!this._map) {
return false;
}
return this.newPointIntersects(this._map.latLngToLayerPoint(latlng), skipFirst);
},
// @method newPointIntersects(): boolean
// Check for intersection if new point was added to this polyline.
// newPoint must be a layer point.
// NOTE: does not support detecting intersection for degenerate cases.
newPointIntersects: function (newPoint, skipFirst) {
var points = this._getProjectedPoints(),
len = points ? points.length : 0,
lastPoint = points ? points[len - 1] : null,
// The previous previous line segment. Previous line segment doesn't need testing.
maxIndex = len - 2;
if (this._tooFewPointsForIntersection(1)) {
return false;
}
return this._lineSegmentsIntersectsRange(lastPoint, newPoint, maxIndex, skipFirst ? 1 : 0);
},
// Polylines with 2 sides can only intersect in cases where points are collinear (we don't support detecting these).
// Cannot have intersection when < 3 line segments (< 4 points)
_tooFewPointsForIntersection: function (extraPoints) {
var points = this._getProjectedPoints(),
len = points ? points.length : 0;
// Increment length by extraPoints if present
len += extraPoints || 0;
return !points || len <= 3;
},
// Checks a line segment intersections with any line segments before its predecessor.
// Don't need to check the predecessor as will never intersect.
_lineSegmentsIntersectsRange: function (p, p1, maxIndex, minIndex) {
var points = this._getProjectedPoints(),
p2, p3;
minIndex = minIndex || 0;
// Check all previous line segments (beside the immediately previous) for intersections
for (var j = maxIndex; j > minIndex; j--) {
p2 = points[j - 1];
p3 = points[j];
if (L.LineUtil.segmentsIntersect(p, p1, p2, p3)) {
return true;
}
}
return false;
},
_getProjectedPoints: function () {
if (!this._defaultShape) {
return this._originalPoints;
}
var points = [],
_shape = this._defaultShape();
for (var i = 0; i < _shape.length; i++) {
points.push(this._map.latLngToLayerPoint(_shape[i]));
}
return points;
}
});
L.Map.mergeOptions({
touchExtend: true
});
/**
* @class L.Map.TouchExtend
* @aka TouchExtend
*/
L.Map.TouchExtend = L.Handler.extend({
// @method initialize(): void
// Sets TouchExtend private accessor variables
initialize: function (map) {
this._map = map;
this._container = map._container;
this._pane = map._panes.overlayPane;
},
// @method addHooks(): void
// Adds dom listener events to the map container
addHooks: function () {
L.DomEvent.on(this._container, 'touchstart', this._onTouchStart, this);
L.DomEvent.on(this._container, 'touchend', this._onTouchEnd, this);
L.DomEvent.on(this._container, 'touchmove', this._onTouchMove, this);
if (this._detectIE()) {
L.DomEvent.on(this._container, 'MSPointerDown', this._onTouchStart, this);
L.DomEvent.on(this._container, 'MSPointerUp', this._onTouchEnd, this);
L.DomEvent.on(this._container, 'MSPointerMove', this._onTouchMove, this);
L.DomEvent.on(this._container, 'MSPointerCancel', this._onTouchCancel, this);
} else {
L.DomEvent.on(this._container, 'touchcancel', this._onTouchCancel, this);
L.DomEvent.on(this._container, 'touchleave', this._onTouchLeave, this);
}
},
// @method removeHooks(): void
// Removes dom listener events from the map container
removeHooks: function () {
L.DomEvent.off(this._container, 'touchstart', this._onTouchStart, this);
L.DomEvent.off(this._container, 'touchend', this._onTouchEnd, this);
L.DomEvent.off(this._container, 'touchmove', this._onTouchMove, this);
if (this._detectIE()) {
L.DomEvent.off(this._container, 'MSPointerDown', this._onTouchStart, this);
L.DomEvent.off(this._container, 'MSPointerUp', this._onTouchEnd, this);
L.DomEvent.off(this._container, 'MSPointerMove', this._onTouchMove, this);
L.DomEvent.off(this._container, 'MSPointerCancel', this._onTouchCancel, this);
} else {
L.DomEvent.off(this._container, 'touchcancel', this._onTouchCancel, this);
L.DomEvent.off(this._container, 'touchleave', this._onTouchLeave, this);
}
},
_touchEvent: function (e, type) {
// #TODO: fix the pageX error that is do a bug in Android where a single touch triggers two click events
// _filterClick is what leaflet uses as a workaround.
// This is a problem with more things than just android. Another problem is touchEnd has no touches in
// its touch list.
var touchEvent = {};
if (typeof e.touches !== 'undefined') {
if (!e.touches.length) {
return;
}
touchEvent = e.touches[0];
} else if (e.pointerType === 'touch') {
touchEvent = e;
if (!this._filterClick(e)) {
return;
}
} else {
return;
}
var containerPoint = this._map.mouseEventToContainerPoint(touchEvent),
layerPoint = this._map.mouseEventToLayerPoint(touchEvent),
latlng = this._map.layerPointToLatLng(layerPoint);
this._map.fire(type, {
latlng: latlng,
layerPoint: layerPoint,
containerPoint: containerPoint,
pageX: touchEvent.pageX,
pageY: touchEvent.pageY,
originalEvent: e
});
},
/** Borrowed from Leaflet and modified for bool ops **/
_filterClick: function (e) {
var timeStamp = (e.timeStamp || e.originalEvent.timeStamp),
elapsed = L.DomEvent._lastClick && (timeStamp - L.DomEvent._lastClick);
// are they closer together than 500ms yet more than 100ms?
// Android typically triggers them ~300ms apart while multiple listeners
// on the same event should be triggered far faster;
// or check if click is simulated on the element, and if it is, reject any non-simulated events
if ((elapsed && elapsed > 100 && elapsed < 500) || (e.target._simulatedClick && !e._simulated)) {
L.DomEvent.stop(e);
return false;
}
L.DomEvent._lastClick = timeStamp;
return true;
},
_onTouchStart: function (e) {
if (!this._map._loaded) {
return;
}
var type = 'touchstart';
this._touchEvent(e, type);
},
_onTouchEnd: function (e) {
if (!this._map._loaded) {
return;
}
var type = 'touchend';
this._touchEvent(e, type);
},
_onTouchCancel: function (e) {
if (!this._map._loaded) {
return;
}
var type = 'touchcancel';
if (this._detectIE()) {
type = 'pointercancel';
}
this._touchEvent(e, type);
},
_onTouchLeave: function (e) {
if (!this._map._loaded) {
return;
}
var type = 'touchleave';
this._touchEvent(e, type);
},
_onTouchMove: function (e) {
if (!this._map._loaded) {
return;
}
var type = 'touchmove';
this._touchEvent(e, type);
},
_detectIE: function () {
var ua = window.navigator.userAgent;
var msie = ua.indexOf('MSIE ');
if (msie > 0) {
// IE 10 or older => return version number
return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
}
var trident = ua.indexOf('Trident/');
if (trident > 0) {
// IE 11 => return version number
var rv = ua.indexOf('rv:');
return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);
}
var edge = ua.indexOf('Edge/');
if (edge > 0) {
// IE 12 => return version number
return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10);
}
// other browser
return false;
}
});
L.Map.addInitHook('addHandler', 'touchExtend', L.Map.TouchExtend);
/**
* @class L.Marker.Touch
* @aka Marker.Touch
*
* This isn't full Touch support. This is just to get markers to also support dom touch events after creation
* #TODO: find a better way of getting markers to support touch.
*/
L.Marker.Touch = L.Marker.extend({
_initInteraction: function () {
if (!this.addInteractiveTarget) {
// 0.7.x support
return this._initInteractionLegacy();
}
// TODO this may need be updated to re-add touch events for 1.0+
return L.Marker.prototype._initInteraction.apply(this);
},
// This is an exact copy of https://github.com/Leaflet/Leaflet/blob/v0.7/src/layer/marker/Marker.js
// with the addition of the touch events
_initInteractionLegacy: function () {
if (!this.options.clickable) {
return;
}
// TODO refactor into something shared with Map/Path/etc. to DRY it up
var icon = this._icon,
events = ['dblclick',
'mousedown',
'mouseover',
'mouseout',
'contextmenu',
'touchstart',
'touchend',
'touchmove'];
if (this._detectIE) {
events.concat(['MSPointerDown',
'MSPointerUp',
'MSPointerMove',
'MSPointerCancel']);
} else {
events.concat(['touchcancel']);
}
L.DomUtil.addClass(icon, 'leaflet-clickable');
L.DomEvent.on(icon, 'click', this._onMouseClick, this);
L.DomEvent.on(icon, 'keypress', this._onKeyPress, this);
for (var i = 0; i < events.length; i++) {
L.DomEvent.on(icon, events[i], this._fireMouseEvent, this);
}
if (L.Handler.MarkerDrag) {
this.dragging = new L.Handler.MarkerDrag(this);
if (this.options.draggable) {
this.dragging.enable();
}
}
},
_detectIE: function () {
var ua = window.navigator.userAgent;
var msie = ua.indexOf('MSIE ');
if (msie > 0) {
// IE 10 or older => return version number
return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
}
var trident = ua.indexOf('Trident/');
if (trident > 0) {
// IE 11 => return version number
var rv = ua.indexOf('rv:');
return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);
}
var edge = ua.indexOf('Edge/');
if (edge > 0) {
// IE 12 => return version number
return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10);
}
// other browser
return false;
}
});
public/src/images/spritesheet-2x.png

3.5 KB

public/src/images/spritesheet.png

1.86 KB

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
viewBox="0 0 600 60"
height="60"
width="600"
id="svg4225"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="spritesheet.svg"
inkscape:export-filename="/home/fpuga/development/upstream/icarto.Leaflet.draw/src/images/spritesheet-2x.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<metadata
id="metadata4258">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs4256"/>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1056"
id="namedview4254"
showgrid="false"
inkscape:zoom="1.3101852"
inkscape:cx="237.56928"
inkscape:cy="7.2419621"
inkscape:window-x="1920"
inkscape:window-y="24"
inkscape:window-maximized="1"
inkscape:current-layer="svg4225"/>
<g
id="enabled"
style="fill:#464646;fill-opacity:1">
<g
id="polyline"
style="fill:#464646;fill-opacity:1">
<path
d="m 18,36 0,6 6,0 0,-6 -6,0 z m 4,4 -2,0 0,-2 2,0 0,2 z"
id="path4229"
inkscape:connector-curvature="0"
style="fill:#464646;fill-opacity:1"/>
<path
d="m 36,18 0,6 6,0 0,-6 -6,0 z m 4,4 -2,0 0,-2 2,0 0,2 z"
id="path4231"
inkscape:connector-curvature="0"
style="fill:#464646;fill-opacity:1"/>
<path
d="m 23.142,39.145 -2.285,-2.29 16,-15.998 2.285,2.285 z"
id="path4233"
inkscape:connector-curvature="0"
style="fill:#464646;fill-opacity:1"/>
</g>
<path
id="polygon"
d="M 100,24.565 97.904,39.395 83.07,42 76,28.773 86.463,18 Z"
inkscape:connector-curvature="0"
style="fill:#464646;fill-opacity:1"/>
<path
id="rectangle"
d="m 140,20 20,0 0,20 -20,0 z"
inkscape:connector-curvature="0"
style="fill:#464646;fill-opacity:1"/>
<path
id="circle"
d="m 221,30 c 0,6.078 -4.926,11 -11,11 -6.074,0 -11,-4.922 -11,-11 0,-6.074 4.926,-11 11,-11 6.074,0 11,4.926 11,11 z"
inkscape:connector-curvature="0"
style="fill:#464646;fill-opacity:1"/>
<path
id="marker"
d="m 270,19 c -4.971,0 -9,4.029 -9,9 0,4.971 5.001,12 9,14 4.001,-2 9,-9.029 9,-14 0,-4.971 -4.029,-9 -9,-9 z m 0,12.5 c -2.484,0 -4.5,-2.014 -4.5,-4.5 0,-2.484 2.016,-4.5 4.5,-4.5 2.485,0 4.5,2.016 4.5,4.5 0,2.486 -2.015,4.5 -4.5,4.5 z"
inkscape:connector-curvature="0"
style="fill:#464646;fill-opacity:1"/>
<g
id="edit"
style="fill:#464646;fill-opacity:1">
<path
d="m 337,30.156 0,0.407 0,5.604 c 0,1.658 -1.344,3 -3,3 l -10,0 c -1.655,0 -3,-1.342 -3,-3 l 0,-10 c 0,-1.657 1.345,-3 3,-3 l 6.345,0 3.19,-3.17 -9.535,0 c -3.313,0 -6,2.687 -6,6 l 0,10 c 0,3.313 2.687,6 6,6 l 10,0 c 3.314,0 6,-2.687 6,-6 l 0,-8.809 -3,2.968"
id="path4240"
inkscape:connector-curvature="0"
style="fill:#464646;fill-opacity:1"/>
<path
d="m 338.72,24.637 -8.892,8.892 -2.828,0 0,-2.829 8.89,-8.89 z"
id="path4242"
inkscape:connector-curvature="0"
style="fill:#464646;fill-opacity:1"/>
<path
d="m 338.697,17.826 4,0 0,4 -4,0 z"
transform="matrix(-0.70698336,-0.70723018,0.70723018,-0.70698336,567.55917,274.78273)"
id="path4244"
inkscape:connector-curvature="0"
style="fill:#464646;fill-opacity:1"/>
</g>
<g
id="remove"
style="fill:#464646;fill-opacity:1">
<path
d="m 381,42 18,0 0,-18 -18,0 0,18 z m 14,-16 2,0 0,14 -2,0 0,-14 z m -4,0 2,0 0,14 -2,0 0,-14 z m -4,0 2,0 0,14 -2,0 0,-14 z m -4,0 2,0 0,14 -2,0 0,-14 z"
id="path4247"
inkscape:connector-curvature="0"
style="fill:#464646;fill-opacity:1"/>
<path
d="m 395,20 0,-4 -10,0 0,4 -6,0 0,2 22,0 0,-2 -6,0 z m -2,0 -6,0 0,-2 6,0 0,2 z"
id="path4249"
inkscape:connector-curvature="0"
style="fill:#464646;fill-opacity:1"/>
</g>
</g>
<g
id="disabled"
transform="translate(120,0)"
style="fill:#bbbbbb">
<use
xlink:href="#edit"
id="edit-disabled"
x="0"
y="0"
width="100%"
height="100%"/>
<use
xlink:href="#remove"
id="remove-disabled"
x="0"
y="0"
width="100%"
height="100%"/>
</g>
<path
style="fill:none;stroke:#464646;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="circle-3"
d="m 581.65725,30 c 0,6.078 -4.926,11 -11,11 -6.074,0 -11,-4.922 -11,-11 0,-6.074 4.926,-11 11,-11 6.074,0 11,4.926 11,11 z"
inkscape:connector-curvature="0"/>
</svg>
/* ================================================================== */
/* Toolbars
/* ================================================================== */
.leaflet-draw-section {
position: relative;
}
.leaflet-draw-toolbar {
margin-top: 12px;
}
.leaflet-draw-toolbar-top {
margin-top: 0;
}
.leaflet-draw-toolbar-notop a:first-child {
border-top-right-radius: 0;
}
.leaflet-draw-toolbar-nobottom a:last-child {
border-bottom-right-radius: 0;
}
.leaflet-draw-toolbar a {
background-image: url('images/spritesheet.png');
background-image: linear-gradient(transparent, transparent), url('images/spritesheet.svg');
background-repeat: no-repeat;
background-size: 300px 30px;
background-clip: padding-box;
}
.leaflet-retina .leaflet-draw-toolbar a {
background-image: url('images/spritesheet-2x.png');
background-image: linear-gradient(transparent, transparent), url('images/spritesheet.svg');
}
.leaflet-draw a {
display: block;
text-align: center;
text-decoration: none;
}
.leaflet-draw a .sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
}
/* ================================================================== */
/* Toolbar actions menu
/* ================================================================== */
.leaflet-draw-actions {
display: none;
list-style: none;
margin: 0;
padding: 0;
position: absolute;
left: 26px; /* leaflet-draw-toolbar.left + leaflet-draw-toolbar.width */
top: 0;
white-space: nowrap;
}
.leaflet-touch .leaflet-draw-actions {
left: 32px;
}
.leaflet-right .leaflet-draw-actions {
right: 26px;
left: auto;
}
.leaflet-touch .leaflet-right .leaflet-draw-actions {
right: 32px;
left: auto;
}
.leaflet-draw-actions li {
display: inline-block;
}
.leaflet-draw-actions li:first-child a {
border-left: none;
}
.leaflet-draw-actions li:last-child a {
-webkit-border-radius: 0 4px 4px 0;
border-radius: 0 4px 4px 0;
}
.leaflet-right .leaflet-draw-actions li:last-child a {
-webkit-border-radius: 0;
border-radius: 0;
}
.leaflet-right .leaflet-draw-actions li:first-child a {
-webkit-border-radius: 4px 0 0 4px;
border-radius: 4px 0 0 4px;
}
.leaflet-draw-actions a {
background-color: #919187;
border-left: 1px solid #AAA;
color: #FFF;
font: 11px/19px "Helvetica Neue", Arial, Helvetica, sans-serif;
line-height: 28px;
text-decoration: none;
padding-left: 10px;
padding-right: 10px;
height: 28px;
}
.leaflet-touch .leaflet-draw-actions a {
font-size: 12px;
line-height: 30px;
height: 30px;
}
.leaflet-draw-actions-bottom {
margin-top: 0;
}
.leaflet-draw-actions-top {
margin-top: 1px;
}
.leaflet-draw-actions-top a,
.leaflet-draw-actions-bottom a {
height: 27px;
line-height: 27px;
}
.leaflet-draw-actions a:hover {
background-color: #A0A098;
}
.leaflet-draw-actions-top.leaflet-draw-actions-bottom a {
height: 26px;
line-height: 26px;
}
/* ================================================================== */
/* Draw toolbar
/* ================================================================== */
.leaflet-draw-toolbar .leaflet-draw-draw-polyline {
background-position: -2px -2px;
}
.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-polyline {
background-position: 0 -1px;
}
.leaflet-draw-toolbar .leaflet-draw-draw-polygon {
background-position: -31px -2px;
}
.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-polygon {
background-position: -29px -1px;
}
.leaflet-draw-toolbar .leaflet-draw-draw-rectangle {
background-position: -62px -2px;
}
.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-rectangle {
background-position: -60px -1px;
}
.leaflet-draw-toolbar .leaflet-draw-draw-circle {
background-position: -92px -2px;
}
.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-circle {
background-position: -90px -1px;
}
.leaflet-draw-toolbar .leaflet-draw-draw-marker {
background-position: -122px -2px;
}
.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-marker {
background-position: -120px -1px;
}
.leaflet-draw-toolbar .leaflet-draw-draw-circlemarker {
background-position: -273px -2px;
}
.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-circlemarker {
background-position: -271px -1px;
}
/* ================================================================== */
/* Edit toolbar
/* ================================================================== */
.leaflet-draw-toolbar .leaflet-draw-edit-edit {
background-position: -152px -2px;
}
.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-edit-edit {
background-position: -150px -1px;
}
.leaflet-draw-toolbar .leaflet-draw-edit-remove {
background-position: -182px -2px;
}
.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-edit-remove {
background-position: -180px -1px;
}
.leaflet-draw-toolbar .leaflet-draw-edit-edit.leaflet-disabled {
background-position: -212px -2px;
}
.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-edit-edit.leaflet-disabled {
background-position: -210px -1px;
}
.leaflet-draw-toolbar .leaflet-draw-edit-remove.leaflet-disabled {
background-position: -242px -2px;
}
.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-edit-remove.leaflet-disabled {
background-position: -240px -2px;
}
/* ================================================================== */
/* Drawing styles
/* ================================================================== */
.leaflet-mouse-marker {
background-color: #fff;
cursor: crosshair;
}
.leaflet-draw-tooltip {
background: rgb(54, 54, 54);
background: rgba(0, 0, 0, 0.5);
border: 1px solid transparent;
-webkit-border-radius: 4px;
border-radius: 4px;
color: #fff;
font: 12px/18px "Helvetica Neue", Arial, Helvetica, sans-serif;
margin-left: 20px;
margin-top: -21px;
padding: 4px 8px;
position: absolute;
visibility: hidden;
white-space: nowrap;
z-index: 6;
}
.leaflet-draw-tooltip:before {
border-right: 6px solid black;
border-right-color: rgba(0, 0, 0, 0.5);
border-top: 6px solid transparent;
border-bottom: 6px solid transparent;
content: "";
position: absolute;
top: 7px;
left: -7px;
}
.leaflet-error-draw-tooltip {
background-color: #F2DEDE;
border: 1px solid #E6B6BD;
color: #B94A48;
}
.leaflet-error-draw-tooltip:before {
border-right-color: #E6B6BD;
}
.leaflet-draw-tooltip-single {
margin-top: -12px
}
.leaflet-draw-tooltip-subtext {
color: #f8d5e4;
}
.leaflet-draw-guide-dash {
font-size: 1%;
opacity: 0.6;
position: absolute;
width: 5px;
height: 5px;
}
/* ================================================================== */
/* Edit styles
/* ================================================================== */
.leaflet-edit-marker-selected {
background-color: rgba(254, 87, 161, 0.1);
border: 4px dashed rgba(254, 87, 161, 0.6);
-webkit-border-radius: 4px;
border-radius: 4px;
box-sizing: content-box;
}
.leaflet-edit-move {
cursor: move;
}
.leaflet-edit-resize {
cursor: pointer;
}
/* ================================================================== */
/* Old IE styles
/* ================================================================== */
.leaflet-oldie .leaflet-draw-toolbar {
border: 1px solid #999;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment