Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

leaflet-polylinedecorator

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

leaflet-polylinedecorator - npm Package Compare versions

Comparing version 0.7.2 to 1.0.1

bower.json

18

example/example.js

@@ -28,4 +28,4 @@

// --- Polygon ---
var polygon = L.polygon([[54, -6], [55, -7], [56, -2], [55, 1], [53, 0], [54, -6]], {color: "#ff7800", weight: 1}).addTo(map);
// --- Polygon, with an inner ring ---
var polygon = L.polygon([[[54, -6], [55, -7], [56, -2], [55, 1], [53, 0]], [[54, -3], [54, -2], [55, -1], [55, -5]]], {color: "#ff7800", weight: 1}).addTo(map);
var pd = L.polylineDecorator(polygon, {

@@ -55,3 +55,3 @@ patterns: [

}).addTo(map);
// --- Example with a rotated marker ---

@@ -88,15 +88,3 @@ var pathPattern = L.polylineDecorator(

}).addTo(map);
// --- Example with a MultiPolygon ---
var multiCoords2 = [
[[55.4788, 4.1748], [53.7487, 4.5263], [52.4560, 7.3388], [56.3165, 7.8662]],
[[53.9302, 9.2724] , [52.8027, 9.8876], [52.1604, 12.0849], [53.5141, 14.5019], [54.9523, 14.3261], [55.5037, 10.5908]]
];
var multiPl = L.multiPolygon(multiCoords2, {weight: 0, fillOpacity: 0}).addTo(map);
L.polylineDecorator(multiPl, {
patterns: [
{offset: 0, repeat: 10, symbol: L.Symbol.dash({pixelSize: 0, pathOptions: {color: '#080'}})}
]
}).addTo(map);
}

@@ -40,7 +40,9 @@

