initial working Path/Polyline implementation
This commit is contained in:
parent
568fd154e2
commit
076255f33f
127
build/deps.js
127
build/deps.js
@ -84,84 +84,87 @@ var deps = {
|
|||||||
desc: 'Extends LayerGroup with mouse events and bindPopup method shared between layers.'
|
desc: 'Extends LayerGroup with mouse events and bindPopup method shared between layers.'
|
||||||
},
|
},
|
||||||
|
|
||||||
Path: {
|
// Path: {
|
||||||
src: ['layer/vector/Path.js',
|
// src: ['layer/vector/Path.js',
|
||||||
'layer/vector/Path.SVG.js',
|
// 'layer/vector/Path.SVG.js',
|
||||||
'layer/vector/Path.Popup.js'],
|
// 'layer/vector/Path.Popup.js'],
|
||||||
desc: 'Vector rendering core (SVG-powered), enables overlaying the map with SVG paths.',
|
// desc: 'Vector rendering core (SVG-powered), enables overlaying the map with SVG paths.',
|
||||||
heading: 'Vector layers'
|
// heading: 'Vector layers'
|
||||||
},
|
// },
|
||||||
|
|
||||||
PathVML: {
|
// PathVML: {
|
||||||
src: ['layer/vector/Path.VML.js'],
|
// src: ['layer/vector/Path.VML.js'],
|
||||||
desc: 'VML fallback for vector rendering core (IE 6-8).'
|
// desc: 'VML fallback for vector rendering core (IE 6-8).'
|
||||||
},
|
// },
|
||||||
|
|
||||||
PathCanvas: {
|
// PathCanvas: {
|
||||||
src: ['layer/vector/canvas/Path.Canvas.js'],
|
// src: ['layer/vector/canvas/Path.Canvas.js'],
|
||||||
deps: ['Path', 'Polyline', 'Polygon', 'Circle'],
|
// deps: ['Path', 'Polyline', 'Polygon', 'Circle'],
|
||||||
desc: 'Canvas fallback for vector rendering core (makes it work on Android 2+).'
|
// desc: 'Canvas fallback for vector rendering core (makes it work on Android 2+).'
|
||||||
},
|
// },
|
||||||
|
|
||||||
Polyline: {
|
// Polyline: {
|
||||||
src: ['geometry/LineUtil.js',
|
// src: ['geometry/LineUtil.js',
|
||||||
'layer/vector/Polyline.js'],
|
// 'layer/vector/Polyline.js'],
|
||||||
deps: ['Path'],
|
// deps: ['Path'],
|
||||||
desc: 'Polyline overlays.'
|
// desc: 'Polyline overlays.'
|
||||||
},
|
// },
|
||||||
|
|
||||||
Polygon: {
|
// Polygon: {
|
||||||
src: ['geometry/PolyUtil.js',
|
// src: ['geometry/PolyUtil.js',
|
||||||
'layer/vector/Polygon.js'],
|
// 'layer/vector/Polygon.js'],
|
||||||
deps: ['Polyline'],
|
// deps: ['Polyline'],
|
||||||
desc: 'Polygon overlays.'
|
// desc: 'Polygon overlays.'
|
||||||
},
|
// },
|
||||||
|
|
||||||
MultiPoly: {
|
// MultiPoly: {
|
||||||
src: ['layer/vector/MultiPoly.js'],
|
// src: ['layer/vector/MultiPoly.js'],
|
||||||
deps: ['FeatureGroup', 'Polyline', 'Polygon'],
|
// deps: ['FeatureGroup', 'Polyline', 'Polygon'],
|
||||||
desc: 'MultiPolygon and MultyPolyline layers.'
|
// desc: 'MultiPolygon and MultyPolyline layers.'
|
||||||
},
|
// },
|
||||||
|
|
||||||
Rectangle: {
|
// Rectangle: {
|
||||||
src: ['layer/vector/Rectangle.js'],
|
// src: ['layer/vector/Rectangle.js'],
|
||||||
deps: ['Polygon'],
|
// deps: ['Polygon'],
|
||||||
desc: ['Rectangle overlays.']
|
// desc: ['Rectangle overlays.']
|
||||||
},
|
// },
|
||||||
|
|
||||||
Circle: {
|
// Circle: {
|
||||||
src: ['layer/vector/Circle.js'],
|
// src: ['layer/vector/Circle.js'],
|
||||||
deps: ['Path'],
|
// deps: ['Path'],
|
||||||
desc: 'Circle overlays (with radius in meters).'
|
// desc: 'Circle overlays (with radius in meters).'
|
||||||
},
|
// },
|
||||||
|
|
||||||
CircleMarker: {
|
// CircleMarker: {
|
||||||
src: ['layer/vector/CircleMarker.js'],
|
// src: ['layer/vector/CircleMarker.js'],
|
||||||
deps: ['Circle'],
|
// deps: ['Circle'],
|
||||||
desc: 'Circle overlays with a constant pixel radius.'
|
// desc: 'Circle overlays with a constant pixel radius.'
|
||||||
},
|
// },
|
||||||
|
|
||||||
VectorsCanvas: {
|
// VectorsCanvas: {
|
||||||
src: ['layer/vector/canvas/Polyline.Canvas.js',
|
// src: ['layer/vector/canvas/Polyline.Canvas.js',
|
||||||
'layer/vector/canvas/Polygon.Canvas.js',
|
// 'layer/vector/canvas/Polygon.Canvas.js',
|
||||||
'layer/vector/canvas/Circle.Canvas.js',
|
// 'layer/vector/canvas/Circle.Canvas.js',
|
||||||
'layer/vector/canvas/CircleMarker.Canvas.js'],
|
// 'layer/vector/canvas/CircleMarker.Canvas.js'],
|
||||||
deps: ['PathCanvas', 'Polyline', 'Polygon', 'Circle', 'CircleMarker'],
|
// deps: ['PathCanvas', 'Polyline', 'Polygon', 'Circle', 'CircleMarker'],
|
||||||
desc: 'Canvas fallback for vector layers (polygons, polylines, circles, circlemarkers)'
|
// desc: 'Canvas fallback for vector layers (polygons, polylines, circles, circlemarkers)'
|
||||||
},
|
// },
|
||||||
|
|
||||||
Vector2: {
|
Vector2: {
|
||||||
src: [
|
src: [
|
||||||
'layer/vector2/Renderer.js',
|
'layer/vector2/Renderer.js',
|
||||||
'layer/vector2/SVG.js'],
|
'layer/vector2/SVG.js',
|
||||||
|
'layer/vector2/Path.js',
|
||||||
|
'geometry/LineUtil.js',
|
||||||
|
'layer/vector2/Polyline.js'],
|
||||||
desc: 'New vector layers implementation.'
|
desc: 'New vector layers implementation.'
|
||||||
},
|
},
|
||||||
|
|
||||||
GeoJSON: {
|
// GeoJSON: {
|
||||||
src: ['layer/GeoJSON.js'],
|
// src: ['layer/GeoJSON.js'],
|
||||||
deps: ['CircleMarker', 'Marker', 'MultiPoly', 'FeatureGroup'],
|
// deps: ['CircleMarker', 'Marker', 'MultiPoly', 'FeatureGroup'],
|
||||||
desc: 'GeoJSON layer, parses the data and adds corresponding layers above.'
|
// desc: 'GeoJSON layer, parses the data and adds corresponding layers above.'
|
||||||
},
|
// },
|
||||||
|
|
||||||
|
|
||||||
MapDrag: {
|
MapDrag: {
|
||||||
|
40
debug/vector/vector2.html
Normal file
40
debug/vector/vector2.html
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Leaflet debug page</title>
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="../../dist/leaflet.css" />
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="../css/screen.css" />
|
||||||
|
<script type="text/javascript" src="../../build/deps.js"></script>
|
||||||
|
<script src="../leaflet-include.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="map" style="width: 800px; height: 600px; border: 1px solid #ccc"></div>
|
||||||
|
|
||||||
|
<script src="route.js"></script>
|
||||||
|
<script>
|
||||||
|
var cloudmadeUrl = 'http://{s}.tile.cloudmade.com/d4fc77ea4a63471cab2423e66626cbb6/997/256/{z}/{x}/{y}.png',
|
||||||
|
cloudmade = new L.TileLayer(cloudmadeUrl, {maxZoom: 18});
|
||||||
|
|
||||||
|
for (var i = 0, latlngs = [], len = route.length; i < len; i++) {
|
||||||
|
latlngs.push(new L.LatLng(route[i][0], route[i][1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
var svg = new L.SVG();
|
||||||
|
var path = new L.Polyline(latlngs, {renderer: svg});
|
||||||
|
|
||||||
|
var map = new L.Map('map', {layers: [cloudmade]});
|
||||||
|
|
||||||
|
map.fitBounds(new L.LatLngBounds(latlngs));
|
||||||
|
|
||||||
|
// map.addLayer(new L.Marker(latlngs[0]));
|
||||||
|
// map.addLayer(new L.Marker(latlngs[len - 1]));
|
||||||
|
|
||||||
|
map.addLayer(svg);
|
||||||
|
map.addLayer(path);
|
||||||
|
|
||||||
|
// path.bindPopup("Hello world");
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
61
src/layer/vector2/Path.js
Normal file
61
src/layer/vector2/Path.js
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
|
||||||
|
L.Path = L.Layer.extend({
|
||||||
|
|
||||||
|
options: {
|
||||||
|
stroke: true,
|
||||||
|
color: '#0033ff',
|
||||||
|
// dashArray: null,
|
||||||
|
// lineCap: null,
|
||||||
|
// lineJoin: null,
|
||||||
|
weight: 5,
|
||||||
|
opacity: 0.5,
|
||||||
|
|
||||||
|
// fill: false,
|
||||||
|
// fillColor: null, same as color by default
|
||||||
|
fillOpacity: 0.2,
|
||||||
|
|
||||||
|
// className: ''
|
||||||
|
clickable: true
|
||||||
|
},
|
||||||
|
|
||||||
|
onAdd: function () {
|
||||||
|
this._renderer._initPath(this);
|
||||||
|
|
||||||
|
this._projectLatlngs();
|
||||||
|
this._updatePath();
|
||||||
|
|
||||||
|
this._renderer._addPath(this);
|
||||||
|
},
|
||||||
|
|
||||||
|
onRemove: function () {
|
||||||
|
this._renderer._removePath(this);
|
||||||
|
},
|
||||||
|
|
||||||
|
getEvents: function () {
|
||||||
|
return {
|
||||||
|
viewreset: this._projectLatlngs,
|
||||||
|
moveend: this._updatePath
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
redraw: function () {
|
||||||
|
if (this._map) {
|
||||||
|
this._projectLatlngs();
|
||||||
|
this._updatePath();
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
_updatePath: function () {
|
||||||
|
if (!this._map) { return; }
|
||||||
|
|
||||||
|
this._clipPoints();
|
||||||
|
this._simplifyPoints();
|
||||||
|
|
||||||
|
this._renderer._updatePoly(this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
L.polyline2 = function (latlngs, options) {
|
||||||
|
return new L.Polyline2(latlngs, options);
|
||||||
|
};
|
107
src/layer/vector2/Polyline.js
Normal file
107
src/layer/vector2/Polyline.js
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
|
||||||
|
L.Polyline = L.Path.extend({
|
||||||
|
|
||||||
|
options: {
|
||||||
|
// how much to simplify the polyline on each zoom level
|
||||||
|
// more = better performance and smoother look, less = more accurate
|
||||||
|
smoothFactor: 1.0
|
||||||
|
// noClip: false
|
||||||
|
},
|
||||||
|
|
||||||
|
initialize: function (latlngs, options) {
|
||||||
|
L.setOptions(this, options);
|
||||||
|
|
||||||
|
this._latlngs = this._convertLatLngs(latlngs);
|
||||||
|
this._renderer = options.renderer;
|
||||||
|
},
|
||||||
|
|
||||||
|
getLatLngs: function () {
|
||||||
|
return this._latlngs;
|
||||||
|
},
|
||||||
|
|
||||||
|
setLatLngs: function (latlngs) {
|
||||||
|
this._latlngs = this._convertLatLngs(latlngs);
|
||||||
|
return this.redraw();
|
||||||
|
},
|
||||||
|
|
||||||
|
addLatLng: function (latlng) {
|
||||||
|
this._latlngs.push(L.latLng(latlng));
|
||||||
|
return this.redraw();
|
||||||
|
},
|
||||||
|
|
||||||
|
spliceLatLngs: function () {
|
||||||
|
var removed = [].splice.apply(this._latlngs, arguments);
|
||||||
|
this._convertLatLngs(this._latlngs, true);
|
||||||
|
this.redraw();
|
||||||
|
return removed;
|
||||||
|
},
|
||||||
|
|
||||||
|
// TODO closestLayerPoint?
|
||||||
|
|
||||||
|
getBounds: function () {
|
||||||
|
return new L.LatLngBounds(this.getLatLngs());
|
||||||
|
},
|
||||||
|
|
||||||
|
_convertLatLngs: function (latlngs, overwrite) {
|
||||||
|
var target = overwrite ? latlngs : [];
|
||||||
|
|
||||||
|
for (var i = 0, len = latlngs.length; i < len; i++) {
|
||||||
|
if (L.Util.isArray(latlngs[i]) && typeof latlngs[i][0] !== 'number') { return; }
|
||||||
|
target[i] = L.latLng(latlngs[i]);
|
||||||
|
}
|
||||||
|
return target;
|
||||||
|
},
|
||||||
|
|
||||||
|
_projectLatlngs: function () {
|
||||||
|
this._originalPoints = [];
|
||||||
|
|
||||||
|
for (var i = 0, len = this._latlngs.length; i < len; i++) {
|
||||||
|
this._originalPoints[i] = this._map.latLngToLayerPoint(this._latlngs[i]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_clipPoints: function () {
|
||||||
|
var points = this._originalPoints;
|
||||||
|
|
||||||
|
if (this.options.noClip) {
|
||||||
|
this._parts = [points];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._parts = [];
|
||||||
|
|
||||||
|
var parts = this._parts,
|
||||||
|
bounds = this._renderer._bounds,
|
||||||
|
len = points.length,
|
||||||
|
i, k, segment;
|
||||||
|
|
||||||
|
for (i = 0, k = 0; i < len - 1; i++) {
|
||||||
|
segment = L.LineUtil.clipSegment(points[i], points[i + 1], bounds, i);
|
||||||
|
|
||||||
|
if (!segment) { continue; }
|
||||||
|
|
||||||
|
parts[k] = parts[k] || [];
|
||||||
|
parts[k].push(segment[0]);
|
||||||
|
|
||||||
|
// if segment goes out of screen, or it's the last one, it's the end of the line part
|
||||||
|
if ((segment[1] !== points[i + 1]) || (i === len - 2)) {
|
||||||
|
parts[k].push(segment[1]);
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// simplify each clipped part of the polyline
|
||||||
|
_simplifyPoints: function () {
|
||||||
|
var parts = this._parts,
|
||||||
|
tolerance = this.options.smoothFactor;
|
||||||
|
|
||||||
|
for (var i = 0, len = parts.length; i < len; i++) {
|
||||||
|
parts[i] = L.LineUtil.simplify(parts[i], tolerance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
L.polyline = function (latlngs, options) {
|
||||||
|
return new L.Polyline(latlngs, options);
|
||||||
|
};
|
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
L.SVG = L.Renderer.extend({
|
L.SVG = L.Renderer.extend({
|
||||||
|
|
||||||
onAdd: function (map) {
|
onAdd: function () {
|
||||||
var container = this._container = L.SVG.create('svg');
|
var container = this._container = L.SVG.create('svg');
|
||||||
|
|
||||||
if (this._zoomAnimated) {
|
if (this._zoomAnimated) {
|
||||||
@ -16,6 +16,9 @@ L.SVG = L.Renderer.extend({
|
|||||||
L.DomUtil.remove(this._container);
|
L.DomUtil.remove(this._container);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// TODO bringToFront, bringToBack
|
||||||
|
// TODO events
|
||||||
|
|
||||||
_update: function () {
|
_update: function () {
|
||||||
if (this._map._animatingZoom) { return; }
|
if (this._map._animatingZoom) { return; }
|
||||||
|
|
||||||
@ -42,13 +45,21 @@ L.SVG = L.Renderer.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_initPath: function (layer) {
|
_initPath: function (layer) {
|
||||||
var path = layer._path = L.SVG.create('path');
|
layer._path = L.SVG.create('path');
|
||||||
|
|
||||||
if (layer.options.className) {
|
if (layer.options.className) {
|
||||||
L.DomUtil.addClass(path, layer.options.className);
|
L.DomUtil.addClass(layer._path, layer.options.className);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._container.appendChild(path);
|
this._updateStyle(layer);
|
||||||
|
},
|
||||||
|
|
||||||
|
_addPath: function (layer) {
|
||||||
|
this._container.appendChild(layer._path);
|
||||||
|
},
|
||||||
|
|
||||||
|
_removePath: function (layer) {
|
||||||
|
L.DomUtil.remove(layer._path);
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateStyle: function (layer) {
|
_updateStyle: function (layer) {
|
||||||
@ -88,7 +99,7 @@ L.SVG = L.Renderer.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_updatePoly: function (layer, closed) {
|
_updatePoly: function (layer, closed) {
|
||||||
layer._path.setAttribute('d', L.SVG.pointsToPath(layer._points, closed) || 'M0 0');
|
layer._path.setAttribute('d', L.SVG.pointsToPath(layer._parts, closed) || 'M0 0');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -116,3 +127,8 @@ L.extend(L.SVG, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
L.Browser.svg = !!(document.createElementNS && L.SVG.create('svg').createSVGRect);
|
L.Browser.svg = !!(document.createElementNS && L.SVG.create('svg').createSVGRect);
|
||||||
|
|
||||||
|
|
||||||
|
L.svg = function () {
|
||||||
|
return new L.SVG();
|
||||||
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user