/* * @Author: hisense.wuhongjian * @Date: 2022-03-22 11:46:54 * @LastEditors: hisense.wuhongjian * @LastEditTime: 2022-03-22 11:46:54 * @Description: 告诉大家这是什么 */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('leaflet')) : typeof define === 'function' && define.amd ? define(['leaflet'], factory) : (factory(global.L)); }(this, (function (L$1) { 'use strict'; L$1 = L$1 && L$1.hasOwnProperty('default') ? L$1['default'] : L$1; // functional re-impl of L.Point.distanceTo, // with no dependency on Leaflet for easier testing function pointDistance(ptA, ptB) { var x = ptB.x - ptA.x; var y = ptB.y - ptA.y; return Math.sqrt(x * x + y * y); } var computeSegmentHeading = function computeSegmentHeading(a, b) { return (Math.atan2(b.y - a.y, b.x - a.x) * 180 / Math.PI + 90 + 360) % 360; }; var asRatioToPathLength = function asRatioToPathLength(_ref, totalPathLength) { var value = _ref.value, isInPixels = _ref.isInPixels; return isInPixels ? value / totalPathLength : value; }; function parseRelativeOrAbsoluteValue(value) { if (typeof value === 'string' && value.indexOf('%') !== -1) { return { value: parseFloat(value) / 100, isInPixels: false }; } var parsedValue = value ? parseFloat(value) : 0; return { value: parsedValue, isInPixels: parsedValue > 0 }; } var pointsEqual = function pointsEqual(a, b) { return a.x === b.x && a.y === b.y; }; function pointsToSegments(pts) { return pts.reduce(function (segments, b, idx, points) { // this test skips same adjacent points if (idx > 0 && !pointsEqual(b, points[idx - 1])) { var a = points[idx - 1]; var distA = segments.length > 0 ? segments[segments.length - 1].distB : 0; var distAB = pointDistance(a, b); segments.push({ a: a, b: b, distA: distA, distB: distA + distAB, heading: computeSegmentHeading(a, b) }); } return segments; }, []); } function projectPatternOnPointPath(pts, pattern) { // 1. split the path into segment infos var segments = pointsToSegments(pts); var nbSegments = segments.length; if (nbSegments === 0) { return []; } var totalPathLength = segments[nbSegments - 1].distB; var offset = asRatioToPathLength(pattern.offset, totalPathLength); var endOffset = asRatioToPathLength(pattern.endOffset, totalPathLength); var repeat = asRatioToPathLength(pattern.repeat, totalPathLength); var repeatIntervalPixels = totalPathLength * repeat; var startOffsetPixels = offset > 0 ? totalPathLength * offset : 0; var endOffsetPixels = endOffset > 0 ? totalPathLength * endOffset : 0; // 2. generate the positions of the pattern as offsets from the path start var positionOffsets = []; var positionOffset = startOffsetPixels; do { positionOffsets.push(positionOffset); positionOffset += repeatIntervalPixels; } while (repeatIntervalPixels > 0 && positionOffset < totalPathLength - endOffsetPixels); // 3. projects offsets to segments var segmentIndex = 0; var segment = segments[0]; return positionOffsets.map(function (positionOffset) { // find the segment matching the offset, // starting from the previous one as offsets are ordered while (positionOffset > segment.distB && segmentIndex < nbSegments - 1) { segmentIndex++; segment = segments[segmentIndex]; } var segmentRatio = (positionOffset - segment.distA) / (segment.distB - segment.distA); return { pt: interpolateBetweenPoints(segment.a, segment.b, segmentRatio), heading: segment.heading }; }); } /** * Finds the point which lies on the segment defined by points A and B, * at the given ratio of the distance from A to B, by linear interpolation. */ function interpolateBetweenPoints(ptA, ptB, ratio) { if (ptB.x !== ptA.x) { return { x: ptA.x + ratio * (ptB.x - ptA.x), y: ptA.y + ratio * (ptB.y - ptA.y) }; } // special case where points lie on the same vertical axis return { x: ptA.x, y: ptA.y + (ptB.y - ptA.y) * ratio }; } (function() { // save these original methods before they are overwritten var proto_initIcon = L.Marker.prototype._initIcon; var proto_setPos = L.Marker.prototype._setPos; var oldIE = (L.DomUtil.TRANSFORM === 'msTransform'); L.Marker.addInitHook(function () { var iconOptions = this.options.icon && this.options.icon.options; var iconAnchor = iconOptions && this.options.icon.options.iconAnchor; if (iconAnchor) { iconAnchor = (iconAnchor[0] + 'px ' + iconAnchor[1] + 'px'); } this.options.rotationOrigin = this.options.rotationOrigin || iconAnchor || 'center bottom' ; this.options.rotationAngle = this.options.rotationAngle || 0; // Ensure marker keeps rotated during dragging this.on('drag', function(e) { e.target._applyRotation(); }); }); L.Marker.include({ _initIcon: function() { proto_initIcon.call(this); }, _setPos: function (pos) { proto_setPos.call(this, pos); this._applyRotation(); }, _applyRotation: function () { if(this.options.rotationAngle) { this._icon.style[L.DomUtil.TRANSFORM+'Origin'] = this.options.rotationOrigin; if(oldIE) { // for IE 9, use the 2D rotation this._icon.style[L.DomUtil.TRANSFORM] = 'rotate(' + this.options.rotationAngle + 'deg)'; } else { // for modern browsers, prefer the 3D accelerated version this._icon.style[L.DomUtil.TRANSFORM] += ' rotateZ(' + this.options.rotationAngle + 'deg)'; } } }, setRotationAngle: function(angle) { this.options.rotationAngle = angle; this.update(); return this; }, setRotationOrigin: function(origin) { this.options.rotationOrigin = origin; this.update(); return this; } }); })(); L$1.Symbol = L$1.Symbol || {}; /** * A simple dash symbol, drawn as a Polyline. * Can also be used for dots, if 'pixelSize' option is given the 0 value. */ L$1.Symbol.Dash = L$1.Class.extend({ options: { pixelSize: 10, pathOptions: {} }, initialize: function initialize(options) { L$1.Util.setOptions(this, options); this.options.pathOptions.clickable = false; }, buildSymbol: function buildSymbol(dirPoint, latLngs, map, index, total) { var opts = this.options; var d2r = Math.PI / 180; // for a dot, nothing more to compute if (opts.pixelSize <= 1) { return L$1.polyline([dirPoint.latLng, dirPoint.latLng], opts.pathOptions); } var midPoint = map.project(dirPoint.latLng); var angle = -(dirPoint.heading - 90) * d2r; var a = L$1.point(midPoint.x + opts.pixelSize * Math.cos(angle + Math.PI) / 2, midPoint.y + opts.pixelSize * Math.sin(angle) / 2); // compute second point by central symmetry to avoid unecessary cos/sin var b = midPoint.add(midPoint.subtract(a)); return L$1.polyline([map.unproject(a), map.unproject(b)], opts.pathOptions); } }); L$1.Symbol.dash = function (options) { return new L$1.Symbol.Dash(options); }; L$1.Symbol.ArrowHead = L$1.Class.extend({ options: { polygon: true, pixelSize: 10, headAngle: 60, pathOptions: { stroke: false, weight: 2 } }, initialize: function initialize(options) { L$1.Util.setOptions(this, options); this.options.pathOptions.clickable = false; }, buildSymbol: function buildSymbol(dirPoint, latLngs, map, index, total) { return this.options.polygon ? L$1.polygon(this._buildArrowPath(dirPoint, map), this.options.pathOptions) : L$1.polyline(this._buildArrowPath(dirPoint, map), this.options.pathOptions); }, _buildArrowPath: function _buildArrowPath(dirPoint, map) { var d2r = Math.PI / 180; var tipPoint = map.project(dirPoint.latLng); var direction = -(dirPoint.heading - 90) * d2r; var radianArrowAngle = this.options.headAngle / 2 * d2r; var headAngle1 = direction + radianArrowAngle; var headAngle2 = direction - radianArrowAngle; var arrowHead1 = L$1.point(tipPoint.x - this.options.pixelSize * Math.cos(headAngle1), tipPoint.y + this.options.pixelSize * Math.sin(headAngle1)); var arrowHead2 = L$1.point(tipPoint.x - this.options.pixelSize * Math.cos(headAngle2), tipPoint.y + this.options.pixelSize * Math.sin(headAngle2)); return [map.unproject(arrowHead1), dirPoint.latLng, map.unproject(arrowHead2)]; } }); L$1.Symbol.arrowHead = function (options) { return new L$1.Symbol.ArrowHead(options); }; L$1.Symbol.Marker = L$1.Class.extend({ options: { markerOptions: {}, rotate: false }, initialize: function initialize(options) { L$1.Util.setOptions(this, options); this.options.markerOptions.clickable = false; this.options.markerOptions.draggable = false; }, buildSymbol: function buildSymbol(directionPoint, latLngs, map, index, total) { if (this.options.rotate) { this.options.markerOptions.rotationAngle = directionPoint.heading + (this.options.angleCorrection || 0); } return L$1.marker(directionPoint.latLng, this.options.markerOptions); } }); L$1.Symbol.marker = function (options) { return new L$1.Symbol.Marker(options); }; var isCoord = function isCoord(c) { return c instanceof L$1.LatLng || Array.isArray(c) && c.length === 2 && typeof c[0] === 'number'; }; var isCoordArray = function isCoordArray(ll) { return Array.isArray(ll) && isCoord(ll[0]); }; L$1.PolylineDecorator = L$1.FeatureGroup.extend({ options: { patterns: [] }, initialize: function initialize(paths, options) { L$1.FeatureGroup.prototype.initialize.call(this); L$1.Util.setOptions(this, options); this._map = null; this._paths = this._initPaths(paths); this._bounds = this._initBounds(); this._patterns = this._initPatterns(this.options.patterns); }, /** * Deals with all the different cases. input can be one of these types: * array of LatLng, array of 2-number arrays, Polyline, Polygon, * array of one of the previous. */ _initPaths: function _initPaths(input, isPolygon) { var _this = this; if (isCoordArray(input)) { // Leaflet Polygons don't need the first point to be repeated, but we do var coords = isPolygon ? input.concat([input[0]]) : input; return [coords]; } if (input instanceof L$1.Polyline) { // we need some recursivity to support multi-poly* return this._initPaths(input.getLatLngs(), input instanceof L$1.Polygon); } if (Array.isArray(input)) { // flatten everything, we just need coordinate lists to apply patterns return input.reduce(function (flatArray, p) { return flatArray.concat(_this._initPaths(p, isPolygon)); }, []); } return []; }, // parse pattern definitions and precompute some values _initPatterns: function _initPatterns(patternDefs) { return patternDefs.map(this._parsePatternDef); }, /** * Changes the patterns used by this decorator * and redraws the new one. */ setPatterns: function setPatterns(patterns) { this.options.patterns = patterns; this._patterns = this._initPatterns(this.options.patterns); this.redraw(); }, /** * Changes the patterns used by this decorator * and redraws the new one. */ setPaths: function setPaths(paths) { this._paths = this._initPaths(paths); this._bounds = this._initBounds(); this.redraw(); }, /** * Parse the pattern definition */ _parsePatternDef: function _parsePatternDef(patternDef, latLngs) { return { symbolFactory: patternDef.symbol, // Parse offset and repeat values, managing the two cases: // absolute (in pixels) or relative (in percentage of the polyline length) offset: parseRelativeOrAbsoluteValue(patternDef.offset), endOffset: parseRelativeOrAbsoluteValue(patternDef.endOffset), repeat: parseRelativeOrAbsoluteValue(patternDef.repeat) }; }, onAdd: function onAdd(map) { this._map = map; this._draw(); this._map.on('moveend', this.redraw, this); }, onRemove: function onRemove(map) { this._map.off('moveend', this.redraw, this); this._map = null; L$1.FeatureGroup.prototype.onRemove.call(this, map); }, /** * As real pattern bounds depends on map zoom and bounds, * we just compute the total bounds of all paths decorated by this instance. */ _initBounds: function _initBounds() { var allPathCoords = this._paths.reduce(function (acc, path) { return acc.concat(path); }, []); return L$1.latLngBounds(allPathCoords); }, getBounds: function getBounds() { return this._bounds; }, /** * Returns an array of ILayers object */ _buildSymbols: function _buildSymbols(latLngs, symbolFactory, directionPoints) { var _this2 = this; return directionPoints.map(function (directionPoint, i) { return symbolFactory.buildSymbol(directionPoint, latLngs, _this2._map, i, directionPoints.length); }); }, /** * Compute pairs of LatLng and heading angle, * that define positions and directions of the symbols on the path */ _getDirectionPoints: function _getDirectionPoints(latLngs, pattern) { var _this3 = this; if (latLngs.length < 2) { return []; } var pathAsPoints = latLngs.map(function (latLng) { return _this3._map.project(latLng); }); return projectPatternOnPointPath(pathAsPoints, pattern).map(function (point) { return { latLng: _this3._map.unproject(L$1.point(point.pt)), heading: point.heading }; }); }, redraw: function redraw() { if (!this._map) { return; } this.clearLayers(); this._draw(); }, /** * Returns all symbols for a given pattern as an array of FeatureGroup */ _getPatternLayers: function _getPatternLayers(pattern) { var _this4 = this; var mapBounds = this._map.getBounds().pad(0.1); return this._paths.map(function (path) { var directionPoints = _this4._getDirectionPoints(path, pattern) // filter out invisible points .filter(function (point) { return mapBounds.contains(point.latLng); }); return L$1.featureGroup(_this4._buildSymbols(path, pattern.symbolFactory, directionPoints)); }); }, /** * Draw all patterns */ _draw: function _draw() { var _this5 = this; this._patterns.map(function (pattern) { return _this5._getPatternLayers(pattern); }).forEach(function (layers) { _this5.addLayer(L$1.featureGroup(layers)); }); } }); /* * Allows compact syntax to be used */ L$1.polylineDecorator = function (paths, options) { return new L$1.PolylineDecorator(paths, options); }; })));