* offsetRatio: the ratio of the total pixel length where the pattern will start
* endOffsetRatio: the ratio of the total pixel length where the pattern will end
* repeatRatio: the ratio of the total pixel length between two points of the pattern
* map: the map, to access the current projection state
*/
projectPatternOnPath: function (path, offsetRatio, repeatRatio, map) {
projectPatternOnPath: function (path, offsetRatio, endOffsetRatio, repeatRatio, map) {
var pathAsPoints = [], i;
for(i=0, l=path.length; i<l; i++) {

@@ -50,3 +52,3 @@ pathAsPoints[i] = map.project(path[i]);

// project the pattern as pixel points
var pattern = this.projectPatternOnPointPath(pathAsPoints, offsetRatio, repeatRatio);
var pattern = this.projectPatternOnPointPath(pathAsPoints, offsetRatio, endOffsetRatio, repeatRatio);
// and convert it to latlngs;

@@ -59,8 +61,10 @@ for(i=0, l=pattern.length; i<l; i++) {

projectPatternOnPointPath: function (pts, offsetRatio, repeatRatio) {
projectPatternOnPointPath: function (pts, offsetRatio, endOffsetRatio, repeatRatio) {
var positions = [];
// 1. compute the absolute interval length in pixels
var repeatIntervalLength = this.getPointPathPixelLength(pts) * repeatRatio;
// 2. find the starting point by using the offsetRatio
// 2. find the starting point by using the offsetRatio and find the last pixel using endOffsetRatio
var previous = this.interpolateOnPointPath(pts, offsetRatio);
var endOffsetPixels = endOffsetRatio > 0 ? this.getPointPathPixelLength(pts) * endOffsetRatio : 0;
positions.push(previous);

@@ -71,7 +75,10 @@ if(repeatRatio > 0) {

remainingPath = remainingPath.slice(previous.predecessor);
remainingPath[0] = previous.pt;
var remainingLength = this.getPointPathPixelLength(remainingPath);
// 4. project as a ratio of the remaining length,
// and repeat while there is room for another point of the pattern
while(repeatIntervalLength <= remainingLength) {
while(repeatIntervalLength <= remainingLength-endOffsetPixels) {
previous = this.interpolateOnPointPath(remainingPath, repeatIntervalLength/remainingLength);

@@ -166,160 +173,3 @@ positions.push(previous);

};
L.RotatedMarker = L.Marker.extend({
options: {
angle: 0
},
_setPos: function (pos) {
L.Marker.prototype._setPos.call(this, pos);
if (L.DomUtil.TRANSFORM) {
// use the CSS transform rule if available
this._icon.style[L.DomUtil.TRANSFORM] += ' rotate(' + this.options.angle + 'deg)';
} else if(L.Browser.ie) {
// fallback for IE6, IE7, IE8
var rad = this.options.angle * L.LatLng.DEG_TO_RAD,
costheta = Math.cos(rad),
sintheta = Math.sin(rad);
this._icon.style.filter += ' progid:DXImageTransform.Microsoft.Matrix(sizingMethod=\'auto expand\', M11=' +
costheta + ', M12=' + (-sintheta) + ', M21=' + sintheta + ', M22=' + costheta + ')';
}
}
});
L.rotatedMarker = function (pos, options) {
return new L.RotatedMarker(pos, options);
};/**
* Defines several classes of symbol factories,
* to be used with L.PolylineDecorator
*/
L.Symbol = L.Symbol || {};
/**
* A simple dash symbol, drawn as a Polyline.
* Can also be used for dots, if 'pixelSize' option is given the 0 value.
*/
L.Symbol.Dash = L.Class.extend({
isZoomDependant: true,
options: {
pixelSize: 10,
pathOptions: { }
},
initialize: function (options) {
L.Util.setOptions(this, options);
this.options.pathOptions.clickable = false;
},
buildSymbol: function(dirPoint, latLngs, map, index, total) {
var opts = this.options;
// for a dot, nothing more to compute
if(opts.pixelSize <= 1) {
return new L.Polyline([dirPoint.latLng, dirPoint.latLng], opts.pathOptions);
}
var midPoint = map.project(dirPoint.latLng);
var angle = (-(dirPoint.heading - 90)) * L.LatLng.DEG_TO_RAD;
var a = new L.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 new L.Polyline([map.unproject(a), map.unproject(b)], opts.pathOptions);
}
});
L.Symbol.dash = function (options) {
return new L.Symbol.Dash(options);
};
L.Symbol.ArrowHead = L.Class.extend({
isZoomDependant: true,
options: {
polygon: true,
pixelSize: 10,
headAngle: 60,
pathOptions: {
stroke: false,
weight: 2
}
},
initialize: function (options) {
L.Util.setOptions(this, options);
this.options.pathOptions.clickable = false;
},
buildSymbol: function(dirPoint, latLngs, map, index, total) {
var opts = this.options;
var path;
if(opts.polygon) {
path = new L.Polygon(this._buildArrowPath(dirPoint, map), opts.pathOptions);
} else {
path = new L.Polyline(this._buildArrowPath(dirPoint, map), opts.pathOptions);
}
return path;
},
_buildArrowPath: function (dirPoint, map) {
var tipPoint = map.project(dirPoint.latLng);
var direction = (-(dirPoint.heading - 90)) * L.LatLng.DEG_TO_RAD;
var radianArrowAngle = this.options.headAngle / 2 * L.LatLng.DEG_TO_RAD;
var headAngle1 = direction + radianArrowAngle,
headAngle2 = direction - radianArrowAngle;
var arrowHead1 = new L.Point(
tipPoint.x - this.options.pixelSize * Math.cos(headAngle1),
tipPoint.y + this.options.pixelSize * Math.sin(headAngle1)),
arrowHead2 = new L.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.Symbol.arrowHead = function (options) {
return new L.Symbol.ArrowHead(options);
};
L.Symbol.Marker = L.Class.extend({
isZoomDependant: false,
options: {
markerOptions: { },
rotate: false
},
initialize: function (options) {
L.Util.setOptions(this, options);
this.options.markerOptions.clickable = false;
this.options.markerOptions.draggable = false;
this.isZoomDependant = (L.Browser.ie && this.options.rotate);
},
buildSymbol: function(directionPoint, latLngs, map, index, total) {
if(!this.options.rotate) {
return new L.Marker(directionPoint.latLng, this.options.markerOptions);
}
else {
this.options.markerOptions.angle = directionPoint.heading;
return new L.RotatedMarker(directionPoint.latLng, this.options.markerOptions);
}
}
});
L.Symbol.marker = function (options) {
return new L.Symbol.Marker(options);
};
L.PolylineDecorator = L.LayerGroup.extend({

@@ -341,3 +191,3 @@ options: {

* array of LatLng, array of 2-number arrays, Polyline, Polygon,
* array of one of the previous, MultiPolyline, MultiPolygon.
* array of one of the previous.
*/

@@ -347,8 +197,3 @@ _initPaths: function(p) {

var isPolygon = false;
if(p instanceof L.MultiPolyline || (isPolygon = (p instanceof L.MultiPolygon))) {
var lines = p.getLatLngs();
for(var i=0; i<lines.length; i++) {
this._initPath(lines[i], isPolygon);
}
} else if(p instanceof L.Polyline) {
if(p instanceof L.Polyline) {
this._initPath(p.getLatLngs(), (p instanceof L.Polygon));

@@ -368,3 +213,3 @@ } else if(L.Util.isArray(p) && p.length > 0) {

return(L.Util.isArray(ll) && ll.length > 0 && (
ll[0] instanceof L.LatLng ||
ll[0] instanceof L.LatLng ||
(L.Util.isArray(ll[0]) && ll[0].length == 2 && typeof ll[0][0] === 'number')

@@ -391,3 +236,3 @@ ));

}
},
},

@@ -405,2 +250,3 @@ _initPatterns: function() {

pattern.isOffsetInPixels ||
pattern.isEndOffsetInPixels ||
pattern.isRepeatInPixels ||

@@ -412,3 +258,3 @@ pattern.symbolFactory.isZoomDependant;

/**
* Changes the patterns used by this decorator
* Changes the patterns used by this decorator
* and redraws the new one.

@@ -423,3 +269,3 @@ */

/**
* Changes the patterns used by this decorator
* Changes the patterns used by this decorator
* and redraws the new one.

@@ -440,5 +286,6 @@ */

isOffsetInPixels: false,
isEndOffsetInPixels: false,
isRepeatInPixels: false
};
// Parse offset and repeat values, managing the two cases:

@@ -449,7 +296,13 @@ // absolute (in pixels) or relative (in percentage of the polyline length)

} else {
pattern.offset = parseFloat(patternDef.offset);
pattern.offset = patternDef.offset ? parseFloat(patternDef.offset) : 0;
pattern.isOffsetInPixels = (pattern.offset > 0);
}
if(typeof patternDef.endOffset === 'string' && patternDef.endOffset.indexOf('%') != -1) {
pattern.endOffset = parseFloat(patternDef.endOffset) / 100;
} else {
pattern.endOffset = patternDef.endOffset ? parseFloat(patternDef.endOffset) : 0;
pattern.isEndOffsetInPixels = (pattern.endOffset > 0);
}
if(typeof patternDef.repeat === 'string' && patternDef.repeat.indexOf('%') != -1) {

@@ -461,5 +314,3 @@ pattern.repeat = parseFloat(patternDef.repeat) / 100;

}
// TODO: 0 => not pixel dependant => 0%
return(pattern);

@@ -507,3 +358,3 @@ },

* that define positions and directions of the symbols
* on the path
* on the path
*/

@@ -517,3 +368,3 @@ _getDirectionPoints: function(pathIndex, pattern) {

var offset, repeat, pathPixelLength = null, latLngs = this._paths[pathIndex];
var offset, endOffset, repeat, pathPixelLength = null, latLngs = this._paths[pathIndex];
if(pattern.isOffsetInPixels) {

@@ -525,12 +376,18 @@ pathPixelLength = L.LineUtil.PolylineDecorator.getPixelLength(latLngs, this._map);

}
if(pattern.isEndOffsetInPixels) {
pathPixelLength = (pathPixelLength !== null) ? pathPixelLength : L.LineUtil.PolylineDecorator.getPixelLength(latLngs, this._map);
endOffset = pattern.endOffset/pathPixelLength;
} else {
endOffset = pattern.endOffset;
}
if(pattern.isRepeatInPixels) {
pathPixelLength = (pathPixelLength !== null) ? pathPixelLength : L.LineUtil.PolylineDecorator.getPixelLength(latLngs, this._map);
repeat = pattern.repeat/pathPixelLength;
repeat = pattern.repeat/pathPixelLength;
} else {
repeat = pattern.repeat;
}
dirPoints = L.LineUtil.PolylineDecorator.projectPatternOnPath(latLngs, offset, repeat, this._map);
dirPoints = L.LineUtil.PolylineDecorator.projectPatternOnPath(latLngs, offset, endOffset, repeat, this._map);
// save in cache to avoid recomputing this
pattern.cache[zoom][pathIndex] = dirPoints;
return dirPoints;

@@ -545,6 +402,6 @@ },

},
/**
* "Soft" redraw, called internally for example on zoom changes,
* keeping the cache.
* keeping the cache.
*/

@@ -554,3 +411,3 @@ _softRedraw: function() {

},
_redraw: function(clearCache) {

@@ -567,3 +424,3 @@ if(this._map === null)

},
/**

@@ -598,1 +455,179 @@ * Draw a single pattern

};
L.RotatedMarker = L.Marker.extend({
options: {
angle: 0
},
statics: {
TRANSFORM_ORIGIN: L.DomUtil.testProp(
['transformOrigin', 'WebkitTransformOrigin', 'OTransformOrigin', 'MozTransformOrigin', 'msTransformOrigin'])
},
_initIcon: function() {
L.Marker.prototype._initIcon.call(this);
this._icon.style[L.RotatedMarker.TRANSFORM_ORIGIN] = '50% 50%';
},
_setPos: function (pos) {
L.Marker.prototype._setPos.call(this, pos);
if (L.DomUtil.TRANSFORM) {
// use the CSS transform rule if available
this._icon.style[L.DomUtil.TRANSFORM] += ' rotate(' + this.options.angle + 'deg)';
} else if(L.Browser.ie) {
// fallback for IE6, IE7, IE8
var rad = this.options.angle * (Math.PI / 180),
costheta = Math.cos(rad),
sintheta = Math.sin(rad);
this._icon.style.filter += ' progid:DXImageTransform.Microsoft.Matrix(sizingMethod=\'auto expand\', M11=' +
costheta + ', M12=' + (-sintheta) + ', M21=' + sintheta + ', M22=' + costheta + ')';
}
},
setAngle: function (ang) {
this.options.angle = ang;
}
});
L.rotatedMarker = function (pos, options) {
return new L.RotatedMarker(pos, options);
};
/**
* Defines several classes of symbol factories,
* to be used with L.PolylineDecorator
*/
L.Symbol = L.Symbol || {};
/**
* A simple dash symbol, drawn as a Polyline.
* Can also be used for dots, if 'pixelSize' option is given the 0 value.
*/
L.Symbol.Dash = L.Class.extend({
isZoomDependant: true,
options: {
pixelSize: 10,
pathOptions: { }
},
initialize: function (options) {
L.Util.setOptions(this, options);
this.options.pathOptions.clickable = false;
},
buildSymbol: function(dirPoint, latLngs, map, index, total) {
var opts = this.options,
d2r = Math.PI / 180;
// for a dot, nothing more to compute
if(opts.pixelSize <= 1) {
return new L.Polyline([dirPoint.latLng, dirPoint.latLng], opts.pathOptions);
}
var midPoint = map.project(dirPoint.latLng);
var angle = (-(dirPoint.heading - 90)) * d2r;
var a = new L.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 new L.Polyline([map.unproject(a), map.unproject(b)], opts.pathOptions);
}
});
L.Symbol.dash = function (options) {
return new L.Symbol.Dash(options);
};
L.Symbol.ArrowHead = L.Class.extend({
isZoomDependant: true,
options: {
polygon: true,
pixelSize: 10,
headAngle: 60,
pathOptions: {
stroke: false,
weight: 2
}
},
initialize: function (options) {
L.Util.setOptions(this, options);
this.options.pathOptions.clickable = false;
},
buildSymbol: function(dirPoint, latLngs, map, index, total) {
var opts = this.options;
var path;
if(opts.polygon) {
path = new L.Polygon(this._buildArrowPath(dirPoint, map), opts.pathOptions);
} else {
path = new L.Polyline(this._buildArrowPath(dirPoint, map), opts.pathOptions);
}
return path;
},
_buildArrowPath: function (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,
headAngle2 = direction - radianArrowAngle;
var arrowHead1 = new L.Point(
tipPoint.x - this.options.pixelSize * Math.cos(headAngle1),
tipPoint.y + this.options.pixelSize * Math.sin(headAngle1)),
arrowHead2 = new L.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.Symbol.arrowHead = function (options) {
return new L.Symbol.ArrowHead(options);
};
L.Symbol.Marker = L.Class.extend({
isZoomDependant: false,
options: {
markerOptions: { },
rotate: false
},
initialize: function (options) {
L.Util.setOptions(this, options);
this.options.markerOptions.clickable = false;
this.options.markerOptions.draggable = false;
this.isZoomDependant = (L.Browser.ie && this.options.rotate);
},
buildSymbol: function(directionPoint, latLngs, map, index, total) {
if(!this.options.rotate) {
return new L.Marker(directionPoint.latLng, this.options.markerOptions);
}
else {
this.options.markerOptions.angle = directionPoint.heading + (this.options.angleCorrection || 0);
return new L.RotatedMarker(directionPoint.latLng, this.options.markerOptions);
}
}
});
L.Symbol.marker = function (options) {
return new L.Symbol.Marker(options);
};
{
"name": "leaflet-polylinedecorator",
"description": "A plug-in for the Leaflet map library to define patterns (like dashes, arrows, icons, etc.) on Polylines",
"keywords": ["leaflet", "map", "polyline", "decorator", "patterns", "overlay"],
"version": "0.7.2",
"version": "1.0.1",
"repository": "bbecquet/Leaflet.PolylineDecorator",
"main": "leaflet.polylineDecorator.js",
"devDependencies": {
"gulp": "^3.9.0",
"gulp-concat": "^2.6.0"
},
"license": "MIT"
}

@@ -5,2 +5,8 @@ # Leaflet PolylineDecorator

## Compatibility with Leaflet versions
The development version of the plugin (on the `master` branch) is targeted at the 1.x version of Leaflet.
For a version of the plugin compatible with the 0.7.x Leaflet release, use the `leaflet-0.7.2` branch.
## Features

@@ -13,21 +19,49 @@

## Screenshot
![screenshot](https://raw.github.com/bbecquet/Leaflet.PolylineDecorator/master/screenshot.png "Screenshot showing different applications of the library")
## Usage
```javascript
var polyline = L.polyline([...]).addTo(map);
var decorator = L.polylineDecorator(polyline, {
patterns: [
// define a pattern of 10px-wide dashes, repeated every 20px on the line
{offset: 0, repeat: '20px', symbol: new L.Symbol.Dash({pixelSize: 10})}
]
}).addTo(map);
```
To create a decorator and add it to the map: `L.polylineDecorator(latlngs, options).addTo(map);`
The `polyline` parameter can be a single array of `L.LatLng` or, with Leaflet's simplified syntax, an array of 2-cells arrays of coordinates.
It is useful if you don't want to actually display a polyline, but just a pattern following coordinates, like a dotted line.
* `latlngs` can be one of the following types:
## Screenshot
* `L.Polyline`
* `L.Polygon`
* an array of `L.LatLng`, or with Leaflet's simplified syntax, an array of 2-cells arrays of coordinates (useful if you just want to draw patterns following coordinates, but not the line itself)
* an array of any of these previous types, to apply the same patterns to multiple lines
![screenshot](https://raw.github.com/bbecquet/Leaflet.PolylineDecorator/master/screenshot.png "Screenshot showing different applications of the library")
* `options` has a single property `patterns`, which is an array of `Pattern` objects.
### `Pattern` definition
Property | Type | Required | Description
--- | --- | --- | ---
`offset`| *see below* | No | Offset of the first pattern symbol, from the start point of the line. Default: 0.
`endOffset`| *see below* | No | Minimum offset of the last pattern symbol, from the end point of the line. Default: 0.
`repeat`| *see below* | Yes | Repetition interval of the pattern symbols. Defines the distance between each consecutive symbol's anchor point.
`symbol`| Symbol factory | Yes | Instance of a symbol factory class.
`offset`, `endOffset` and `repeat` can be each defined as a number, in pixels, or in percentage of the line's length, as a string (ex: `'10%'`).
### Methods
Method | Description
--- | ---
`setPaths(latlngs)` | Changes the path(s) the decorator applies to. `latlngs` can be all the types supported by the constructor. Useful for example if you remove polyline from a set, or coordinates change.
`setPatterns(<Pattern[]> patterns)` | Changes the decorator's pattern definitions, and update the symbols accordingly.
## Example
```javascript
var polyline = L.polyline([...]).addTo(map);
var decorator = L.polylineDecorator(polyline, {
patterns: [
// defines a pattern of 10px-wide dashes, repeated every 20px on the line
{offset: 0, repeat: 20, symbol: L.Symbol.dash({pixelSize: 10})}
]
}).addTo(map);
```
## Performance note

@@ -38,9 +72,1 @@

In cases where it's applicable (dash patterns), you should probably use instead the `dashArray` property of `L.Path`, as it's natively drawn by the browser.
## TODO
* Documentation
* Optimize rendering and mem footprint
* Other symbol types
* Animations(?)

@@ -40,7 +40,9 @@

* offsetRatio: the ratio of the total pixel length where the pattern will start
* endOffsetRatio: the ratio of the total pixel length where the pattern will end
* repeatRatio: the ratio of the total pixel length between two points of the pattern
* map: the map, to access the current projection state
*/
projectPatternOnPath: function (path, offsetRatio, repeatRatio, map) {
projectPatternOnPath: function (path, offsetRatio, endOffsetRatio, repeatRatio, map) {
var pathAsPoints = [], i;
for(i=0, l=path.length; i<l; i++) {

@@ -50,3 +52,3 @@ pathAsPoints[i] = map.project(path[i]);

// project the pattern as pixel points
var pattern = this.projectPatternOnPointPath(pathAsPoints, offsetRatio, repeatRatio);
var pattern = this.projectPatternOnPointPath(pathAsPoints, offsetRatio, endOffsetRatio, repeatRatio);
// and convert it to latlngs;

@@ -59,8 +61,10 @@ for(i=0, l=pattern.length; i<l; i++) {

projectPatternOnPointPath: function (pts, offsetRatio, repeatRatio) {
projectPatternOnPointPath: function (pts, offsetRatio, endOffsetRatio, repeatRatio) {
var positions = [];
// 1. compute the absolute interval length in pixels
var repeatIntervalLength = this.getPointPathPixelLength(pts) * repeatRatio;
// 2. find the starting point by using the offsetRatio
// 2. find the starting point by using the offsetRatio and find the last pixel using endOffsetRatio
var previous = this.interpolateOnPointPath(pts, offsetRatio);
var endOffsetPixels = endOffsetRatio > 0 ? this.getPointPathPixelLength(pts) * endOffsetRatio : 0;
positions.push(previous);

@@ -71,7 +75,10 @@ if(repeatRatio > 0) {

remainingPath = remainingPath.slice(previous.predecessor);
remainingPath[0] = previous.pt;
var remainingLength = this.getPointPathPixelLength(remainingPath);
// 4. project as a ratio of the remaining length,
// and repeat while there is room for another point of the pattern
while(repeatIntervalLength <= remainingLength) {
while(repeatIntervalLength <= remainingLength-endOffsetPixels) {
previous = this.interpolateOnPointPath(remainingPath, repeatIntervalLength/remainingLength);

@@ -165,2 +172,2 @@ positions.push(previous);

}
};
};

@@ -18,3 +18,3 @@

* array of LatLng, array of 2-number arrays, Polyline, Polygon,
* array of one of the previous, MultiPolyline, MultiPolygon.
* array of one of the previous.
*/

@@ -24,8 +24,3 @@ _initPaths: function(p) {

var isPolygon = false;
if(p instanceof L.MultiPolyline || (isPolygon = (p instanceof L.MultiPolygon))) {
var lines = p.getLatLngs();
for(var i=0; i<lines.length; i++) {
this._initPath(lines[i], isPolygon);
}
} else if(p instanceof L.Polyline) {
if(p instanceof L.Polyline) {
this._initPath(p.getLatLngs(), (p instanceof L.Polygon));

@@ -45,3 +40,3 @@ } else if(L.Util.isArray(p) && p.length > 0) {

return(L.Util.isArray(ll) && ll.length > 0 && (
ll[0] instanceof L.LatLng ||
ll[0] instanceof L.LatLng ||
(L.Util.isArray(ll[0]) && ll[0].length == 2 && typeof ll[0][0] === 'number')

@@ -68,3 +63,3 @@ ));

}
},
},

@@ -82,2 +77,3 @@ _initPatterns: function() {

pattern.isOffsetInPixels ||
pattern.isEndOffsetInPixels ||
pattern.isRepeatInPixels ||

@@ -89,3 +85,3 @@ pattern.symbolFactory.isZoomDependant;

/**
* Changes the patterns used by this decorator
* Changes the patterns used by this decorator
* and redraws the new one.

@@ -100,3 +96,3 @@ */

/**
* Changes the patterns used by this decorator
* Changes the patterns used by this decorator
* and redraws the new one.

@@ -117,5 +113,6 @@ */

isOffsetInPixels: false,
isEndOffsetInPixels: false,
isRepeatInPixels: false
};
// Parse offset and repeat values, managing the two cases:

@@ -126,7 +123,13 @@ // absolute (in pixels) or relative (in percentage of the polyline length)

} else {
pattern.offset = parseFloat(patternDef.offset);
pattern.offset = patternDef.offset ? parseFloat(patternDef.offset) : 0;
pattern.isOffsetInPixels = (pattern.offset > 0);
}
if(typeof patternDef.endOffset === 'string' && patternDef.endOffset.indexOf('%') != -1) {
pattern.endOffset = parseFloat(patternDef.endOffset) / 100;
} else {
pattern.endOffset = patternDef.endOffset ? parseFloat(patternDef.endOffset) : 0;
pattern.isEndOffsetInPixels = (pattern.endOffset > 0);
}
if(typeof patternDef.repeat === 'string' && patternDef.repeat.indexOf('%') != -1) {

@@ -138,5 +141,3 @@ pattern.repeat = parseFloat(patternDef.repeat) / 100;

}
// TODO: 0 => not pixel dependant => 0%
return(pattern);

@@ -184,3 +185,3 @@ },

* that define positions and directions of the symbols
* on the path
* on the path
*/

@@ -194,3 +195,3 @@ _getDirectionPoints: function(pathIndex, pattern) {

var offset, repeat, pathPixelLength = null, latLngs = this._paths[pathIndex];
var offset, endOffset, repeat, pathPixelLength = null, latLngs = this._paths[pathIndex];
if(pattern.isOffsetInPixels) {

@@ -202,12 +203,18 @@ pathPixelLength = L.LineUtil.PolylineDecorator.getPixelLength(latLngs, this._map);

}
if(pattern.isEndOffsetInPixels) {
pathPixelLength = (pathPixelLength !== null) ? pathPixelLength : L.LineUtil.PolylineDecorator.getPixelLength(latLngs, this._map);
endOffset = pattern.endOffset/pathPixelLength;
} else {
endOffset = pattern.endOffset;
}
if(pattern.isRepeatInPixels) {
pathPixelLength = (pathPixelLength !== null) ? pathPixelLength : L.LineUtil.PolylineDecorator.getPixelLength(latLngs, this._map);
repeat = pattern.repeat/pathPixelLength;
repeat = pattern.repeat/pathPixelLength;
} else {
repeat = pattern.repeat;
}
dirPoints = L.LineUtil.PolylineDecorator.projectPatternOnPath(latLngs, offset, repeat, this._map);
dirPoints = L.LineUtil.PolylineDecorator.projectPatternOnPath(latLngs, offset, endOffset, repeat, this._map);
// save in cache to avoid recomputing this
pattern.cache[zoom][pathIndex] = dirPoints;
return dirPoints;

@@ -222,6 +229,6 @@ },

},
/**
* "Soft" redraw, called internally for example on zoom changes,
* keeping the cache.
* keeping the cache.
*/

@@ -231,3 +238,3 @@ _softRedraw: function() {

},
_redraw: function(clearCache) {

@@ -244,3 +251,3 @@ if(this._map === null)

},
/**

@@ -247,0 +254,0 @@ * Draw a single pattern

@@ -5,5 +5,17 @@ L.RotatedMarker = L.Marker.extend({

},
statics: {
TRANSFORM_ORIGIN: L.DomUtil.testProp(
['transformOrigin', 'WebkitTransformOrigin', 'OTransformOrigin', 'MozTransformOrigin', 'msTransformOrigin'])
},
_initIcon: function() {
L.Marker.prototype._initIcon.call(this);
this._icon.style[L.RotatedMarker.TRANSFORM_ORIGIN] = '50% 50%';
},
_setPos: function (pos) {
L.Marker.prototype._setPos.call(this, pos);
if (L.DomUtil.TRANSFORM) {

@@ -14,8 +26,12 @@ // use the CSS transform rule if available

// fallback for IE6, IE7, IE8
var rad = this.options.angle * L.LatLng.DEG_TO_RAD,
var rad = this.options.angle * (Math.PI / 180),
costheta = Math.cos(rad),
sintheta = Math.sin(rad);
this._icon.style.filter += ' progid:DXImageTransform.Microsoft.Matrix(sizingMethod=\'auto expand\', M11=' +
costheta + ', M12=' + (-sintheta) + ', M21=' + sintheta + ', M22=' + costheta + ')';
this._icon.style.filter += ' progid:DXImageTransform.Microsoft.Matrix(sizingMethod=\'auto expand\', M11=' +
costheta + ', M12=' + (-sintheta) + ', M21=' + sintheta + ', M22=' + costheta + ')';
}
},
setAngle: function (ang) {
this.options.angle = ang;
}

@@ -26,2 +42,2 @@ });

return new L.RotatedMarker(pos, options);
};
};

@@ -26,3 +26,4 @@ /**

buildSymbol: function(dirPoint, latLngs, map, index, total) {
var opts = this.options;
var opts = this.options,
d2r = Math.PI / 180;

@@ -35,3 +36,3 @@ // for a dot, nothing more to compute

var midPoint = map.project(dirPoint.latLng);
var angle = (-(dirPoint.heading - 90)) * L.LatLng.DEG_TO_RAD;
var angle = (-(dirPoint.heading - 90)) * d2r;
var a = new L.Point(

@@ -81,5 +82,6 @@ midPoint.x + opts.pixelSize * Math.cos(angle + Math.PI) / 2,

_buildArrowPath: function (dirPoint, map) {
var d2r = Math.PI / 180;
var tipPoint = map.project(dirPoint.latLng);
var direction = (-(dirPoint.heading - 90)) * L.LatLng.DEG_TO_RAD;
var radianArrowAngle = this.options.headAngle / 2 * L.LatLng.DEG_TO_RAD;
var direction = (-(dirPoint.heading - 90)) * d2r;
var radianArrowAngle = this.options.headAngle / 2 * d2r;

@@ -127,3 +129,3 @@ var headAngle1 = direction + radianArrowAngle,

else {
this.options.markerOptions.angle = directionPoint.heading;
this.options.markerOptions.angle = directionPoint.heading + (this.options.angleCorrection || 0);
return new L.RotatedMarker(directionPoint.latLng, this.options.markerOptions);

@@ -130,0 +132,0 @@ }

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc