UNPKG

galadrielmap_sk

Version:

a server-based chartplotter navigation software for pleasure crafts, motorhomes, and off-road cars. It's can be used on tablets and smartphones without install any app. Only browser need.

421 lines (341 loc) 13.9 kB
!(function() { 'use strict'; L.Marker.Measurement = L[L.Layer ? 'Layer' : 'Class'].extend({ options: { pane: 'markerPane' }, initialize: function(latlng, measurement, title, rotation, options) { L.setOptions(this, options); this._latlng = latlng; this._measurement = measurement; this._title = title; this._rotation = rotation; }, addTo: function(map) { map.addLayer(this); return this; }, onAdd: function(map) { this._map = map; var pane = this.getPane ? this.getPane() : map.getPanes().markerPane; var el = this._element = L.DomUtil.create('div', 'leaflet-zoom-animated leaflet-measure-path-measurement', pane); var inner = L.DomUtil.create('div', '', el); inner.title = this._title; inner.innerHTML = this._measurement; map.on('zoomanim', this._animateZoom, this); this._setPosition(); }, onRemove: function(map) { map.off('zoomanim', this._animateZoom, this); var pane = this.getPane ? this.getPane() : map.getPanes().markerPane; pane.removeChild(this._element); this._map = null; }, _setPosition: function() { L.DomUtil.setPosition(this._element, this._map.latLngToLayerPoint(this._latlng)); this._element.style.transform += ' rotate(' + this._rotation + 'rad)'; }, _animateZoom: function(opt) { var pos = this._map._latLngToNewLayerPoint(this._latlng, opt.zoom, opt.center).round(); L.DomUtil.setPosition(this._element, pos); this._element.style.transform += ' rotate(' + this._rotation + 'rad)'; } }); L.marker.measurement = function(latLng, measurement, title, rotation, options) { return new L.Marker.Measurement(latLng, measurement, title, rotation, options); }; var formatDistance = function(d) { var unit, feet; if (this._measurementOptions.imperial) { feet = d / 0.3048; if (feet > 3000) { d = d / 1609.344; unit = 'mi'; } else { d = feet; unit = 'ft'; } } else { if (d > 1000) { d = d / 1000; unit = 'km'; } else { unit = 'm'; } } if (d < 100) { return d.toFixed(1) + ' ' + unit; } else { return Math.round(d) + ' ' + unit; } } var formatArea = function(a) { var unit, sqfeet; if (this._measurementOptions.imperial) { if (a > 404.685642) { a = a / 4046.85642; unit = 'ac'; } else { a = a / 0.09290304; unit = 'ft²'; } } else { if (a > 1000000) { a = a / 1000000; unit = 'km²'; } else { unit = 'm²'; } } if (a < 100) { return a.toFixed(1) + ' ' + unit; } else { return Math.round(a) + ' ' + unit; } } var RADIUS = 6378137; // ringArea function copied from geojson-area // (https://github.com/mapbox/geojson-area) // This function is distributed under a separate license, // see LICENSE.md. var ringArea = function ringArea(coords) { var rad = function rad(_) { return _ * Math.PI / 180; }; var p1, p2, p3, lowerIndex, middleIndex, upperIndex, area = 0, coordsLength = coords.length; if (coordsLength > 2) { for (var i = 0; i < coordsLength; i++) { if (i === coordsLength - 2) {// i = N-2 lowerIndex = coordsLength - 2; middleIndex = coordsLength -1; upperIndex = 0; } else if (i === coordsLength - 1) {// i = N-1 lowerIndex = coordsLength - 1; middleIndex = 0; upperIndex = 1; } else { // i = 0 to N-3 lowerIndex = i; middleIndex = i+1; upperIndex = i+2; } p1 = coords[lowerIndex]; p2 = coords[middleIndex]; p3 = coords[upperIndex]; area += ( rad(p3.lng) - rad(p1.lng) ) * Math.sin( rad(p2.lat)); } area = area * RADIUS * RADIUS / 2; } return Math.abs(area); }; /** * Handles the init hook for polylines and circles. * Implements the showOnHover functionality if called for. */ var addInitHook = function() { var showOnHover = this.options.measurementOptions && this.options.measurementOptions.showOnHover; if (this.options.showMeasurements && !showOnHover) { this.showMeasurements(); } if (this.options.showMeasurements && showOnHover) { this.on('mouseover', function() { this.showMeasurements(); }); this.on('mouseout', function() { this.hideMeasurements(); }); } }; var circleArea = function circleArea(d) { var rho = d / RADIUS; return 2 * Math.PI * RADIUS * RADIUS * (1 - Math.cos(rho)); }; var override = function(method, fn, hookAfter) { if (!hookAfter) { return function() { var originalReturnValue = method.apply(this, arguments); var args = Array.prototype.slice.call(arguments) args.push(originalReturnValue); return fn.apply(this, args); } } else { return function() { fn.apply(this, arguments); return method.apply(this, arguments); } } }; L.Polyline.include({ showMeasurements: function(options) { if (!this._map || this._measurementLayer) return this; this._measurementOptions = L.extend({ showOnHover: (options && options.showOnHover) || false, minPixelDistance: 30, showDistances: true, showArea: true, showTotalDistance: true, lang: { totalLength: 'Total length', totalArea: 'Total area', segmentLength: 'Segment length' } }, options || {}); this._measurementLayer = L.layerGroup().addTo(this._map); this.updateMeasurements(); this._map.on('zoomend', this.updateMeasurements, this); return this; }, hideMeasurements: function() { if (!this._map) return this; this._map.off('zoomend', this.updateMeasurements, this); if (!this._measurementLayer) return this; this._map.removeLayer(this._measurementLayer); this._measurementLayer = null; return this; }, onAdd: override(L.Polyline.prototype.onAdd, function(originalReturnValue) { var showOnHover = this.options.measurementOptions && this.options.measurementOptions.showOnHover; if (this.options.showMeasurements && !showOnHover) { this.showMeasurements(this.options.measurementOptions); } return originalReturnValue; }), onRemove: override(L.Polyline.prototype.onRemove, function(originalReturnValue) { this.hideMeasurements(); return originalReturnValue; }, true), setLatLngs: override(L.Polyline.prototype.setLatLngs, function(originalReturnValue) { this.updateMeasurements(); return originalReturnValue; }), spliceLatLngs: override(L.Polyline.prototype.spliceLatLngs, function(originalReturnValue) { this.updateMeasurements(); return originalReturnValue; }), formatDistance: formatDistance, formatArea: formatArea, updateMeasurements: function() { if (!this._measurementLayer) return this; var latLngs = this.getLatLngs(), isPolygon = this instanceof L.Polygon, options = this._measurementOptions, totalDist = 0, formatter, ll1, ll2, p1, p2, pixelDist, dist; if (latLngs && latLngs.length && L.Util.isArray(latLngs[0])) { // Outer ring is stored as an array in the first element, // use that instead. latLngs = latLngs[0]; } this._measurementLayer.clearLayers(); if (this._measurementOptions.showDistances && latLngs.length > 1) { formatter = this._measurementOptions.formatDistance || L.bind(this.formatDistance, this); for (var i = 1, len = latLngs.length; (isPolygon && i <= len) || i < len; i++) { ll1 = latLngs[i - 1]; ll2 = latLngs[i % len]; dist = ll1.distanceTo(ll2); totalDist += dist; p1 = this._map.latLngToLayerPoint(ll1); p2 = this._map.latLngToLayerPoint(ll2); pixelDist = p1.distanceTo(p2); if (pixelDist >= options.minPixelDistance) { L.marker.measurement( this._map.layerPointToLatLng([(p1.x + p2.x) / 2, (p1.y + p2.y) / 2]), formatter(dist), options.lang.segmentLength, this._getRotation(ll1, ll2), options) .addTo(this._measurementLayer); } } // Show total length for polylines if (!isPolygon && this._measurementOptions.showTotalDistance) { L.marker.measurement(ll2, formatter(totalDist), options.lang.totalLength, 0, options) .addTo(this._measurementLayer); } } if (isPolygon && options.showArea && latLngs.length > 2) { formatter = options.formatArea || L.bind(this.formatArea, this); var area = ringArea(latLngs); L.marker.measurement(this.getBounds().getCenter(), formatter(area), options.lang.totalArea, 0, options) .addTo(this._measurementLayer); } return this; }, _getRotation: function(ll1, ll2) { var p1 = this._map.project(ll1), p2 = this._map.project(ll2); return Math.atan((p2.y - p1.y) / (p2.x - p1.x)); } }); L.Polyline.addInitHook(function() { addInitHook.call(this); }); L.Circle.include({ showMeasurements: function(options) { if (!this._map || this._measurementLayer) return this; this._measurementOptions = L.extend({ showOnHover: false, showArea: true, lang: { totalArea: 'Total area', } }, options || {}); this._measurementLayer = L.layerGroup().addTo(this._map); this.updateMeasurements(); this._map.on('zoomend', this.updateMeasurements, this); return this; }, hideMeasurements: function() { if (!this._map) return this; this._map.on('zoomend', this.updateMeasurements, this); if (!this._measurementLayer) return this; this._map.removeLayer(this._measurementLayer); this._measurementLayer = null; return this; }, onAdd: override(L.Circle.prototype.onAdd, function(originalReturnValue) { var showOnHover = this.options.measurementOptions && this.options.measurementOptions.showOnHover; if (this.options.showMeasurements && !showOnHover) { this.showMeasurements(this.options.measurementOptions); } return originalReturnValue; }), onRemove: override(L.Circle.prototype.onRemove, function(originalReturnValue) { this.hideMeasurements(); return originalReturnValue; }, true), setLatLng: override(L.Circle.prototype.setLatLng, function(originalReturnValue) { this.updateMeasurements(); return originalReturnValue; }), setRadius: override(L.Circle.prototype.setRadius, function(originalReturnValue) { this.updateMeasurements(); return originalReturnValue; }), formatArea: formatArea, updateMeasurements: function() { if (!this._measurementLayer) return; var latLng = this.getLatLng(), options = this._measurementOptions, formatter = options.formatArea || L.bind(this.formatArea, this); this._measurementLayer.clearLayers(); if (options.showArea) { formatter = options.formatArea || L.bind(this.formatArea, this); var area = circleArea(this.getRadius()); L.marker.measurement(latLng, formatter(area), options.lang.totalArea, 0, options) .addTo(this._measurementLayer); } } }) L.Circle.addInitHook(function() { addInitHook.call(this); }); })();