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.'
|
||||
},
|
||||
|
||||
Path: {
|
||||
src: ['layer/vector/Path.js',
|
||||
'layer/vector/Path.SVG.js',
|
||||
'layer/vector/Path.Popup.js'],
|
||||
desc: 'Vector rendering core (SVG-powered), enables overlaying the map with SVG paths.',
|
||||
heading: 'Vector layers'
|
||||
},
|
||||
// Path: {
|
||||
// src: ['layer/vector/Path.js',
|
||||
// 'layer/vector/Path.SVG.js',
|
||||
// 'layer/vector/Path.Popup.js'],
|
||||
// desc: 'Vector rendering core (SVG-powered), enables overlaying the map with SVG paths.',
|
||||
// heading: 'Vector layers'
|
||||
// },
|
||||
|
||||
PathVML: {
|
||||
src: ['layer/vector/Path.VML.js'],
|
||||
desc: 'VML fallback for vector rendering core (IE 6-8).'
|
||||
},
|
||||
// PathVML: {
|
||||
// src: ['layer/vector/Path.VML.js'],
|
||||
// desc: 'VML fallback for vector rendering core (IE 6-8).'
|
||||
// },
|
||||
|
||||
PathCanvas: {
|
||||
src: ['layer/vector/canvas/Path.Canvas.js'],
|
||||
deps: ['Path', 'Polyline', 'Polygon', 'Circle'],
|
||||
desc: 'Canvas fallback for vector rendering core (makes it work on Android 2+).'
|
||||
},
|
||||
// PathCanvas: {
|
||||
// src: ['layer/vector/canvas/Path.Canvas.js'],
|
||||
// deps: ['Path', 'Polyline', 'Polygon', 'Circle'],
|
||||
// desc: 'Canvas fallback for vector rendering core (makes it work on Android 2+).'
|
||||
// },
|
||||
|
||||
Polyline: {
|
||||
src: ['geometry/LineUtil.js',
|
||||
'layer/vector/Polyline.js'],
|
||||
deps: ['Path'],
|
||||
desc: 'Polyline overlays.'
|
||||
},
|
||||
// Polyline: {
|
||||
// src: ['geometry/LineUtil.js',
|
||||
// 'layer/vector/Polyline.js'],
|
||||
// deps: ['Path'],
|
||||
// desc: 'Polyline overlays.'
|
||||
// },
|
||||
|
||||
Polygon: {
|
||||
src: ['geometry/PolyUtil.js',
|
||||
'layer/vector/Polygon.js'],
|
||||
deps: ['Polyline'],
|
||||
desc: 'Polygon overlays.'
|
||||
},
|
||||
// Polygon: {
|
||||
// src: ['geometry/PolyUtil.js',
|
||||
// 'layer/vector/Polygon.js'],
|
||||
// deps: ['Polyline'],
|
||||
// desc: 'Polygon overlays.'
|
||||
// },
|
||||
|
||||
MultiPoly: {
|
||||
src: ['layer/vector/MultiPoly.js'],
|
||||
deps: ['FeatureGroup', 'Polyline', 'Polygon'],
|
||||
desc: 'MultiPolygon and MultyPolyline layers.'
|
||||
},
|
||||
// MultiPoly: {
|
||||
// src: ['layer/vector/MultiPoly.js'],
|
||||
// deps: ['FeatureGroup', 'Polyline', 'Polygon'],
|
||||
// desc: 'MultiPolygon and MultyPolyline layers.'
|
||||
// },
|
||||
|
||||
Rectangle: {
|
||||
src: ['layer/vector/Rectangle.js'],
|
||||
deps: ['Polygon'],
|
||||
desc: ['Rectangle overlays.']
|
||||
},
|
||||
// Rectangle: {
|
||||
// src: ['layer/vector/Rectangle.js'],
|
||||
// deps: ['Polygon'],
|
||||
// desc: ['Rectangle overlays.']
|
||||
// },
|
||||
|
||||
Circle: {
|
||||
src: ['layer/vector/Circle.js'],
|
||||
deps: ['Path'],
|
||||
desc: 'Circle overlays (with radius in meters).'
|
||||
},
|
||||
// Circle: {
|
||||
// src: ['layer/vector/Circle.js'],
|
||||
// deps: ['Path'],
|
||||
// desc: 'Circle overlays (with radius in meters).'
|
||||
// },
|
||||
|
||||
CircleMarker: {
|
||||
src: ['layer/vector/CircleMarker.js'],
|
||||
deps: ['Circle'],
|
||||
desc: 'Circle overlays with a constant pixel radius.'
|
||||
},
|
||||
// CircleMarker: {
|
||||
// src: ['layer/vector/CircleMarker.js'],
|
||||
// deps: ['Circle'],
|
||||
// desc: 'Circle overlays with a constant pixel radius.'
|
||||
// },
|
||||
|
||||
VectorsCanvas: {
|
||||
src: ['layer/vector/canvas/Polyline.Canvas.js',
|
||||
'layer/vector/canvas/Polygon.Canvas.js',
|
||||
'layer/vector/canvas/Circle.Canvas.js',
|
||||
'layer/vector/canvas/CircleMarker.Canvas.js'],
|
||||
deps: ['PathCanvas', 'Polyline', 'Polygon', 'Circle', 'CircleMarker'],
|
||||
desc: 'Canvas fallback for vector layers (polygons, polylines, circles, circlemarkers)'
|
||||
},
|
||||
// VectorsCanvas: {
|
||||
// src: ['layer/vector/canvas/Polyline.Canvas.js',
|
||||
// 'layer/vector/canvas/Polygon.Canvas.js',
|
||||
// 'layer/vector/canvas/Circle.Canvas.js',
|
||||
// 'layer/vector/canvas/CircleMarker.Canvas.js'],
|
||||
// deps: ['PathCanvas', 'Polyline', 'Polygon', 'Circle', 'CircleMarker'],
|
||||
// desc: 'Canvas fallback for vector layers (polygons, polylines, circles, circlemarkers)'
|
||||
// },
|
||||
|
||||
Vector2: {
|
||||
src: [
|
||||
'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.'
|
||||
},
|
||||
|
||||
GeoJSON: {
|
||||
src: ['layer/GeoJSON.js'],
|
||||
deps: ['CircleMarker', 'Marker', 'MultiPoly', 'FeatureGroup'],
|
||||
desc: 'GeoJSON layer, parses the data and adds corresponding layers above.'
|
||||
},
|
||||
// GeoJSON: {
|
||||
// src: ['layer/GeoJSON.js'],
|
||||
// deps: ['CircleMarker', 'Marker', 'MultiPoly', 'FeatureGroup'],
|
||||
// desc: 'GeoJSON layer, parses the data and adds corresponding layers above.'
|
||||
// },
|
||||
|
||||
|
||||
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({
|
||||
|
||||
onAdd: function (map) {
|
||||
onAdd: function () {
|
||||
var container = this._container = L.SVG.create('svg');
|
||||
|
||||
if (this._zoomAnimated) {
|
||||
@ -16,6 +16,9 @@ L.SVG = L.Renderer.extend({
|
||||
L.DomUtil.remove(this._container);
|
||||
},
|
||||
|
||||
// TODO bringToFront, bringToBack
|
||||
// TODO events
|
||||
|
||||
_update: function () {
|
||||
if (this._map._animatingZoom) { return; }
|
||||
|
||||
@ -42,13 +45,21 @@ L.SVG = L.Renderer.extend({
|
||||
},
|
||||
|
||||
_initPath: function (layer) {
|
||||
var path = layer._path = L.SVG.create('path');
|
||||
layer._path = L.SVG.create('path');
|
||||
|
||||
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) {
|
||||
@ -88,7 +99,7 @@ L.SVG = L.Renderer.extend({
|
||||
},
|
||||
|
||||
_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.svg = function () {
|
||||
return new L.SVG();
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user