build to single distributables with gulp, check-in dist not bower_components
11
.gitignore
vendored
|
|
@ -1,11 +1,4 @@
|
||||||
bower_components/leaflet-routing/libs/
|
bower_components/
|
||||||
bower_components/leaflet-routing/examples/
|
node_modules/
|
||||||
bower_components/Leaflet.Elevation/*
|
|
||||||
!bower_components/Leaflet.Elevation/dist/
|
|
||||||
!bower_components/Leaflet.Elevation/src/
|
|
||||||
bower_components/async/*
|
|
||||||
!bower_components/async/lib/
|
|
||||||
!bower_components/async/README.md
|
|
||||||
!bower_components/async/LICENSE
|
|
||||||
nbproject/
|
nbproject/
|
||||||
.idea/
|
.idea/
|
||||||
|
|
|
||||||
22
README.md
|
|
@ -48,7 +48,27 @@ This is needed for pre-loading the selected profile (unless you allowed local fi
|
||||||
|
|
||||||
python -m SimpleHTTPServer
|
python -m SimpleHTTPServer
|
||||||
|
|
||||||
2. open http://localhost:8000/brouter-web/
|
2. open http://localhost:8000/brouter-web/
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
Requires [Node and npm](http://nodejs.org/) (or [io.js](https://iojs.org)), [Bower](http://bower.io/) and [Gulp](http://gulpjs.com/):
|
||||||
|
|
||||||
|
npm install -g bower
|
||||||
|
npm install -g gulp
|
||||||
|
|
||||||
|
Install:
|
||||||
|
|
||||||
|
npm install
|
||||||
|
bower install
|
||||||
|
|
||||||
|
Build:
|
||||||
|
|
||||||
|
gulp
|
||||||
|
|
||||||
|
Develop:
|
||||||
|
|
||||||
|
gulp watch
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|
|
||||||
67
bower.json
|
|
@ -1,16 +1,71 @@
|
||||||
{
|
{
|
||||||
"name": "brouter-web",
|
"name": "brouter-web",
|
||||||
"version": "0.1.0",
|
"version": "0.5.0",
|
||||||
"main": "js/index.js",
|
"main": "dist/**/*",
|
||||||
"ignore": [
|
"ignore": [
|
||||||
"**/.*",
|
"**/.*",
|
||||||
"bower_components"
|
"bower_components"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"leaflet": "~0.7.3",
|
||||||
"leaflet-search": "*",
|
"leaflet-search": "*",
|
||||||
"leaflet-plugins": "*",
|
"leaflet-plugins": "~1.3.2",
|
||||||
"leaflet-routing": "nrenner/leaflet-routing#styles",
|
"leaflet-routing": "Turistforeningen/leaflet-routing#gh-pages",
|
||||||
"Leaflet.Elevation": "MrMufflon/Leaflet.Elevation#master",
|
"async": "~0.9.2",
|
||||||
"async": "*"
|
"d3": "~3.5.5",
|
||||||
|
"leaflet.draw": "~0.2.3",
|
||||||
|
"bootstrap": "~3.3.4",
|
||||||
|
"DataTables": "~1.10.5",
|
||||||
|
"Leaflet.Elevation": "MrMufflon/Leaflet.Elevation#master"
|
||||||
|
},
|
||||||
|
"overrides": {
|
||||||
|
"leaflet": {
|
||||||
|
"main": [
|
||||||
|
"dist/leaflet-src.js",
|
||||||
|
"dist/leaflet.css",
|
||||||
|
"dist/images/*.png"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"leaflet-search": {
|
||||||
|
"main": [
|
||||||
|
"dist/leaflet-search.src.js",
|
||||||
|
"dist/leaflet-search.min.css",
|
||||||
|
"images/*.+(png|gif)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"leaflet-plugins": {
|
||||||
|
"main": [
|
||||||
|
"control/Permalink.js",
|
||||||
|
"control/Permalink.Layer.js",
|
||||||
|
"layer/tile/Bing.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"leaflet-routing": {
|
||||||
|
"main": [
|
||||||
|
"src/utils/LineUtil.Snapping.js",
|
||||||
|
"src/utils/Marker.Snapping.js",
|
||||||
|
"src/L.Routing.js",
|
||||||
|
"src/L.Routing.Draw.js",
|
||||||
|
"src/L.Routing.Edit.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"leaflet.draw": {
|
||||||
|
"main": [
|
||||||
|
"dist/leaflet.draw-src.js",
|
||||||
|
"dist/leaflet.draw.css",
|
||||||
|
"dist/images/*.png"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"bootstrap": {
|
||||||
|
"main": [
|
||||||
|
"dist/js/bootstrap.js",
|
||||||
|
"dist/css/bootstrap.css",
|
||||||
|
"dist/css/bootstrap-theme.css",
|
||||||
|
"dist/fonts/*"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Leaflet.Elevation": {
|
||||||
|
"dependencies": null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
.lime-theme .leaflet-control.elevation .background{background-color:rgba(156,194,34,.2);-webkit-border-radius:5px;-moz-border-radius:5px;-ms-border-radius:5px;-o-border-radius:5px;border-radius:5px}.lime-theme .leaflet-control.elevation .axis line,.lime-theme .leaflet-control.elevation .axis path{fill:none;stroke:#566b13;stroke-width:2}.lime-theme .leaflet-control.elevation .area{fill:#9cc222}.lime-theme .leaflet-control.elevation .mouse-focus-line{pointer-events:none;stroke-width:1;stroke:#101404}.lime-theme .leaflet-control.elevation .elevation-toggle{cursor:pointer;box-shadow:0 1px 7px rgba(0,0,0,.4);-webkit-border-radius:5px;border-radius:5px;width:36px;height:36px;background:url(images/elevation.png) no-repeat center center #f8f8f9}.lime-theme .leaflet-control.elevation-collapsed .background{display:none}.lime-theme .leaflet-control.elevation-collapsed .elevation-toggle{display:block}.lime-theme .leaflet-control.elevation .mouse-drag{fill:rgba(99,126,11,.4)}.lime-theme .leaflet-overlay-pane .height-focus{stroke:#9cc222;fill:#9cc222}.lime-theme .leaflet-overlay-pane .height-focus.line{pointer-events:none;stroke-width:2}.steelblue-theme .leaflet-control.elevation .background{background-color:rgba(70,130,180,.2);-webkit-border-radius:5px;-moz-border-radius:5px;-ms-border-radius:5px;-o-border-radius:5px;border-radius:5px}.steelblue-theme .leaflet-control.elevation .axis line,.steelblue-theme .leaflet-control.elevation .axis path{fill:none;stroke:#0d1821;stroke-width:2}.steelblue-theme .leaflet-control.elevation .area{fill:#4682b4}.steelblue-theme .leaflet-control.elevation .mouse-focus-line{pointer-events:none;stroke-width:1;stroke:#0d1821}.steelblue-theme .leaflet-control.elevation .elevation-toggle{cursor:pointer;box-shadow:0 1px 7px rgba(0,0,0,.4);-webkit-border-radius:5px;border-radius:5px;width:36px;height:36px;background:url(images/elevation.png) no-repeat center center #f8f8f9}.steelblue-theme .leaflet-control.elevation-collapsed .background{display:none}.steelblue-theme .leaflet-control.elevation-collapsed .elevation-toggle{display:block}.steelblue-theme .leaflet-control.elevation .mouse-drag{fill:rgba(23,74,117,.4)}.steelblue-theme .leaflet-overlay-pane .height-focus{stroke:#4682b4;fill:#4682b4}.steelblue-theme .leaflet-overlay-pane .height-focus.line{pointer-events:none;stroke-width:2}.purple-theme .leaflet-control.elevation .background{background-color:rgba(115,44,123,.2);-webkit-border-radius:5px;-moz-border-radius:5px;-ms-border-radius:5px;-o-border-radius:5px;border-radius:5px}.purple-theme .leaflet-control.elevation .axis line,.purple-theme .leaflet-control.elevation .axis path{fill:none;stroke:#2d1130;stroke-width:2}.purple-theme .leaflet-control.elevation .area{fill:#732c7b}.purple-theme .leaflet-control.elevation .mouse-focus-line{pointer-events:none;stroke-width:1;stroke:#000}.purple-theme .leaflet-control.elevation .elevation-toggle{cursor:pointer;box-shadow:0 1px 7px rgba(0,0,0,.4);-webkit-border-radius:5px;border-radius:5px;width:36px;height:36px;background:url(images/elevation.png) no-repeat center center #f8f8f9}.purple-theme .leaflet-control.elevation-collapsed .background{display:none}.purple-theme .leaflet-control.elevation-collapsed .elevation-toggle{display:block}.purple-theme .leaflet-control.elevation .mouse-drag{fill:rgba(74,14,80,.4)}.purple-theme .leaflet-overlay-pane .height-focus{stroke:#732c7b;fill:#732c7b}.purple-theme .leaflet-overlay-pane .height-focus.line{pointer-events:none;stroke-width:2}
|
|
||||||
|
|
@ -1,675 +0,0 @@
|
||||||
L.Control.Elevation = L.Control.extend({
|
|
||||||
options: {
|
|
||||||
position: "topright",
|
|
||||||
theme: "lime-theme",
|
|
||||||
width: 600,
|
|
||||||
height: 175,
|
|
||||||
margins: {
|
|
||||||
top: 10,
|
|
||||||
right: 20,
|
|
||||||
bottom: 30,
|
|
||||||
left: 60
|
|
||||||
},
|
|
||||||
useHeightIndicator: true,
|
|
||||||
interpolation: "linear",
|
|
||||||
hoverNumber: {
|
|
||||||
decimalsX: 3,
|
|
||||||
decimalsY: 0,
|
|
||||||
formatter: undefined
|
|
||||||
},
|
|
||||||
xTicks: undefined,
|
|
||||||
yTicks: undefined,
|
|
||||||
collapsed: false,
|
|
||||||
yAxisMin: undefined,
|
|
||||||
yAxisMax: undefined,
|
|
||||||
forceAxisBounds: false
|
|
||||||
},
|
|
||||||
|
|
||||||
onRemove: function(map) {
|
|
||||||
this._container = null;
|
|
||||||
},
|
|
||||||
|
|
||||||
onAdd: function(map) {
|
|
||||||
this._map = map;
|
|
||||||
|
|
||||||
var opts = this.options;
|
|
||||||
var margin = opts.margins;
|
|
||||||
opts.xTicks = opts.xTicks || Math.round(this._width() / 75);
|
|
||||||
opts.yTicks = opts.yTicks || Math.round(this._height() / 30);
|
|
||||||
opts.hoverNumber.formatter = opts.hoverNumber.formatter || this._formatter;
|
|
||||||
|
|
||||||
//append theme name on body
|
|
||||||
d3.select("body").classed(opts.theme, true);
|
|
||||||
|
|
||||||
var x = this._x = d3.scale.linear()
|
|
||||||
.range([0, this._width()]);
|
|
||||||
|
|
||||||
var y = this._y = d3.scale.linear()
|
|
||||||
.range([this._height(), 0]);
|
|
||||||
|
|
||||||
var area = this._area = d3.svg.area()
|
|
||||||
.interpolate(opts.interpolation)
|
|
||||||
.x(function(d) {
|
|
||||||
return x(d.dist);
|
|
||||||
})
|
|
||||||
.y0(this._height())
|
|
||||||
.y1(function(d) {
|
|
||||||
return y(d.altitude);
|
|
||||||
});
|
|
||||||
|
|
||||||
var container = this._container = L.DomUtil.create("div", "elevation");
|
|
||||||
|
|
||||||
this._initToggle();
|
|
||||||
|
|
||||||
var cont = d3.select(container);
|
|
||||||
cont.attr("width", opts.width);
|
|
||||||
var svg = cont.append("svg");
|
|
||||||
svg.attr("width", opts.width)
|
|
||||||
.attr("class", "background")
|
|
||||||
.attr("height", opts.height)
|
|
||||||
.append("g")
|
|
||||||
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
|
|
||||||
|
|
||||||
var line = d3.svg.line();
|
|
||||||
line = line
|
|
||||||
.x(function(d) {
|
|
||||||
return d3.mouse(svg.select("g"))[0];
|
|
||||||
})
|
|
||||||
.y(function(d) {
|
|
||||||
return this._height();
|
|
||||||
});
|
|
||||||
|
|
||||||
var g = d3.select(this._container).select("svg").select("g");
|
|
||||||
|
|
||||||
this._areapath = g.append("path")
|
|
||||||
.attr("class", "area");
|
|
||||||
|
|
||||||
var background = this._background = g.append("rect")
|
|
||||||
.attr("width", this._width())
|
|
||||||
.attr("height", this._height())
|
|
||||||
.style("fill", "none")
|
|
||||||
.style("stroke", "none")
|
|
||||||
.style("pointer-events", "all");
|
|
||||||
|
|
||||||
if (L.Browser.touch) {
|
|
||||||
|
|
||||||
background.on("touchmove.drag", this._dragHandler.bind(this)).
|
|
||||||
on("touchstart.drag", this._dragStartHandler.bind(this)).
|
|
||||||
on("touchstart.focus", this._mousemoveHandler.bind(this));
|
|
||||||
L.DomEvent.on(this._container, 'touchend', this._dragEndHandler, this);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
background.on("mousemove.focus", this._mousemoveHandler.bind(this)).
|
|
||||||
on("mouseout.focus", this._mouseoutHandler.bind(this)).
|
|
||||||
on("mousedown.drag", this._dragStartHandler.bind(this)).
|
|
||||||
on("mousemove.drag", this._dragHandler.bind(this));
|
|
||||||
L.DomEvent.on(this._container, 'mouseup', this._dragEndHandler, this);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
this._xaxisgraphicnode = g.append("g");
|
|
||||||
this._yaxisgraphicnode = g.append("g");
|
|
||||||
this._appendXaxis(this._xaxisgraphicnode);
|
|
||||||
this._appendYaxis(this._yaxisgraphicnode);
|
|
||||||
|
|
||||||
var focusG = this._focusG = g.append("g");
|
|
||||||
this._mousefocus = focusG.append('svg:line')
|
|
||||||
.attr('class', 'mouse-focus-line')
|
|
||||||
.attr('x2', '0')
|
|
||||||
.attr('y2', '0')
|
|
||||||
.attr('x1', '0')
|
|
||||||
.attr('y1', '0');
|
|
||||||
this._focuslabelX = focusG.append("svg:text")
|
|
||||||
.style("pointer-events", "none")
|
|
||||||
.attr("class", "mouse-focus-label-x");
|
|
||||||
this._focuslabelY = focusG.append("svg:text")
|
|
||||||
.style("pointer-events", "none")
|
|
||||||
.attr("class", "mouse-focus-label-y");
|
|
||||||
|
|
||||||
if (this._data) {
|
|
||||||
this._applyData();
|
|
||||||
}
|
|
||||||
|
|
||||||
return container;
|
|
||||||
},
|
|
||||||
|
|
||||||
_dragHandler: function() {
|
|
||||||
|
|
||||||
//we don´t want map events to occur here
|
|
||||||
d3.event.preventDefault();
|
|
||||||
d3.event.stopPropagation();
|
|
||||||
|
|
||||||
this._gotDragged = true;
|
|
||||||
|
|
||||||
this._drawDragRectangle();
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Draws the currently dragged rectabgle over the chart.
|
|
||||||
*/
|
|
||||||
_drawDragRectangle: function() {
|
|
||||||
|
|
||||||
if (!this._dragStartCoords) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var dragEndCoords = this._dragCurrentCoords = d3.mouse(this._background.node());
|
|
||||||
|
|
||||||
var x1 = Math.min(this._dragStartCoords[0], dragEndCoords[0]),
|
|
||||||
x2 = Math.max(this._dragStartCoords[0], dragEndCoords[0]);
|
|
||||||
|
|
||||||
if (!this._dragRectangle && !this._dragRectangleG) {
|
|
||||||
var g = d3.select(this._container).select("svg").select("g");
|
|
||||||
|
|
||||||
this._dragRectangleG = g.append("g");
|
|
||||||
|
|
||||||
this._dragRectangle = this._dragRectangleG.append("rect")
|
|
||||||
.attr("width", x2 - x1)
|
|
||||||
.attr("height", this._height())
|
|
||||||
.attr("x", x1)
|
|
||||||
.attr('class', 'mouse-drag')
|
|
||||||
.style("pointer-events", "none");
|
|
||||||
} else {
|
|
||||||
this._dragRectangle.attr("width", x2 - x1)
|
|
||||||
.attr("x", x1);
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Removes the drag rectangle and zoms back to the total extent of the data.
|
|
||||||
*/
|
|
||||||
_resetDrag: function() {
|
|
||||||
|
|
||||||
if (this._dragRectangleG) {
|
|
||||||
|
|
||||||
this._dragRectangleG.remove();
|
|
||||||
this._dragRectangleG = null;
|
|
||||||
this._dragRectangle = null;
|
|
||||||
|
|
||||||
this._hidePositionMarker();
|
|
||||||
|
|
||||||
this._map.fitBounds(this._fullExtent);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Handles end of dragg operations. Zooms the map to the selected items extent.
|
|
||||||
*/
|
|
||||||
_dragEndHandler: function() {
|
|
||||||
|
|
||||||
if (!this._dragStartCoords || !this._gotDragged) {
|
|
||||||
this._dragStartCoords = null;
|
|
||||||
this._gotDragged = false;
|
|
||||||
this._resetDrag();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._hidePositionMarker();
|
|
||||||
|
|
||||||
var item1 = this._findItemForX(this._dragStartCoords[0]),
|
|
||||||
item2 = this._findItemForX(this._dragCurrentCoords[0]);
|
|
||||||
|
|
||||||
this._fitSection(item1, item2);
|
|
||||||
|
|
||||||
this._dragStartCoords = null;
|
|
||||||
this._gotDragged = false;
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
_dragStartHandler: function() {
|
|
||||||
|
|
||||||
d3.event.preventDefault();
|
|
||||||
d3.event.stopPropagation();
|
|
||||||
|
|
||||||
this._gotDragged = false;
|
|
||||||
|
|
||||||
this._dragStartCoords = d3.mouse(this._background.node());
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Finds a data entry for a given x-coordinate of the diagram
|
|
||||||
*/
|
|
||||||
_findItemForX: function(x) {
|
|
||||||
var bisect = d3.bisector(function(d) {
|
|
||||||
return d.dist;
|
|
||||||
}).left;
|
|
||||||
var xinvert = this._x.invert(x);
|
|
||||||
return bisect(this._data, xinvert);
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Make the map fit the route section between given indexes. */
|
|
||||||
_fitSection: function(index1, index2) {
|
|
||||||
|
|
||||||
var start = Math.min(index1, index2),
|
|
||||||
end = Math.max(index1, index2);
|
|
||||||
|
|
||||||
var ext = this._calculateFullExtent(this._data.slice(start, end));
|
|
||||||
|
|
||||||
this._map.fitBounds(ext);
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
_initToggle: function() {
|
|
||||||
|
|
||||||
/* inspired by L.Control.Layers */
|
|
||||||
|
|
||||||
var container = this._container;
|
|
||||||
|
|
||||||
//Makes this work on IE10 Touch devices by stopping it from firing a mouseout event when the touch is released
|
|
||||||
container.setAttribute('aria-haspopup', true);
|
|
||||||
|
|
||||||
if (!L.Browser.touch) {
|
|
||||||
L.DomEvent
|
|
||||||
.disableClickPropagation(container);
|
|
||||||
//.disableScrollPropagation(container);
|
|
||||||
} else {
|
|
||||||
L.DomEvent.on(container, 'click', L.DomEvent.stopPropagation);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.options.collapsed) {
|
|
||||||
this._collapse();
|
|
||||||
|
|
||||||
if (!L.Browser.android) {
|
|
||||||
L.DomEvent
|
|
||||||
.on(container, 'mouseover', this._expand, this)
|
|
||||||
.on(container, 'mouseout', this._collapse, this);
|
|
||||||
}
|
|
||||||
var link = this._button = L.DomUtil.create('a', 'elevation-toggle', container);
|
|
||||||
link.href = '#';
|
|
||||||
link.title = 'Elevation';
|
|
||||||
|
|
||||||
if (L.Browser.touch) {
|
|
||||||
L.DomEvent
|
|
||||||
.on(link, 'click', L.DomEvent.stop)
|
|
||||||
.on(link, 'click', this._expand, this);
|
|
||||||
} else {
|
|
||||||
L.DomEvent.on(link, 'focus', this._expand, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._map.on('click', this._collapse, this);
|
|
||||||
// TODO keyboard accessibility
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_expand: function() {
|
|
||||||
this._container.className = this._container.className.replace(' elevation-collapsed', '');
|
|
||||||
},
|
|
||||||
|
|
||||||
_collapse: function() {
|
|
||||||
L.DomUtil.addClass(this._container, 'elevation-collapsed');
|
|
||||||
},
|
|
||||||
|
|
||||||
_width: function() {
|
|
||||||
var opts = this.options;
|
|
||||||
return opts.width - opts.margins.left - opts.margins.right;
|
|
||||||
},
|
|
||||||
|
|
||||||
_height: function() {
|
|
||||||
var opts = this.options;
|
|
||||||
return opts.height - opts.margins.top - opts.margins.bottom;
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Fromatting funciton using the given decimals and seperator
|
|
||||||
*/
|
|
||||||
_formatter: function(num, dec, sep) {
|
|
||||||
var res;
|
|
||||||
if (dec === 0) {
|
|
||||||
res = Math.round(num) + "";
|
|
||||||
} else {
|
|
||||||
res = L.Util.formatNum(num, dec) + "";
|
|
||||||
}
|
|
||||||
var numbers = res.split(".");
|
|
||||||
if (numbers[1]) {
|
|
||||||
var d = dec - numbers[1].length;
|
|
||||||
for (; d > 0; d--) {
|
|
||||||
numbers[1] += "0";
|
|
||||||
}
|
|
||||||
res = numbers.join(sep || ".");
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
},
|
|
||||||
|
|
||||||
_appendYaxis: function(y) {
|
|
||||||
y.attr("class", "y axis")
|
|
||||||
.call(d3.svg.axis()
|
|
||||||
.scale(this._y)
|
|
||||||
.ticks(this.options.yTicks)
|
|
||||||
.orient("left"))
|
|
||||||
.append("text")
|
|
||||||
.attr("x", -45)
|
|
||||||
.attr("y", 3)
|
|
||||||
.style("text-anchor", "end")
|
|
||||||
.text("m");
|
|
||||||
},
|
|
||||||
|
|
||||||
_appendXaxis: function(x) {
|
|
||||||
x.attr("class", "x axis")
|
|
||||||
.attr("transform", "translate(0," + this._height() + ")")
|
|
||||||
.call(d3.svg.axis()
|
|
||||||
.scale(this._x)
|
|
||||||
.ticks(this.options.xTicks)
|
|
||||||
.orient("bottom"))
|
|
||||||
.append("text")
|
|
||||||
.attr("x", this._width() + 20)
|
|
||||||
.attr("y", 15)
|
|
||||||
.style("text-anchor", "end")
|
|
||||||
.text("km");
|
|
||||||
},
|
|
||||||
|
|
||||||
_updateAxis: function() {
|
|
||||||
this._xaxisgraphicnode.selectAll("g").remove();
|
|
||||||
this._xaxisgraphicnode.selectAll("path").remove();
|
|
||||||
this._xaxisgraphicnode.selectAll("text").remove();
|
|
||||||
this._yaxisgraphicnode.selectAll("g").remove();
|
|
||||||
this._yaxisgraphicnode.selectAll("path").remove();
|
|
||||||
this._yaxisgraphicnode.selectAll("text").remove();
|
|
||||||
this._appendXaxis(this._xaxisgraphicnode);
|
|
||||||
this._appendYaxis(this._yaxisgraphicnode);
|
|
||||||
},
|
|
||||||
|
|
||||||
_mouseoutHandler: function() {
|
|
||||||
|
|
||||||
this._hidePositionMarker();
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Hides the position-/heigth indication marker drawn onto the map
|
|
||||||
*/
|
|
||||||
_hidePositionMarker: function() {
|
|
||||||
|
|
||||||
if (this._marker) {
|
|
||||||
this._map.removeLayer(this._marker);
|
|
||||||
this._marker = null;
|
|
||||||
}
|
|
||||||
if (this._mouseHeightFocus) {
|
|
||||||
this._mouseHeightFocus.style("visibility", "hidden");
|
|
||||||
this._mouseHeightFocusLabel.style("visibility", "hidden");
|
|
||||||
}
|
|
||||||
if (this._pointG) {
|
|
||||||
this._pointG.style("visibility", "hidden");
|
|
||||||
}
|
|
||||||
this._focusG.style("visibility", "hidden");
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Handles the moueseover the chart and displays distance and altitude level
|
|
||||||
*/
|
|
||||||
_mousemoveHandler: function(d, i, ctx) {
|
|
||||||
if (!this._data || this._data.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var coords = d3.mouse(this._background.node());
|
|
||||||
var opts = this.options;
|
|
||||||
this._focusG.style("visibility", "visible");
|
|
||||||
this._mousefocus.attr('x1', coords[0])
|
|
||||||
.attr('y1', 0)
|
|
||||||
.attr('x2', coords[0])
|
|
||||||
.attr('y2', this._height())
|
|
||||||
.classed('hidden', false);
|
|
||||||
var bisect = d3.bisector(function(d) {
|
|
||||||
return d.dist;
|
|
||||||
}).left;
|
|
||||||
|
|
||||||
var item = this._data[this._findItemForX(coords[0])],
|
|
||||||
alt = item.altitude,
|
|
||||||
dist = item.dist,
|
|
||||||
ll = item.latlng,
|
|
||||||
numY = opts.hoverNumber.formatter(alt, opts.hoverNumber.decimalsY),
|
|
||||||
numX = opts.hoverNumber.formatter(dist, opts.hoverNumber.decimalsX);
|
|
||||||
|
|
||||||
this._focuslabelX.attr("x", coords[0])
|
|
||||||
.text(numY + " m");
|
|
||||||
this._focuslabelY.attr("y", this._height() - 5)
|
|
||||||
.attr("x", coords[0])
|
|
||||||
.text(numX + " km");
|
|
||||||
|
|
||||||
var layerpoint = this._map.latLngToLayerPoint(ll);
|
|
||||||
|
|
||||||
//if we use a height indicator we create one with SVG
|
|
||||||
//otherwise we show a marker
|
|
||||||
if (opts.useHeightIndicator) {
|
|
||||||
|
|
||||||
if (!this._mouseHeightFocus) {
|
|
||||||
|
|
||||||
var heightG = d3.select(".leaflet-overlay-pane svg")
|
|
||||||
.append("g");
|
|
||||||
this._mouseHeightFocus = heightG.append('svg:line')
|
|
||||||
.attr('class', 'height-focus line')
|
|
||||||
.attr('x2', '0')
|
|
||||||
.attr('y2', '0')
|
|
||||||
.attr('x1', '0')
|
|
||||||
.attr('y1', '0');
|
|
||||||
|
|
||||||
var pointG = this._pointG = heightG.append("g");
|
|
||||||
pointG.append("svg:circle")
|
|
||||||
.attr("r", 6)
|
|
||||||
.attr("cx", 0)
|
|
||||||
.attr("cy", 0)
|
|
||||||
.attr("class", "height-focus circle-lower");
|
|
||||||
|
|
||||||
this._mouseHeightFocusLabel = heightG.append("svg:text")
|
|
||||||
.attr("class", "height-focus-label")
|
|
||||||
.style("pointer-events", "none");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
var normalizedAlt = this._height() / this._maxElevation * alt;
|
|
||||||
var normalizedY = layerpoint.y - normalizedAlt;
|
|
||||||
this._mouseHeightFocus.attr("x1", layerpoint.x)
|
|
||||||
.attr("x2", layerpoint.x)
|
|
||||||
.attr("y1", layerpoint.y)
|
|
||||||
.attr("y2", normalizedY)
|
|
||||||
.style("visibility", "visible");
|
|
||||||
|
|
||||||
this._pointG.attr("transform", "translate(" + layerpoint.x + "," + layerpoint.y + ")")
|
|
||||||
.style("visibility", "visible");
|
|
||||||
|
|
||||||
this._mouseHeightFocusLabel.attr("x", layerpoint.x)
|
|
||||||
.attr("y", normalizedY)
|
|
||||||
.text(alt + " m")
|
|
||||||
.style("visibility", "visible");
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
if (!this._marker) {
|
|
||||||
|
|
||||||
this._marker = new L.Marker(ll).addTo(this._map);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
this._marker.setLatLng(ll);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Parsing of GeoJSON data lines and their elevation in z-coordinate
|
|
||||||
*/
|
|
||||||
_addGeoJSONData: function(coords) {
|
|
||||||
if (coords) {
|
|
||||||
var data = this._data || [];
|
|
||||||
var dist = this._dist || 0;
|
|
||||||
var ele = this._maxElevation || 0;
|
|
||||||
for (var i = 0; i < coords.length; i++) {
|
|
||||||
var s = new L.LatLng(coords[i][1], coords[i][0]);
|
|
||||||
var e = new L.LatLng(coords[i ? i - 1 : 0][1], coords[i ? i - 1 : 0][0]);
|
|
||||||
var newdist = s.distanceTo(e);
|
|
||||||
dist = dist + Math.round(newdist / 1000 * 100000) / 100000;
|
|
||||||
ele = ele < coords[i][2] ? coords[i][2] : ele;
|
|
||||||
data.push({
|
|
||||||
dist: dist,
|
|
||||||
altitude: coords[i][2],
|
|
||||||
x: coords[i][0],
|
|
||||||
y: coords[i][1],
|
|
||||||
latlng: s
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this._dist = dist;
|
|
||||||
this._data = data;
|
|
||||||
this._maxElevation = ele;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Parsing function for GPX data as used by https://github.com/mpetazzoni/leaflet-gpx
|
|
||||||
*/
|
|
||||||
_addGPXdata: function(coords) {
|
|
||||||
if (coords) {
|
|
||||||
var data = this._data || [];
|
|
||||||
var dist = this._dist || 0;
|
|
||||||
var ele = this._maxElevation || 0;
|
|
||||||
for (var i = 0; i < coords.length; i++) {
|
|
||||||
var s = coords[i];
|
|
||||||
var e = coords[i ? i - 1 : 0];
|
|
||||||
var newdist = s.distanceTo(e);
|
|
||||||
dist = dist + Math.round(newdist / 1000 * 100000) / 100000;
|
|
||||||
ele = ele < s.meta.ele ? s.meta.ele : ele;
|
|
||||||
data.push({
|
|
||||||
dist: dist,
|
|
||||||
altitude: s.meta.ele,
|
|
||||||
x: s.lng,
|
|
||||||
y: s.lat,
|
|
||||||
latlng: s
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this._dist = dist;
|
|
||||||
this._data = data;
|
|
||||||
this._maxElevation = ele;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_addData: function(d) {
|
|
||||||
var geom = d && d.geometry && d.geometry;
|
|
||||||
var i;
|
|
||||||
|
|
||||||
if (geom) {
|
|
||||||
switch (geom.type) {
|
|
||||||
case 'LineString':
|
|
||||||
this._addGeoJSONData(geom.coordinates);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'MultiLineString':
|
|
||||||
for (i = 0; i < geom.coordinates.length; i++) {
|
|
||||||
this._addGeoJSONData(geom.coordinates[i]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new Error('Invalid GeoJSON object.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var feat = d && d.type === "FeatureCollection";
|
|
||||||
if (feat) {
|
|
||||||
for (i = 0; i < d.features.length; i++) {
|
|
||||||
this._addData(d.features[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (d && d._latlngs) {
|
|
||||||
this._addGPXdata(d._latlngs);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Calculates the full extent of the data array
|
|
||||||
*/
|
|
||||||
_calculateFullExtent: function(data) {
|
|
||||||
|
|
||||||
if (!data || data.length < 1) {
|
|
||||||
throw new Error("no data in parameters");
|
|
||||||
}
|
|
||||||
|
|
||||||
var ext = new L.latLngBounds(data[0].latlng, data[0].latlng);
|
|
||||||
|
|
||||||
data.forEach(function(item) {
|
|
||||||
ext.extend(item.latlng);
|
|
||||||
});
|
|
||||||
|
|
||||||
return ext;
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Add data to the diagram either from GPX or GeoJSON and
|
|
||||||
* update the axis domain and data
|
|
||||||
*/
|
|
||||||
addData: function(d) {
|
|
||||||
this._addData(d);
|
|
||||||
if (this._container) {
|
|
||||||
this._applyData();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_applyData: function() {
|
|
||||||
var xdomain = d3.extent(this._data, function(d) {
|
|
||||||
return d.dist;
|
|
||||||
});
|
|
||||||
var ydomain = d3.extent(this._data, function(d) {
|
|
||||||
return d.altitude;
|
|
||||||
});
|
|
||||||
var opts = this.options;
|
|
||||||
|
|
||||||
if (opts.yAxisMin !== undefined && (opts.yAxisMin < ydomain[0] || opts.forceAxisBounds)) {
|
|
||||||
ydomain[0] = opts.yAxisMin;
|
|
||||||
}
|
|
||||||
if (opts.yAxisMax !== undefined && (opts.yAxisMax > ydomain[1] || opts.forceAxisBounds)) {
|
|
||||||
ydomain[1] = opts.yAxisMax;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._x.domain(xdomain);
|
|
||||||
this._y.domain(ydomain);
|
|
||||||
this._areapath.datum(this._data)
|
|
||||||
.attr("d", this._area);
|
|
||||||
this._updateAxis();
|
|
||||||
|
|
||||||
this._fullExtent = this._calculateFullExtent(this._data);
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Reset data
|
|
||||||
*/
|
|
||||||
_clearData: function() {
|
|
||||||
this._data = null;
|
|
||||||
this._dist = null;
|
|
||||||
this._maxElevation = null;
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Reset data and display
|
|
||||||
*/
|
|
||||||
clear: function() {
|
|
||||||
|
|
||||||
this._clearData();
|
|
||||||
|
|
||||||
if (!this._areapath) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// workaround for 'Error: Problem parsing d=""' in Webkit when empty data
|
|
||||||
// https://groups.google.com/d/msg/d3-js/7rFxpXKXFhI/HzIO_NPeDuMJ
|
|
||||||
//this._areapath.datum(this._data).attr("d", this._area);
|
|
||||||
this._areapath.attr("d", "M0 0");
|
|
||||||
|
|
||||||
this._x.domain([0, 1]);
|
|
||||||
this._y.domain([0, 1]);
|
|
||||||
this._updateAxis();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
L.control.elevation = function(options) {
|
|
||||||
return new L.Control.Elevation(options);
|
|
||||||
};
|
|
||||||
|
Before Width: | Height: | Size: 683 B |
|
|
@ -1,675 +0,0 @@
|
||||||
L.Control.Elevation = L.Control.extend({
|
|
||||||
options: {
|
|
||||||
position: "topright",
|
|
||||||
theme: "lime-theme",
|
|
||||||
width: 600,
|
|
||||||
height: 175,
|
|
||||||
margins: {
|
|
||||||
top: 10,
|
|
||||||
right: 20,
|
|
||||||
bottom: 30,
|
|
||||||
left: 60
|
|
||||||
},
|
|
||||||
useHeightIndicator: true,
|
|
||||||
interpolation: "linear",
|
|
||||||
hoverNumber: {
|
|
||||||
decimalsX: 3,
|
|
||||||
decimalsY: 0,
|
|
||||||
formatter: undefined
|
|
||||||
},
|
|
||||||
xTicks: undefined,
|
|
||||||
yTicks: undefined,
|
|
||||||
collapsed: false,
|
|
||||||
yAxisMin: undefined,
|
|
||||||
yAxisMax: undefined,
|
|
||||||
forceAxisBounds: false
|
|
||||||
},
|
|
||||||
|
|
||||||
onRemove: function(map) {
|
|
||||||
this._container = null;
|
|
||||||
},
|
|
||||||
|
|
||||||
onAdd: function(map) {
|
|
||||||
this._map = map;
|
|
||||||
|
|
||||||
var opts = this.options;
|
|
||||||
var margin = opts.margins;
|
|
||||||
opts.xTicks = opts.xTicks || Math.round(this._width() / 75);
|
|
||||||
opts.yTicks = opts.yTicks || Math.round(this._height() / 30);
|
|
||||||
opts.hoverNumber.formatter = opts.hoverNumber.formatter || this._formatter;
|
|
||||||
|
|
||||||
//append theme name on body
|
|
||||||
d3.select("body").classed(opts.theme, true);
|
|
||||||
|
|
||||||
var x = this._x = d3.scale.linear()
|
|
||||||
.range([0, this._width()]);
|
|
||||||
|
|
||||||
var y = this._y = d3.scale.linear()
|
|
||||||
.range([this._height(), 0]);
|
|
||||||
|
|
||||||
var area = this._area = d3.svg.area()
|
|
||||||
.interpolate(opts.interpolation)
|
|
||||||
.x(function(d) {
|
|
||||||
return x(d.dist);
|
|
||||||
})
|
|
||||||
.y0(this._height())
|
|
||||||
.y1(function(d) {
|
|
||||||
return y(d.altitude);
|
|
||||||
});
|
|
||||||
|
|
||||||
var container = this._container = L.DomUtil.create("div", "elevation");
|
|
||||||
|
|
||||||
this._initToggle();
|
|
||||||
|
|
||||||
var cont = d3.select(container);
|
|
||||||
cont.attr("width", opts.width);
|
|
||||||
var svg = cont.append("svg");
|
|
||||||
svg.attr("width", opts.width)
|
|
||||||
.attr("class", "background")
|
|
||||||
.attr("height", opts.height)
|
|
||||||
.append("g")
|
|
||||||
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
|
|
||||||
|
|
||||||
var line = d3.svg.line();
|
|
||||||
line = line
|
|
||||||
.x(function(d) {
|
|
||||||
return d3.mouse(svg.select("g"))[0];
|
|
||||||
})
|
|
||||||
.y(function(d) {
|
|
||||||
return this._height();
|
|
||||||
});
|
|
||||||
|
|
||||||
var g = d3.select(this._container).select("svg").select("g");
|
|
||||||
|
|
||||||
this._areapath = g.append("path")
|
|
||||||
.attr("class", "area");
|
|
||||||
|
|
||||||
var background = this._background = g.append("rect")
|
|
||||||
.attr("width", this._width())
|
|
||||||
.attr("height", this._height())
|
|
||||||
.style("fill", "none")
|
|
||||||
.style("stroke", "none")
|
|
||||||
.style("pointer-events", "all");
|
|
||||||
|
|
||||||
if (L.Browser.touch) {
|
|
||||||
|
|
||||||
background.on("touchmove.drag", this._dragHandler.bind(this)).
|
|
||||||
on("touchstart.drag", this._dragStartHandler.bind(this)).
|
|
||||||
on("touchstart.focus", this._mousemoveHandler.bind(this));
|
|
||||||
L.DomEvent.on(this._container, 'touchend', this._dragEndHandler, this);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
background.on("mousemove.focus", this._mousemoveHandler.bind(this)).
|
|
||||||
on("mouseout.focus", this._mouseoutHandler.bind(this)).
|
|
||||||
on("mousedown.drag", this._dragStartHandler.bind(this)).
|
|
||||||
on("mousemove.drag", this._dragHandler.bind(this));
|
|
||||||
L.DomEvent.on(this._container, 'mouseup', this._dragEndHandler, this);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
this._xaxisgraphicnode = g.append("g");
|
|
||||||
this._yaxisgraphicnode = g.append("g");
|
|
||||||
this._appendXaxis(this._xaxisgraphicnode);
|
|
||||||
this._appendYaxis(this._yaxisgraphicnode);
|
|
||||||
|
|
||||||
var focusG = this._focusG = g.append("g");
|
|
||||||
this._mousefocus = focusG.append('svg:line')
|
|
||||||
.attr('class', 'mouse-focus-line')
|
|
||||||
.attr('x2', '0')
|
|
||||||
.attr('y2', '0')
|
|
||||||
.attr('x1', '0')
|
|
||||||
.attr('y1', '0');
|
|
||||||
this._focuslabelX = focusG.append("svg:text")
|
|
||||||
.style("pointer-events", "none")
|
|
||||||
.attr("class", "mouse-focus-label-x");
|
|
||||||
this._focuslabelY = focusG.append("svg:text")
|
|
||||||
.style("pointer-events", "none")
|
|
||||||
.attr("class", "mouse-focus-label-y");
|
|
||||||
|
|
||||||
if (this._data) {
|
|
||||||
this._applyData();
|
|
||||||
}
|
|
||||||
|
|
||||||
return container;
|
|
||||||
},
|
|
||||||
|
|
||||||
_dragHandler: function() {
|
|
||||||
|
|
||||||
//we don´t want map events to occur here
|
|
||||||
d3.event.preventDefault();
|
|
||||||
d3.event.stopPropagation();
|
|
||||||
|
|
||||||
this._gotDragged = true;
|
|
||||||
|
|
||||||
this._drawDragRectangle();
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Draws the currently dragged rectabgle over the chart.
|
|
||||||
*/
|
|
||||||
_drawDragRectangle: function() {
|
|
||||||
|
|
||||||
if (!this._dragStartCoords) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var dragEndCoords = this._dragCurrentCoords = d3.mouse(this._background.node());
|
|
||||||
|
|
||||||
var x1 = Math.min(this._dragStartCoords[0], dragEndCoords[0]),
|
|
||||||
x2 = Math.max(this._dragStartCoords[0], dragEndCoords[0]);
|
|
||||||
|
|
||||||
if (!this._dragRectangle && !this._dragRectangleG) {
|
|
||||||
var g = d3.select(this._container).select("svg").select("g");
|
|
||||||
|
|
||||||
this._dragRectangleG = g.append("g");
|
|
||||||
|
|
||||||
this._dragRectangle = this._dragRectangleG.append("rect")
|
|
||||||
.attr("width", x2 - x1)
|
|
||||||
.attr("height", this._height())
|
|
||||||
.attr("x", x1)
|
|
||||||
.attr('class', 'mouse-drag')
|
|
||||||
.style("pointer-events", "none");
|
|
||||||
} else {
|
|
||||||
this._dragRectangle.attr("width", x2 - x1)
|
|
||||||
.attr("x", x1);
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Removes the drag rectangle and zoms back to the total extent of the data.
|
|
||||||
*/
|
|
||||||
_resetDrag: function() {
|
|
||||||
|
|
||||||
if (this._dragRectangleG) {
|
|
||||||
|
|
||||||
this._dragRectangleG.remove();
|
|
||||||
this._dragRectangleG = null;
|
|
||||||
this._dragRectangle = null;
|
|
||||||
|
|
||||||
this._hidePositionMarker();
|
|
||||||
|
|
||||||
this._map.fitBounds(this._fullExtent);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Handles end of dragg operations. Zooms the map to the selected items extent.
|
|
||||||
*/
|
|
||||||
_dragEndHandler: function() {
|
|
||||||
|
|
||||||
if (!this._dragStartCoords || !this._gotDragged) {
|
|
||||||
this._dragStartCoords = null;
|
|
||||||
this._gotDragged = false;
|
|
||||||
this._resetDrag();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._hidePositionMarker();
|
|
||||||
|
|
||||||
var item1 = this._findItemForX(this._dragStartCoords[0]),
|
|
||||||
item2 = this._findItemForX(this._dragCurrentCoords[0]);
|
|
||||||
|
|
||||||
this._fitSection(item1, item2);
|
|
||||||
|
|
||||||
this._dragStartCoords = null;
|
|
||||||
this._gotDragged = false;
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
_dragStartHandler: function() {
|
|
||||||
|
|
||||||
d3.event.preventDefault();
|
|
||||||
d3.event.stopPropagation();
|
|
||||||
|
|
||||||
this._gotDragged = false;
|
|
||||||
|
|
||||||
this._dragStartCoords = d3.mouse(this._background.node());
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Finds a data entry for a given x-coordinate of the diagram
|
|
||||||
*/
|
|
||||||
_findItemForX: function(x) {
|
|
||||||
var bisect = d3.bisector(function(d) {
|
|
||||||
return d.dist;
|
|
||||||
}).left;
|
|
||||||
var xinvert = this._x.invert(x);
|
|
||||||
return bisect(this._data, xinvert);
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Make the map fit the route section between given indexes. */
|
|
||||||
_fitSection: function(index1, index2) {
|
|
||||||
|
|
||||||
var start = Math.min(index1, index2),
|
|
||||||
end = Math.max(index1, index2);
|
|
||||||
|
|
||||||
var ext = this._calculateFullExtent(this._data.slice(start, end));
|
|
||||||
|
|
||||||
this._map.fitBounds(ext);
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
_initToggle: function() {
|
|
||||||
|
|
||||||
/* inspired by L.Control.Layers */
|
|
||||||
|
|
||||||
var container = this._container;
|
|
||||||
|
|
||||||
//Makes this work on IE10 Touch devices by stopping it from firing a mouseout event when the touch is released
|
|
||||||
container.setAttribute('aria-haspopup', true);
|
|
||||||
|
|
||||||
if (!L.Browser.touch) {
|
|
||||||
L.DomEvent
|
|
||||||
.disableClickPropagation(container);
|
|
||||||
//.disableScrollPropagation(container);
|
|
||||||
} else {
|
|
||||||
L.DomEvent.on(container, 'click', L.DomEvent.stopPropagation);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.options.collapsed) {
|
|
||||||
this._collapse();
|
|
||||||
|
|
||||||
if (!L.Browser.android) {
|
|
||||||
L.DomEvent
|
|
||||||
.on(container, 'mouseover', this._expand, this)
|
|
||||||
.on(container, 'mouseout', this._collapse, this);
|
|
||||||
}
|
|
||||||
var link = this._button = L.DomUtil.create('a', 'elevation-toggle', container);
|
|
||||||
link.href = '#';
|
|
||||||
link.title = 'Elevation';
|
|
||||||
|
|
||||||
if (L.Browser.touch) {
|
|
||||||
L.DomEvent
|
|
||||||
.on(link, 'click', L.DomEvent.stop)
|
|
||||||
.on(link, 'click', this._expand, this);
|
|
||||||
} else {
|
|
||||||
L.DomEvent.on(link, 'focus', this._expand, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._map.on('click', this._collapse, this);
|
|
||||||
// TODO keyboard accessibility
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_expand: function() {
|
|
||||||
this._container.className = this._container.className.replace(' elevation-collapsed', '');
|
|
||||||
},
|
|
||||||
|
|
||||||
_collapse: function() {
|
|
||||||
L.DomUtil.addClass(this._container, 'elevation-collapsed');
|
|
||||||
},
|
|
||||||
|
|
||||||
_width: function() {
|
|
||||||
var opts = this.options;
|
|
||||||
return opts.width - opts.margins.left - opts.margins.right;
|
|
||||||
},
|
|
||||||
|
|
||||||
_height: function() {
|
|
||||||
var opts = this.options;
|
|
||||||
return opts.height - opts.margins.top - opts.margins.bottom;
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Fromatting funciton using the given decimals and seperator
|
|
||||||
*/
|
|
||||||
_formatter: function(num, dec, sep) {
|
|
||||||
var res;
|
|
||||||
if (dec === 0) {
|
|
||||||
res = Math.round(num) + "";
|
|
||||||
} else {
|
|
||||||
res = L.Util.formatNum(num, dec) + "";
|
|
||||||
}
|
|
||||||
var numbers = res.split(".");
|
|
||||||
if (numbers[1]) {
|
|
||||||
var d = dec - numbers[1].length;
|
|
||||||
for (; d > 0; d--) {
|
|
||||||
numbers[1] += "0";
|
|
||||||
}
|
|
||||||
res = numbers.join(sep || ".");
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
},
|
|
||||||
|
|
||||||
_appendYaxis: function(y) {
|
|
||||||
y.attr("class", "y axis")
|
|
||||||
.call(d3.svg.axis()
|
|
||||||
.scale(this._y)
|
|
||||||
.ticks(this.options.yTicks)
|
|
||||||
.orient("left"))
|
|
||||||
.append("text")
|
|
||||||
.attr("x", -45)
|
|
||||||
.attr("y", 3)
|
|
||||||
.style("text-anchor", "end")
|
|
||||||
.text("m");
|
|
||||||
},
|
|
||||||
|
|
||||||
_appendXaxis: function(x) {
|
|
||||||
x.attr("class", "x axis")
|
|
||||||
.attr("transform", "translate(0," + this._height() + ")")
|
|
||||||
.call(d3.svg.axis()
|
|
||||||
.scale(this._x)
|
|
||||||
.ticks(this.options.xTicks)
|
|
||||||
.orient("bottom"))
|
|
||||||
.append("text")
|
|
||||||
.attr("x", this._width() + 20)
|
|
||||||
.attr("y", 15)
|
|
||||||
.style("text-anchor", "end")
|
|
||||||
.text("km");
|
|
||||||
},
|
|
||||||
|
|
||||||
_updateAxis: function() {
|
|
||||||
this._xaxisgraphicnode.selectAll("g").remove();
|
|
||||||
this._xaxisgraphicnode.selectAll("path").remove();
|
|
||||||
this._xaxisgraphicnode.selectAll("text").remove();
|
|
||||||
this._yaxisgraphicnode.selectAll("g").remove();
|
|
||||||
this._yaxisgraphicnode.selectAll("path").remove();
|
|
||||||
this._yaxisgraphicnode.selectAll("text").remove();
|
|
||||||
this._appendXaxis(this._xaxisgraphicnode);
|
|
||||||
this._appendYaxis(this._yaxisgraphicnode);
|
|
||||||
},
|
|
||||||
|
|
||||||
_mouseoutHandler: function() {
|
|
||||||
|
|
||||||
this._hidePositionMarker();
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Hides the position-/heigth indication marker drawn onto the map
|
|
||||||
*/
|
|
||||||
_hidePositionMarker: function() {
|
|
||||||
|
|
||||||
if (this._marker) {
|
|
||||||
this._map.removeLayer(this._marker);
|
|
||||||
this._marker = null;
|
|
||||||
}
|
|
||||||
if (this._mouseHeightFocus) {
|
|
||||||
this._mouseHeightFocus.style("visibility", "hidden");
|
|
||||||
this._mouseHeightFocusLabel.style("visibility", "hidden");
|
|
||||||
}
|
|
||||||
if (this._pointG) {
|
|
||||||
this._pointG.style("visibility", "hidden");
|
|
||||||
}
|
|
||||||
this._focusG.style("visibility", "hidden");
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Handles the moueseover the chart and displays distance and altitude level
|
|
||||||
*/
|
|
||||||
_mousemoveHandler: function(d, i, ctx) {
|
|
||||||
if (!this._data || this._data.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var coords = d3.mouse(this._background.node());
|
|
||||||
var opts = this.options;
|
|
||||||
this._focusG.style("visibility", "visible");
|
|
||||||
this._mousefocus.attr('x1', coords[0])
|
|
||||||
.attr('y1', 0)
|
|
||||||
.attr('x2', coords[0])
|
|
||||||
.attr('y2', this._height())
|
|
||||||
.classed('hidden', false);
|
|
||||||
var bisect = d3.bisector(function(d) {
|
|
||||||
return d.dist;
|
|
||||||
}).left;
|
|
||||||
|
|
||||||
var item = this._data[this._findItemForX(coords[0])],
|
|
||||||
alt = item.altitude,
|
|
||||||
dist = item.dist,
|
|
||||||
ll = item.latlng,
|
|
||||||
numY = opts.hoverNumber.formatter(alt, opts.hoverNumber.decimalsY),
|
|
||||||
numX = opts.hoverNumber.formatter(dist, opts.hoverNumber.decimalsX);
|
|
||||||
|
|
||||||
this._focuslabelX.attr("x", coords[0])
|
|
||||||
.text(numY + " m");
|
|
||||||
this._focuslabelY.attr("y", this._height() - 5)
|
|
||||||
.attr("x", coords[0])
|
|
||||||
.text(numX + " km");
|
|
||||||
|
|
||||||
var layerpoint = this._map.latLngToLayerPoint(ll);
|
|
||||||
|
|
||||||
//if we use a height indicator we create one with SVG
|
|
||||||
//otherwise we show a marker
|
|
||||||
if (opts.useHeightIndicator) {
|
|
||||||
|
|
||||||
if (!this._mouseHeightFocus) {
|
|
||||||
|
|
||||||
var heightG = d3.select(".leaflet-overlay-pane svg")
|
|
||||||
.append("g");
|
|
||||||
this._mouseHeightFocus = heightG.append('svg:line')
|
|
||||||
.attr('class', 'height-focus line')
|
|
||||||
.attr('x2', '0')
|
|
||||||
.attr('y2', '0')
|
|
||||||
.attr('x1', '0')
|
|
||||||
.attr('y1', '0');
|
|
||||||
|
|
||||||
var pointG = this._pointG = heightG.append("g");
|
|
||||||
pointG.append("svg:circle")
|
|
||||||
.attr("r", 6)
|
|
||||||
.attr("cx", 0)
|
|
||||||
.attr("cy", 0)
|
|
||||||
.attr("class", "height-focus circle-lower");
|
|
||||||
|
|
||||||
this._mouseHeightFocusLabel = heightG.append("svg:text")
|
|
||||||
.attr("class", "height-focus-label")
|
|
||||||
.style("pointer-events", "none");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
var normalizedAlt = this._height() / this._maxElevation * alt;
|
|
||||||
var normalizedY = layerpoint.y - normalizedAlt;
|
|
||||||
this._mouseHeightFocus.attr("x1", layerpoint.x)
|
|
||||||
.attr("x2", layerpoint.x)
|
|
||||||
.attr("y1", layerpoint.y)
|
|
||||||
.attr("y2", normalizedY)
|
|
||||||
.style("visibility", "visible");
|
|
||||||
|
|
||||||
this._pointG.attr("transform", "translate(" + layerpoint.x + "," + layerpoint.y + ")")
|
|
||||||
.style("visibility", "visible");
|
|
||||||
|
|
||||||
this._mouseHeightFocusLabel.attr("x", layerpoint.x)
|
|
||||||
.attr("y", normalizedY)
|
|
||||||
.text(alt + " m")
|
|
||||||
.style("visibility", "visible");
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
if (!this._marker) {
|
|
||||||
|
|
||||||
this._marker = new L.Marker(ll).addTo(this._map);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
this._marker.setLatLng(ll);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Parsing of GeoJSON data lines and their elevation in z-coordinate
|
|
||||||
*/
|
|
||||||
_addGeoJSONData: function(coords) {
|
|
||||||
if (coords) {
|
|
||||||
var data = this._data || [];
|
|
||||||
var dist = this._dist || 0;
|
|
||||||
var ele = this._maxElevation || 0;
|
|
||||||
for (var i = 0; i < coords.length; i++) {
|
|
||||||
var s = new L.LatLng(coords[i][1], coords[i][0]);
|
|
||||||
var e = new L.LatLng(coords[i ? i - 1 : 0][1], coords[i ? i - 1 : 0][0]);
|
|
||||||
var newdist = s.distanceTo(e);
|
|
||||||
dist = dist + Math.round(newdist / 1000 * 100000) / 100000;
|
|
||||||
ele = ele < coords[i][2] ? coords[i][2] : ele;
|
|
||||||
data.push({
|
|
||||||
dist: dist,
|
|
||||||
altitude: coords[i][2],
|
|
||||||
x: coords[i][0],
|
|
||||||
y: coords[i][1],
|
|
||||||
latlng: s
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this._dist = dist;
|
|
||||||
this._data = data;
|
|
||||||
this._maxElevation = ele;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Parsing function for GPX data as used by https://github.com/mpetazzoni/leaflet-gpx
|
|
||||||
*/
|
|
||||||
_addGPXdata: function(coords) {
|
|
||||||
if (coords) {
|
|
||||||
var data = this._data || [];
|
|
||||||
var dist = this._dist || 0;
|
|
||||||
var ele = this._maxElevation || 0;
|
|
||||||
for (var i = 0; i < coords.length; i++) {
|
|
||||||
var s = coords[i];
|
|
||||||
var e = coords[i ? i - 1 : 0];
|
|
||||||
var newdist = s.distanceTo(e);
|
|
||||||
dist = dist + Math.round(newdist / 1000 * 100000) / 100000;
|
|
||||||
ele = ele < s.meta.ele ? s.meta.ele : ele;
|
|
||||||
data.push({
|
|
||||||
dist: dist,
|
|
||||||
altitude: s.meta.ele,
|
|
||||||
x: s.lng,
|
|
||||||
y: s.lat,
|
|
||||||
latlng: s
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this._dist = dist;
|
|
||||||
this._data = data;
|
|
||||||
this._maxElevation = ele;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_addData: function(d) {
|
|
||||||
var geom = d && d.geometry && d.geometry;
|
|
||||||
var i;
|
|
||||||
|
|
||||||
if (geom) {
|
|
||||||
switch (geom.type) {
|
|
||||||
case 'LineString':
|
|
||||||
this._addGeoJSONData(geom.coordinates);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'MultiLineString':
|
|
||||||
for (i = 0; i < geom.coordinates.length; i++) {
|
|
||||||
this._addGeoJSONData(geom.coordinates[i]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new Error('Invalid GeoJSON object.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var feat = d && d.type === "FeatureCollection";
|
|
||||||
if (feat) {
|
|
||||||
for (i = 0; i < d.features.length; i++) {
|
|
||||||
this._addData(d.features[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (d && d._latlngs) {
|
|
||||||
this._addGPXdata(d._latlngs);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Calculates the full extent of the data array
|
|
||||||
*/
|
|
||||||
_calculateFullExtent: function(data) {
|
|
||||||
|
|
||||||
if (!data || data.length < 1) {
|
|
||||||
throw new Error("no data in parameters");
|
|
||||||
}
|
|
||||||
|
|
||||||
var ext = new L.latLngBounds(data[0].latlng, data[0].latlng);
|
|
||||||
|
|
||||||
data.forEach(function(item) {
|
|
||||||
ext.extend(item.latlng);
|
|
||||||
});
|
|
||||||
|
|
||||||
return ext;
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Add data to the diagram either from GPX or GeoJSON and
|
|
||||||
* update the axis domain and data
|
|
||||||
*/
|
|
||||||
addData: function(d) {
|
|
||||||
this._addData(d);
|
|
||||||
if (this._container) {
|
|
||||||
this._applyData();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_applyData: function() {
|
|
||||||
var xdomain = d3.extent(this._data, function(d) {
|
|
||||||
return d.dist;
|
|
||||||
});
|
|
||||||
var ydomain = d3.extent(this._data, function(d) {
|
|
||||||
return d.altitude;
|
|
||||||
});
|
|
||||||
var opts = this.options;
|
|
||||||
|
|
||||||
if (opts.yAxisMin !== undefined && (opts.yAxisMin < ydomain[0] || opts.forceAxisBounds)) {
|
|
||||||
ydomain[0] = opts.yAxisMin;
|
|
||||||
}
|
|
||||||
if (opts.yAxisMax !== undefined && (opts.yAxisMax > ydomain[1] || opts.forceAxisBounds)) {
|
|
||||||
ydomain[1] = opts.yAxisMax;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._x.domain(xdomain);
|
|
||||||
this._y.domain(ydomain);
|
|
||||||
this._areapath.datum(this._data)
|
|
||||||
.attr("d", this._area);
|
|
||||||
this._updateAxis();
|
|
||||||
|
|
||||||
this._fullExtent = this._calculateFullExtent(this._data);
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Reset data
|
|
||||||
*/
|
|
||||||
_clearData: function() {
|
|
||||||
this._data = null;
|
|
||||||
this._dist = null;
|
|
||||||
this._maxElevation = null;
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Reset data and display
|
|
||||||
*/
|
|
||||||
clear: function() {
|
|
||||||
|
|
||||||
this._clearData();
|
|
||||||
|
|
||||||
if (!this._areapath) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// workaround for 'Error: Problem parsing d=""' in Webkit when empty data
|
|
||||||
// https://groups.google.com/d/msg/d3-js/7rFxpXKXFhI/HzIO_NPeDuMJ
|
|
||||||
//this._areapath.datum(this._data).attr("d", this._area);
|
|
||||||
this._areapath.attr("d", "M0 0");
|
|
||||||
|
|
||||||
this._x.domain([0, 1]);
|
|
||||||
this._y.domain([0, 1]);
|
|
||||||
this._updateAxis();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
L.control.elevation = function(options) {
|
|
||||||
return new L.Control.Elevation(options);
|
|
||||||
};
|
|
||||||
|
|
@ -1,70 +0,0 @@
|
||||||
.@{theme}{
|
|
||||||
|
|
||||||
.leaflet-control.elevation .background{
|
|
||||||
background-color:@background;
|
|
||||||
.rounded-corners;
|
|
||||||
}
|
|
||||||
|
|
||||||
.leaflet-control.elevation{
|
|
||||||
.axis path,
|
|
||||||
.axis line {
|
|
||||||
fill: none;
|
|
||||||
stroke: @axis-color;
|
|
||||||
stroke-width:@stroke-width-axis;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.leaflet-control.elevation .area {
|
|
||||||
fill: @base-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
.leaflet-control.elevation .mouse-focus-line {
|
|
||||||
pointer-events: none;
|
|
||||||
stroke-width:@stroke-width-mouse-focus;
|
|
||||||
stroke:@stroke-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
.leaflet-control.elevation .elevation-toggle {
|
|
||||||
cursor: pointer;
|
|
||||||
box-shadow: 0 1px 7px rgba(0,0,0,0.4);
|
|
||||||
-webkit-border-radius: 5px;
|
|
||||||
border-radius: 5px;
|
|
||||||
width: 36px;
|
|
||||||
height: 36px;
|
|
||||||
background: url('images/elevation.png') no-repeat center center #f8f8f9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.leaflet-control.elevation-collapsed .background {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.leaflet-control.elevation-collapsed .elevation-toggle {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.leaflet-control.elevation{
|
|
||||||
.mouse-focus-label-y,
|
|
||||||
.mouse-focus-label-x {
|
|
||||||
|
|
||||||
}
|
|
||||||
.mouse-drag{
|
|
||||||
fill:@drag-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.leaflet-overlay-pane {
|
|
||||||
.height-focus{
|
|
||||||
stroke:@base-color;
|
|
||||||
fill:@base-color;
|
|
||||||
}
|
|
||||||
.height-focus.line{
|
|
||||||
pointer-events: none;
|
|
||||||
stroke-width:@stroke-width-height-focus;
|
|
||||||
}
|
|
||||||
.height-focus-label{
|
|
||||||
|
|
||||||
}
|
|
||||||
.height-focus.circle-lower {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
@theme : lime-theme;
|
|
||||||
@base-color : #9CC222;
|
|
||||||
@highlight-color : #637E0B;
|
|
||||||
@background : fade(@base-color,20%);
|
|
||||||
@drag-color : fade(@highlight-color,40%);
|
|
||||||
@axis-color : darken(@base-color,20%);
|
|
||||||
@stroke-color : darken(@base-color,40%);
|
|
||||||
@stroke-width-mouse-focus : 1;
|
|
||||||
@stroke-width-height-focus: 2;
|
|
||||||
@stroke-width-axis : 2;
|
|
||||||
|
|
||||||
.rounded-corners (@radius: 5px) {
|
|
||||||
-webkit-border-radius: @radius;
|
|
||||||
-moz-border-radius: @radius;
|
|
||||||
-ms-border-radius: @radius;
|
|
||||||
-o-border-radius: @radius;
|
|
||||||
border-radius: @radius;
|
|
||||||
}
|
|
||||||
|
|
||||||
@import "../L.Control.Elevation.less";
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
@theme : purple-theme;
|
|
||||||
@base-color : #732C7B;
|
|
||||||
@highlight-color : #4A0E50;
|
|
||||||
@background : fade(@base-color,20%);
|
|
||||||
@drag-color : fade(@highlight-color,40%);
|
|
||||||
@axis-color : darken(@base-color,20%);
|
|
||||||
@stroke-color : darken(@base-color,40%);
|
|
||||||
@stroke-width-mouse-focus : 1;
|
|
||||||
@stroke-width-height-focus: 2;
|
|
||||||
@stroke-width-axis : 2;
|
|
||||||
|
|
||||||
.rounded-corners (@radius: 5px) {
|
|
||||||
-webkit-border-radius: @radius;
|
|
||||||
-moz-border-radius: @radius;
|
|
||||||
-ms-border-radius: @radius;
|
|
||||||
-o-border-radius: @radius;
|
|
||||||
border-radius: @radius;
|
|
||||||
}
|
|
||||||
|
|
||||||
@import "../L.Control.Elevation.less";
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
@theme : steelblue-theme;
|
|
||||||
@base-color : #4682B4;
|
|
||||||
@highlight-color : #174A75;
|
|
||||||
@background : fade(@base-color,20%);
|
|
||||||
@drag-color : fade(@highlight-color,40%);
|
|
||||||
@axis-color : darken(@base-color,40%);
|
|
||||||
@stroke-color : darken(@base-color,40%);
|
|
||||||
@stroke-width-mouse-focus : 1;
|
|
||||||
@stroke-width-height-focus: 2;
|
|
||||||
@stroke-width-axis : 2;
|
|
||||||
|
|
||||||
.rounded-corners (@radius: 5px) {
|
|
||||||
-webkit-border-radius: @radius;
|
|
||||||
-moz-border-radius: @radius;
|
|
||||||
-ms-border-radius: @radius;
|
|
||||||
-o-border-radius: @radius;
|
|
||||||
border-radius: @radius;
|
|
||||||
}
|
|
||||||
|
|
||||||
@import "../L.Control.Elevation.less";
|
|
||||||
|
Before Width: | Height: | Size: 708 B |
|
|
@ -1,93 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
height="26"
|
|
||||||
width="26"
|
|
||||||
id="svg2"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.47 r22583"
|
|
||||||
sodipodi:docname="elevation.svg"
|
|
||||||
inkscape:export-filename="/home/z4k/www/maps/Leaflet.Elevation/src/images/elevation.png"
|
|
||||||
inkscape:export-xdpi="90"
|
|
||||||
inkscape:export-ydpi="90">
|
|
||||||
<metadata
|
|
||||||
id="metadata20">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<defs
|
|
||||||
id="defs18">
|
|
||||||
<inkscape:perspective
|
|
||||||
sodipodi:type="inkscape:persp3d"
|
|
||||||
inkscape:vp_x="0 : 13 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_z="26 : 13 : 1"
|
|
||||||
inkscape:persp3d-origin="13 : 8.6666667 : 1"
|
|
||||||
id="perspective22" />
|
|
||||||
<inkscape:perspective
|
|
||||||
id="perspective5368"
|
|
||||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
|
||||||
inkscape:vp_z="1 : 0.5 : 1"
|
|
||||||
inkscape:vp_y="0 : 1000 : 0"
|
|
||||||
inkscape:vp_x="0 : 0.5 : 1"
|
|
||||||
sodipodi:type="inkscape:persp3d" />
|
|
||||||
</defs>
|
|
||||||
<sodipodi:namedview
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1"
|
|
||||||
objecttolerance="10"
|
|
||||||
gridtolerance="10"
|
|
||||||
guidetolerance="10"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:window-width="1336"
|
|
||||||
inkscape:window-height="716"
|
|
||||||
id="namedview16"
|
|
||||||
showgrid="false"
|
|
||||||
inkscape:zoom="12.836708"
|
|
||||||
inkscape:cx="9.2793304"
|
|
||||||
inkscape:cy="10.065073"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="0"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="svg2" />
|
|
||||||
<path
|
|
||||||
sodipodi:nodetypes="ccccccc"
|
|
||||||
d="M 23.116338,20.847501 18.876285,12.717757 15.034906,12.602581 12.270363,14.369079 9.9164116,8.9203569 4.723308,15.1073 l 0,5.740201"
|
|
||||||
style="fill:#addb55;fill-opacity:0.83794466000000001;stroke:none;opacity:0.8503937"
|
|
||||||
id="path4581"
|
|
||||||
inkscape:export-filename="/home/z4k/www/climbo/images/dis.png"
|
|
||||||
inkscape:export-xdpi="37.075794"
|
|
||||||
inkscape:export-ydpi="37.075794" />
|
|
||||||
<path
|
|
||||||
id="path4508"
|
|
||||||
style="fill:none;stroke:#70ab00;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
|
||||||
d="m 4.7148336,14.751112 1.0850165,0 4.3152399,-6.1185111 2.522013,5.5932591 2.482614,-2.287207 3.698573,0.128868 4.049243,8.326572 0,0.440076"
|
|
||||||
sodipodi:nodetypes="cccccccc"
|
|
||||||
inkscape:export-filename="/home/z4k/www/climbo/images/dis.png"
|
|
||||||
inkscape:export-xdpi="37.075794"
|
|
||||||
inkscape:export-ydpi="37.075794" />
|
|
||||||
<path
|
|
||||||
style="fill:none;stroke:#737373;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
|
|
||||||
d="m 3.4214623,4.9854716 0,19.7870054"
|
|
||||||
id="path2825" />
|
|
||||||
<path
|
|
||||||
style="fill:none;stroke:#737373;stroke-width:1px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
|
|
||||||
d="m 24.68144,22.435429 -23.75282884,0"
|
|
||||||
id="path2827"
|
|
||||||
sodipodi:nodetypes="cc" />
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 3.4 KiB |
19
bower_components/async/LICENSE
vendored
|
|
@ -1,19 +0,0 @@
|
||||||
Copyright (c) 2010-2014 Caolan McMahon
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
1646
bower_components/async/README.md
vendored
1123
bower_components/async/lib/async.js
vendored
14
bower_components/leaflet-plugins/.bower.json
vendored
|
|
@ -1,14 +0,0 @@
|
||||||
{
|
|
||||||
"name": "leaflet-plugins",
|
|
||||||
"homepage": "https://github.com/shramov/leaflet-plugins",
|
|
||||||
"version": "1.1.2",
|
|
||||||
"_release": "1.1.2",
|
|
||||||
"_resolution": {
|
|
||||||
"type": "version",
|
|
||||||
"tag": "v1.1.2",
|
|
||||||
"commit": "de2380a9efa24b3b43fb780219363f171f9f3140"
|
|
||||||
},
|
|
||||||
"_source": "git://github.com/shramov/leaflet-plugins.git",
|
|
||||||
"_target": "*",
|
|
||||||
"_originalSource": "leaflet-plugins"
|
|
||||||
}
|
|
||||||
11
bower_components/leaflet-plugins/.jshintrc
vendored
|
|
@ -1,11 +0,0 @@
|
||||||
{
|
|
||||||
"browser": true,
|
|
||||||
"eqeqeq": true,
|
|
||||||
"undef": true,
|
|
||||||
"quotmark": "single",
|
|
||||||
"trailing": true,
|
|
||||||
"laxbreak": true,
|
|
||||||
"globals": {
|
|
||||||
"L": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
22
bower_components/leaflet-plugins/LICENSE
vendored
|
|
@ -1,22 +0,0 @@
|
||||||
Copyright (c) 2011-2014, Pavel Shramov, Bruno Bergot
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification, are
|
|
||||||
permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice, this list of
|
|
||||||
conditions and the following disclaimer.
|
|
||||||
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice, this list
|
|
||||||
of conditions and the following disclaimer in the documentation and/or other materials
|
|
||||||
provided with the distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
||||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
||||||
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
||||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
|
||||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
41
bower_components/leaflet-plugins/README.asciidoc
vendored
|
|
@ -1,41 +0,0 @@
|
||||||
Leaflet plugins
|
|
||||||
===============
|
|
||||||
|
|
||||||
== What's it?
|
|
||||||
|
|
||||||
Miscellaneous plugins for Leaflet library for services that need to display
|
|
||||||
route information and need satellite imagery from different providers.
|
|
||||||
Currently it consists of:
|
|
||||||
|
|
||||||
- Vector layers (`layer/vector/`):
|
|
||||||
* GPX
|
|
||||||
* KML
|
|
||||||
|
|
||||||
- Providers (`layer/tile`):
|
|
||||||
* Google - using Google Maps API v3;
|
|
||||||
* Yandex - using Yandex Maps API v2;
|
|
||||||
* Bing - with proper attribution.
|
|
||||||
|
|
||||||
All these providers are implemented with respect to terms of use.
|
|
||||||
|
|
||||||
Also there are some useful control plugins (`control/`):
|
|
||||||
|
|
||||||
* Permalink - OpenLayers compatible permanent link with support for storing
|
|
||||||
location data in hash part (#lat=...);
|
|
||||||
* Distance - simple tool to measure distances on maps
|
|
||||||
|
|
||||||
== How to get?
|
|
||||||
|
|
||||||
http://psha.org.ru/cgit/psha/leaflet-plugins.git
|
|
||||||
|
|
||||||
or
|
|
||||||
|
|
||||||
http://github.com/shramov/leaflet-plugins.git
|
|
||||||
|
|
||||||
== Russian docs
|
|
||||||
|
|
||||||
See link:http://psha.org.ru/b/leaflet-plugins.ru.html[russian documentation] for more info.
|
|
||||||
|
|
||||||
////////////////////////////////////
|
|
||||||
vim: sts=4 sw=4 et tw=80 ft=asciidoc
|
|
||||||
////////////////////////////////////
|
|
||||||
28
bower_components/leaflet-plugins/build/Makefile
vendored
|
|
@ -1,28 +0,0 @@
|
||||||
JS := $(wildcard ../layer/*/*.js ../layer/*.js ../control/*js)
|
|
||||||
#JS += control/Scale.js control/Distance.js
|
|
||||||
#JS += control/Permalink.js $(wildcard control/Permalink.*.js)
|
|
||||||
JS := $(shell python ./deps.py $(JS))
|
|
||||||
|
|
||||||
#JS_EXTRA := $(JS) $(wildcard layer/*.js)
|
|
||||||
all: compiled.yui.js compiled.closure.js
|
|
||||||
|
|
||||||
compile: $(patsubst %,compiled/%,$(JS))
|
|
||||||
|
|
||||||
closure/%: ../%
|
|
||||||
mkdir -p $(dir $@)
|
|
||||||
java -jar /tmp/closure.jar --compilation_level ADVANCED_OPTIMIZATIONS --charset UTF-8 --js $< --js_output_file $@.tmp
|
|
||||||
mv $@.tmp $@
|
|
||||||
|
|
||||||
yui/%: ../%
|
|
||||||
mkdir -p $(dir $@)
|
|
||||||
yui-compressor --charset UTF-8 -o $@.tmp $<
|
|
||||||
mv $@.tmp $@
|
|
||||||
|
|
||||||
compiled.yui.js: $(patsubst ../%,yui/%,$(JS))
|
|
||||||
compiled.closure.js: $(patsubst ../%,closure/%,$(JS))
|
|
||||||
|
|
||||||
compiled.%.js:
|
|
||||||
for f in $^; do cat $$f >> $@.tmp; echo >> $@.tmp; done
|
|
||||||
mv $@.tmp $@
|
|
||||||
|
|
||||||
.PHONY: all compile
|
|
||||||
26
bower_components/leaflet-plugins/build/deps.py
vendored
|
|
@ -1,26 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# vim: sts=4 sw=4 et
|
|
||||||
|
|
||||||
import os, sys
|
|
||||||
|
|
||||||
printed = set()
|
|
||||||
|
|
||||||
def includes(f):
|
|
||||||
d = os.path.dirname(f)
|
|
||||||
for l in open(f):
|
|
||||||
if l.startswith('//#include'):
|
|
||||||
yield os.path.join(d, l.strip().split(None, 1)[1].strip(""""'"""))
|
|
||||||
|
|
||||||
work = list(sys.argv[1:])
|
|
||||||
|
|
||||||
while work:
|
|
||||||
f = work.pop(0)
|
|
||||||
if f in printed:
|
|
||||||
continue
|
|
||||||
i = list(filter(lambda x: x not in printed, includes(f)))
|
|
||||||
if i:
|
|
||||||
work = i + [f] + work
|
|
||||||
continue
|
|
||||||
printed.add(f)
|
|
||||||
print f
|
|
||||||
|
|
||||||
128
bower_components/leaflet-plugins/control/Distance.js
vendored
|
|
@ -1,128 +0,0 @@
|
||||||
/* global console: true */
|
|
||||||
L.Control.Distance = L.Control.extend({
|
|
||||||
options: {
|
|
||||||
position: 'topleft',
|
|
||||||
popups: true
|
|
||||||
},
|
|
||||||
|
|
||||||
initialize: function (options) {
|
|
||||||
L.Util.setOptions(this, options);
|
|
||||||
this._line = new L.Polyline([], {editable: true});
|
|
||||||
this._line.on('edit', this._update, this);
|
|
||||||
this._line.on('click', function(e) {});
|
|
||||||
this._active = false;
|
|
||||||
},
|
|
||||||
|
|
||||||
getLine: function() { return this._line; },
|
|
||||||
|
|
||||||
onAdd: function(map) {
|
|
||||||
var className = 'leaflet-control-distance',
|
|
||||||
container = this._container = L.DomUtil.create('div', className);
|
|
||||||
|
|
||||||
function cb() {
|
|
||||||
if (this._active)
|
|
||||||
this._calc_disable();
|
|
||||||
else
|
|
||||||
this._calc_enable();
|
|
||||||
}
|
|
||||||
|
|
||||||
var link = this._link = this._createButton('Edit', 'leaflet-control-distance leaflet-control-distance-edit', container, cb, this);
|
|
||||||
var del = this._link_delete = this._createButton('Delete', 'leaflet-control-distance leaflet-control-distance-delete', container, this._reset, this);
|
|
||||||
var text = this._text = L.DomUtil.create('div', 'leaflet-control-distance-text', container);
|
|
||||||
|
|
||||||
//text.style.display = 'inline';
|
|
||||||
//text.style.float = 'right';
|
|
||||||
|
|
||||||
this._map.addLayer(this._line);
|
|
||||||
this._calc_disable();
|
|
||||||
return container;
|
|
||||||
},
|
|
||||||
|
|
||||||
_createButton: function (title, className, container, fn, context) {
|
|
||||||
var link = L.DomUtil.create('a', className, container);
|
|
||||||
link.href = '#';
|
|
||||||
link.title = title;
|
|
||||||
|
|
||||||
L.DomEvent
|
|
||||||
.addListener(link, 'click', L.DomEvent.stopPropagation)
|
|
||||||
.addListener(link, 'click', L.DomEvent.preventDefault)
|
|
||||||
.addListener(link, 'click', fn, context);
|
|
||||||
|
|
||||||
return link;
|
|
||||||
},
|
|
||||||
|
|
||||||
onRemove: function(map) {
|
|
||||||
this._calc_disable();
|
|
||||||
},
|
|
||||||
|
|
||||||
_calc_enable: function() {
|
|
||||||
this._map.on('click', this._add_point, this);
|
|
||||||
|
|
||||||
this._map.getContainer().style.cursor = 'crosshair';
|
|
||||||
//this._map.addLayer(this._line);
|
|
||||||
L.DomUtil.addClass(this._link, 'leaflet-control-distance-active');
|
|
||||||
this._container.appendChild(this._link_delete);
|
|
||||||
this._container.appendChild(this._text);
|
|
||||||
this._active = true;
|
|
||||||
this._line.editing.enable();
|
|
||||||
if (!this._map.hasLayer(this._line))
|
|
||||||
this._map.addLayer(this._line);
|
|
||||||
this._update();
|
|
||||||
},
|
|
||||||
|
|
||||||
_calc_disable: function() {
|
|
||||||
this._map.off('click', this._add_point, this);
|
|
||||||
//this._map.removeLayer(this._line);
|
|
||||||
this._map.getContainer().style.cursor = 'default';
|
|
||||||
this._container.removeChild(this._link_delete);
|
|
||||||
this._container.removeChild(this._text);
|
|
||||||
L.DomUtil.removeClass(this._link, 'leaflet-control-distance-active');
|
|
||||||
this._active = false;
|
|
||||||
this._line.editing.disable();
|
|
||||||
},
|
|
||||||
|
|
||||||
_add_point: function (e) {
|
|
||||||
var len = this._line.getLatLngs().length;
|
|
||||||
this._line.addLatLng(e.latlng);
|
|
||||||
this._line.editing.updateMarkers();
|
|
||||||
this._line.fire('edit', {});
|
|
||||||
},
|
|
||||||
|
|
||||||
_reset: function(e) {
|
|
||||||
this._line.setLatLngs([]);
|
|
||||||
this._line.fire('edit', {});
|
|
||||||
this._line.redraw();
|
|
||||||
this._line.editing.updateMarkers();
|
|
||||||
},
|
|
||||||
|
|
||||||
_update: function(e) {
|
|
||||||
console.info('Update');
|
|
||||||
this._text.textContent = this._d2txt(this._distance_calc());
|
|
||||||
},
|
|
||||||
|
|
||||||
_d2txt: function(d) {
|
|
||||||
if (d < 2000)
|
|
||||||
return d.toFixed(0) + ' m';
|
|
||||||
else
|
|
||||||
return (d/1000).toFixed(1) + ' km';
|
|
||||||
},
|
|
||||||
|
|
||||||
_distance_calc: function(e) {
|
|
||||||
var ll = this._line.getLatLngs();
|
|
||||||
var d = 0, p = null;
|
|
||||||
for (var i = 0; i < ll.length; i++) {
|
|
||||||
if (i)
|
|
||||||
d += p.distanceTo(ll[i]);
|
|
||||||
if (this.options.popups) {
|
|
||||||
var m = this._line.editing._markers[i];
|
|
||||||
if (m) {
|
|
||||||
m.bindPopup(this._d2txt(d));
|
|
||||||
m.on('mouseover', m.openPopup, m);
|
|
||||||
m.on('mouseout', m.closePopup, m);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p = ll[i];
|
|
||||||
}
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
||||||
/*
|
|
||||||
* Add async initialization of layers to L.Control.Layers
|
|
||||||
*/
|
|
||||||
L.Control.Layers.include({
|
|
||||||
_loadScripts: function(scripts, cb, args) {
|
|
||||||
if (!scripts || scripts.length === 0)
|
|
||||||
return cb(args);
|
|
||||||
var _this = this, s = scripts.pop(), c;
|
|
||||||
c = L.Control.Layers._script_cache[s];
|
|
||||||
if (c === undefined) {
|
|
||||||
c = {url: s, wait: []};
|
|
||||||
//console.info("Load " + s);
|
|
||||||
var script = document.createElement('script');
|
|
||||||
script.src = s;
|
|
||||||
script.type = 'text/javascript';
|
|
||||||
script.onload = function () {
|
|
||||||
var i = 0;
|
|
||||||
for (i = 0; i < c.wait.length; i++)
|
|
||||||
c.wait[i]();
|
|
||||||
};
|
|
||||||
c.e = script;
|
|
||||||
document.getElementsByTagName('head')[0].appendChild(script);
|
|
||||||
}
|
|
||||||
function _cb() { _this._loadScripts(scripts, cb, args); }
|
|
||||||
c.wait.push(_cb);
|
|
||||||
if (c.e.readyState === 'completed')
|
|
||||||
_cb();
|
|
||||||
L.Control.Layers._script_cache[s] = c;
|
|
||||||
},
|
|
||||||
|
|
||||||
addLayerDef: function(name, def) {
|
|
||||||
if (this._layer_defs === undefined)
|
|
||||||
this._layer_defs = {};
|
|
||||||
this._layer_defs[name] = def;
|
|
||||||
},
|
|
||||||
|
|
||||||
addLayerDefs: function(defs) {
|
|
||||||
if (this._layer_defs === undefined)
|
|
||||||
this._layer_defs = {};
|
|
||||||
L.Util.extend(this._layer_defs, defs);
|
|
||||||
},
|
|
||||||
|
|
||||||
loadLayer: function(name, deflt) {
|
|
||||||
var _this = this, l = this._layer_defs[name];
|
|
||||||
l['default'] = deflt;
|
|
||||||
this._loadScripts(l.js.reverse(), function(l) {_this._loadLayer(l);}, l);
|
|
||||||
},
|
|
||||||
|
|
||||||
_loadLayer: function(l) {
|
|
||||||
var x = l.init();
|
|
||||||
if (l['default'] && this._map)
|
|
||||||
this._map.addLayer(x);
|
|
||||||
if (!l.overlay)
|
|
||||||
this.addBaseLayer(x, l.name);
|
|
||||||
else
|
|
||||||
this.addOverlay(x, l.name);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
L.Control.Layers._script_cache = {};
|
|
||||||
|
|
@ -1,76 +0,0 @@
|
||||||
//#include "Permalink.js
|
|
||||||
|
|
||||||
L.Control.Permalink.include({
|
|
||||||
/*
|
|
||||||
options: {
|
|
||||||
useMarker: true,
|
|
||||||
markerOptions: {}
|
|
||||||
},
|
|
||||||
*/
|
|
||||||
|
|
||||||
initialize_layer: function() {
|
|
||||||
//console.info("Initialize layer");
|
|
||||||
this.on('update', this._set_layer, this);
|
|
||||||
this.on('add', this._onadd_layer, this);
|
|
||||||
},
|
|
||||||
|
|
||||||
_onadd_layer: function(e) {
|
|
||||||
//console.info("onAdd::layer", e);
|
|
||||||
this._map.on('layeradd', this._update_layer, this);
|
|
||||||
this._map.on('layerremove', this._update_layer, this);
|
|
||||||
this._update_layer();
|
|
||||||
},
|
|
||||||
|
|
||||||
_update_layer: function() {
|
|
||||||
if (!this.options.layers) return;
|
|
||||||
//console.info(this.options.layers);
|
|
||||||
var layer = this.options.layers.currentBaseLayer();
|
|
||||||
if (layer)
|
|
||||||
this._update({layer: layer.name});
|
|
||||||
},
|
|
||||||
|
|
||||||
_set_layer: function(e) {
|
|
||||||
//console.info("Set layer", e);
|
|
||||||
var p = e.params;
|
|
||||||
if (!this.options.layers || !p.layer) return;
|
|
||||||
this.options.layers.chooseBaseLayer(p.layer);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
L.Control.Layers.include({
|
|
||||||
chooseBaseLayer: function(name) {
|
|
||||||
var layer, obj;
|
|
||||||
for (var i in this._layers) {
|
|
||||||
if (!this._layers.hasOwnProperty(i))
|
|
||||||
continue;
|
|
||||||
obj = this._layers[i];
|
|
||||||
if (!obj.overlay && obj.name === name)
|
|
||||||
layer = obj.layer;
|
|
||||||
}
|
|
||||||
if (!layer || this._map.hasLayer(layer))
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (var j in this._layers) {
|
|
||||||
if (!this._layers.hasOwnProperty(j))
|
|
||||||
continue;
|
|
||||||
obj = this._layers[j];
|
|
||||||
if (!obj.overlay && this._map.hasLayer(obj.layer))
|
|
||||||
this._map.removeLayer(obj.layer);
|
|
||||||
}
|
|
||||||
this._map.addLayer(layer);
|
|
||||||
this._update();
|
|
||||||
},
|
|
||||||
|
|
||||||
currentBaseLayer: function() {
|
|
||||||
for (var i in this._layers) {
|
|
||||||
if (!this._layers.hasOwnProperty(i))
|
|
||||||
continue;
|
|
||||||
var obj = this._layers[i];
|
|
||||||
//console.info("Layer: ", obj.name, obj);
|
|
||||||
if (obj.overlay) continue;
|
|
||||||
if (!obj.overlay && this._map.hasLayer(obj.layer))
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
//#include "Permalink.js
|
|
||||||
|
|
||||||
L.Control.Permalink.include({
|
|
||||||
/*
|
|
||||||
options: {
|
|
||||||
line: null
|
|
||||||
},
|
|
||||||
*/
|
|
||||||
|
|
||||||
initialize_line: function() {
|
|
||||||
this.on('update', this._set_line, this);
|
|
||||||
this.on('add', this._onadd_line, this);
|
|
||||||
},
|
|
||||||
|
|
||||||
_onadd_line: function(e) {
|
|
||||||
//console.info("onAdd::line", e);
|
|
||||||
if (!this.options.line) return;
|
|
||||||
this.options.line.on('edit', this._update_line, this);
|
|
||||||
this._update_line();
|
|
||||||
},
|
|
||||||
|
|
||||||
_update_line: function() {
|
|
||||||
if (!this.options.line) return;
|
|
||||||
var line = this.options.line;
|
|
||||||
if (!line) return;
|
|
||||||
var text = [], coords = line.getLatLngs();
|
|
||||||
if (!coords.length)
|
|
||||||
return this._update({line: null});
|
|
||||||
for (var i in coords)
|
|
||||||
text.push(coords[i].lat.toFixed(4) + ',' + coords[i].lng.toFixed(4));
|
|
||||||
this._update({line: text.join(';')});
|
|
||||||
},
|
|
||||||
|
|
||||||
_set_line: function(e) {
|
|
||||||
//console.info("Set line", e.params.line);
|
|
||||||
var p = e.params, l = this.options.line;
|
|
||||||
if (!l || !p.line) return;
|
|
||||||
var coords = [], text = p.line.split(';');
|
|
||||||
for (var i in text) {
|
|
||||||
var ll = text[i].split(',');
|
|
||||||
if (ll.length !== 2) continue;
|
|
||||||
coords.push(new L.LatLng(ll[0], ll[1]));
|
|
||||||
}
|
|
||||||
if (!coords.length) return;
|
|
||||||
l.setLatLngs(coords);
|
|
||||||
if (!this._map.hasLayer(l))
|
|
||||||
this._map.addLayer(l);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
//#include "Permalink.js
|
|
||||||
|
|
||||||
L.Control.Permalink.include({
|
|
||||||
/*
|
|
||||||
options: {
|
|
||||||
useMarker: true,
|
|
||||||
markerOptions: {}
|
|
||||||
},
|
|
||||||
*/
|
|
||||||
|
|
||||||
initialize_marker: function() {
|
|
||||||
//console.info("Initialize marker");
|
|
||||||
this.on('update', this._set_marker, this);
|
|
||||||
},
|
|
||||||
|
|
||||||
_set_marker: function(e) {
|
|
||||||
//console.info("Set marker", e);
|
|
||||||
var p = e.params;
|
|
||||||
//if (!this.options.useMarker) return;
|
|
||||||
if (this._marker) return;
|
|
||||||
if (p.marker !== 1) return;
|
|
||||||
if (p.mlat !== undefined && p.mlon !== undefined)
|
|
||||||
return this._update({mlat: null, mlon: null,
|
|
||||||
lat: p.mlat, lon: p.mlon, marker: 1});
|
|
||||||
this._marker = new L.Marker(new L.LatLng(p.lat, p.lon),
|
|
||||||
this.options.markerOptions);
|
|
||||||
this._marker.bindPopup('<a href="' + this._update_href() + '">' + this.options.text + '</a>');
|
|
||||||
this._map.addLayer(this._marker);
|
|
||||||
this._update({marker: null});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
@ -1,163 +0,0 @@
|
||||||
L.Control.Permalink = L.Control.extend({
|
|
||||||
includes: L.Mixin.Events,
|
|
||||||
|
|
||||||
options: {
|
|
||||||
position: 'bottomleft',
|
|
||||||
useAnchor: true,
|
|
||||||
useLocation: false,
|
|
||||||
text: 'Permalink'
|
|
||||||
},
|
|
||||||
|
|
||||||
initialize: function(options) {
|
|
||||||
L.Util.setOptions(this, options);
|
|
||||||
this._params = {};
|
|
||||||
this._set_urlvars();
|
|
||||||
this.on('update', this._set_center, this);
|
|
||||||
for (var i in this) {
|
|
||||||
if (typeof(i) === 'string' && i.indexOf('initialize_') === 0)
|
|
||||||
this[i]();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
onAdd: function(map) {
|
|
||||||
this._container = L.DomUtil.create('div', 'leaflet-control-attribution leaflet-control-permalink');
|
|
||||||
L.DomEvent.disableClickPropagation(this._container);
|
|
||||||
this._map = map;
|
|
||||||
this._href = L.DomUtil.create('a', null, this._container);
|
|
||||||
this._href.innerHTML = this.options.text;
|
|
||||||
|
|
||||||
map.on('moveend', this._update_center, this);
|
|
||||||
this.fire('update', {params: this._params});
|
|
||||||
this._update_center();
|
|
||||||
|
|
||||||
if (this.options.useAnchor && 'onhashchange' in window) {
|
|
||||||
var _this = this, fn = window.onhashchange;
|
|
||||||
window.onhashchange = function() {
|
|
||||||
_this._set_urlvars();
|
|
||||||
if (fn) return fn();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
this.fire('add', {map: map});
|
|
||||||
|
|
||||||
return this._container;
|
|
||||||
},
|
|
||||||
|
|
||||||
_update_center: function() {
|
|
||||||
if (!this._map) return;
|
|
||||||
|
|
||||||
var center = this._round_point(this._map.getCenter());
|
|
||||||
this._update({zoom: this._map.getZoom(), lat: center.lat, lon: center.lng});
|
|
||||||
},
|
|
||||||
|
|
||||||
_update_href: function() {
|
|
||||||
var params = L.Util.getParamString(this._params);
|
|
||||||
var sep = '?';
|
|
||||||
if (this.options.useAnchor) sep = '#';
|
|
||||||
var url = this._url_base + sep + params.slice(1);
|
|
||||||
if (this._href) this._href.setAttribute('href', url);
|
|
||||||
if (this.options.useLocation)
|
|
||||||
location.replace('#' + params.slice(1));
|
|
||||||
return url;
|
|
||||||
},
|
|
||||||
|
|
||||||
_round_point : function(point) {
|
|
||||||
var bounds = this._map.getBounds(), size = this._map.getSize();
|
|
||||||
var ne = bounds.getNorthEast(), sw = bounds.getSouthWest();
|
|
||||||
|
|
||||||
var round = function (x, p) {
|
|
||||||
if (p === 0) return x;
|
|
||||||
var shift = 1;
|
|
||||||
while (p < 1 && p > -1) {
|
|
||||||
x *= 10;
|
|
||||||
p *= 10;
|
|
||||||
shift *= 10;
|
|
||||||
}
|
|
||||||
return Math.floor(x)/shift;
|
|
||||||
};
|
|
||||||
point.lat = round(point.lat, (ne.lat - sw.lat) / size.y);
|
|
||||||
point.lng = round(point.lng, (ne.lng - sw.lng) / size.x);
|
|
||||||
return point;
|
|
||||||
},
|
|
||||||
|
|
||||||
_update: function(obj, source) {
|
|
||||||
//console.info('Update', obj, this._params);
|
|
||||||
for(var i in obj) {
|
|
||||||
if (!obj.hasOwnProperty(i)) continue;
|
|
||||||
if (obj[i] !== null && obj[i] !== undefined)
|
|
||||||
this._params[i] = obj[i];
|
|
||||||
else
|
|
||||||
delete this._params[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
this._update_href();
|
|
||||||
},
|
|
||||||
|
|
||||||
_set_urlvars: function()
|
|
||||||
{
|
|
||||||
this._url_base = window.location.href.split('#')[0].split('?')[0];
|
|
||||||
|
|
||||||
var p;
|
|
||||||
if (this.options.useAnchor)
|
|
||||||
p = L.UrlUtil.queryParse(L.UrlUtil.hash());
|
|
||||||
else
|
|
||||||
p = L.UrlUtil.queryParse(L.UrlUtil.query());
|
|
||||||
|
|
||||||
function eq(x, y) {
|
|
||||||
for(var i in x)
|
|
||||||
if (x.hasOwnProperty(i) && x[i] !== y[i])
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (eq(p, this._params) && eq(this._params, p))
|
|
||||||
return;
|
|
||||||
this._params = p;
|
|
||||||
this._update_href();
|
|
||||||
this.fire('update', {params: this._params});
|
|
||||||
},
|
|
||||||
|
|
||||||
_set_center: function(e)
|
|
||||||
{
|
|
||||||
//console.info('Update center', e);
|
|
||||||
var params = e.params;
|
|
||||||
if (params.zoom === undefined ||
|
|
||||||
params.lat === undefined ||
|
|
||||||
params.lon === undefined) return;
|
|
||||||
this._map.setView(new L.LatLng(params.lat, params.lon), params.zoom);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
L.UrlUtil = {
|
|
||||||
queryParse: function(s) {
|
|
||||||
var p = {};
|
|
||||||
var sep = '&';
|
|
||||||
if (s.search('&') !== -1)
|
|
||||||
sep = '&';
|
|
||||||
var params = s.split(sep);
|
|
||||||
for(var i = 0; i < params.length; i++) {
|
|
||||||
var tmp = params[i].split('=');
|
|
||||||
if (tmp.length !== 2) continue;
|
|
||||||
p[tmp[0]] = decodeURI(tmp[1]);
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
},
|
|
||||||
|
|
||||||
query: function() {
|
|
||||||
var href = window.location.href.split('#')[0], idx = href.indexOf('?');
|
|
||||||
if (idx < 0)
|
|
||||||
return '';
|
|
||||||
return href.slice(idx+1);
|
|
||||||
},
|
|
||||||
|
|
||||||
hash: function() { return window.location.hash.slice(1); },
|
|
||||||
|
|
||||||
updateParamString: function (q, obj) {
|
|
||||||
var p = L.UrlUtil.queryParse(q);
|
|
||||||
for (var i in obj) {
|
|
||||||
if (obj.hasOwnProperty(i))
|
|
||||||
p[i] = obj[i];
|
|
||||||
}
|
|
||||||
return L.Util.getParamString(p).slice(1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
BIN
bower_components/leaflet-plugins/css/cross.png
vendored
|
Before Width: | Height: | Size: 1.6 KiB |
|
|
@ -1,48 +0,0 @@
|
||||||
.leaflet-control-distance {
|
|
||||||
-moz-border-radius: 7px;
|
|
||||||
-webkit-border-radius: 7px;
|
|
||||||
border-radius: 7px;
|
|
||||||
|
|
||||||
padding: 5px;
|
|
||||||
background-color: rgba(0, 0, 0, 0.25);
|
|
||||||
}
|
|
||||||
|
|
||||||
.leaflet-control-distance a, .leaflet-control-distance div {
|
|
||||||
-moz-border-radius: 4px;
|
|
||||||
-webkit-border-radius: 4px;
|
|
||||||
border-radius: 4px;
|
|
||||||
|
|
||||||
padding: 2px;
|
|
||||||
background-position: 50% 50%;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-color: rgba(255, 255, 255, 0.75);
|
|
||||||
}
|
|
||||||
|
|
||||||
.leaflet-control-distance a {
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.leaflet-control-distance div {
|
|
||||||
font: 11px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
|
|
||||||
color: #333;
|
|
||||||
height: 16px;
|
|
||||||
margin-top: 5px;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.leaflet-control-distance-edit {
|
|
||||||
/* http://openclipart.org/detail/114727/ftview-ruler-by-anonymous */
|
|
||||||
background-image: url('measure.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
.leaflet-control-distance-delete {
|
|
||||||
margin-left: 5px;
|
|
||||||
/* Based on http://openclipart.org/detail/34729/architetto----tasto-8-by-anonymous */
|
|
||||||
background-image: url('cross.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
a.leaflet-control-distance-active {
|
|
||||||
background-color: yellow;
|
|
||||||
}
|
|
||||||
BIN
bower_components/leaflet-plugins/css/measure.png
vendored
|
Before Width: | Height: | Size: 470 B |
97
bower_components/leaflet-plugins/css/osb.css
vendored
|
|
@ -1,97 +0,0 @@
|
||||||
.osb-popup {
|
|
||||||
font-family: sans-serif;
|
|
||||||
font-size: small;
|
|
||||||
max-width: 380px;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
.osb-popup a:link, .osb-popup a:visited {
|
|
||||||
border-bottom: 1px dotted #C0C0C0;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
.osb-popup a:link {
|
|
||||||
color: #990000;
|
|
||||||
}
|
|
||||||
.osb-popup a:visited {
|
|
||||||
color: #500000;
|
|
||||||
}
|
|
||||||
.osb-popup a:link:hover, .osb-popup a:visited:hover {
|
|
||||||
border-bottom: 1px solid #C0C0C0;
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
.osb-popup a:link:focus .osb-popup a:visited:focus {
|
|
||||||
outline: 1px dotted #C0C0C0;
|
|
||||||
}
|
|
||||||
.osb-popup a:link:active, .osb-popup a:visited:active {
|
|
||||||
border-bottom: 1px solid #F0F0F0;
|
|
||||||
color: red;
|
|
||||||
outline: 1px solid #C0C0C0;
|
|
||||||
}
|
|
||||||
.osb-popup h1 {
|
|
||||||
color: #176BC1;
|
|
||||||
font-size: medium;
|
|
||||||
margin-bottom: 7px;
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
.osb-popup p {
|
|
||||||
margin-bottom: 0;
|
|
||||||
margin-top: 5px;
|
|
||||||
}
|
|
||||||
.osb-popup p.Comment {
|
|
||||||
margin-left: 15px;
|
|
||||||
margin-top: 5px;
|
|
||||||
}
|
|
||||||
.osb-popup p.Note {
|
|
||||||
border-top: 1px solid gray;
|
|
||||||
font-size: x-small;
|
|
||||||
margin-top: 7px;
|
|
||||||
padding-top: 3px;
|
|
||||||
}
|
|
||||||
.osb-popup form + p {
|
|
||||||
border-top: 1px solid gray;
|
|
||||||
margin-top: 15px;
|
|
||||||
padding-top: 10px;
|
|
||||||
}
|
|
||||||
.osb-popup ul {
|
|
||||||
border-top: 1px solid gray;
|
|
||||||
margin: 10px 0 0;
|
|
||||||
padding: 5px 0 0;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.osb-popup ul li {
|
|
||||||
display: inline;
|
|
||||||
margin-left: 12px;
|
|
||||||
margin-right: 12px;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
.osb-popup form {
|
|
||||||
margin-bottom: 0;
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
.osb-popup form.osb-comment {
|
|
||||||
border-top: 1px solid gray;
|
|
||||||
padding-top: 5px;
|
|
||||||
}
|
|
||||||
.osb-popup form div {
|
|
||||||
margin-left: 15px;
|
|
||||||
margin-right: 15px;
|
|
||||||
margin-top: 5px;
|
|
||||||
}
|
|
||||||
.osb-popup form div.osb-footer {
|
|
||||||
margin-bottom: 0;
|
|
||||||
margin-top: 15px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.osb-popup span.osb-inputlabel {
|
|
||||||
display: inline-block;
|
|
||||||
margin-right: 10px;
|
|
||||||
min-width: 110px;
|
|
||||||
}
|
|
||||||
.osb-popup input[type="text"] {
|
|
||||||
min-width: 190px;
|
|
||||||
}
|
|
||||||
.osb-popup input[type="button"] {
|
|
||||||
margin-left: 3px;
|
|
||||||
margin-right: 3px;
|
|
||||||
min-width: 75px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,915 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<kml xmlns="http://www.opengis.net/kml/2.2">
|
|
||||||
<Document>
|
|
||||||
<name>KML Samples</name>
|
|
||||||
<open>1</open>
|
|
||||||
<description>Unleash your creativity with the help of these examples!</description>
|
|
||||||
<Style id="downArrowIcon">
|
|
||||||
<IconStyle>
|
|
||||||
<Icon>
|
|
||||||
<href>http://maps.google.com/mapfiles/kml/pal4/icon28.png</href>
|
|
||||||
</Icon>
|
|
||||||
</IconStyle>
|
|
||||||
</Style>
|
|
||||||
<Style id="globeIcon">
|
|
||||||
<IconStyle>
|
|
||||||
<Icon>
|
|
||||||
<href>http://maps.google.com/mapfiles/kml/pal3/icon19.png</href>
|
|
||||||
</Icon>
|
|
||||||
</IconStyle>
|
|
||||||
<LineStyle>
|
|
||||||
<width>2</width>
|
|
||||||
</LineStyle>
|
|
||||||
</Style>
|
|
||||||
<Style id="transPurpleLineGreenPoly">
|
|
||||||
<LineStyle>
|
|
||||||
<color>7fff00ff</color>
|
|
||||||
<width>4</width>
|
|
||||||
</LineStyle>
|
|
||||||
<PolyStyle>
|
|
||||||
<color>7f00ff00</color>
|
|
||||||
</PolyStyle>
|
|
||||||
</Style>
|
|
||||||
<Style id="yellowLineGreenPoly">
|
|
||||||
<LineStyle>
|
|
||||||
<color>7f00ffff</color>
|
|
||||||
<width>4</width>
|
|
||||||
</LineStyle>
|
|
||||||
<PolyStyle>
|
|
||||||
<color>7f00ff00</color>
|
|
||||||
</PolyStyle>
|
|
||||||
</Style>
|
|
||||||
<Style id="thickBlackLine">
|
|
||||||
<LineStyle>
|
|
||||||
<color>87000000</color>
|
|
||||||
<width>10</width>
|
|
||||||
</LineStyle>
|
|
||||||
</Style>
|
|
||||||
<Style id="redLineBluePoly">
|
|
||||||
<LineStyle>
|
|
||||||
<color>ff0000ff</color>
|
|
||||||
</LineStyle>
|
|
||||||
<PolyStyle>
|
|
||||||
<color>ffff0000</color>
|
|
||||||
</PolyStyle>
|
|
||||||
</Style>
|
|
||||||
<Style id="blueLineRedPoly">
|
|
||||||
<LineStyle>
|
|
||||||
<color>ffff0000</color>
|
|
||||||
</LineStyle>
|
|
||||||
<PolyStyle>
|
|
||||||
<color>ff0000ff</color>
|
|
||||||
</PolyStyle>
|
|
||||||
</Style>
|
|
||||||
<Style id="transRedPoly">
|
|
||||||
<LineStyle>
|
|
||||||
<width>1.5</width>
|
|
||||||
</LineStyle>
|
|
||||||
<PolyStyle>
|
|
||||||
<color>7d0000ff</color>
|
|
||||||
</PolyStyle>
|
|
||||||
</Style>
|
|
||||||
<Style id="transBluePoly">
|
|
||||||
<LineStyle>
|
|
||||||
<width>1.5</width>
|
|
||||||
</LineStyle>
|
|
||||||
<PolyStyle>
|
|
||||||
<color>7dff0000</color>
|
|
||||||
</PolyStyle>
|
|
||||||
</Style>
|
|
||||||
<Style id="transGreenPoly">
|
|
||||||
<LineStyle>
|
|
||||||
<width>1.5</width>
|
|
||||||
</LineStyle>
|
|
||||||
<PolyStyle>
|
|
||||||
<color>7d00ff00</color>
|
|
||||||
</PolyStyle>
|
|
||||||
</Style>
|
|
||||||
<Style id="transYellowPoly">
|
|
||||||
<LineStyle>
|
|
||||||
<width>1.5</width>
|
|
||||||
</LineStyle>
|
|
||||||
<PolyStyle>
|
|
||||||
<color>7d00ffff</color>
|
|
||||||
</PolyStyle>
|
|
||||||
</Style>
|
|
||||||
<Style id="noDrivingDirections">
|
|
||||||
<BalloonStyle>
|
|
||||||
<text><![CDATA[
|
|
||||||
<b>$[name]</b>
|
|
||||||
<br /><br />
|
|
||||||
$[description]
|
|
||||||
]]></text>
|
|
||||||
</BalloonStyle>
|
|
||||||
</Style>
|
|
||||||
<Folder>
|
|
||||||
<name>Placemarks</name>
|
|
||||||
<description>These are just some of the different kinds of placemarks with
|
|
||||||
which you can mark your favorite places</description>
|
|
||||||
<LookAt>
|
|
||||||
<longitude>-122.0839597145766</longitude>
|
|
||||||
<latitude>37.42222904525232</latitude>
|
|
||||||
<altitude>0</altitude>
|
|
||||||
<heading>-148.4122922628044</heading>
|
|
||||||
<tilt>40.5575073395506</tilt>
|
|
||||||
<range>500.6566641072245</range>
|
|
||||||
</LookAt>
|
|
||||||
<Placemark>
|
|
||||||
<name>Simple placemark</name>
|
|
||||||
<description>Attached to the ground. Intelligently places itself at the
|
|
||||||
height of the underlying terrain.</description>
|
|
||||||
<Point>
|
|
||||||
<coordinates>-122.0822035425683,37.42228990140251,0</coordinates>
|
|
||||||
</Point>
|
|
||||||
</Placemark>
|
|
||||||
<Placemark>
|
|
||||||
<name>Floating placemark</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<description>Floats a defined distance above the ground.</description>
|
|
||||||
<LookAt>
|
|
||||||
<longitude>-122.0839597145766</longitude>
|
|
||||||
<latitude>37.42222904525232</latitude>
|
|
||||||
<altitude>0</altitude>
|
|
||||||
<heading>-148.4122922628044</heading>
|
|
||||||
<tilt>40.5575073395506</tilt>
|
|
||||||
<range>500.6566641072245</range>
|
|
||||||
</LookAt>
|
|
||||||
<styleUrl>#downArrowIcon</styleUrl>
|
|
||||||
<Point>
|
|
||||||
<altitudeMode>relativeToGround</altitudeMode>
|
|
||||||
<coordinates>-122.084075,37.4220033612141,50</coordinates>
|
|
||||||
</Point>
|
|
||||||
</Placemark>
|
|
||||||
<Placemark>
|
|
||||||
<name>Extruded placemark</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<description>Tethered to the ground by a customizable
|
|
||||||
"tail"</description>
|
|
||||||
<LookAt>
|
|
||||||
<longitude>-122.0845787421525</longitude>
|
|
||||||
<latitude>37.42215078737763</latitude>
|
|
||||||
<altitude>0</altitude>
|
|
||||||
<heading>-148.4126684946234</heading>
|
|
||||||
<tilt>40.55750733918048</tilt>
|
|
||||||
<range>365.2646606980322</range>
|
|
||||||
</LookAt>
|
|
||||||
<styleUrl>#globeIcon</styleUrl>
|
|
||||||
<Point>
|
|
||||||
<extrude>1</extrude>
|
|
||||||
<altitudeMode>relativeToGround</altitudeMode>
|
|
||||||
<coordinates>-122.0857667006183,37.42156927867553,50</coordinates>
|
|
||||||
</Point>
|
|
||||||
</Placemark>
|
|
||||||
</Folder>
|
|
||||||
<Folder>
|
|
||||||
<name>Styles and Markup</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<description>With KML it is easy to create rich, descriptive markup to
|
|
||||||
annotate and enrich your placemarks</description>
|
|
||||||
<LookAt>
|
|
||||||
<longitude>-122.0845787422371</longitude>
|
|
||||||
<latitude>37.42215078726837</latitude>
|
|
||||||
<altitude>0</altitude>
|
|
||||||
<heading>-148.4126777488172</heading>
|
|
||||||
<tilt>40.55750733930874</tilt>
|
|
||||||
<range>365.2646826292919</range>
|
|
||||||
</LookAt>
|
|
||||||
<styleUrl>#noDrivingDirections</styleUrl>
|
|
||||||
<Document>
|
|
||||||
<name>Highlighted Icon</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<description>Place your mouse over the icon to see it display the new
|
|
||||||
icon</description>
|
|
||||||
<LookAt>
|
|
||||||
<longitude>-122.0856552124024</longitude>
|
|
||||||
<latitude>37.4224281311035</latitude>
|
|
||||||
<altitude>0</altitude>
|
|
||||||
<heading>0</heading>
|
|
||||||
<tilt>0</tilt>
|
|
||||||
<range>265.8520424250024</range>
|
|
||||||
</LookAt>
|
|
||||||
<Style id="highlightPlacemark">
|
|
||||||
<IconStyle>
|
|
||||||
<Icon>
|
|
||||||
<href>http://maps.google.com/mapfiles/kml/paddle/red-stars.png</href>
|
|
||||||
</Icon>
|
|
||||||
</IconStyle>
|
|
||||||
</Style>
|
|
||||||
<Style id="normalPlacemark">
|
|
||||||
<IconStyle>
|
|
||||||
<Icon>
|
|
||||||
<href>http://maps.google.com/mapfiles/kml/paddle/wht-blank.png</href>
|
|
||||||
</Icon>
|
|
||||||
</IconStyle>
|
|
||||||
</Style>
|
|
||||||
<StyleMap id="exampleStyleMap">
|
|
||||||
<Pair>
|
|
||||||
<key>normal</key>
|
|
||||||
<styleUrl>#normalPlacemark</styleUrl>
|
|
||||||
</Pair>
|
|
||||||
<Pair>
|
|
||||||
<key>highlight</key>
|
|
||||||
<styleUrl>#highlightPlacemark</styleUrl>
|
|
||||||
</Pair>
|
|
||||||
</StyleMap>
|
|
||||||
<Placemark>
|
|
||||||
<name>Roll over this icon</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<styleUrl>#exampleStyleMap</styleUrl>
|
|
||||||
<Point>
|
|
||||||
<coordinates>-122.0856545755255,37.42243077405461,0</coordinates>
|
|
||||||
</Point>
|
|
||||||
</Placemark>
|
|
||||||
</Document>
|
|
||||||
<Placemark>
|
|
||||||
<name>Descriptive HTML</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<description><![CDATA[Click on the blue link!<br><br>
|
|
||||||
Placemark descriptions can be enriched by using many standard HTML tags.<br>
|
|
||||||
For example:
|
|
||||||
<hr>
|
|
||||||
Styles:<br>
|
|
||||||
<i>Italics</i>,
|
|
||||||
<b>Bold</b>,
|
|
||||||
<u>Underlined</u>,
|
|
||||||
<s>Strike Out</s>,
|
|
||||||
subscript<sub>subscript</sub>,
|
|
||||||
superscript<sup>superscript</sup>,
|
|
||||||
<big>Big</big>,
|
|
||||||
<small>Small</small>,
|
|
||||||
<tt>Typewriter</tt>,
|
|
||||||
<em>Emphasized</em>,
|
|
||||||
<strong>Strong</strong>,
|
|
||||||
<code>Code</code>
|
|
||||||
<hr>
|
|
||||||
Fonts:<br>
|
|
||||||
<font color="red">red by name</font>,
|
|
||||||
<font color="#408010">leaf green by hexadecimal RGB</font>
|
|
||||||
<br>
|
|
||||||
<font size=1>size 1</font>,
|
|
||||||
<font size=2>size 2</font>,
|
|
||||||
<font size=3>size 3</font>,
|
|
||||||
<font size=4>size 4</font>,
|
|
||||||
<font size=5>size 5</font>,
|
|
||||||
<font size=6>size 6</font>,
|
|
||||||
<font size=7>size 7</font>
|
|
||||||
<br>
|
|
||||||
<font face=times>Times</font>,
|
|
||||||
<font face=verdana>Verdana</font>,
|
|
||||||
<font face=arial>Arial</font><br>
|
|
||||||
<hr>
|
|
||||||
Links:
|
|
||||||
<br>
|
|
||||||
<a href="http://earth.google.com/">Google Earth!</a>
|
|
||||||
<br>
|
|
||||||
or: Check out our website at www.google.com
|
|
||||||
<hr>
|
|
||||||
Alignment:<br>
|
|
||||||
<p align=left>left</p>
|
|
||||||
<p align=center>center</p>
|
|
||||||
<p align=right>right</p>
|
|
||||||
<hr>
|
|
||||||
Ordered Lists:<br>
|
|
||||||
<ol><li>First</li><li>Second</li><li>Third</li></ol>
|
|
||||||
<ol type="a"><li>First</li><li>Second</li><li>Third</li></ol>
|
|
||||||
<ol type="A"><li>First</li><li>Second</li><li>Third</li></ol>
|
|
||||||
<hr>
|
|
||||||
Unordered Lists:<br>
|
|
||||||
<ul><li>A</li><li>B</li><li>C</li></ul>
|
|
||||||
<ul type="circle"><li>A</li><li>B</li><li>C</li></ul>
|
|
||||||
<ul type="square"><li>A</li><li>B</li><li>C</li></ul>
|
|
||||||
<hr>
|
|
||||||
Definitions:<br>
|
|
||||||
<dl>
|
|
||||||
<dt>Google:</dt><dd>The best thing since sliced bread</dd>
|
|
||||||
</dl>
|
|
||||||
<hr>
|
|
||||||
Centered:<br><center>
|
|
||||||
Time present and time past<br>
|
|
||||||
Are both perhaps present in time future,<br>
|
|
||||||
And time future contained in time past.<br>
|
|
||||||
If all time is eternally present<br>
|
|
||||||
All time is unredeemable.<br>
|
|
||||||
</center>
|
|
||||||
<hr>
|
|
||||||
Block Quote:
|
|
||||||
<br>
|
|
||||||
<blockquote>
|
|
||||||
We shall not cease from exploration<br>
|
|
||||||
And the end of all our exploring<br>
|
|
||||||
Will be to arrive where we started<br>
|
|
||||||
And know the place for the first time.<br>
|
|
||||||
<i>-- T.S. Eliot</i>
|
|
||||||
</blockquote>
|
|
||||||
<br>
|
|
||||||
<hr>
|
|
||||||
Headings:<br>
|
|
||||||
<h1>Header 1</h1>
|
|
||||||
<h2>Header 2</h2>
|
|
||||||
<h3>Header 3</h3>
|
|
||||||
<h3>Header 4</h4>
|
|
||||||
<h3>Header 5</h5>
|
|
||||||
<hr>
|
|
||||||
Images:<br>
|
|
||||||
<i>Remote image</i><br>
|
|
||||||
<img src="//developers.google.com/kml/documentation/images/googleSample.png"><br>
|
|
||||||
<i>Scaled image</i><br>
|
|
||||||
<img src="//developers.google.com/kml/documentation/images/googleSample.png" width=100><br>
|
|
||||||
<hr>
|
|
||||||
Simple Tables:<br>
|
|
||||||
<table border="1" padding="1">
|
|
||||||
<tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
|
|
||||||
<tr><td>a</td><td>b</td><td>c</td><td>d</td><td>e</td></tr>
|
|
||||||
</table>
|
|
||||||
<br>
|
|
||||||
[Did you notice that double-clicking on the placemark doesn't cause the viewer to take you anywhere? This is because it is possible to directly author a "placeless placemark". If you look at the code for this example, you will see that it has neither a point coordinate nor a LookAt element.]]]></description>
|
|
||||||
</Placemark>
|
|
||||||
</Folder>
|
|
||||||
<Folder>
|
|
||||||
<name>Ground Overlays</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<description>Examples of ground overlays</description>
|
|
||||||
<GroundOverlay>
|
|
||||||
<name>Large-scale overlay on terrain</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<description>Overlay shows Mount Etna erupting on July 13th, 2001.</description>
|
|
||||||
<LookAt>
|
|
||||||
<longitude>15.02468937557116</longitude>
|
|
||||||
<latitude>37.67395167941667</latitude>
|
|
||||||
<altitude>0</altitude>
|
|
||||||
<heading>-16.5581842842829</heading>
|
|
||||||
<tilt>58.31228652890705</tilt>
|
|
||||||
<range>30350.36838438907</range>
|
|
||||||
</LookAt>
|
|
||||||
<Icon>
|
|
||||||
<href>http://developers.google.com/kml/documentation/images/etna.jpg</href>
|
|
||||||
</Icon>
|
|
||||||
<LatLonBox>
|
|
||||||
<north>37.91904192681665</north>
|
|
||||||
<south>37.46543388598137</south>
|
|
||||||
<east>15.35832653742206</east>
|
|
||||||
<west>14.60128369746704</west>
|
|
||||||
<rotation>-0.1556640799496235</rotation>
|
|
||||||
</LatLonBox>
|
|
||||||
</GroundOverlay>
|
|
||||||
</Folder>
|
|
||||||
<Folder>
|
|
||||||
<name>Screen Overlays</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<description>Screen overlays have to be authored directly in KML. These
|
|
||||||
examples illustrate absolute and dynamic positioning in screen space.</description>
|
|
||||||
<ScreenOverlay>
|
|
||||||
<name>Simple crosshairs</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<description>This screen overlay uses fractional positioning to put the
|
|
||||||
image in the exact center of the screen</description>
|
|
||||||
<Icon>
|
|
||||||
<href>http://developers.google.com/kml/documentation/images/crosshairs.png</href>
|
|
||||||
</Icon>
|
|
||||||
<overlayXY x="0.5" y="0.5" xunits="fraction" yunits="fraction"/>
|
|
||||||
<screenXY x="0.5" y="0.5" xunits="fraction" yunits="fraction"/>
|
|
||||||
<rotationXY x="0.5" y="0.5" xunits="fraction" yunits="fraction"/>
|
|
||||||
<size x="0" y="0" xunits="pixels" yunits="pixels"/>
|
|
||||||
</ScreenOverlay>
|
|
||||||
<ScreenOverlay>
|
|
||||||
<name>Absolute Positioning: Top left</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<Icon>
|
|
||||||
<href>http://developers.google.com/kml/documentation/images/top_left.jpg</href>
|
|
||||||
</Icon>
|
|
||||||
<overlayXY x="0" y="1" xunits="fraction" yunits="fraction"/>
|
|
||||||
<screenXY x="0" y="1" xunits="fraction" yunits="fraction"/>
|
|
||||||
<rotationXY x="0" y="0" xunits="fraction" yunits="fraction"/>
|
|
||||||
<size x="0" y="0" xunits="fraction" yunits="fraction"/>
|
|
||||||
</ScreenOverlay>
|
|
||||||
<ScreenOverlay>
|
|
||||||
<name>Absolute Positioning: Top right</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<Icon>
|
|
||||||
<href>http://developers.google.com/kml/documentation/images/top_right.jpg</href>
|
|
||||||
</Icon>
|
|
||||||
<overlayXY x="1" y="1" xunits="fraction" yunits="fraction"/>
|
|
||||||
<screenXY x="1" y="1" xunits="fraction" yunits="fraction"/>
|
|
||||||
<rotationXY x="0" y="0" xunits="fraction" yunits="fraction"/>
|
|
||||||
<size x="0" y="0" xunits="fraction" yunits="fraction"/>
|
|
||||||
</ScreenOverlay>
|
|
||||||
<ScreenOverlay>
|
|
||||||
<name>Absolute Positioning: Bottom left</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<Icon>
|
|
||||||
<href>http://developers.google.com/kml/documentation/images/bottom_left.jpg</href>
|
|
||||||
</Icon>
|
|
||||||
<overlayXY x="0" y="-1" xunits="fraction" yunits="fraction"/>
|
|
||||||
<screenXY x="0" y="0" xunits="fraction" yunits="fraction"/>
|
|
||||||
<rotationXY x="0" y="0" xunits="fraction" yunits="fraction"/>
|
|
||||||
<size x="0" y="0" xunits="fraction" yunits="fraction"/>
|
|
||||||
</ScreenOverlay>
|
|
||||||
<ScreenOverlay>
|
|
||||||
<name>Absolute Positioning: Bottom right</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<Icon>
|
|
||||||
<href>http://developers.google.com/kml/documentation/images/bottom_right.jpg</href>
|
|
||||||
</Icon>
|
|
||||||
<overlayXY x="1" y="-1" xunits="fraction" yunits="fraction"/>
|
|
||||||
<screenXY x="1" y="0" xunits="fraction" yunits="fraction"/>
|
|
||||||
<rotationXY x="0" y="0" xunits="fraction" yunits="fraction"/>
|
|
||||||
<size x="0" y="0" xunits="fraction" yunits="fraction"/>
|
|
||||||
</ScreenOverlay>
|
|
||||||
<ScreenOverlay>
|
|
||||||
<name>Dynamic Positioning: Top of screen</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<Icon>
|
|
||||||
<href>http://developers.google.com/kml/documentation/images/dynamic_screenoverlay.jpg</href>
|
|
||||||
</Icon>
|
|
||||||
<overlayXY x="0" y="1" xunits="fraction" yunits="fraction"/>
|
|
||||||
<screenXY x="0" y="1" xunits="fraction" yunits="fraction"/>
|
|
||||||
<rotationXY x="0" y="0" xunits="fraction" yunits="fraction"/>
|
|
||||||
<size x="1" y="0.2" xunits="fraction" yunits="fraction"/>
|
|
||||||
</ScreenOverlay>
|
|
||||||
<ScreenOverlay>
|
|
||||||
<name>Dynamic Positioning: Right of screen</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<Icon>
|
|
||||||
<href>http://developers.google.com/kml/documentation/images/dynamic_right.jpg</href>
|
|
||||||
</Icon>
|
|
||||||
<overlayXY x="1" y="1" xunits="fraction" yunits="fraction"/>
|
|
||||||
<screenXY x="1" y="1" xunits="fraction" yunits="fraction"/>
|
|
||||||
<rotationXY x="0" y="0" xunits="fraction" yunits="fraction"/>
|
|
||||||
<size x="0" y="1" xunits="fraction" yunits="fraction"/>
|
|
||||||
</ScreenOverlay>
|
|
||||||
</Folder>
|
|
||||||
<Folder>
|
|
||||||
<name>Paths</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<description>Examples of paths. Note that the tessellate tag is by default
|
|
||||||
set to 0. If you want to create tessellated lines, they must be authored
|
|
||||||
(or edited) directly in KML.</description>
|
|
||||||
<Placemark>
|
|
||||||
<name>Tessellated</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<description><![CDATA[If the <tessellate> tag has a value of 1, the line will contour to the underlying terrain]]></description>
|
|
||||||
<LookAt>
|
|
||||||
<longitude>-112.0822680013139</longitude>
|
|
||||||
<latitude>36.09825589333556</latitude>
|
|
||||||
<altitude>0</altitude>
|
|
||||||
<heading>103.8120432044965</heading>
|
|
||||||
<tilt>62.04855796276328</tilt>
|
|
||||||
<range>2889.145007690472</range>
|
|
||||||
</LookAt>
|
|
||||||
<LineString>
|
|
||||||
<tessellate>1</tessellate>
|
|
||||||
<coordinates> -112.0814237830345,36.10677870477137,0
|
|
||||||
-112.0870267752693,36.0905099328766,0 </coordinates>
|
|
||||||
</LineString>
|
|
||||||
</Placemark>
|
|
||||||
<Placemark>
|
|
||||||
<name>Untessellated</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<description><![CDATA[If the <tessellate> tag has a value of 0, the line follow a simple straight-line path from point to point]]></description>
|
|
||||||
<LookAt>
|
|
||||||
<longitude>-112.0822680013139</longitude>
|
|
||||||
<latitude>36.09825589333556</latitude>
|
|
||||||
<altitude>0</altitude>
|
|
||||||
<heading>103.8120432044965</heading>
|
|
||||||
<tilt>62.04855796276328</tilt>
|
|
||||||
<range>2889.145007690472</range>
|
|
||||||
</LookAt>
|
|
||||||
<LineString>
|
|
||||||
<tessellate>0</tessellate>
|
|
||||||
<coordinates> -112.080622229595,36.10673460007995,0
|
|
||||||
-112.085242575315,36.09049598612422,0 </coordinates>
|
|
||||||
</LineString>
|
|
||||||
</Placemark>
|
|
||||||
<Placemark>
|
|
||||||
<name>Absolute</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<description>Transparent purple line</description>
|
|
||||||
<LookAt>
|
|
||||||
<longitude>-112.2719329043177</longitude>
|
|
||||||
<latitude>36.08890633450894</latitude>
|
|
||||||
<altitude>0</altitude>
|
|
||||||
<heading>-106.8161545998597</heading>
|
|
||||||
<tilt>44.60763714063257</tilt>
|
|
||||||
<range>2569.386744398339</range>
|
|
||||||
</LookAt>
|
|
||||||
<styleUrl>#transPurpleLineGreenPoly</styleUrl>
|
|
||||||
<LineString>
|
|
||||||
<tessellate>1</tessellate>
|
|
||||||
<altitudeMode>absolute</altitudeMode>
|
|
||||||
<coordinates> -112.265654928602,36.09447672602546,2357
|
|
||||||
-112.2660384528238,36.09342608838671,2357
|
|
||||||
-112.2668139013453,36.09251058776881,2357
|
|
||||||
-112.2677826834445,36.09189827357996,2357
|
|
||||||
-112.2688557510952,36.0913137941187,2357
|
|
||||||
-112.2694810717219,36.0903677207521,2357
|
|
||||||
-112.2695268555611,36.08932171487285,2357
|
|
||||||
-112.2690144567276,36.08850916060472,2357
|
|
||||||
-112.2681528815339,36.08753813597956,2357
|
|
||||||
-112.2670588176031,36.08682685262568,2357
|
|
||||||
-112.2657374587321,36.08646312301303,2357 </coordinates>
|
|
||||||
</LineString>
|
|
||||||
</Placemark>
|
|
||||||
<Placemark>
|
|
||||||
<name>Absolute Extruded</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<description>Transparent green wall with yellow outlines</description>
|
|
||||||
<LookAt>
|
|
||||||
<longitude>-112.2643334742529</longitude>
|
|
||||||
<latitude>36.08563154742419</latitude>
|
|
||||||
<altitude>0</altitude>
|
|
||||||
<heading>-125.7518698668815</heading>
|
|
||||||
<tilt>44.61038665812578</tilt>
|
|
||||||
<range>4451.842204068102</range>
|
|
||||||
</LookAt>
|
|
||||||
<styleUrl>#yellowLineGreenPoly</styleUrl>
|
|
||||||
<LineString>
|
|
||||||
<extrude>1</extrude>
|
|
||||||
<tessellate>1</tessellate>
|
|
||||||
<altitudeMode>absolute</altitudeMode>
|
|
||||||
<coordinates> -112.2550785337791,36.07954952145647,2357
|
|
||||||
-112.2549277039738,36.08117083492122,2357
|
|
||||||
-112.2552505069063,36.08260761307279,2357
|
|
||||||
-112.2564540158376,36.08395660588506,2357
|
|
||||||
-112.2580238976449,36.08511401044813,2357
|
|
||||||
-112.2595218489022,36.08584355239394,2357
|
|
||||||
-112.2608216347552,36.08612634548589,2357
|
|
||||||
-112.262073428656,36.08626019085147,2357
|
|
||||||
-112.2633204928495,36.08621519860091,2357
|
|
||||||
-112.2644963846444,36.08627897945274,2357
|
|
||||||
-112.2656969554589,36.08649599090644,2357 </coordinates>
|
|
||||||
</LineString>
|
|
||||||
</Placemark>
|
|
||||||
<Placemark>
|
|
||||||
<name>Relative</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<description>Black line (10 pixels wide), height tracks terrain</description>
|
|
||||||
<LookAt>
|
|
||||||
<longitude>-112.2580438551384</longitude>
|
|
||||||
<latitude>36.1072674824385</latitude>
|
|
||||||
<altitude>0</altitude>
|
|
||||||
<heading>4.947421249553717</heading>
|
|
||||||
<tilt>44.61324882043339</tilt>
|
|
||||||
<range>2927.61105910266</range>
|
|
||||||
</LookAt>
|
|
||||||
<styleUrl>#thickBlackLine</styleUrl>
|
|
||||||
<LineString>
|
|
||||||
<tessellate>1</tessellate>
|
|
||||||
<altitudeMode>relativeToGround</altitudeMode>
|
|
||||||
<coordinates> -112.2532845153347,36.09886943729116,645
|
|
||||||
-112.2540466121145,36.09919570465255,645
|
|
||||||
-112.254734666947,36.09984998366178,645
|
|
||||||
-112.255493345654,36.10051310621746,645
|
|
||||||
-112.2563157098468,36.10108441943419,645
|
|
||||||
-112.2568033076439,36.10159722088088,645
|
|
||||||
-112.257494011321,36.10204323542867,645
|
|
||||||
-112.2584106072308,36.10229131995655,645
|
|
||||||
-112.2596588987972,36.10240001286358,645
|
|
||||||
-112.2610581199487,36.10213176873407,645
|
|
||||||
-112.2626285262793,36.10157011437219,645 </coordinates>
|
|
||||||
</LineString>
|
|
||||||
</Placemark>
|
|
||||||
<Placemark>
|
|
||||||
<name>Relative Extruded</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<description>Opaque blue walls with red outline, height tracks terrain</description>
|
|
||||||
<LookAt>
|
|
||||||
<longitude>-112.2683594333433</longitude>
|
|
||||||
<latitude>36.09884362144909</latitude>
|
|
||||||
<altitude>0</altitude>
|
|
||||||
<heading>-72.24271551768405</heading>
|
|
||||||
<tilt>44.60855445139561</tilt>
|
|
||||||
<range>2184.193522571467</range>
|
|
||||||
</LookAt>
|
|
||||||
<styleUrl>#redLineBluePoly</styleUrl>
|
|
||||||
<LineString>
|
|
||||||
<extrude>1</extrude>
|
|
||||||
<tessellate>1</tessellate>
|
|
||||||
<altitudeMode>relativeToGround</altitudeMode>
|
|
||||||
<coordinates> -112.2656634181359,36.09445214722695,630
|
|
||||||
-112.2652238941097,36.09520916122063,630
|
|
||||||
-112.2645079986395,36.09580763864907,630
|
|
||||||
-112.2638827428817,36.09628572284063,630
|
|
||||||
-112.2635746835406,36.09679275951239,630
|
|
||||||
-112.2635711822407,36.09740038871899,630
|
|
||||||
-112.2640296531825,36.09804913435539,630
|
|
||||||
-112.264327720538,36.09880337400301,630
|
|
||||||
-112.2642436562271,36.09963644790288,630
|
|
||||||
-112.2639148687042,36.10055381117246,630
|
|
||||||
-112.2626894973474,36.10149062823369,630 </coordinates>
|
|
||||||
</LineString>
|
|
||||||
</Placemark>
|
|
||||||
</Folder>
|
|
||||||
<Folder>
|
|
||||||
<name>Polygons</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<description>Examples of polygon shapes</description>
|
|
||||||
<Folder>
|
|
||||||
<name>Google Campus</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<description>A collection showing how easy it is to create 3-dimensional
|
|
||||||
buildings</description>
|
|
||||||
<LookAt>
|
|
||||||
<longitude>-122.084120030116</longitude>
|
|
||||||
<latitude>37.42174011925477</latitude>
|
|
||||||
<altitude>0</altitude>
|
|
||||||
<heading>-34.82469740081282</heading>
|
|
||||||
<tilt>53.454348562403</tilt>
|
|
||||||
<range>276.7870053764046</range>
|
|
||||||
</LookAt>
|
|
||||||
<Placemark>
|
|
||||||
<name>Building 40</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<styleUrl>#transRedPoly</styleUrl>
|
|
||||||
<Polygon>
|
|
||||||
<extrude>1</extrude>
|
|
||||||
<altitudeMode>relativeToGround</altitudeMode>
|
|
||||||
<outerBoundaryIs>
|
|
||||||
<LinearRing>
|
|
||||||
<coordinates> -122.0848938459612,37.42257124044786,17
|
|
||||||
-122.0849580979198,37.42211922626856,17
|
|
||||||
-122.0847469573047,37.42207183952619,17
|
|
||||||
-122.0845725380962,37.42209006729676,17
|
|
||||||
-122.0845954886723,37.42215932700895,17
|
|
||||||
-122.0838521118269,37.42227278564371,17
|
|
||||||
-122.083792243335,37.42203539112084,17
|
|
||||||
-122.0835076656616,37.42209006957106,17
|
|
||||||
-122.0834709464152,37.42200987395161,17
|
|
||||||
-122.0831221085748,37.4221046494946,17
|
|
||||||
-122.0829247374572,37.42226503990386,17
|
|
||||||
-122.0829339169385,37.42231242843094,17
|
|
||||||
-122.0833837359737,37.42225046087618,17
|
|
||||||
-122.0833607854248,37.42234159228745,17
|
|
||||||
-122.0834204551642,37.42237075460644,17
|
|
||||||
-122.083659133885,37.42251292011001,17
|
|
||||||
-122.0839758438952,37.42265873093781,17
|
|
||||||
-122.0842374743331,37.42265143972521,17
|
|
||||||
-122.0845036949503,37.4226514386435,17
|
|
||||||
-122.0848020460801,37.42261133916315,17
|
|
||||||
-122.0847882750515,37.42256395055121,17
|
|
||||||
-122.0848938459612,37.42257124044786,17 </coordinates>
|
|
||||||
</LinearRing>
|
|
||||||
</outerBoundaryIs>
|
|
||||||
</Polygon>
|
|
||||||
</Placemark>
|
|
||||||
<Placemark>
|
|
||||||
<name>Building 41</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<styleUrl>#transBluePoly</styleUrl>
|
|
||||||
<Polygon>
|
|
||||||
<extrude>1</extrude>
|
|
||||||
<altitudeMode>relativeToGround</altitudeMode>
|
|
||||||
<outerBoundaryIs>
|
|
||||||
<LinearRing>
|
|
||||||
<coordinates> -122.0857412771483,37.42227033155257,17
|
|
||||||
-122.0858169768481,37.42231408832346,17
|
|
||||||
-122.085852582875,37.42230337469744,17
|
|
||||||
-122.0858799945639,37.42225686138789,17
|
|
||||||
-122.0858860101409,37.4222311076138,17
|
|
||||||
-122.0858069157288,37.42220250173855,17
|
|
||||||
-122.0858379542653,37.42214027058678,17
|
|
||||||
-122.0856732640519,37.42208690214408,17
|
|
||||||
-122.0856022926407,37.42214885429042,17
|
|
||||||
-122.0855902778436,37.422128290487,17
|
|
||||||
-122.0855841672237,37.42208171967246,17
|
|
||||||
-122.0854852065741,37.42210455874995,17
|
|
||||||
-122.0855067264352,37.42214267949824,17
|
|
||||||
-122.0854430712915,37.42212783846172,17
|
|
||||||
-122.0850990714904,37.42251282407603,17
|
|
||||||
-122.0856769818632,37.42281815323651,17
|
|
||||||
-122.0860162273783,37.42244918858722,17
|
|
||||||
-122.0857260327004,37.42229239604253,17
|
|
||||||
-122.0857412771483,37.42227033155257,17 </coordinates>
|
|
||||||
</LinearRing>
|
|
||||||
</outerBoundaryIs>
|
|
||||||
</Polygon>
|
|
||||||
</Placemark>
|
|
||||||
<Placemark>
|
|
||||||
<name>Building 42</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<styleUrl>#transGreenPoly</styleUrl>
|
|
||||||
<Polygon>
|
|
||||||
<extrude>1</extrude>
|
|
||||||
<altitudeMode>relativeToGround</altitudeMode>
|
|
||||||
<outerBoundaryIs>
|
|
||||||
<LinearRing>
|
|
||||||
<coordinates> -122.0857862287242,37.42136208886969,25
|
|
||||||
-122.0857312990603,37.42136935989481,25
|
|
||||||
-122.0857312992918,37.42140934910903,25
|
|
||||||
-122.0856077073679,37.42138390166565,25
|
|
||||||
-122.0855802426516,37.42137299550869,25
|
|
||||||
-122.0852186221971,37.42137299504316,25
|
|
||||||
-122.0852277765639,37.42161656508265,25
|
|
||||||
-122.0852598189347,37.42160565894403,25
|
|
||||||
-122.0852598185499,37.42168200156,25
|
|
||||||
-122.0852369311478,37.42170017860346,25
|
|
||||||
-122.0852643957828,37.42176197982575,25
|
|
||||||
-122.0853239032746,37.42176198013907,25
|
|
||||||
-122.0853559454324,37.421852864452,25
|
|
||||||
-122.0854108752463,37.42188921823734,25
|
|
||||||
-122.0854795379357,37.42189285337048,25
|
|
||||||
-122.0855436229819,37.42188921797546,25
|
|
||||||
-122.0856260178042,37.42186013499926,25
|
|
||||||
-122.085937287963,37.42186013453605,25
|
|
||||||
-122.0859428718666,37.42160898590042,25
|
|
||||||
-122.0859655469861,37.42157992759144,25
|
|
||||||
-122.0858640462341,37.42147115002957,25
|
|
||||||
-122.0858548911215,37.42140571326184,25
|
|
||||||
-122.0858091162768,37.4214057134039,25
|
|
||||||
-122.0857862287242,37.42136208886969,25 </coordinates>
|
|
||||||
</LinearRing>
|
|
||||||
</outerBoundaryIs>
|
|
||||||
</Polygon>
|
|
||||||
</Placemark>
|
|
||||||
<Placemark>
|
|
||||||
<name>Building 43</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<styleUrl>#transYellowPoly</styleUrl>
|
|
||||||
<Polygon>
|
|
||||||
<extrude>1</extrude>
|
|
||||||
<altitudeMode>relativeToGround</altitudeMode>
|
|
||||||
<outerBoundaryIs>
|
|
||||||
<LinearRing>
|
|
||||||
<coordinates> -122.0844371128284,37.42177253003091,19
|
|
||||||
-122.0845118855746,37.42191111542896,19
|
|
||||||
-122.0850470999805,37.42178755121535,19
|
|
||||||
-122.0850719913391,37.42143663023161,19
|
|
||||||
-122.084916406232,37.42137237822116,19
|
|
||||||
-122.0842193868167,37.42137237801626,19
|
|
||||||
-122.08421938659,37.42147617161496,19
|
|
||||||
-122.0838086419991,37.4214613409357,19
|
|
||||||
-122.0837899728564,37.42131306410796,19
|
|
||||||
-122.0832796534698,37.42129328840593,19
|
|
||||||
-122.0832609819207,37.42139213944298,19
|
|
||||||
-122.0829373621737,37.42137236399876,19
|
|
||||||
-122.0829062425667,37.42151569778871,19
|
|
||||||
-122.0828502269665,37.42176282576465,19
|
|
||||||
-122.0829435788635,37.42176776969635,19
|
|
||||||
-122.083217411188,37.42179248552686,19
|
|
||||||
-122.0835970430103,37.4217480074456,19
|
|
||||||
-122.0839455556771,37.42169364237603,19
|
|
||||||
-122.0840077894637,37.42176283815853,19
|
|
||||||
-122.084113587521,37.42174801104392,19
|
|
||||||
-122.0840762473784,37.42171341292375,19
|
|
||||||
-122.0841447047739,37.42167881534569,19
|
|
||||||
-122.084144704223,37.42181720660197,19
|
|
||||||
-122.0842503333074,37.4218170700446,19
|
|
||||||
-122.0844371128284,37.42177253003091,19 </coordinates>
|
|
||||||
</LinearRing>
|
|
||||||
</outerBoundaryIs>
|
|
||||||
</Polygon>
|
|
||||||
</Placemark>
|
|
||||||
</Folder>
|
|
||||||
<Folder>
|
|
||||||
<name>Extruded Polygon</name>
|
|
||||||
<description>A simple way to model a building</description>
|
|
||||||
<Placemark>
|
|
||||||
<name>The Pentagon</name>
|
|
||||||
<LookAt>
|
|
||||||
<longitude>-77.05580139178142</longitude>
|
|
||||||
<latitude>38.870832443487</latitude>
|
|
||||||
<heading>59.88865561738225</heading>
|
|
||||||
<tilt>48.09646074797388</tilt>
|
|
||||||
<range>742.0552506670548</range>
|
|
||||||
</LookAt>
|
|
||||||
<Polygon>
|
|
||||||
<extrude>1</extrude>
|
|
||||||
<altitudeMode>relativeToGround</altitudeMode>
|
|
||||||
<outerBoundaryIs>
|
|
||||||
<LinearRing>
|
|
||||||
<coordinates> -77.05788457660967,38.87253259892824,100
|
|
||||||
-77.05465973756702,38.87291016281703,100
|
|
||||||
-77.05315536854791,38.87053267794386,100
|
|
||||||
-77.05552622493516,38.868757801256,100
|
|
||||||
-77.05844056290393,38.86996206506943,100
|
|
||||||
-77.05788457660967,38.87253259892824,100 </coordinates>
|
|
||||||
</LinearRing>
|
|
||||||
</outerBoundaryIs>
|
|
||||||
<innerBoundaryIs>
|
|
||||||
<LinearRing>
|
|
||||||
<coordinates> -77.05668055019126,38.87154239798456,100
|
|
||||||
-77.05542625960818,38.87167890344077,100
|
|
||||||
-77.05485125901024,38.87076535397792,100
|
|
||||||
-77.05577677433152,38.87008686581446,100
|
|
||||||
-77.05691162017543,38.87054446963351,100
|
|
||||||
-77.05668055019126,38.87154239798456,100 </coordinates>
|
|
||||||
</LinearRing>
|
|
||||||
</innerBoundaryIs>
|
|
||||||
</Polygon>
|
|
||||||
</Placemark>
|
|
||||||
</Folder>
|
|
||||||
<Folder>
|
|
||||||
<name>Absolute and Relative</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<description>Four structures whose roofs meet exactly. Turn on/off
|
|
||||||
terrain to see the difference between relative and absolute
|
|
||||||
positioning.</description>
|
|
||||||
<LookAt>
|
|
||||||
<longitude>-112.3348969157552</longitude>
|
|
||||||
<latitude>36.14845533214919</latitude>
|
|
||||||
<altitude>0</altitude>
|
|
||||||
<heading>-86.91235037566909</heading>
|
|
||||||
<tilt>49.30695423894192</tilt>
|
|
||||||
<range>990.6761201087104</range>
|
|
||||||
</LookAt>
|
|
||||||
<Placemark>
|
|
||||||
<name>Absolute</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<styleUrl>#transBluePoly</styleUrl>
|
|
||||||
<Polygon>
|
|
||||||
<tessellate>1</tessellate>
|
|
||||||
<altitudeMode>absolute</altitudeMode>
|
|
||||||
<outerBoundaryIs>
|
|
||||||
<LinearRing>
|
|
||||||
<coordinates> -112.3372510731295,36.14888505105317,1784
|
|
||||||
-112.3356128688403,36.14781540589019,1784
|
|
||||||
-112.3368169371048,36.14658677734382,1784
|
|
||||||
-112.3384408457543,36.14762778914076,1784
|
|
||||||
-112.3372510731295,36.14888505105317,1784 </coordinates>
|
|
||||||
</LinearRing>
|
|
||||||
</outerBoundaryIs>
|
|
||||||
</Polygon>
|
|
||||||
</Placemark>
|
|
||||||
<Placemark>
|
|
||||||
<name>Absolute Extruded</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<styleUrl>#transRedPoly</styleUrl>
|
|
||||||
<Polygon>
|
|
||||||
<extrude>1</extrude>
|
|
||||||
<tessellate>1</tessellate>
|
|
||||||
<altitudeMode>absolute</altitudeMode>
|
|
||||||
<outerBoundaryIs>
|
|
||||||
<LinearRing>
|
|
||||||
<coordinates> -112.3396586818843,36.14637618647505,1784
|
|
||||||
-112.3380597654315,36.14531751871353,1784
|
|
||||||
-112.3368254237788,36.14659596244607,1784
|
|
||||||
-112.3384555043203,36.14762621763982,1784
|
|
||||||
-112.3396586818843,36.14637618647505,1784 </coordinates>
|
|
||||||
</LinearRing>
|
|
||||||
</outerBoundaryIs>
|
|
||||||
</Polygon>
|
|
||||||
</Placemark>
|
|
||||||
<Placemark>
|
|
||||||
<name>Relative</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<LookAt>
|
|
||||||
<longitude>-112.3350152490417</longitude>
|
|
||||||
<latitude>36.14943123077423</latitude>
|
|
||||||
<altitude>0</altitude>
|
|
||||||
<heading>-118.9214100848499</heading>
|
|
||||||
<tilt>37.92486261093203</tilt>
|
|
||||||
<range>345.5169113679813</range>
|
|
||||||
</LookAt>
|
|
||||||
<styleUrl>#transGreenPoly</styleUrl>
|
|
||||||
<Polygon>
|
|
||||||
<tessellate>1</tessellate>
|
|
||||||
<altitudeMode>relativeToGround</altitudeMode>
|
|
||||||
<outerBoundaryIs>
|
|
||||||
<LinearRing>
|
|
||||||
<coordinates> -112.3349463145932,36.14988705767721,100
|
|
||||||
-112.3354019540677,36.14941108398372,100
|
|
||||||
-112.3344428289146,36.14878490381308,100
|
|
||||||
-112.3331289492913,36.14780840132443,100
|
|
||||||
-112.3317019516947,36.14680755678357,100
|
|
||||||
-112.331131440106,36.1474173426228,100
|
|
||||||
-112.332616324338,36.14845453364654,100
|
|
||||||
-112.3339876620524,36.14926570522069,100
|
|
||||||
-112.3349463145932,36.14988705767721,100 </coordinates>
|
|
||||||
</LinearRing>
|
|
||||||
</outerBoundaryIs>
|
|
||||||
</Polygon>
|
|
||||||
</Placemark>
|
|
||||||
<Placemark>
|
|
||||||
<name>Relative Extruded</name>
|
|
||||||
<visibility>0</visibility>
|
|
||||||
<LookAt>
|
|
||||||
<longitude>-112.3351587892382</longitude>
|
|
||||||
<latitude>36.14979247129029</latitude>
|
|
||||||
<altitude>0</altitude>
|
|
||||||
<heading>-55.42811560891606</heading>
|
|
||||||
<tilt>56.10280503739589</tilt>
|
|
||||||
<range>401.0997279712519</range>
|
|
||||||
</LookAt>
|
|
||||||
<styleUrl>#transYellowPoly</styleUrl>
|
|
||||||
<Polygon>
|
|
||||||
<extrude>1</extrude>
|
|
||||||
<tessellate>1</tessellate>
|
|
||||||
<altitudeMode>relativeToGround</altitudeMode>
|
|
||||||
<outerBoundaryIs>
|
|
||||||
<LinearRing>
|
|
||||||
<coordinates> -112.3348783983763,36.1514008468736,100
|
|
||||||
-112.3372535345629,36.14888517553886,100
|
|
||||||
-112.3356068927954,36.14781612679284,100
|
|
||||||
-112.3350034807972,36.14846469024177,100
|
|
||||||
-112.3358353861232,36.1489624162954,100
|
|
||||||
-112.3345888301373,36.15026229372507,100
|
|
||||||
-112.3337937856278,36.14978096026463,100
|
|
||||||
-112.3331798208424,36.1504472788618,100
|
|
||||||
-112.3348783983763,36.1514008468736,100 </coordinates>
|
|
||||||
</LinearRing>
|
|
||||||
</outerBoundaryIs>
|
|
||||||
</Polygon>
|
|
||||||
</Placemark>
|
|
||||||
</Folder>
|
|
||||||
</Folder>
|
|
||||||
</Document>
|
|
||||||
</kml>
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Leaflet</title>
|
|
||||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
|
||||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
|
||||||
<script src="../layer/tile/Bing.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div style="width:100%; height:100%" id="map"></div>
|
|
||||||
<script type='text/javascript'>
|
|
||||||
var map = new L.Map('map', {center: new L.LatLng(67.6755, 33.936), zoom: 10 });
|
|
||||||
var osm = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
|
|
||||||
var bing = new L.BingLayer("Anqm0F_JjIZvT0P3abS6KONpaBaKuTnITRrnYuiJCE0WOhH6ZbE4DzeT6brvKVR5");
|
|
||||||
map.addLayer(bing);
|
|
||||||
map.addControl(new L.Control.Layers({'OSM':osm, "Bing":bing}, {}));
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Leaflet</title>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
|
||||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
|
||||||
<!--<script src="http://api-maps.yandex.ru/2.0/?load=package.map&lang=ru-RU" type="text/javascript"></script>-->
|
|
||||||
<script src="../layer/Layer.Deferred.js"></script>
|
|
||||||
<!--<script src="../layer/tile/Yandex.js"></script>-->
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div style="width:100%; height:100%" id="map"></div>
|
|
||||||
<script type='text/javascript'>
|
|
||||||
var map = new L.Map('map', {center: new L.LatLng(67.6755, 33.936), zoom: 10, zoomAnimation: false });
|
|
||||||
var osm = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
|
|
||||||
|
|
||||||
var layerdefs = {
|
|
||||||
mapnik: { name: "Mapnik", js: [],
|
|
||||||
init: function() {return new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');}},
|
|
||||||
kosmo: { name: "Космоснимки", js: [],
|
|
||||||
init: function() {return new L.TileLayer('http://{s}.tile.osmosnimki.ru/kosmo/{z}/{x}/{y}.png', {attribution:'Tiles Courtesy of <a href="http://kosmosnimki.ru/" target="_blank">kosmosnimki.ru</a>'});}},
|
|
||||||
gsat: { name: "Google", js: ["../layer/tile/Google.js", "http://maps.google.com/maps/api/js?v=3&sensor=false&callback=L.Google.asyncInitialize"],
|
|
||||||
init: function() {return new L.Google(); }},
|
|
||||||
ysat: { name: "Yandex", js: ["../layer/tile/Yandex.js", "http://api-maps.yandex.ru/2.0/?load=package.map&lang=ru-RU"],
|
|
||||||
init: function() {return new L.Yandex("satellite"); }},
|
|
||||||
nyak: { name: "НЯК", js: ["../layer/tile/Yandex.js", "http://api-maps.yandex.ru/2.0/?load=package.map&lang=ru-RU"],
|
|
||||||
init: function() {return new L.Yandex("publicMap"); }},
|
|
||||||
traffic: { name: "Пробки", js: ["../layer/tile/Yandex.js", "http://api-maps.yandex.ru/2.0/?load=package.map&lang=ru-RU"],
|
|
||||||
init: function() {return new L.Yandex("null", {traffic: true, opacity: 0.8, overlay: true}); }, overlay: true},
|
|
||||||
mso: { name: "Mapsurfer", js: [], overlay: true,
|
|
||||||
init: function() {return new L.TileLayer('http://129.206.74.245:8003/tms_h.ashx?x={x}&y={y}&z={z}');}}
|
|
||||||
};
|
|
||||||
|
|
||||||
var yndx = new L.DeferredLayer(layerdefs.ysat);
|
|
||||||
var kosmo = new L.DeferredLayer(layerdefs.kosmo);
|
|
||||||
var google = new L.DeferredLayer(layerdefs.gsat);
|
|
||||||
var ytraffic = new L.DeferredLayer(layerdefs.traffic);
|
|
||||||
var mso = new L.DeferredLayer(layerdefs.mso);
|
|
||||||
|
|
||||||
L.control.layers(
|
|
||||||
{
|
|
||||||
'OSM':osm,
|
|
||||||
"Kosmo":kosmo,
|
|
||||||
"Google":google,
|
|
||||||
"Yandex":yndx
|
|
||||||
},{
|
|
||||||
"Пробки":ytraffic,
|
|
||||||
"OpenMapSurfer":mso
|
|
||||||
}
|
|
||||||
).addTo(map);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
<html>
|
|
||||||
<!--
|
|
||||||
vim: sts=4 sw=4 et
|
|
||||||
-->
|
|
||||||
<head>
|
|
||||||
<title>Leaflet</title>
|
|
||||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
|
||||||
<link rel="stylesheet" href="../css/distance.css" />
|
|
||||||
<link rel="stylesheet" href="http://leaflet.github.io/Leaflet.draw/leaflet.draw.css" />
|
|
||||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
|
||||||
<script src="http://leaflet.github.io/Leaflet.draw/leaflet.draw.js"></script>
|
|
||||||
<script src="../layer/vector/GPX.js"></script>
|
|
||||||
<script src="../control/Scale.js"></script>
|
|
||||||
<script src="../control/Permalink.js"></script>
|
|
||||||
<script src="../control/Permalink.Line.js"></script>
|
|
||||||
<script src="../control/Distance.js"></script>
|
|
||||||
</head>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<!-- define a DIV into which the map will appear. Make it take up the whole window -->
|
|
||||||
<div style="width:100%; height:100%" id="map"></div>
|
|
||||||
<script type='text/javascript'>
|
|
||||||
</script>
|
|
||||||
<script type="text/javascript">
|
|
||||||
|
|
||||||
var map = new L.Map('map', {center: new L.LatLng(58.4, 43.0), zoom: 11});
|
|
||||||
var osm = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
|
|
||||||
|
|
||||||
map.addLayer(osm);
|
|
||||||
var d = new L.Control.Distance(); map.addControl(d);
|
|
||||||
map.addControl(new L.Control.Scale());
|
|
||||||
map.addControl(new L.Control.Permalink({line: d.getLine(), useLocation: true}));
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
1077
bower_components/leaflet-plugins/examples/fells_loop.gpx
vendored
|
|
@ -1,33 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Google Custom Styles // Leaflet</title>
|
|
||||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
|
||||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
|
||||||
<script src="http://maps.google.com/maps/api/js?v=3&sensor=false"></script>
|
|
||||||
<script src="../layer/tile/Google.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<!-- define a DIV into which the map will appear. Make it take up the whole window -->
|
|
||||||
<div style="width:100%; height:100%" id="map"></div>
|
|
||||||
<script type='text/javascript'>
|
|
||||||
var map = new L.Map('map', {center: new L.LatLng(53.9618, 58.4277), zoom: 13});
|
|
||||||
var osm = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
|
|
||||||
|
|
||||||
var styles = [
|
|
||||||
{
|
|
||||||
featureType: 'all',
|
|
||||||
stylers: [{hue: '#ff0000'}]
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
var ggl = new L.Google('ROADMAP', {
|
|
||||||
mapOptions: {
|
|
||||||
styles: styles
|
|
||||||
}
|
|
||||||
});
|
|
||||||
map.addLayer(ggl);
|
|
||||||
map.addControl(new L.Control.Layers( {'OSM':osm, 'Google':ggl}, {}));
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Google // Leaflet</title>
|
|
||||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
|
||||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
|
||||||
<script src="http://maps.google.com/maps/api/js?v=3&sensor=false"></script>
|
|
||||||
<script src="../layer/tile/Google.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<!-- define a DIV into which the map will appear. Make it take up the whole window -->
|
|
||||||
<div style="width:100%; height:100%" id="map"></div>
|
|
||||||
<script type='text/javascript'>
|
|
||||||
var map = new L.Map('map', {center: new L.LatLng(53.9618, 58.4277), zoom: 13});
|
|
||||||
var osm = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
|
|
||||||
var ggl = new L.Google();
|
|
||||||
var ggl2 = new L.Google('TERRAIN');
|
|
||||||
map.addLayer(ggl);
|
|
||||||
map.addControl(new L.Control.Layers( {'OSM':osm, 'Google':ggl, 'Google Terrain':ggl2}, {}));
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Leaflet - GPX track without Waypoints</title>
|
|
||||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
|
||||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
|
||||||
<script src="../layer/vector/GPX.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<!-- define a DIV into which the map will appear. Make it take up the whole window -->
|
|
||||||
<div style="width:100%; height:100%" id="map"></div>
|
|
||||||
<script type='text/javascript'>
|
|
||||||
var map = new L.Map('map', {center: new L.LatLng(58.4, 43.0), zoom: 11});
|
|
||||||
var osm = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
|
|
||||||
|
|
||||||
var track = new L.GPX("fells_loop.gpx", {async: true, display_wpt:false})
|
|
||||||
.on("loaded", function(e) { map.fitBounds(e.target.getBounds()); });
|
|
||||||
|
|
||||||
map.addLayer(track);
|
|
||||||
map.addLayer(osm);
|
|
||||||
map.addControl(new L.Control.Layers({}, {'GPX':track}));
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Leaflet</title>
|
|
||||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
|
||||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
|
||||||
<script src="../layer/vector/GPX.js"></script>
|
|
||||||
<script src="../layer/vector/GPX.Speed.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<!-- define a DIV into which the map will appear. Make it take up the whole window -->
|
|
||||||
<div style="width:100%; height:100%" id="map"></div>
|
|
||||||
<script type='text/javascript'>
|
|
||||||
var map = new L.Map('map', {center: new L.LatLng(58.4, 43.0), zoom: 11});
|
|
||||||
var osm = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
|
|
||||||
|
|
||||||
var track = new L.GPX("speed.gpx", {async: true})
|
|
||||||
.on("loaded", function(e) { map.fitBounds(e.target.getBounds()); })
|
|
||||||
.speedSplitEnable({maxSpeed: 100, chunks: 1000});
|
|
||||||
|
|
||||||
map.addLayer(track);
|
|
||||||
map.addLayer(osm);
|
|
||||||
map.addControl(new L.Control.Layers({}, {'GPX':track}));
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Leaflet</title>
|
|
||||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
|
||||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
|
||||||
<script src="../layer/vector/GPX.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<!-- define a DIV into which the map will appear. Make it take up the whole window -->
|
|
||||||
<div style="width:100%; height:100%" id="map"></div>
|
|
||||||
<script type='text/javascript'>
|
|
||||||
var map = new L.Map('map', {center: new L.LatLng(58.4, 43.0), zoom: 11});
|
|
||||||
var osm = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
|
|
||||||
|
|
||||||
var track = new L.GPX("fells_loop.gpx", {async: true})
|
|
||||||
.on("loaded", function(e) { map.fitBounds(e.target.getBounds()); });
|
|
||||||
|
|
||||||
map.addLayer(track);
|
|
||||||
map.addLayer(osm);
|
|
||||||
map.addControl(new L.Control.Layers({}, {'GPX':track}));
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Leaflet</title>
|
|
||||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
|
||||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
|
||||||
<script src="../layer/vector/KML.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<!-- define a DIV into which the map will appear. Make it take up the whole window -->
|
|
||||||
<div style="width:100%; height:100%" id="map"></div>
|
|
||||||
<script type='text/javascript'>
|
|
||||||
var map = new L.Map('map', {center: new L.LatLng(58.4, 43.0), zoom: 11});
|
|
||||||
var osm = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
|
|
||||||
|
|
||||||
var track = new L.KML("KML_Samples.kml", {async: true});
|
|
||||||
track.on("loaded", function(e) { map.fitBounds(e.target.getBounds()); });
|
|
||||||
|
|
||||||
map.addLayer(track);
|
|
||||||
map.addLayer(osm);
|
|
||||||
map.addControl(new L.Control.Layers({}, {'Track':track}));
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Leaflet</title>
|
|
||||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
|
||||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
|
||||||
<script src="../layer/Icon.Canvas.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div style="width:100%; height:100%" id="map"></div>
|
|
||||||
<script type='text/javascript'>
|
|
||||||
|
|
||||||
var map = new L.Map('map', {center: new L.LatLng(67.66904, 33.68595), zoom: 10});
|
|
||||||
map.addLayer(new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'));
|
|
||||||
|
|
||||||
var circle = new L.Icon.Canvas({iconSize: new L.Point(30, 30)});
|
|
||||||
circle.draw = function(ctx, w, h) {
|
|
||||||
ctx.translate(w/2, h/2);
|
|
||||||
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.fillStyle = "#F00";
|
|
||||||
ctx.arc(0, 0, w/2-1, 0, Math.PI*2, true);
|
|
||||||
ctx.fill();
|
|
||||||
|
|
||||||
ctx.lineWidth = 2;
|
|
||||||
ctx.strokeStyle = '#FFF';
|
|
||||||
ctx.moveTo(-w/5, -h/5);
|
|
||||||
ctx.lineTo(w/5, h/5);
|
|
||||||
ctx.moveTo(-w/5, h/5);
|
|
||||||
ctx.lineTo(w/5, -h/5);
|
|
||||||
ctx.stroke();
|
|
||||||
ctx.closePath();
|
|
||||||
}
|
|
||||||
|
|
||||||
map.addLayer(new L.Marker(map.getCenter(), {icon: circle, draggable: true, opacity: 0.7}));
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Leaflet</title>
|
|
||||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
|
||||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
|
||||||
<script src="../layer/Marker.Rotate.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div style="width:100%; height:100%" id="map"></div>
|
|
||||||
<script type='text/javascript'>
|
|
||||||
var map = new L.Map('map', {center: new L.LatLng(67.6755, 33.936), zoom: 10});
|
|
||||||
map.addLayer(new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'));
|
|
||||||
|
|
||||||
var marker = new L.Marker(map.getCenter(), {iconAngle: 90});
|
|
||||||
map.addLayer(marker);
|
|
||||||
|
|
||||||
var angle = 0;
|
|
||||||
function _rotate() {
|
|
||||||
marker.setIconAngle(angle);
|
|
||||||
angle = (angle + 10) % 360;
|
|
||||||
setTimeout(_rotate, 1000);
|
|
||||||
}
|
|
||||||
_rotate();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Leaflet</title>
|
|
||||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
|
||||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
|
||||||
<script src="../layer/Marker.Text.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div style="width:100%; height:100%" id="map"></div>
|
|
||||||
<script type='text/javascript'>
|
|
||||||
var map = new L.Map('map', {center: new L.LatLng(67.66904, 33.68595), zoom: 10});
|
|
||||||
map.addLayer(new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'));
|
|
||||||
|
|
||||||
var marker = new L.Marker.Text(map.getCenter(), 'Sweet!');
|
|
||||||
map.addLayer(new L.Marker(map.getCenter(), {opacity: 0.5}));
|
|
||||||
map.addLayer(marker);
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
<html>
|
|
||||||
<!--
|
|
||||||
vim: sts=4 sw=4 et
|
|
||||||
-->
|
|
||||||
<head>
|
|
||||||
<title>Leaflet</title>
|
|
||||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
|
||||||
<link rel="stylesheet" href="../css/osb.css" />
|
|
||||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
|
||||||
<script src="../layer/OpenStreetBugs.js"></script>
|
|
||||||
</head>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div style="width:100%; height:100%" id="map"></div>
|
|
||||||
<script type="text/javascript">
|
|
||||||
|
|
||||||
var map = new L.Map('map', {center: new L.LatLng(57.62, 39.89), zoom: 11});
|
|
||||||
|
|
||||||
map.addLayer(new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'));
|
|
||||||
map.addLayer(new L.OpenStreetBugs());
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Leaflet</title>
|
|
||||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
|
||||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
|
||||||
<script src="../layer/vector/OSM.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div style="width:100%; height:100%" id="map"></div>
|
|
||||||
<script type='text/javascript'>
|
|
||||||
var map = new L.Map('map', {center: new L.LatLng(55.7, 37.6), zoom: 9, zoomAnimation: false });
|
|
||||||
map.addLayer(new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'));
|
|
||||||
var layer = new L.OSM('ulugo.osm')
|
|
||||||
.on("loaded", function(e) { map.fitBounds(e.target.getBounds()); });
|
|
||||||
map.addLayer(layer);
|
|
||||||
map.addControl(new L.Control.Layers({}, {"OSM":layer}));
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Leaflet</title>
|
|
||||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
|
||||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
|
||||||
<script src="../control/Permalink.js"></script>
|
|
||||||
<script src="../control/Permalink.Marker.js"></script>
|
|
||||||
<script src="../control/Permalink.Layer.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div style="width:100%; height:100%" id="map"></div>
|
|
||||||
<script type='text/javascript'>
|
|
||||||
var map = new L.Map('map', {center: new L.LatLng(67.6755, 33.936), zoom: 10});
|
|
||||||
var osm = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
|
|
||||||
map.addLayer(osm);
|
|
||||||
var kosm = new L.TileLayer('http://{s}.tile.osmosnimki.ru/kosmo/{z}/{x}/{y}.png', {attribution:'Tiles Courtesy of <a href="http://kosmosnimki.ru/" target="_blank">kosmosnimki.ru</a>'});
|
|
||||||
var layers = new L.Control.Layers({'OSM':osm, "Kosmo":kosm});
|
|
||||||
map.addControl(layers);
|
|
||||||
map.addControl(new L.Control.Permalink({text: 'Permalink', layers: layers}));
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
80059
bower_components/leaflet-plugins/examples/speed.gpx
vendored
|
|
@ -1,24 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Leaflet</title>
|
|
||||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
|
||||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
|
||||||
<script src="http://api-maps.yandex.ru/2.0/?load=package.map&lang=ru-RU" type="text/javascript"></script>
|
|
||||||
<script src="../layer/tile/Yandex.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div style="width:100%; height:100%" id="map"></div>
|
|
||||||
<script type='text/javascript'>
|
|
||||||
var map = new L.Map('map', {center: new L.LatLng(67.6755, 33.936), zoom: 10, zoomAnimation: false });
|
|
||||||
var osm = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
|
|
||||||
var yndx = new L.Yandex();
|
|
||||||
var ytraffic = new L.Yandex("null", {traffic:true, opacity:0.8, overlay:true});
|
|
||||||
|
|
||||||
map.addLayer(osm);
|
|
||||||
map.addLayer(ytraffic);
|
|
||||||
map.addControl(new L.Control.Layers({'OSM':osm, "Yandex":yndx},
|
|
||||||
{"Traffic":ytraffic}));
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
L.Icon.Canvas = L.Icon.extend({
|
|
||||||
options: {
|
|
||||||
iconSize: new L.Point(20, 20), // Have to be supplied
|
|
||||||
/*
|
|
||||||
iconAnchor: (Point)
|
|
||||||
popupAnchor: (Point)
|
|
||||||
*/
|
|
||||||
className: 'leaflet-canvas-icon'
|
|
||||||
},
|
|
||||||
|
|
||||||
createIcon: function () {
|
|
||||||
var e = document.createElement('canvas');
|
|
||||||
this._setIconStyles(e, 'icon');
|
|
||||||
var s = this.options.iconSize;
|
|
||||||
e.width = s.x;
|
|
||||||
e.height = s.y;
|
|
||||||
this.draw(e.getContext('2d'), s.x, s.y);
|
|
||||||
return e;
|
|
||||||
},
|
|
||||||
|
|
||||||
createShadow: function () {
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
|
|
||||||
draw: function(canvas, width, height) {
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
@ -1,57 +0,0 @@
|
||||||
L.DeferredLayer = L.LayerGroup.extend({
|
|
||||||
options: {
|
|
||||||
js: [],
|
|
||||||
init: null
|
|
||||||
},
|
|
||||||
|
|
||||||
_script_cache: {},
|
|
||||||
|
|
||||||
initialize: function(options) {
|
|
||||||
L.Util.setOptions(this, options);
|
|
||||||
L.LayerGroup.prototype.initialize.apply(this);
|
|
||||||
this._loaded = false;
|
|
||||||
},
|
|
||||||
|
|
||||||
onAdd: function(map) {
|
|
||||||
L.LayerGroup.prototype.onAdd.apply(this, [map]);
|
|
||||||
if (this._loaded) return;
|
|
||||||
//console.info('Script cache', this._script_cache);
|
|
||||||
var loaded = function() {
|
|
||||||
//console.info('Loaded', this, this.options);
|
|
||||||
this._loaded = true;
|
|
||||||
var l = this.options.init();
|
|
||||||
if (l)
|
|
||||||
this.addLayer(l);
|
|
||||||
};
|
|
||||||
this._loadScripts(this.options.js.reverse(), L.Util.bind(loaded, this));
|
|
||||||
},
|
|
||||||
|
|
||||||
_loadScripts: function(scripts, cb, args) {
|
|
||||||
if (!scripts || scripts.length === 0)
|
|
||||||
return cb(args);
|
|
||||||
var _this = this, s = scripts.pop(), c;
|
|
||||||
c = this._script_cache[s];
|
|
||||||
if (c === undefined) {
|
|
||||||
c = {url: s, wait: []};
|
|
||||||
//console.info('Load ', s);
|
|
||||||
var script = document.createElement('script');
|
|
||||||
script.src = s;
|
|
||||||
script.type = 'text/javascript';
|
|
||||||
script.onload = function () {
|
|
||||||
//console.info('Element(cb)', c.e.readyState);
|
|
||||||
c.e.readyState = 'completed';
|
|
||||||
var i = 0;
|
|
||||||
for (i = 0; i < c.wait.length; i++)
|
|
||||||
c.wait[i]();
|
|
||||||
};
|
|
||||||
c.e = script;
|
|
||||||
document.getElementsByTagName('head')[0].appendChild(script);
|
|
||||||
}
|
|
||||||
function _cb() { _this._loadScripts(scripts, cb, args); }
|
|
||||||
c.wait.push(_cb);
|
|
||||||
//console.info('Element', c.e.readyState);
|
|
||||||
if (c.e.readyState === 'completed')
|
|
||||||
_cb();
|
|
||||||
this._script_cache[s] = c;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
/*
|
|
||||||
* Based on comments by @runanet and @coomsie
|
|
||||||
* https://github.com/CloudMade/Leaflet/issues/386
|
|
||||||
*
|
|
||||||
* Wrapping function is needed to preserve L.Marker.update function
|
|
||||||
*/
|
|
||||||
(function () {
|
|
||||||
var _old__setPos = L.Marker.prototype._setPos;
|
|
||||||
L.Marker.include({
|
|
||||||
_updateImg: function(i, a, s) {
|
|
||||||
a = L.point(s).divideBy(2)._subtract(L.point(a));
|
|
||||||
var transform = '';
|
|
||||||
transform += ' translate(' + -a.x + 'px, ' + -a.y + 'px)';
|
|
||||||
transform += ' rotate(' + this.options.iconAngle + 'deg)';
|
|
||||||
transform += ' translate(' + a.x + 'px, ' + a.y + 'px)';
|
|
||||||
i.style[L.DomUtil.TRANSFORM] += transform;
|
|
||||||
},
|
|
||||||
|
|
||||||
setIconAngle: function (iconAngle) {
|
|
||||||
this.options.iconAngle = iconAngle;
|
|
||||||
if (this._map)
|
|
||||||
this.update();
|
|
||||||
},
|
|
||||||
|
|
||||||
_setPos: function (pos) {
|
|
||||||
if (this._icon)
|
|
||||||
this._icon.style[L.DomUtil.TRANSFORM] = '';
|
|
||||||
if (this._shadow)
|
|
||||||
this._shadow.style[L.DomUtil.TRANSFORM] = '';
|
|
||||||
|
|
||||||
_old__setPos.apply(this,[pos]);
|
|
||||||
|
|
||||||
if (this.options.iconAngle) {
|
|
||||||
var a = this.options.icon.options.iconAnchor;
|
|
||||||
var s = this.options.icon.options.iconSize;
|
|
||||||
var i;
|
|
||||||
if (this._icon) {
|
|
||||||
i = this._icon;
|
|
||||||
this._updateImg(i, a, s);
|
|
||||||
}
|
|
||||||
if (this._shadow) {
|
|
||||||
if (this.options.icon.options.shadowAnchor)
|
|
||||||
a = this.options.icon.options.shadowAnchor;
|
|
||||||
s = this.options.icon.options.shadowSize;
|
|
||||||
i = this._shadow;
|
|
||||||
this._updateImg(i, a, s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}());
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
L.Icon.Text = L.Icon.extend({
|
|
||||||
initialize: function (text, options) {
|
|
||||||
this._text = text;
|
|
||||||
L.Icon.prototype.initialize.apply(this, [options]);
|
|
||||||
},
|
|
||||||
|
|
||||||
createIcon: function() {
|
|
||||||
var el = document.createElement('div');
|
|
||||||
el.appendChild(document.createTextNode(this._text));
|
|
||||||
this._setIconStyles(el, 'icon');
|
|
||||||
el.style.textShadow = '2px 2px 2px #fff';
|
|
||||||
return el;
|
|
||||||
},
|
|
||||||
|
|
||||||
createShadow: function() { return null; }
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
L.Marker.Text = L.Marker.extend({
|
|
||||||
initialize: function (latlng, text, options) {
|
|
||||||
L.Marker.prototype.initialize.apply(this, [latlng, options]);
|
|
||||||
this._fakeicon = new L.Icon.Text(text);
|
|
||||||
},
|
|
||||||
|
|
||||||
_initIcon: function() {
|
|
||||||
L.Marker.prototype._initIcon.apply(this);
|
|
||||||
|
|
||||||
var i = this._icon, s = this._shadow, obj = this.options.icon;
|
|
||||||
this._icon = this._shadow = null;
|
|
||||||
|
|
||||||
this.options.icon = this._fakeicon;
|
|
||||||
L.Marker.prototype._initIcon.apply(this);
|
|
||||||
this.options.icon = obj;
|
|
||||||
|
|
||||||
if (s) {
|
|
||||||
s.parentNode.removeChild(s);
|
|
||||||
this._icon.appendChild(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
i.parentNode.removeChild(i);
|
|
||||||
this._icon.appendChild(i);
|
|
||||||
|
|
||||||
var w = this._icon.clientWidth, h = this._icon.clientHeight;
|
|
||||||
this._icon.style.marginLeft = -w / 2 + 'px';
|
|
||||||
//this._icon.style.backgroundColor = "red";
|
|
||||||
var off = new L.Point(w/2, 0);
|
|
||||||
if (L.Browser.webkit) off.y = -h;
|
|
||||||
L.DomUtil.setPosition(i, off);
|
|
||||||
if (s) L.DomUtil.setPosition(s, off);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
@ -1,496 +0,0 @@
|
||||||
/* global alert: true */
|
|
||||||
L.OpenStreetBugs = L.FeatureGroup.extend({
|
|
||||||
options : {
|
|
||||||
serverURL : 'http://openstreetbugs.schokokeks.org/api/0.1/',
|
|
||||||
readonly : false,
|
|
||||||
setCookie : true,
|
|
||||||
username : 'NoName',
|
|
||||||
cookieLifetime : 1000,
|
|
||||||
cookiePath : null,
|
|
||||||
permalinkZoom : 14,
|
|
||||||
permalinkUrl: null,
|
|
||||||
opacity : 0.7,
|
|
||||||
showOpen: true,
|
|
||||||
showClosed: true,
|
|
||||||
iconOpen: 'http://openstreetbugs.schokokeks.org/client/open_bug_marker.png',
|
|
||||||
iconClosed:'http://openstreetbugs.schokokeks.org/client/closed_bug_marker.png',
|
|
||||||
iconActive: undefined,
|
|
||||||
editArea: 0.01,
|
|
||||||
popupOptions: {autoPan: false},
|
|
||||||
dblClick: true
|
|
||||||
},
|
|
||||||
|
|
||||||
initialize : function(options)
|
|
||||||
{
|
|
||||||
var tmp = L.Util.extend({}, this.options.popupOptions, (options || {}).popupOptions);
|
|
||||||
L.Util.setOptions(this, options);
|
|
||||||
this.options.popupOptions = tmp;
|
|
||||||
|
|
||||||
putAJAXMarker.layers.push(this);
|
|
||||||
|
|
||||||
this.bugs = {};
|
|
||||||
this._layers = {};
|
|
||||||
|
|
||||||
var username = this.get_cookie('osbUsername');
|
|
||||||
if (username)
|
|
||||||
this.options.username = username;
|
|
||||||
|
|
||||||
L.OpenStreetBugs.setCSS();
|
|
||||||
},
|
|
||||||
|
|
||||||
onAdd : function(map)
|
|
||||||
{
|
|
||||||
L.FeatureGroup.prototype.onAdd.apply(this, [map]);
|
|
||||||
|
|
||||||
this._map.on('moveend', this.loadBugs, this);
|
|
||||||
this.loadBugs();
|
|
||||||
if (!this.options.readonly) {
|
|
||||||
if (this.options.dblClick) {
|
|
||||||
map.doubleClickZoom.disable();
|
|
||||||
map.on('dblclick', this.addBug, this);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
map.on('click', this.addBug, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.fire('add');
|
|
||||||
},
|
|
||||||
|
|
||||||
onRemove : function(map)
|
|
||||||
{
|
|
||||||
this._map.off('moveend', this.loadBugs, this);
|
|
||||||
this._iterateLayers(map.removeLayer, map);
|
|
||||||
delete this._map;
|
|
||||||
if (!this.options.readonly) {
|
|
||||||
if (this.options.dblClick) {
|
|
||||||
map.doubleClickZoom.enable();
|
|
||||||
map.off('dblclick', this.addBug, this);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
map.off('click', this.addBug, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.fire('remove');
|
|
||||||
},
|
|
||||||
|
|
||||||
set_cookie : function(name, value)
|
|
||||||
{
|
|
||||||
var expires = (new Date((new Date()).getTime() + 604800000)).toGMTString(); // one week from now
|
|
||||||
document.cookie = name+'='+encodeURIComponent(value)+';';
|
|
||||||
},
|
|
||||||
|
|
||||||
get_cookie : function(name)
|
|
||||||
{
|
|
||||||
var cookies = (document.cookie || '').split(/;\s*/);
|
|
||||||
for(var i=0; i<cookies.length; i++)
|
|
||||||
{
|
|
||||||
var cookie = cookies[i].split('=');
|
|
||||||
if(cookie[0] === name)
|
|
||||||
return decodeURIComponent(cookie[1]);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
|
|
||||||
loadBugs : function()
|
|
||||||
{
|
|
||||||
//if(!this.getVisibility())
|
|
||||||
// return true;
|
|
||||||
|
|
||||||
var bounds = this._map.getBounds();
|
|
||||||
if(!bounds) return false;
|
|
||||||
var sw = bounds.getSouthWest(), ne = bounds.getNorthEast();
|
|
||||||
|
|
||||||
function round(number, digits) {
|
|
||||||
var factor = Math.pow(10, digits);
|
|
||||||
return Math.round(number*factor)/factor;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.apiRequest('getBugs'
|
|
||||||
+ '?t='+round(ne.lat, 5)
|
|
||||||
+ '&r='+round(ne.lng, 5)
|
|
||||||
+ '&b='+round(sw.lat, 5)
|
|
||||||
+ '&l='+round(sw.lng, 5));
|
|
||||||
},
|
|
||||||
|
|
||||||
apiRequest : function(url, reload)
|
|
||||||
{
|
|
||||||
var script = document.createElement('script');
|
|
||||||
script.type = 'text/javascript';
|
|
||||||
script.src = this.options.serverURL + url + '&nocache='+(new Date()).getTime();
|
|
||||||
var _this = this;
|
|
||||||
script.onload = function(e) {
|
|
||||||
document.body.removeChild(this);
|
|
||||||
if (reload) _this.loadBugs();
|
|
||||||
};
|
|
||||||
document.body.appendChild(script);
|
|
||||||
},
|
|
||||||
|
|
||||||
createMarker: function(id, force)
|
|
||||||
{
|
|
||||||
var bug = putAJAXMarker.bugs[id];
|
|
||||||
if(this.bugs[id])
|
|
||||||
{
|
|
||||||
if (force || this.bugs[id].osb.closed !== bug[2])
|
|
||||||
this.removeLayer(this.bugs[id]);
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var closed = bug[2];
|
|
||||||
|
|
||||||
if (closed && !this.options.showClosed) return;
|
|
||||||
if (!closed && !this.options.showOpen) return;
|
|
||||||
|
|
||||||
var icon_url = null;
|
|
||||||
var class_popup = ' osb';
|
|
||||||
if (bug[2]) {
|
|
||||||
icon_url = this.options.iconClosed;
|
|
||||||
class_popup += ' osbClosed';
|
|
||||||
}
|
|
||||||
else if (bug[1].length === 1) {
|
|
||||||
icon_url = this.options.iconOpen;
|
|
||||||
class_popup += ' osbOpen';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (this.options.iconActive) {
|
|
||||||
icon_url = this.options.iconActive;
|
|
||||||
class_popup += ' osbActive';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
icon_url = this.options.iconOpen;
|
|
||||||
class_popup += ' osbOpen';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var feature = new L.Marker(bug[0], {icon:new this.osbIcon({iconUrl: icon_url})});
|
|
||||||
feature.osb = {id: id, closed: closed};
|
|
||||||
this.addLayer(feature);
|
|
||||||
this.bugs[id] = feature;
|
|
||||||
this.setPopupContent(id);
|
|
||||||
feature._popup.options.className += class_popup;
|
|
||||||
|
|
||||||
if (this.options.bugid && (parseInt(this.options.bugid) === id))
|
|
||||||
feature.openPopup();
|
|
||||||
|
|
||||||
//this.events.triggerEvent('markerAdded');
|
|
||||||
},
|
|
||||||
|
|
||||||
osbIcon : L.Icon.extend({
|
|
||||||
options: {
|
|
||||||
iconUrl: 'http://openstreetbugs.schokokeks.org/client/open_bug_marker.png',
|
|
||||||
iconSize: new L.Point(22, 22),
|
|
||||||
shadowSize: new L.Point(0, 0),
|
|
||||||
iconAnchor: new L.Point(11, 11),
|
|
||||||
popupAnchor: new L.Point(0, -11)
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
|
|
||||||
setPopupContent: function(id) {
|
|
||||||
if(this.bugs[id]._popup_content)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var el1,el2,el3;
|
|
||||||
var layer = this;
|
|
||||||
|
|
||||||
var rawbug = putAJAXMarker.bugs[id];
|
|
||||||
var isclosed = rawbug[2];
|
|
||||||
|
|
||||||
var newContent = L.DomUtil.create('div', 'osb-popup');
|
|
||||||
var h1 = L.DomUtil.create('h1', null, newContent);
|
|
||||||
if (rawbug[2])
|
|
||||||
h1.textContent = L.i18n('Fixed Error');
|
|
||||||
else if (rawbug[1].length === 1)
|
|
||||||
h1.textContent = L.i18n('Unresolved Error');
|
|
||||||
else
|
|
||||||
h1.textContent = L.i18n('Active Error');
|
|
||||||
|
|
||||||
var divinfo = L.DomUtil.create('div', 'osb-info', newContent);
|
|
||||||
var table = L.DomUtil.create('table', 'osb-table', divinfo);
|
|
||||||
for(var i=0; i<rawbug[1].length; i++)
|
|
||||||
{
|
|
||||||
var tr = L.DomUtil.create('tr', 'osb-tr-info', table);
|
|
||||||
tr.setAttribute('valign','top');
|
|
||||||
var td_nickname = L.DomUtil.create('td', 'osb-td-nickname', tr);
|
|
||||||
td_nickname.textContent = rawbug[5][i] + ':';
|
|
||||||
var td_datetime = L.DomUtil.create('td', 'osb-td-datetime', tr);
|
|
||||||
td_datetime.textContent = rawbug[6][i];
|
|
||||||
var td_comment = L.DomUtil.create('td', 'osb-td-comment', L.DomUtil.create('tr', 'osb-tr-comment', table));
|
|
||||||
td_comment.setAttribute('colspan','2');
|
|
||||||
td_comment.setAttribute('charoff','2');
|
|
||||||
td_comment.textContent = rawbug[4][i];
|
|
||||||
}
|
|
||||||
|
|
||||||
function create_link(ul, text) {
|
|
||||||
var a = L.DomUtil.create('a', null,
|
|
||||||
L.DomUtil.create('li', null, ul));
|
|
||||||
a.href = '#';
|
|
||||||
a.textContent = L.i18n(text);
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
var ul = L.DomUtil.create('ul', null, newContent);
|
|
||||||
var _this = this;
|
|
||||||
var bug = this.bugs[id];
|
|
||||||
|
|
||||||
function showComment(title, add_comment) {
|
|
||||||
h1.textContent_old = h1.textContent;
|
|
||||||
h1.textContent = L.i18n(title);
|
|
||||||
var form = _this.createCommentForm();
|
|
||||||
form.osbid.value = id;
|
|
||||||
form.cancel.onclick = function (e) {
|
|
||||||
h1.textContent = h1.textContent_old;
|
|
||||||
newContent.removeChild(form);
|
|
||||||
newContent.appendChild(ul);
|
|
||||||
};
|
|
||||||
form.ok.onclick = function(e) {
|
|
||||||
bug.closePopup();
|
|
||||||
if (!add_comment)
|
|
||||||
_this.closeBug(form);
|
|
||||||
else
|
|
||||||
_this.submitComment(form);
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
newContent.appendChild(form);
|
|
||||||
newContent.removeChild(ul);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isclosed && !this.options.readonly) {
|
|
||||||
var a;
|
|
||||||
a = create_link(ul, 'Add comment');
|
|
||||||
a.onclick = function(e) { return showComment('Add comment', true); };
|
|
||||||
|
|
||||||
a = create_link(ul, 'Mark as Fixed');
|
|
||||||
a.onclick = function(e) { return showComment('Close bug', false); };
|
|
||||||
}
|
|
||||||
var a_josm = create_link(ul, 'JOSM');
|
|
||||||
a_josm.onclick = function() { _this.remoteEdit(rawbug[0]); };
|
|
||||||
|
|
||||||
var a_link = create_link(ul, 'Link');
|
|
||||||
var vars = {lat:rawbug[0].lat, lon:rawbug[0].lng, zoom:this.options.permalinkZoom, bugid:id};
|
|
||||||
if (this.options.permalinkUrl)
|
|
||||||
a_link.href = L.Util.template(this.options.permalinkUrl, vars);
|
|
||||||
else
|
|
||||||
a_link.href = location.protocol + '//' + location.host + location.pathname +
|
|
||||||
L.Util.getParamString(vars);
|
|
||||||
|
|
||||||
|
|
||||||
bug._popup_content = newContent;
|
|
||||||
bug.bindPopup(newContent, this.options.popupOptions);
|
|
||||||
bug._popup.options.maxWidth=410;
|
|
||||||
bug._popup.options.minWidth=410;
|
|
||||||
bug.on('mouseover', bug.openTempPopup, bug);
|
|
||||||
},
|
|
||||||
|
|
||||||
submitComment: function(form) {
|
|
||||||
if (!form.osbcomment.value) return;
|
|
||||||
var nickname = form.osbnickname.value || this.options.username;
|
|
||||||
this.apiRequest('editPOIexec'
|
|
||||||
+ '?id='+encodeURIComponent(form.osbid.value)
|
|
||||||
+ '&text='+encodeURIComponent(form.osbcomment.value + ' [' + nickname + ']')
|
|
||||||
+ '&format=js', true
|
|
||||||
);
|
|
||||||
this.set_cookie('osbUsername',nickname);
|
|
||||||
this.options.username=nickname;
|
|
||||||
},
|
|
||||||
|
|
||||||
closeBug: function(form) {
|
|
||||||
var id = form.osbid.value;
|
|
||||||
this.submitComment(form);
|
|
||||||
this.apiRequest('closePOIexec'
|
|
||||||
+ '?id='+encodeURIComponent(id)
|
|
||||||
+ '&format=js', true
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
createCommentForm: function(elt) {
|
|
||||||
var form = L.DomUtil.create('form', 'osb-add-comment', elt);
|
|
||||||
var content = '';
|
|
||||||
content += '<input name="osbid" type="hidden"/>';
|
|
||||||
content += '<input name="osblat" type="hidden"/>';
|
|
||||||
content += '<input name="osblon" type="hidden"/>';
|
|
||||||
content += '<div><span class="osb-inputlabel">'+L.i18n('Nickname')+':</span><input type="text" name="osbnickname"></div>';
|
|
||||||
content += '<div><span class="osb-inputlabel">'+L.i18n('Comment')+':</span><input type="text" name="osbcomment"></div>';
|
|
||||||
content += '<div class="osb-formfooter"><input type="submit" name="ok"/><input type="button" name="cancel"/></div>';
|
|
||||||
form.innerHTML = content;
|
|
||||||
form.ok.value = L.i18n('OK');
|
|
||||||
form.cancel.value = L.i18n('Cancel');
|
|
||||||
form.osbnickname.value = this.options.username;
|
|
||||||
return form;
|
|
||||||
},
|
|
||||||
|
|
||||||
addBug: function(e) {
|
|
||||||
var newContent = L.DomUtil.create('div', 'osb-popup');
|
|
||||||
|
|
||||||
newContent.innerHTML += '<h1>'+L.i18n('New bug')+'</h1>';
|
|
||||||
newContent.innerHTML += '<div class="osbCreateInfo">'+L.i18n('Find your bug?')+'<br />'+L.i18n('Contact details and someone will fix it.')+'</div>';
|
|
||||||
|
|
||||||
var popup = new L.Popup();
|
|
||||||
var _this = this;
|
|
||||||
var form = this.createCommentForm(newContent);
|
|
||||||
form.osblat.value = e.latlng.lat;
|
|
||||||
form.osblon.value = e.latlng.lng;
|
|
||||||
form.ok.value = L.i18n('Add comment');
|
|
||||||
form.onsubmit = function(e) {
|
|
||||||
_this._map.closePopup(popup);
|
|
||||||
_this.createBug(form);
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
form.cancel.onclick = function(e) { _this._map.closePopup(popup); };
|
|
||||||
|
|
||||||
popup.setLatLng(e.latlng);
|
|
||||||
popup.setContent(newContent);
|
|
||||||
popup.options.maxWidth=410;
|
|
||||||
popup.options.minWidth=410;
|
|
||||||
popup.options.className += ' osb osbCreate';
|
|
||||||
|
|
||||||
this._map.openPopup(popup);
|
|
||||||
},
|
|
||||||
|
|
||||||
createBug: function(form) {
|
|
||||||
if (!form.osbcomment.value) return;
|
|
||||||
var nickname = form.osbnickname.value || this.options.username;
|
|
||||||
this.apiRequest('addPOIexec'
|
|
||||||
+ '?lat='+encodeURIComponent(form.osblat.value)
|
|
||||||
+ '&lon='+encodeURIComponent(form.osblon.value)
|
|
||||||
+ '&text='+encodeURIComponent(form.osbcomment.value + ' [' + nickname + ']')
|
|
||||||
+ '&format=js', true
|
|
||||||
);
|
|
||||||
this.set_cookie('osbUsername',nickname);
|
|
||||||
this.options.username=nickname;
|
|
||||||
},
|
|
||||||
|
|
||||||
remoteEdit: function(x) {
|
|
||||||
var ydelta = this.options.editArea || 0.01;
|
|
||||||
var xdelta = ydelta * 2;
|
|
||||||
var p = [ 'left=' + (x.lng - xdelta), 'bottom=' + (x.lat - ydelta), 'right=' + (x.lng + xdelta), 'top=' + (x.lat + ydelta)];
|
|
||||||
var url = 'http://localhost:8111/load_and_zoom?' + p.join('&');
|
|
||||||
var frame = L.DomUtil.create('iframe', null);
|
|
||||||
frame.style.display = 'none';
|
|
||||||
frame.src = url;
|
|
||||||
document.body.appendChild(frame);
|
|
||||||
frame.onload = function(e) { document.body.removeChild(frame); };
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
L.OpenStreetBugs.setCSS = function() {
|
|
||||||
if(L.OpenStreetBugs.setCSS.done)
|
|
||||||
return;
|
|
||||||
else
|
|
||||||
L.OpenStreetBugs.setCSS.done = true;
|
|
||||||
|
|
||||||
// See http://www.hunlock.com/blogs/Totally_Pwn_CSS_with_Javascript
|
|
||||||
var idx = 0;
|
|
||||||
var addRule = function(selector, rules) {
|
|
||||||
var s = document.styleSheets[0];
|
|
||||||
var rule;
|
|
||||||
if(s.addRule) // M$IE
|
|
||||||
rule = s.addRule(selector, rules, idx);
|
|
||||||
else
|
|
||||||
rule = s.insertRule(selector + ' { ' + rules + ' }', idx);
|
|
||||||
s.style = L.Util.extend(s.style || {}, rules);
|
|
||||||
idx++;
|
|
||||||
};
|
|
||||||
|
|
||||||
addRule('.osb-popup dl', 'margin:0; padding:0;');
|
|
||||||
addRule('.osb-popup dt', 'margin:0; padding:0; font-weight:bold; float:left; clear:left;');
|
|
||||||
addRule('.osb-popup dt:after', 'content: ": ";');
|
|
||||||
addRule('* html .osb-popup dt', 'margin-right:1ex;');
|
|
||||||
addRule('.osb-popup dd', 'margin:0; padding:0;');
|
|
||||||
addRule('.osb-popup ul.buttons', 'list-style-type:none; padding:0; margin:0;');
|
|
||||||
addRule('.osb-popup ul.buttons li', 'display:inline; margin:0; padding:0;');
|
|
||||||
addRule('.osb-popup h3', 'font-size:1.2em; margin:.2em 0 .7em 0;');
|
|
||||||
};
|
|
||||||
|
|
||||||
function putAJAXMarker(id, lon, lat, text, closed)
|
|
||||||
{
|
|
||||||
var comments = text.split(/<hr \/>/);
|
|
||||||
var comments_only = [];
|
|
||||||
var nickname = [];
|
|
||||||
var datetime = [];
|
|
||||||
var info = null;
|
|
||||||
var isplit = 0;
|
|
||||||
var i;
|
|
||||||
for(i=0; i<comments.length; i++) {
|
|
||||||
info = null;
|
|
||||||
isplit = 0;
|
|
||||||
comments[i] = comments[i].replace(/"/g, '"').replace(/</g, '<').replace(/>/g, '>').replace(/&/g, '&');
|
|
||||||
isplit = comments[i].lastIndexOf('[');
|
|
||||||
if (isplit > 0) {
|
|
||||||
comments_only[i] = comments[i].substr(0,isplit-1);
|
|
||||||
info = comments[i].substr(isplit+1);
|
|
||||||
nickname[i] = info.substr(0,info.lastIndexOf(','));
|
|
||||||
datetime[i] = info.substr(info.lastIndexOf(',')+2);
|
|
||||||
datetime[i] = datetime[i].substr(0,datetime[i].lastIndexOf(']'));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
comments_only[i] = comments[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var old = putAJAXMarker.bugs[id];
|
|
||||||
putAJAXMarker.bugs[id] = [
|
|
||||||
new L.LatLng(lat, lon),
|
|
||||||
comments,
|
|
||||||
closed,
|
|
||||||
text,
|
|
||||||
comments_only,
|
|
||||||
nickname,
|
|
||||||
datetime
|
|
||||||
];
|
|
||||||
var force = (old && old[3]) !== text;
|
|
||||||
for(i=0; i<putAJAXMarker.layers.length; i++)
|
|
||||||
putAJAXMarker.layers[i].createMarker(id, force);
|
|
||||||
}
|
|
||||||
|
|
||||||
function osbResponse(error)
|
|
||||||
{
|
|
||||||
if(error)
|
|
||||||
alert('Error: '+error);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
putAJAXMarker.layers = [ ];
|
|
||||||
putAJAXMarker.bugs = { };
|
|
||||||
|
|
||||||
L.Marker.include({
|
|
||||||
openTempPopup: function() {
|
|
||||||
this.openPopup();
|
|
||||||
this.off('click', this.openPopup, this);
|
|
||||||
|
|
||||||
function onclick() {
|
|
||||||
this.off('mouseout', onout, this);
|
|
||||||
this.off('click', onclick, this);
|
|
||||||
this.on('click', this.openPopup, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onout() {
|
|
||||||
onclick.call(this);
|
|
||||||
this.closePopup();
|
|
||||||
}
|
|
||||||
this.on('mouseout', onout, this);
|
|
||||||
this.on('click', onclick, this);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
L.i18n = function(s) { return (L.i18n.lang[L.i18n.current] || {})[s] || s; };
|
|
||||||
L.i18n.current = 'ru';
|
|
||||||
L.i18n.lang = {};
|
|
||||||
L.i18n.extend = function(lang, args) {
|
|
||||||
L.i18n.lang[lang] = L.Util.extend(L.i18n.lang[lang] || {}, args);
|
|
||||||
};
|
|
||||||
|
|
||||||
L.i18n.extend('ru', {
|
|
||||||
'Fixed Error':'Ошибка исправлена',
|
|
||||||
'Unresolved Error':'Неисправленная ошибка',
|
|
||||||
'Active Error':'Ошибка уточняется',
|
|
||||||
'Description':'Описание',
|
|
||||||
'Comment':'Описание',
|
|
||||||
'Add comment':'Дополнить',
|
|
||||||
'Mark as Fixed':'Исправлено',
|
|
||||||
'Link':'Ссылка',
|
|
||||||
'Cancel':'Отмена',
|
|
||||||
'New bug':'Я нашел ошибку',
|
|
||||||
'Find your bug?':'Нашли ошибку?',
|
|
||||||
'Contact details and someone will fix it.':'Напишите подробнее и кто-нибудь её исправит.'
|
|
||||||
});
|
|
||||||
125
bower_components/leaflet-plugins/layer/tile/Bing.js
vendored
|
|
@ -1,125 +0,0 @@
|
||||||
/* global console: true */
|
|
||||||
L.BingLayer = L.TileLayer.extend({
|
|
||||||
options: {
|
|
||||||
subdomains: [0, 1, 2, 3],
|
|
||||||
type: 'Aerial',
|
|
||||||
attribution: 'Bing',
|
|
||||||
culture: ''
|
|
||||||
},
|
|
||||||
|
|
||||||
initialize: function(key, options) {
|
|
||||||
L.Util.setOptions(this, options);
|
|
||||||
|
|
||||||
this._key = key;
|
|
||||||
this._url = null;
|
|
||||||
this.meta = {};
|
|
||||||
this.loadMetadata();
|
|
||||||
},
|
|
||||||
|
|
||||||
tile2quad: function(x, y, z) {
|
|
||||||
var quad = '';
|
|
||||||
for (var i = z; i > 0; i--) {
|
|
||||||
var digit = 0;
|
|
||||||
var mask = 1 << (i - 1);
|
|
||||||
if ((x & mask) !== 0) digit += 1;
|
|
||||||
if ((y & mask) !== 0) digit += 2;
|
|
||||||
quad = quad + digit;
|
|
||||||
}
|
|
||||||
return quad;
|
|
||||||
},
|
|
||||||
|
|
||||||
getTileUrl: function(p, z) {
|
|
||||||
var zoom = this._getZoomForUrl();
|
|
||||||
var subdomains = this.options.subdomains,
|
|
||||||
s = this.options.subdomains[Math.abs((p.x + p.y) % subdomains.length)];
|
|
||||||
return this._url.replace('{subdomain}', s)
|
|
||||||
.replace('{quadkey}', this.tile2quad(p.x, p.y, zoom))
|
|
||||||
.replace('{culture}', this.options.culture);
|
|
||||||
},
|
|
||||||
|
|
||||||
loadMetadata: function() {
|
|
||||||
var _this = this;
|
|
||||||
var cbid = '_bing_metadata_' + L.Util.stamp(this);
|
|
||||||
window[cbid] = function (meta) {
|
|
||||||
_this.meta = meta;
|
|
||||||
window[cbid] = undefined;
|
|
||||||
var e = document.getElementById(cbid);
|
|
||||||
e.parentNode.removeChild(e);
|
|
||||||
if (meta.errorDetails) {
|
|
||||||
if (window.console) console.log('Leaflet Bing Plugin Error - Got metadata: ' + meta.errorDetails);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_this.initMetadata();
|
|
||||||
};
|
|
||||||
var url = document.location.protocol + '//dev.virtualearth.net/REST/v1/Imagery/Metadata/' + this.options.type + '?include=ImageryProviders&jsonp=' + cbid +
|
|
||||||
'&key=' + this._key + '&UriScheme=' + document.location.protocol.slice(0, -1);
|
|
||||||
var script = document.createElement('script');
|
|
||||||
script.type = 'text/javascript';
|
|
||||||
script.src = url;
|
|
||||||
script.id = cbid;
|
|
||||||
document.getElementsByTagName('head')[0].appendChild(script);
|
|
||||||
},
|
|
||||||
|
|
||||||
initMetadata: function() {
|
|
||||||
var r = this.meta.resourceSets[0].resources[0];
|
|
||||||
this.options.subdomains = r.imageUrlSubdomains;
|
|
||||||
this._url = r.imageUrl;
|
|
||||||
this._providers = [];
|
|
||||||
if (r.imageryProviders) {
|
|
||||||
for (var i = 0; i < r.imageryProviders.length; i++) {
|
|
||||||
var p = r.imageryProviders[i];
|
|
||||||
for (var j = 0; j < p.coverageAreas.length; j++) {
|
|
||||||
var c = p.coverageAreas[j];
|
|
||||||
var coverage = {zoomMin: c.zoomMin, zoomMax: c.zoomMax, active: false};
|
|
||||||
var bounds = new L.LatLngBounds(
|
|
||||||
new L.LatLng(c.bbox[0]+0.01, c.bbox[1]+0.01),
|
|
||||||
new L.LatLng(c.bbox[2]-0.01, c.bbox[3]-0.01)
|
|
||||||
);
|
|
||||||
coverage.bounds = bounds;
|
|
||||||
coverage.attrib = p.attribution;
|
|
||||||
this._providers.push(coverage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this._update();
|
|
||||||
},
|
|
||||||
|
|
||||||
_update: function() {
|
|
||||||
if (this._url === null || !this._map) return;
|
|
||||||
this._update_attribution();
|
|
||||||
L.TileLayer.prototype._update.apply(this, []);
|
|
||||||
},
|
|
||||||
|
|
||||||
_update_attribution: function() {
|
|
||||||
var bounds = this._map.getBounds();
|
|
||||||
var zoom = this._map.getZoom();
|
|
||||||
for (var i = 0; i < this._providers.length; i++) {
|
|
||||||
var p = this._providers[i];
|
|
||||||
if ((zoom <= p.zoomMax && zoom >= p.zoomMin) &&
|
|
||||||
bounds.intersects(p.bounds)) {
|
|
||||||
if (!p.active && this._map.attributionControl)
|
|
||||||
this._map.attributionControl.addAttribution(p.attrib);
|
|
||||||
p.active = true;
|
|
||||||
} else {
|
|
||||||
if (p.active && this._map.attributionControl)
|
|
||||||
this._map.attributionControl.removeAttribution(p.attrib);
|
|
||||||
p.active = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
onRemove: function(map) {
|
|
||||||
for (var i = 0; i < this._providers.length; i++) {
|
|
||||||
var p = this._providers[i];
|
|
||||||
if (p.active && this._map.attributionControl) {
|
|
||||||
this._map.attributionControl.removeAttribution(p.attrib);
|
|
||||||
p.active = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
L.TileLayer.prototype.onRemove.apply(this, [map]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
L.bingLayer = function (key, options) {
|
|
||||||
return new L.BingLayer(key, options);
|
|
||||||
};
|
|
||||||
|
|
@ -1,200 +0,0 @@
|
||||||
/*
|
|
||||||
* Google layer using Google Maps API
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* global google: true */
|
|
||||||
|
|
||||||
L.Google = L.Class.extend({
|
|
||||||
includes: L.Mixin.Events,
|
|
||||||
|
|
||||||
options: {
|
|
||||||
minZoom: 0,
|
|
||||||
maxZoom: 18,
|
|
||||||
tileSize: 256,
|
|
||||||
subdomains: 'abc',
|
|
||||||
errorTileUrl: '',
|
|
||||||
attribution: '',
|
|
||||||
opacity: 1,
|
|
||||||
continuousWorld: false,
|
|
||||||
noWrap: false,
|
|
||||||
mapOptions: {
|
|
||||||
backgroundColor: '#dddddd'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Possible types: SATELLITE, ROADMAP, HYBRID, TERRAIN
|
|
||||||
initialize: function(type, options) {
|
|
||||||
L.Util.setOptions(this, options);
|
|
||||||
|
|
||||||
this._ready = google.maps.Map !== undefined;
|
|
||||||
if (!this._ready) L.Google.asyncWait.push(this);
|
|
||||||
|
|
||||||
this._type = type || 'SATELLITE';
|
|
||||||
},
|
|
||||||
|
|
||||||
onAdd: function(map, insertAtTheBottom) {
|
|
||||||
this._map = map;
|
|
||||||
this._insertAtTheBottom = insertAtTheBottom;
|
|
||||||
|
|
||||||
// create a container div for tiles
|
|
||||||
this._initContainer();
|
|
||||||
this._initMapObject();
|
|
||||||
|
|
||||||
// set up events
|
|
||||||
map.on('viewreset', this._resetCallback, this);
|
|
||||||
|
|
||||||
this._limitedUpdate = L.Util.limitExecByInterval(this._update, 150, this);
|
|
||||||
map.on('move', this._update, this);
|
|
||||||
|
|
||||||
map.on('zoomanim', this._handleZoomAnim, this);
|
|
||||||
|
|
||||||
//20px instead of 1em to avoid a slight overlap with google's attribution
|
|
||||||
map._controlCorners.bottomright.style.marginBottom = '20px';
|
|
||||||
|
|
||||||
this._reset();
|
|
||||||
this._update();
|
|
||||||
},
|
|
||||||
|
|
||||||
onRemove: function(map) {
|
|
||||||
this._map._container.removeChild(this._container);
|
|
||||||
//this._container = null;
|
|
||||||
|
|
||||||
this._map.off('viewreset', this._resetCallback, this);
|
|
||||||
|
|
||||||
this._map.off('move', this._update, this);
|
|
||||||
|
|
||||||
this._map.off('zoomanim', this._handleZoomAnim, this);
|
|
||||||
|
|
||||||
map._controlCorners.bottomright.style.marginBottom = '0em';
|
|
||||||
//this._map.off('moveend', this._update, this);
|
|
||||||
},
|
|
||||||
|
|
||||||
getAttribution: function() {
|
|
||||||
return this.options.attribution;
|
|
||||||
},
|
|
||||||
|
|
||||||
setOpacity: function(opacity) {
|
|
||||||
this.options.opacity = opacity;
|
|
||||||
if (opacity < 1) {
|
|
||||||
L.DomUtil.setOpacity(this._container, opacity);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
setElementSize: function(e, size) {
|
|
||||||
e.style.width = size.x + 'px';
|
|
||||||
e.style.height = size.y + 'px';
|
|
||||||
},
|
|
||||||
|
|
||||||
_initContainer: function() {
|
|
||||||
var tilePane = this._map._container,
|
|
||||||
first = tilePane.firstChild;
|
|
||||||
|
|
||||||
if (!this._container) {
|
|
||||||
this._container = L.DomUtil.create('div', 'leaflet-google-layer leaflet-top leaflet-left');
|
|
||||||
this._container.id = '_GMapContainer_' + L.Util.stamp(this);
|
|
||||||
this._container.style.zIndex = 'auto';
|
|
||||||
}
|
|
||||||
|
|
||||||
tilePane.insertBefore(this._container, first);
|
|
||||||
|
|
||||||
this.setOpacity(this.options.opacity);
|
|
||||||
this.setElementSize(this._container, this._map.getSize());
|
|
||||||
},
|
|
||||||
|
|
||||||
_initMapObject: function() {
|
|
||||||
if (!this._ready) return;
|
|
||||||
this._google_center = new google.maps.LatLng(0, 0);
|
|
||||||
var map = new google.maps.Map(this._container, {
|
|
||||||
center: this._google_center,
|
|
||||||
zoom: 0,
|
|
||||||
tilt: 0,
|
|
||||||
mapTypeId: google.maps.MapTypeId[this._type],
|
|
||||||
disableDefaultUI: true,
|
|
||||||
keyboardShortcuts: false,
|
|
||||||
draggable: false,
|
|
||||||
disableDoubleClickZoom: true,
|
|
||||||
scrollwheel: false,
|
|
||||||
streetViewControl: false,
|
|
||||||
styles: this.options.mapOptions.styles,
|
|
||||||
backgroundColor: this.options.mapOptions.backgroundColor
|
|
||||||
});
|
|
||||||
|
|
||||||
var _this = this;
|
|
||||||
this._reposition = google.maps.event.addListenerOnce(map, 'center_changed',
|
|
||||||
function() { _this.onReposition(); });
|
|
||||||
this._google = map;
|
|
||||||
|
|
||||||
google.maps.event.addListenerOnce(map, 'idle',
|
|
||||||
function() { _this._checkZoomLevels(); });
|
|
||||||
},
|
|
||||||
|
|
||||||
_checkZoomLevels: function() {
|
|
||||||
//setting the zoom level on the Google map may result in a different zoom level than the one requested
|
|
||||||
//(it won't go beyond the level for which they have data).
|
|
||||||
// verify and make sure the zoom levels on both Leaflet and Google maps are consistent
|
|
||||||
if (this._google.getZoom() !== this._map.getZoom()) {
|
|
||||||
//zoom levels are out of sync. Set the leaflet zoom level to match the google one
|
|
||||||
this._map.setZoom( this._google.getZoom() );
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_resetCallback: function(e) {
|
|
||||||
this._reset(e.hard);
|
|
||||||
},
|
|
||||||
|
|
||||||
_reset: function(clearOldContainer) {
|
|
||||||
this._initContainer();
|
|
||||||
},
|
|
||||||
|
|
||||||
_update: function(e) {
|
|
||||||
if (!this._google) return;
|
|
||||||
this._resize();
|
|
||||||
|
|
||||||
var center = e && e.latlng ? e.latlng : this._map.getCenter();
|
|
||||||
var _center = new google.maps.LatLng(center.lat, center.lng);
|
|
||||||
|
|
||||||
this._google.setCenter(_center);
|
|
||||||
this._google.setZoom(this._map.getZoom());
|
|
||||||
|
|
||||||
this._checkZoomLevels();
|
|
||||||
//this._google.fitBounds(google_bounds);
|
|
||||||
},
|
|
||||||
|
|
||||||
_resize: function() {
|
|
||||||
var size = this._map.getSize();
|
|
||||||
if (this._container.style.width === size.x &&
|
|
||||||
this._container.style.height === size.y)
|
|
||||||
return;
|
|
||||||
this.setElementSize(this._container, size);
|
|
||||||
this.onReposition();
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
_handleZoomAnim: function (e) {
|
|
||||||
var center = e.center;
|
|
||||||
var _center = new google.maps.LatLng(center.lat, center.lng);
|
|
||||||
|
|
||||||
this._google.setCenter(_center);
|
|
||||||
this._google.setZoom(e.zoom);
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
onReposition: function() {
|
|
||||||
if (!this._google) return;
|
|
||||||
google.maps.event.trigger(this._google, 'resize');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
L.Google.asyncWait = [];
|
|
||||||
L.Google.asyncInitialize = function() {
|
|
||||||
var i;
|
|
||||||
for (i = 0; i < L.Google.asyncWait.length; i++) {
|
|
||||||
var o = L.Google.asyncWait[i];
|
|
||||||
o._ready = true;
|
|
||||||
if (o._container) {
|
|
||||||
o._initMapObject();
|
|
||||||
o._update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
L.Google.asyncWait = [];
|
|
||||||
};
|
|
||||||
|
|
@ -1,161 +0,0 @@
|
||||||
/*
|
|
||||||
* L.TileLayer is used for standard xyz-numbered tile layers.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* global ymaps: true */
|
|
||||||
/* global console: true */
|
|
||||||
|
|
||||||
L.Yandex = L.Class.extend({
|
|
||||||
includes: L.Mixin.Events,
|
|
||||||
|
|
||||||
options: {
|
|
||||||
minZoom: 0,
|
|
||||||
maxZoom: 18,
|
|
||||||
attribution: '',
|
|
||||||
opacity: 1,
|
|
||||||
traffic: false
|
|
||||||
},
|
|
||||||
|
|
||||||
// Possible types: map, satellite, hybrid, publicMap, publicMapHybrid
|
|
||||||
initialize: function(type, options) {
|
|
||||||
L.Util.setOptions(this, options);
|
|
||||||
|
|
||||||
this._type = 'yandex#' + (type || 'map');
|
|
||||||
},
|
|
||||||
|
|
||||||
onAdd: function(map, insertAtTheBottom) {
|
|
||||||
this._map = map;
|
|
||||||
this._insertAtTheBottom = insertAtTheBottom;
|
|
||||||
|
|
||||||
// create a container div for tiles
|
|
||||||
this._initContainer();
|
|
||||||
this._initMapObject();
|
|
||||||
|
|
||||||
// set up events
|
|
||||||
map.on('viewreset', this._resetCallback, this);
|
|
||||||
|
|
||||||
this._limitedUpdate = L.Util.limitExecByInterval(this._update, 150, this);
|
|
||||||
map.on('move', this._update, this);
|
|
||||||
|
|
||||||
map._controlCorners.bottomright.style.marginBottom = '3em';
|
|
||||||
|
|
||||||
this._reset();
|
|
||||||
this._update(true);
|
|
||||||
},
|
|
||||||
|
|
||||||
onRemove: function(map) {
|
|
||||||
this._map._container.removeChild(this._container);
|
|
||||||
|
|
||||||
this._map.off('viewreset', this._resetCallback, this);
|
|
||||||
|
|
||||||
this._map.off('move', this._update, this);
|
|
||||||
|
|
||||||
map._controlCorners.bottomright.style.marginBottom = '0em';
|
|
||||||
},
|
|
||||||
|
|
||||||
getAttribution: function() {
|
|
||||||
return this.options.attribution;
|
|
||||||
},
|
|
||||||
|
|
||||||
setOpacity: function(opacity) {
|
|
||||||
this.options.opacity = opacity;
|
|
||||||
if (opacity < 1) {
|
|
||||||
L.DomUtil.setOpacity(this._container, opacity);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
setElementSize: function(e, size) {
|
|
||||||
e.style.width = size.x + 'px';
|
|
||||||
e.style.height = size.y + 'px';
|
|
||||||
},
|
|
||||||
|
|
||||||
_initContainer: function() {
|
|
||||||
var tilePane = this._map._container,
|
|
||||||
first = tilePane.firstChild;
|
|
||||||
|
|
||||||
if (!this._container) {
|
|
||||||
this._container = L.DomUtil.create('div', 'leaflet-yandex-layer leaflet-top leaflet-left');
|
|
||||||
this._container.id = '_YMapContainer_' + L.Util.stamp(this);
|
|
||||||
this._container.style.zIndex = 'auto';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.options.overlay) {
|
|
||||||
first = this._map._container.getElementsByClassName('leaflet-map-pane')[0];
|
|
||||||
first = first.nextSibling;
|
|
||||||
// XXX: Bug with layer order
|
|
||||||
if (L.Browser.opera)
|
|
||||||
this._container.className += ' leaflet-objects-pane';
|
|
||||||
}
|
|
||||||
tilePane.insertBefore(this._container, first);
|
|
||||||
|
|
||||||
this.setOpacity(this.options.opacity);
|
|
||||||
this.setElementSize(this._container, this._map.getSize());
|
|
||||||
},
|
|
||||||
|
|
||||||
_initMapObject: function() {
|
|
||||||
if (this._yandex) return;
|
|
||||||
|
|
||||||
// Check that ymaps.Map is ready
|
|
||||||
if (ymaps.Map === undefined) {
|
|
||||||
if (console) {
|
|
||||||
console.debug('L.Yandex: Waiting on ymaps.load("package.map")');
|
|
||||||
}
|
|
||||||
return ymaps.load(['package.map'], this._initMapObject, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If traffic layer is requested check if control.TrafficControl is ready
|
|
||||||
if (this.options.traffic)
|
|
||||||
if (ymaps.control === undefined ||
|
|
||||||
ymaps.control.TrafficControl === undefined) {
|
|
||||||
if (console) {
|
|
||||||
console.debug('L.Yandex: loading traffic and controls');
|
|
||||||
}
|
|
||||||
return ymaps.load(['package.traffic', 'package.controls'],
|
|
||||||
this._initMapObject, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
var map = new ymaps.Map(this._container, {center: [0,0], zoom: 0, behaviors: []});
|
|
||||||
|
|
||||||
if (this.options.traffic)
|
|
||||||
map.controls.add(new ymaps.control.TrafficControl({shown: true}));
|
|
||||||
|
|
||||||
if (this._type === 'yandex#null') {
|
|
||||||
this._type = new ymaps.MapType('null', []);
|
|
||||||
map.container.getElement().style.background = 'transparent';
|
|
||||||
}
|
|
||||||
map.setType(this._type);
|
|
||||||
|
|
||||||
this._yandex = map;
|
|
||||||
this._update(true);
|
|
||||||
},
|
|
||||||
|
|
||||||
_resetCallback: function(e) {
|
|
||||||
this._reset(e.hard);
|
|
||||||
},
|
|
||||||
|
|
||||||
_reset: function(clearOldContainer) {
|
|
||||||
this._initContainer();
|
|
||||||
},
|
|
||||||
|
|
||||||
_update: function(force) {
|
|
||||||
if (!this._yandex) return;
|
|
||||||
this._resize(force);
|
|
||||||
|
|
||||||
var center = this._map.getCenter();
|
|
||||||
var _center = [center.lat, center.lng];
|
|
||||||
var zoom = this._map.getZoom();
|
|
||||||
|
|
||||||
if (force || this._yandex.getZoom() !== zoom)
|
|
||||||
this._yandex.setZoom(zoom);
|
|
||||||
this._yandex.panTo(_center, {duration: 0, delay: 0});
|
|
||||||
},
|
|
||||||
|
|
||||||
_resize: function(force) {
|
|
||||||
var size = this._map.getSize(), style = this._container.style;
|
|
||||||
if (style.width === size.x + 'px' && style.height === size.y + 'px')
|
|
||||||
if (force !== true) return;
|
|
||||||
this.setElementSize(this._container, size);
|
|
||||||
var b = this._map.getBounds(), sw = b.getSouthWest(), ne = b.getNorthEast();
|
|
||||||
this._yandex.container.fitToViewport();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
@ -1,80 +0,0 @@
|
||||||
//#include 'GPX.js'
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
|
|
||||||
function d2h(d) {
|
|
||||||
var hex = '0123456789ABCDEF';
|
|
||||||
var r = '';
|
|
||||||
d = Math.floor(d);
|
|
||||||
while (d !== 0) {
|
|
||||||
r = hex[d % 16] + r;
|
|
||||||
d = Math.floor(d / 16);
|
|
||||||
}
|
|
||||||
while (r.length < 2) r = '0' + r;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gradient(color) {
|
|
||||||
// First arc (0, PI) in HSV colorspace
|
|
||||||
function f2h(d) { return d2h(256 * d); }
|
|
||||||
if (color < 0)
|
|
||||||
return '#FF0000';
|
|
||||||
else if (color < 1.0/3)
|
|
||||||
return '#FF' + f2h(3 * color) + '00';
|
|
||||||
else if (color < 2.0/3)
|
|
||||||
return '#' + f2h(2 - 3 * color) + 'FF00';
|
|
||||||
else if (color < 1)
|
|
||||||
return '#00FF' + f2h(3 * color - 2);
|
|
||||||
else
|
|
||||||
return '#00FFFF';
|
|
||||||
}
|
|
||||||
|
|
||||||
function gpx2time(s) {
|
|
||||||
// 2011-09-24T12:07:53Z
|
|
||||||
if (s.length !== 10 + 1 + 8 + 1)
|
|
||||||
return new Date();
|
|
||||||
return new Date(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
L.GPX.include({
|
|
||||||
options: {
|
|
||||||
maxSpeed: 110,
|
|
||||||
chunks: 200
|
|
||||||
},
|
|
||||||
|
|
||||||
speedSplitEnable: function(options) {
|
|
||||||
L.Util.setOptions(this, options);
|
|
||||||
return this.on('addline', this.speed_split, this);
|
|
||||||
},
|
|
||||||
|
|
||||||
speedSplitDisable: function() {
|
|
||||||
return this.off('addline', this.speed_split, this);
|
|
||||||
},
|
|
||||||
|
|
||||||
speed_split: function(e) {
|
|
||||||
var l = e.line.pop(), ll = l.getLatLngs();
|
|
||||||
var chunk = Math.floor(ll.length / this.options.chunks);
|
|
||||||
if (chunk < 3) chunk = 3;
|
|
||||||
var p = null;
|
|
||||||
for (var i = 0; i < ll.length; i += chunk) {
|
|
||||||
var d = 0, t = null;
|
|
||||||
if (i + chunk > ll.length)
|
|
||||||
chunk = ll.length - i;
|
|
||||||
for (var j = 0; j < chunk; j++) {
|
|
||||||
if (p) d += p.distanceTo(ll[i+j]);
|
|
||||||
p = ll[i + j];
|
|
||||||
if (!t) t = gpx2time(p.meta.time);
|
|
||||||
}
|
|
||||||
p = ll[i + chunk - 1];
|
|
||||||
t = (gpx2time(p.meta.time) - t) / (3600 * 1000);
|
|
||||||
var speed = 0.001 * d / t;
|
|
||||||
//console.info('Dist: ' + d + '; Speed: ' + speed);
|
|
||||||
var color = gradient(speed / this.options.maxSpeed);
|
|
||||||
var poly = new L.Polyline(ll.slice(i, i+chunk+1), {color: color, weight: 2, opacity: 1});
|
|
||||||
poly.bindPopup('Dist: ' + d.toFixed() + 'm; Speed: ' + speed.toFixed(2) + ' km/h');
|
|
||||||
e.line.push(poly);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
})();
|
|
||||||
141
bower_components/leaflet-plugins/layer/vector/GPX.js
vendored
|
|
@ -1,141 +0,0 @@
|
||||||
L.GPX = L.FeatureGroup.extend({
|
|
||||||
initialize: function(gpx, options) {
|
|
||||||
L.Util.setOptions(this, options);
|
|
||||||
this._gpx = gpx;
|
|
||||||
this._layers = {};
|
|
||||||
|
|
||||||
if (gpx) {
|
|
||||||
this.addGPX(gpx, options, this.options.async);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
loadXML: function(url, cb, options, async) {
|
|
||||||
if (async === undefined) async = this.options.async;
|
|
||||||
if (options === undefined) options = this.options;
|
|
||||||
|
|
||||||
var req = new window.XMLHttpRequest();
|
|
||||||
req.open('GET', url, async);
|
|
||||||
try {
|
|
||||||
req.overrideMimeType('text/xml'); // unsupported by IE
|
|
||||||
} catch(e) {}
|
|
||||||
req.onreadystatechange = function() {
|
|
||||||
if (req.readyState !== 4) return;
|
|
||||||
if(req.status === 200) cb(req.responseXML, options);
|
|
||||||
};
|
|
||||||
req.send(null);
|
|
||||||
},
|
|
||||||
|
|
||||||
_humanLen: function(l) {
|
|
||||||
if (l < 2000)
|
|
||||||
return l.toFixed(0) + ' m';
|
|
||||||
else
|
|
||||||
return (l/1000).toFixed(1) + ' km';
|
|
||||||
},
|
|
||||||
|
|
||||||
_polylineLen: function(line)//line is a L.Polyline()
|
|
||||||
{
|
|
||||||
var ll = line._latlngs;
|
|
||||||
var d = 0, p = null;
|
|
||||||
for (var i = 0; i < ll.length; i++)
|
|
||||||
{
|
|
||||||
if(i && p)
|
|
||||||
d += p.distanceTo(ll[i]);
|
|
||||||
p = ll[i];
|
|
||||||
}
|
|
||||||
return d;
|
|
||||||
},
|
|
||||||
|
|
||||||
addGPX: function(url, options, async) {
|
|
||||||
var _this = this;
|
|
||||||
var cb = function(gpx, options) { _this._addGPX(gpx, options); };
|
|
||||||
this.loadXML(url, cb, options, async);
|
|
||||||
},
|
|
||||||
|
|
||||||
_addGPX: function(gpx, options) {
|
|
||||||
var layers = this.parseGPX(gpx, options);
|
|
||||||
if (!layers) return;
|
|
||||||
this.addLayer(layers);
|
|
||||||
this.fire('loaded');
|
|
||||||
},
|
|
||||||
|
|
||||||
parseGPX: function(xml, options) {
|
|
||||||
var j, i, el, layers = [];
|
|
||||||
var named = false, tags = [['rte','rtept'], ['trkseg','trkpt']];
|
|
||||||
|
|
||||||
for (j = 0; j < tags.length; j++) {
|
|
||||||
el = xml.getElementsByTagName(tags[j][0]);
|
|
||||||
for (i = 0; i < el.length; i++) {
|
|
||||||
var l = this.parse_trkseg(el[i], xml, options, tags[j][1]);
|
|
||||||
for (var k = 0; k < l.length; k++) {
|
|
||||||
if (this.parse_name(el[i], l[k])) named = true;
|
|
||||||
layers.push(l[k]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
el = xml.getElementsByTagName('wpt');
|
|
||||||
if (options.display_wpt !== false) {
|
|
||||||
for (i = 0; i < el.length; i++) {
|
|
||||||
var marker = this.parse_wpt(el[i], xml, options);
|
|
||||||
if (!marker) continue;
|
|
||||||
if (this.parse_name(el[i], marker)) named = true;
|
|
||||||
layers.push(marker);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!layers.length) return;
|
|
||||||
var layer = layers[0];
|
|
||||||
if (layers.length > 1)
|
|
||||||
layer = new L.FeatureGroup(layers);
|
|
||||||
if (!named) this.parse_name(xml, layer);
|
|
||||||
return layer;
|
|
||||||
},
|
|
||||||
|
|
||||||
parse_name: function(xml, layer) {
|
|
||||||
var i, el, txt='', name, descr='', len=0;
|
|
||||||
el = xml.getElementsByTagName('name');
|
|
||||||
if (el.length)
|
|
||||||
name = el[0].childNodes[0].nodeValue;
|
|
||||||
el = xml.getElementsByTagName('desc');
|
|
||||||
for (i = 0; i < el.length; i++) {
|
|
||||||
for (var j = 0; j < el[i].childNodes.length; j++)
|
|
||||||
descr = descr + el[i].childNodes[j].nodeValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(layer instanceof L.Path)
|
|
||||||
len = this._polylineLen(layer);
|
|
||||||
|
|
||||||
if (name) txt += '<h2>' + name + '</h2>' + descr;
|
|
||||||
if (len) txt += '<p>' + this._humanLen(len) + '</p>';
|
|
||||||
|
|
||||||
if (layer && layer._popup === undefined) layer.bindPopup(txt);
|
|
||||||
return txt;
|
|
||||||
},
|
|
||||||
|
|
||||||
parse_trkseg: function(line, xml, options, tag) {
|
|
||||||
var el = line.getElementsByTagName(tag);
|
|
||||||
if (!el.length) return [];
|
|
||||||
var coords = [];
|
|
||||||
for (var i = 0; i < el.length; i++) {
|
|
||||||
var ll = new L.LatLng(el[i].getAttribute('lat'),
|
|
||||||
el[i].getAttribute('lon'));
|
|
||||||
ll.meta = {};
|
|
||||||
for (var j in el[i].childNodes) {
|
|
||||||
var e = el[i].childNodes[j];
|
|
||||||
if (!e.tagName) continue;
|
|
||||||
ll.meta[e.tagName] = e.textContent;
|
|
||||||
}
|
|
||||||
coords.push(ll);
|
|
||||||
}
|
|
||||||
var l = [new L.Polyline(coords, options)];
|
|
||||||
this.fire('addline', {line:l});
|
|
||||||
return l;
|
|
||||||
},
|
|
||||||
|
|
||||||
parse_wpt: function(e, xml, options) {
|
|
||||||
var m = new L.Marker(new L.LatLng(e.getAttribute('lat'),
|
|
||||||
e.getAttribute('lon')), options);
|
|
||||||
this.fire('addpoint', {point:m});
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
355
bower_components/leaflet-plugins/layer/vector/KML.js
vendored
|
|
@ -1,355 +0,0 @@
|
||||||
L.KML = L.FeatureGroup.extend({
|
|
||||||
options: {
|
|
||||||
async: true
|
|
||||||
},
|
|
||||||
|
|
||||||
initialize: function(kml, options) {
|
|
||||||
L.Util.setOptions(this, options);
|
|
||||||
this._kml = kml;
|
|
||||||
this._layers = {};
|
|
||||||
|
|
||||||
if (kml) {
|
|
||||||
this.addKML(kml, options, this.options.async);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
loadXML: function(url, cb, options, async) {
|
|
||||||
if (async === undefined) async = this.options.async;
|
|
||||||
if (options === undefined) options = this.options;
|
|
||||||
|
|
||||||
var req = new window.XMLHttpRequest();
|
|
||||||
req.open('GET', url, async);
|
|
||||||
try {
|
|
||||||
req.overrideMimeType('text/xml'); // unsupported by IE
|
|
||||||
} catch(e) {}
|
|
||||||
req.onreadystatechange = function() {
|
|
||||||
if (req.readyState !== 4) return;
|
|
||||||
if (req.status === 200) cb(req.responseXML, options);
|
|
||||||
};
|
|
||||||
req.send(null);
|
|
||||||
},
|
|
||||||
|
|
||||||
addKML: function(url, options, async) {
|
|
||||||
var _this = this;
|
|
||||||
var cb = function(gpx, options) { _this._addKML(gpx, options); };
|
|
||||||
this.loadXML(url, cb, options, async);
|
|
||||||
},
|
|
||||||
|
|
||||||
_addKML: function(xml, options) {
|
|
||||||
var layers = L.KML.parseKML(xml);
|
|
||||||
if (!layers || !layers.length) return;
|
|
||||||
for (var i = 0; i < layers.length; i++) {
|
|
||||||
this.fire('addlayer', {
|
|
||||||
layer: layers[i]
|
|
||||||
});
|
|
||||||
this.addLayer(layers[i]);
|
|
||||||
}
|
|
||||||
this.latLngs = L.KML.getLatLngs(xml);
|
|
||||||
this.fire('loaded');
|
|
||||||
},
|
|
||||||
|
|
||||||
latLngs: []
|
|
||||||
});
|
|
||||||
|
|
||||||
L.Util.extend(L.KML, {
|
|
||||||
|
|
||||||
parseKML: function (xml) {
|
|
||||||
var style = this.parseStyle(xml);
|
|
||||||
this.parseStyleMap(xml, style);
|
|
||||||
var el = xml.getElementsByTagName('Folder');
|
|
||||||
var layers = [], l;
|
|
||||||
for (var i = 0; i < el.length; i++) {
|
|
||||||
if (!this._check_folder(el[i])) { continue; }
|
|
||||||
l = this.parseFolder(el[i], style);
|
|
||||||
if (l) { layers.push(l); }
|
|
||||||
}
|
|
||||||
el = xml.getElementsByTagName('Placemark');
|
|
||||||
for (var j = 0; j < el.length; j++) {
|
|
||||||
if (!this._check_folder(el[j])) { continue; }
|
|
||||||
l = this.parsePlacemark(el[j], xml, style);
|
|
||||||
if (l) { layers.push(l); }
|
|
||||||
}
|
|
||||||
return layers;
|
|
||||||
},
|
|
||||||
|
|
||||||
// Return false if e's first parent Folder is not [folder]
|
|
||||||
// - returns true if no parent Folders
|
|
||||||
_check_folder: function (e, folder) {
|
|
||||||
e = e.parentElement;
|
|
||||||
while (e && e.tagName !== 'Folder')
|
|
||||||
{
|
|
||||||
e = e.parentElement;
|
|
||||||
}
|
|
||||||
return !e || e === folder;
|
|
||||||
},
|
|
||||||
|
|
||||||
parseStyle: function (xml) {
|
|
||||||
var style = {};
|
|
||||||
var sl = xml.getElementsByTagName('Style');
|
|
||||||
|
|
||||||
//for (var i = 0; i < sl.length; i++) {
|
|
||||||
var attributes = {color: true, width: true, Icon: true, href: true,
|
|
||||||
hotSpot: true};
|
|
||||||
|
|
||||||
function _parse(xml) {
|
|
||||||
var options = {};
|
|
||||||
for (var i = 0; i < xml.childNodes.length; i++) {
|
|
||||||
var e = xml.childNodes[i];
|
|
||||||
var key = e.tagName;
|
|
||||||
if (!attributes[key]) { continue; }
|
|
||||||
if (key === 'hotSpot')
|
|
||||||
{
|
|
||||||
for (var j = 0; j < e.attributes.length; j++) {
|
|
||||||
options[e.attributes[j].name] = e.attributes[j].nodeValue;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var value = e.childNodes[0].nodeValue;
|
|
||||||
if (key === 'color') {
|
|
||||||
options.opacity = parseInt(value.substring(0, 2), 16) / 255.0;
|
|
||||||
options.color = '#' + value.substring(6, 8) + value.substring(4, 6) + value.substring(2, 4);
|
|
||||||
} else if (key === 'width') {
|
|
||||||
options.weight = value;
|
|
||||||
} else if (key === 'Icon') {
|
|
||||||
ioptions = _parse(e);
|
|
||||||
if (ioptions.href) { options.href = ioptions.href; }
|
|
||||||
} else if (key === 'href') {
|
|
||||||
options.href = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < sl.length; i++) {
|
|
||||||
var e = sl[i], el;
|
|
||||||
var options = {}, poptions = {}, ioptions = {};
|
|
||||||
el = e.getElementsByTagName('LineStyle');
|
|
||||||
if (el && el[0]) { options = _parse(el[0]); }
|
|
||||||
el = e.getElementsByTagName('PolyStyle');
|
|
||||||
if (el && el[0]) { poptions = _parse(el[0]); }
|
|
||||||
if (poptions.color) { options.fillColor = poptions.color; }
|
|
||||||
if (poptions.opacity) { options.fillOpacity = poptions.opacity; }
|
|
||||||
el = e.getElementsByTagName('IconStyle');
|
|
||||||
if (el && el[0]) { ioptions = _parse(el[0]); }
|
|
||||||
if (ioptions.href) {
|
|
||||||
// save anchor info until the image is loaded
|
|
||||||
options.icon = new L.KMLIcon({
|
|
||||||
iconUrl: ioptions.href,
|
|
||||||
shadowUrl: null,
|
|
||||||
iconAnchorRef: {x: ioptions.x, y: ioptions.y},
|
|
||||||
iconAnchorType: {x: ioptions.xunits, y: ioptions.yunits}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
style['#' + e.getAttribute('id')] = options;
|
|
||||||
}
|
|
||||||
return style;
|
|
||||||
},
|
|
||||||
|
|
||||||
parseStyleMap: function (xml, existingStyles) {
|
|
||||||
var sl = xml.getElementsByTagName('StyleMap');
|
|
||||||
|
|
||||||
for (var i = 0; i < sl.length; i++) {
|
|
||||||
var e = sl[i], el;
|
|
||||||
var smKey, smStyleUrl;
|
|
||||||
|
|
||||||
el = e.getElementsByTagName('key');
|
|
||||||
if (el && el[0]) { smKey = el[0].textContent; }
|
|
||||||
el = e.getElementsByTagName('styleUrl');
|
|
||||||
if (el && el[0]) { smStyleUrl = el[0].textContent; }
|
|
||||||
|
|
||||||
if (smKey === 'normal')
|
|
||||||
{
|
|
||||||
existingStyles['#' + e.getAttribute('id')] = existingStyles[smStyleUrl];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
},
|
|
||||||
|
|
||||||
parseFolder: function (xml, style) {
|
|
||||||
var el, layers = [], l;
|
|
||||||
el = xml.getElementsByTagName('Folder');
|
|
||||||
for (var i = 0; i < el.length; i++) {
|
|
||||||
if (!this._check_folder(el[i], xml)) { continue; }
|
|
||||||
l = this.parseFolder(el[i], style);
|
|
||||||
if (l) { layers.push(l); }
|
|
||||||
}
|
|
||||||
el = xml.getElementsByTagName('Placemark');
|
|
||||||
for (var j = 0; j < el.length; j++) {
|
|
||||||
if (!this._check_folder(el[j], xml)) { continue; }
|
|
||||||
l = this.parsePlacemark(el[j], xml, style);
|
|
||||||
if (l) { layers.push(l); }
|
|
||||||
}
|
|
||||||
if (!layers.length) { return; }
|
|
||||||
if (layers.length === 1) { return layers[0]; }
|
|
||||||
return new L.FeatureGroup(layers);
|
|
||||||
},
|
|
||||||
|
|
||||||
parsePlacemark: function (place, xml, style) {
|
|
||||||
var i, j, el, options = {};
|
|
||||||
el = place.getElementsByTagName('styleUrl');
|
|
||||||
for (i = 0; i < el.length; i++) {
|
|
||||||
var url = el[i].childNodes[0].nodeValue;
|
|
||||||
for (var a in style[url])
|
|
||||||
{
|
|
||||||
// for jshint
|
|
||||||
if (true)
|
|
||||||
{
|
|
||||||
options[a] = style[url][a];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var layers = [];
|
|
||||||
|
|
||||||
var parse = ['LineString', 'Polygon', 'Point'];
|
|
||||||
for (j in parse) {
|
|
||||||
// for jshint
|
|
||||||
if (true)
|
|
||||||
{
|
|
||||||
var tag = parse[j];
|
|
||||||
el = place.getElementsByTagName(tag);
|
|
||||||
for (i = 0; i < el.length; i++) {
|
|
||||||
var l = this['parse' + tag](el[i], xml, options);
|
|
||||||
if (l) { layers.push(l); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!layers.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var layer = layers[0];
|
|
||||||
if (layers.length > 1) {
|
|
||||||
layer = new L.FeatureGroup(layers);
|
|
||||||
}
|
|
||||||
|
|
||||||
var name, descr = '';
|
|
||||||
el = place.getElementsByTagName('name');
|
|
||||||
if (el.length && el[0].childNodes.length) {
|
|
||||||
name = el[0].childNodes[0].nodeValue;
|
|
||||||
}
|
|
||||||
el = place.getElementsByTagName('description');
|
|
||||||
for (i = 0; i < el.length; i++) {
|
|
||||||
for (j = 0; j < el[i].childNodes.length; j++) {
|
|
||||||
descr = descr + el[i].childNodes[j].nodeValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name) {
|
|
||||||
layer.bindPopup('<h2>' + name + '</h2>' + descr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return layer;
|
|
||||||
},
|
|
||||||
|
|
||||||
parseCoords: function (xml) {
|
|
||||||
var el = xml.getElementsByTagName('coordinates');
|
|
||||||
return this._read_coords(el[0]);
|
|
||||||
},
|
|
||||||
|
|
||||||
parseLineString: function (line, xml, options) {
|
|
||||||
var coords = this.parseCoords(line);
|
|
||||||
if (!coords.length) { return; }
|
|
||||||
return new L.Polyline(coords, options);
|
|
||||||
},
|
|
||||||
|
|
||||||
parsePoint: function (line, xml, options) {
|
|
||||||
var el = line.getElementsByTagName('coordinates');
|
|
||||||
if (!el.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var ll = el[0].childNodes[0].nodeValue.split(',');
|
|
||||||
return new L.KMLMarker(new L.LatLng(ll[1], ll[0]), options);
|
|
||||||
},
|
|
||||||
|
|
||||||
parsePolygon: function (line, xml, options) {
|
|
||||||
var el, polys = [], inner = [], i, coords;
|
|
||||||
el = line.getElementsByTagName('outerBoundaryIs');
|
|
||||||
for (i = 0; i < el.length; i++) {
|
|
||||||
coords = this.parseCoords(el[i]);
|
|
||||||
if (coords) {
|
|
||||||
polys.push(coords);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
el = line.getElementsByTagName('innerBoundaryIs');
|
|
||||||
for (i = 0; i < el.length; i++) {
|
|
||||||
coords = this.parseCoords(el[i]);
|
|
||||||
if (coords) {
|
|
||||||
inner.push(coords);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!polys.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (options.fillColor) {
|
|
||||||
options.fill = true;
|
|
||||||
}
|
|
||||||
if (polys.length === 1) {
|
|
||||||
return new L.Polygon(polys.concat(inner), options);
|
|
||||||
}
|
|
||||||
return new L.MultiPolygon(polys, options);
|
|
||||||
},
|
|
||||||
|
|
||||||
getLatLngs: function (xml) {
|
|
||||||
var el = xml.getElementsByTagName('coordinates');
|
|
||||||
var coords = [];
|
|
||||||
for (var j = 0; j < el.length; j++) {
|
|
||||||
// text might span many childNodes
|
|
||||||
coords = coords.concat(this._read_coords(el[j]));
|
|
||||||
}
|
|
||||||
return coords;
|
|
||||||
},
|
|
||||||
|
|
||||||
_read_coords: function (el) {
|
|
||||||
var text = '', coords = [], i;
|
|
||||||
for (i = 0; i < el.childNodes.length; i++) {
|
|
||||||
text = text + el.childNodes[i].nodeValue;
|
|
||||||
}
|
|
||||||
text = text.split(/[\s\n]+/);
|
|
||||||
for (i = 0; i < text.length; i++) {
|
|
||||||
var ll = text[i].split(',');
|
|
||||||
if (ll.length < 2) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
coords.push(new L.LatLng(ll[1], ll[0]));
|
|
||||||
}
|
|
||||||
return coords;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
L.KMLIcon = L.Icon.extend({
|
|
||||||
|
|
||||||
createIcon: function () {
|
|
||||||
var img = this._createIcon('icon');
|
|
||||||
img.onload = function () {
|
|
||||||
var i = img;
|
|
||||||
this.style.width = i.width + 'px';
|
|
||||||
this.style.height = i.height + 'px';
|
|
||||||
|
|
||||||
if (this.anchorType.x === 'UNITS_FRACTION' || this.anchorType.x === 'fraction') {
|
|
||||||
img.style.marginLeft = (-this.anchor.x * i.width) + 'px';
|
|
||||||
}
|
|
||||||
if (this.anchorType.y === 'UNITS_FRACTION' || this.anchorType.x === 'fraction') {
|
|
||||||
img.style.marginTop = (-(1 - this.anchor.y) * i.height) + 'px';
|
|
||||||
}
|
|
||||||
this.style.display = '';
|
|
||||||
};
|
|
||||||
return img;
|
|
||||||
},
|
|
||||||
|
|
||||||
_setIconStyles: function (img, name) {
|
|
||||||
L.Icon.prototype._setIconStyles.apply(this, [img, name]);
|
|
||||||
// save anchor information to the image
|
|
||||||
img.anchor = this.options.iconAnchorRef;
|
|
||||||
img.anchorType = this.options.iconAnchorType;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
L.KMLMarker = L.Marker.extend({
|
|
||||||
options: {
|
|
||||||
icon: new L.KMLIcon.Default()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
173
bower_components/leaflet-plugins/layer/vector/OSM.js
vendored
|
|
@ -1,173 +0,0 @@
|
||||||
/* global console: true */
|
|
||||||
|
|
||||||
L.OSM = L.FeatureGroup.extend({
|
|
||||||
options: {
|
|
||||||
async: true,
|
|
||||||
forceAll: false
|
|
||||||
},
|
|
||||||
|
|
||||||
initialize: function(url, options) {
|
|
||||||
L.Util.setOptions(this, options);
|
|
||||||
this._url = url;
|
|
||||||
this._layers = {};
|
|
||||||
|
|
||||||
if (url) {
|
|
||||||
this.addXML(url, options, this.options.async);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
loadXML: function(url, cb, options, async) {
|
|
||||||
if (async === undefined) async = this.options.async;
|
|
||||||
if (options === undefined) options = this.options;
|
|
||||||
|
|
||||||
var req = new window.XMLHttpRequest();
|
|
||||||
req.open('GET', url, async);
|
|
||||||
req.overrideMimeType('text/xml');
|
|
||||||
req.onreadystatechange = function() {
|
|
||||||
if (req.readyState !== 4) return;
|
|
||||||
if (req.status === 200) cb(req.responseXML, options);
|
|
||||||
};
|
|
||||||
req.send(null);
|
|
||||||
},
|
|
||||||
|
|
||||||
addXML: function(url, options, async) {
|
|
||||||
var _this = this;
|
|
||||||
var cb = function(xml, options) { _this._addXML(xml, options); };
|
|
||||||
this.loadXML(url, cb, options, async);
|
|
||||||
},
|
|
||||||
|
|
||||||
_addXML: function(xml, options) {
|
|
||||||
var layers = this.parseOSM(xml, options);
|
|
||||||
if (!layers) return;
|
|
||||||
this.addLayer(layers);
|
|
||||||
this.fire('loaded');
|
|
||||||
},
|
|
||||||
|
|
||||||
parseOSM: function(xml, options) {
|
|
||||||
var i, el, ll, layers = [];
|
|
||||||
var nodes = {};
|
|
||||||
var ways = {};
|
|
||||||
var named = false;
|
|
||||||
|
|
||||||
el = xml.getElementsByTagName('node');
|
|
||||||
for (i = 0; i < el.length; i++) {
|
|
||||||
var l = this.parse_node(el[i], xml, options);
|
|
||||||
if (l === undefined) continue;
|
|
||||||
nodes[l.osmid] = l;
|
|
||||||
if (!this.options.forceAll && !l.tags.length) continue;
|
|
||||||
var m = this.named_node(l, options);
|
|
||||||
if (!ll) ll = m.getLatLng();
|
|
||||||
if (this.parse_name(m, l, 'Node')) named = true;
|
|
||||||
layers.push(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
el = xml.getElementsByTagName('way');
|
|
||||||
for (i = 0; i < el.length; i++) {
|
|
||||||
if (i > 10) break;
|
|
||||||
var way = this.parse_way(el[i], nodes, options);
|
|
||||||
if (!way) continue;
|
|
||||||
if (!ll) ll = way.getLatLngs()[0];
|
|
||||||
if (this.parse_name(way, way, 'Way')) named = true;
|
|
||||||
layers.push(way);
|
|
||||||
ways[way.osmid] = way;
|
|
||||||
}
|
|
||||||
|
|
||||||
el = xml.getElementsByTagName('relation');
|
|
||||||
for (i = 0; i < el.length; i++) {
|
|
||||||
if (i > 10) break;
|
|
||||||
var relation = this.parse_relation(el[i], ways, options);
|
|
||||||
if (!relation) continue;
|
|
||||||
if (!ll) ll = relation.getLatLngs()[0];
|
|
||||||
if (this.parse_name(relation, relation, 'Relation')) named = true;
|
|
||||||
layers.push(relation);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!layers.length) return;
|
|
||||||
var layer = layers[0];
|
|
||||||
if (layers.length > 1)
|
|
||||||
layer = new L.FeatureGroup(layers);
|
|
||||||
if (!named) this.parse_name(xml, layer);
|
|
||||||
layer.focusPoint = ll;
|
|
||||||
return layer;
|
|
||||||
},
|
|
||||||
|
|
||||||
parse_name: function(layer, obj, obj_name) {
|
|
||||||
console.info('parse name');
|
|
||||||
console.info(this.options);
|
|
||||||
if (!this.options.forceAll)
|
|
||||||
if (!obj.tags || !obj.tags.length) return;
|
|
||||||
var i, txt = '<table>';
|
|
||||||
for (i = 0; i < obj.tags.length; i++) {
|
|
||||||
var t = obj.tags[i];
|
|
||||||
txt += '<tr><td>' + t.k + '</td><td>=</td><td>' + t.v + '</td></tr>';
|
|
||||||
}
|
|
||||||
txt += '</table>';
|
|
||||||
txt = '<h2>' + obj_name + ' ' + obj.osmid + '</h2>' + txt;
|
|
||||||
if (layer) layer.bindPopup(txt);
|
|
||||||
return txt;
|
|
||||||
},
|
|
||||||
|
|
||||||
parse_tags: function(line) {
|
|
||||||
var tags = [], el = line.getElementsByTagName('tag');
|
|
||||||
for (var i = 0; i < el.length; i++)
|
|
||||||
tags.push({k: el[i].getAttribute('k'), v: el[i].getAttribute('v')});
|
|
||||||
return tags;
|
|
||||||
},
|
|
||||||
|
|
||||||
parse_node: function(e) {
|
|
||||||
var n = { osmid: e.getAttribute('id'),
|
|
||||||
lat:e.getAttribute('lat'),
|
|
||||||
lon:e.getAttribute('lon')
|
|
||||||
};
|
|
||||||
n.ll = new L.LatLng(n.lat, n.lon);
|
|
||||||
n.tags = this.parse_tags(e);
|
|
||||||
return n;
|
|
||||||
},
|
|
||||||
|
|
||||||
parse_way: function(line, nodes, options) {
|
|
||||||
var el = line.getElementsByTagName('nd');
|
|
||||||
if (!el.length) return;
|
|
||||||
var coords = [], tags = [];
|
|
||||||
for (var i = 0; i < el.length; i++) {
|
|
||||||
var ref = el[i].getAttribute('ref'), n = nodes[ref];
|
|
||||||
if (!n) return;
|
|
||||||
coords.push(n.ll);
|
|
||||||
}
|
|
||||||
var layer = new L.Polyline(coords, options);
|
|
||||||
layer.tags = this.parse_tags(line);
|
|
||||||
layer.osmid = line.getAttribute('id');
|
|
||||||
return layer;
|
|
||||||
},
|
|
||||||
|
|
||||||
parse_relation: function(line, ways, options) {
|
|
||||||
var el = line.getElementsByTagName('member');
|
|
||||||
if (!el.length) return;
|
|
||||||
var rt, coords = [], tags = this.parse_tags(line);
|
|
||||||
var i;
|
|
||||||
for (i = 0; i < tags.length; i++)
|
|
||||||
if (tags[i].k === 'type') rt = tags[i].v;
|
|
||||||
|
|
||||||
if (rt !== 'multipolygon' && rt !== 'boundary' && rt !== 'waterway')
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (i = 0; i < el.length; i++) {
|
|
||||||
var mt = el[i].getAttribute('type'), ref = el[i].getAttribute('ref');
|
|
||||||
if (mt !== 'way') continue;
|
|
||||||
var w = ways[ref];
|
|
||||||
console.info('Way: ' + ref + ' ' + w);
|
|
||||||
if (!w) return;
|
|
||||||
coords.push(w);
|
|
||||||
}
|
|
||||||
console.info('Coords: ' + coords.length);
|
|
||||||
if (!coords.length) return;
|
|
||||||
var layer = new L.MultiPolyline(coords, options);
|
|
||||||
layer.tags = this.parse_tags(line);
|
|
||||||
layer.osmid = line.getAttribute('id');
|
|
||||||
return layer;
|
|
||||||
},
|
|
||||||
|
|
||||||
named_node: function(node, options) {
|
|
||||||
var marker = new L.Marker(new L.LatLng(node.lat, node.lon), options);
|
|
||||||
return marker;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
28
bower_components/leaflet-plugins/package.json
vendored
|
|
@ -1,28 +0,0 @@
|
||||||
{
|
|
||||||
"author": "Pavel Shramov",
|
|
||||||
"name": "leaflet-plugins",
|
|
||||||
"version": "1.1.2",
|
|
||||||
"description": "Miscellaneous plugins for Leaflet library for services that need to display route information and need satellite imagery from different providers",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git@github.com:shramov/leaflet-plugins.git"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"test": "jshint control/* layer/*"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"jshint": "2.5.0"
|
|
||||||
},
|
|
||||||
"contributors": [
|
|
||||||
"Bruno Bergot <bruno@eliaz.fr>",
|
|
||||||
"Andrey Lushchick <andrew@lushchick.org>"
|
|
||||||
],
|
|
||||||
"keywords": [
|
|
||||||
"leaflet",
|
|
||||||
"plugins",
|
|
||||||
"map",
|
|
||||||
"google",
|
|
||||||
"bing",
|
|
||||||
"yandex"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
13
bower_components/leaflet-routing/.bower.json
vendored
|
|
@ -1,13 +0,0 @@
|
||||||
{
|
|
||||||
"name": "leaflet-routing",
|
|
||||||
"homepage": "https://github.com/nrenner/leaflet-routing",
|
|
||||||
"_release": "ed9a880cb3",
|
|
||||||
"_resolution": {
|
|
||||||
"type": "branch",
|
|
||||||
"branch": "styles",
|
|
||||||
"commit": "ed9a880cb353e1f2ef1c5de56bb2ac2758578663"
|
|
||||||
},
|
|
||||||
"_source": "git://github.com/nrenner/leaflet-routing.git",
|
|
||||||
"_target": "styles",
|
|
||||||
"_originalSource": "nrenner/leaflet-routing"
|
|
||||||
}
|
|
||||||
1
bower_components/leaflet-routing/.gitignore
vendored
|
|
@ -1 +0,0 @@
|
||||||
*.swp
|
|
||||||
41
bower_components/leaflet-routing/CHANGELOG.md
vendored
|
|
@ -1,41 +0,0 @@
|
||||||
Changelog
|
|
||||||
=========
|
|
||||||
|
|
||||||
### 0.2.0 (Unreadlesed)
|
|
||||||
|
|
||||||
**Features**
|
|
||||||
|
|
||||||
* Add option for overriding draw shortcuts (#23)
|
|
||||||
* Add option for disabling drawing marker (#18)
|
|
||||||
* Add options for tooltips (waypoint, segment)
|
|
||||||
* Disable shortcuts by setting `options.shortcut` to `false`.
|
|
||||||
* Add support for loading GeoJSON without waypoints (#16).
|
|
||||||
* Add option to #loadGeoJSON() to disable map fit bounds.
|
|
||||||
* Add [OSM demo](http://turistforeningen.github.io/leaflet-routing/examples/osm.html)
|
|
||||||
* …as well as countless updates to the readme and code readability.
|
|
||||||
|
|
||||||
**Breaking changes**
|
|
||||||
|
|
||||||
* Default shortcut key for draw enable is `d`
|
|
||||||
* Default shortcut key for draw disable is `q`
|
|
||||||
|
|
||||||
### 0.1.1 March 11, 2014
|
|
||||||
|
|
||||||
**Features**
|
|
||||||
|
|
||||||
* Add changelog overview (#14)
|
|
||||||
* Add Change map bounds when loading GeoJSON (#13)
|
|
||||||
|
|
||||||
**Bugfixes**
|
|
||||||
|
|
||||||
* Fix undefined evaluation when snapping layer is not avaiable (#15)
|
|
||||||
* Fail gracefully when loading invalid GeoJSON (#12)
|
|
||||||
|
|
||||||
### 0.1.0 March 10, 2014
|
|
||||||
|
|
||||||
* Implements `#loadGeoJSON()` method (#3)
|
|
||||||
|
|
||||||
#### Backwards compability note
|
|
||||||
|
|
||||||
* Format of `properties.waypoints` in `#toGeoJSON()` is changed according to #3.
|
|
||||||
|
|
||||||
22
bower_components/leaflet-routing/LICENSE
vendored
|
|
@ -1,22 +0,0 @@
|
||||||
Copyright (c) 2014, Den Norske Turistforening
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification, are
|
|
||||||
permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice, this list of
|
|
||||||
conditions and the following disclaimer.
|
|
||||||
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice, this list
|
|
||||||
of conditions and the following disclaimer in the documentation and/or other materials
|
|
||||||
provided with the distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
||||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
||||||
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
||||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
|
||||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
183
bower_components/leaflet-routing/README.md
vendored
|
|
@ -1,183 +0,0 @@
|
||||||
Leaflet.Routing
|
|
||||||
===============
|
|
||||||
|
|
||||||
Leaflet.Routing is a routing controller for the popular Leaflet mapping
|
|
||||||
framework. The module provides an intuitive interface for routing paths between
|
|
||||||
waypoints using any user specified routing service. A demo using the OSM data
|
|
||||||
can be found
|
|
||||||
[here](http://turistforeningen.github.io/leaflet-routing/examples/osm.html).
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
* Route handling interface for Leaflet
|
|
||||||
* Use your own routing backend, or OSM
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
var routing = new L.Routing({
|
|
||||||
position: 'topright'
|
|
||||||
,routing: {
|
|
||||||
router: myRouterFunction
|
|
||||||
}
|
|
||||||
,tooltips: {
|
|
||||||
waypoint: 'Waypoint. Drag to move; Click to remove.',
|
|
||||||
segment: 'Drag to create a new waypoint'
|
|
||||||
}
|
|
||||||
,styles: { // see http://leafletjs.com/reference.html#polyline-options
|
|
||||||
trailer: {} // drawing line
|
|
||||||
,track: {} // calculated route result
|
|
||||||
,nodata: {} // line when no result (error)
|
|
||||||
}
|
|
||||||
,snapping: {
|
|
||||||
layers: [mySnappingLayer]
|
|
||||||
,sensitivity: 15
|
|
||||||
,vertexonly: false
|
|
||||||
}
|
|
||||||
,shortcut: {
|
|
||||||
draw: {
|
|
||||||
enable: 68 // 'd'
|
|
||||||
,disable: 81 // 'q'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
map.addControl(routing);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Enable Drawing
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
routing.draw(true);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Enable Routing `NOT IMPLEMENTED`
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
routing.routing(true);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Enable Snapping `NOT IMPLEMETED`
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
routing.snapping(true);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Recalculate the complete route by routing each segment
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
routing.rerouteAllSegments(callback);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Get first waypoint
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
var first = routing.getFirst();
|
|
||||||
```
|
|
||||||
|
|
||||||
### Get last waypoint
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
var last = routing.getLast();
|
|
||||||
```
|
|
||||||
|
|
||||||
### Get all waypoints
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
var waypointsArray = routing.getWaypoints();
|
|
||||||
```
|
|
||||||
|
|
||||||
### Routing to Polyline
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
var polyline = routing.toPolyline();
|
|
||||||
```
|
|
||||||
|
|
||||||
### To GeoJSON
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
var geoJSON3D = routing.toGeoJSON();
|
|
||||||
var geoJSON2D = routing.toGeoJSON(false);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Load GeoJSON
|
|
||||||
|
|
||||||
Load GeoJSON with and without `properties.waypoints`.
|
|
||||||
|
|
||||||
#### Options
|
|
||||||
|
|
||||||
* `number` waypointDistance - distance between inserted waypoints for GeoJSON without waypoints.
|
|
||||||
* `boolean` fitBounds - fit map arround loaded GeoJSON.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
routing.loadGeoJSON(geojson, [options], function(err) {
|
|
||||||
if (err) {
|
|
||||||
console.log(err);
|
|
||||||
} else {
|
|
||||||
console.log('Finished loading GeoJSON');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## Events
|
|
||||||
|
|
||||||
All events form Leaflet.Routing is prefixed with `routing:`.
|
|
||||||
|
|
||||||
### Usage
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
routing.on('routing:someEvent', function() {
|
|
||||||
console.log('routing:someEvent triggered');
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### L.Routing Events
|
|
||||||
|
|
||||||
| Event name | Description |
|
|
||||||
|------------|-------------|
|
|
||||||
| `routing:draw-start` | Fired when drawing mode is started |
|
|
||||||
| `routing:draw-new` | Fired when drawing mode is started for a new route |
|
|
||||||
| `routing:draw-continue` | Fired when drawing mode is started for an existing route |
|
|
||||||
| `routing:draw-stop` | Fired when drawing mode ends |
|
|
||||||
| `routing:edit-start` | Fired when editing mode starts |
|
|
||||||
| `routing:edit-end` | Fired when editing mode ends |
|
|
||||||
|
|
||||||
### Waypoint Events
|
|
||||||
|
|
||||||
| Event name | Description |
|
|
||||||
|------------|-------------|
|
|
||||||
| `routing:routeWaypointStart` | Fired when a new or existing waypoint is created or moved |
|
|
||||||
| `routing:routeWaypointEnd` | Fired when routing is finished for new or moved waypoint |
|
|
||||||
|
|
||||||
### Segment Events
|
|
||||||
|
|
||||||
| Event name | Description |
|
|
||||||
|------------|-------------|
|
|
||||||
| `routing:rerouteAllSegmentsStart` | Fired when rerouting of all segments starts |
|
|
||||||
| `routing:rerouteAllSegmentsEnd` | Fired when rerouting of all segments completes |
|
|
||||||
|
|
||||||
## Copyright
|
|
||||||
|
|
||||||
Copyright (c) 2014, Den Norske Turistforening
|
|
||||||
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification, are permitted
|
|
||||||
provided that the following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions
|
|
||||||
and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
|
|
||||||
and the following disclaimer in the documentation and/or other materials provided with the
|
|
||||||
distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|
||||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
|
||||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
|
||||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
68
bower_components/leaflet-routing/app.css
vendored
|
|
@ -1,68 +0,0 @@
|
||||||
#map {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.line-mouse-marker {
|
|
||||||
background-color: #ffffff;
|
|
||||||
border: 2px solid black;
|
|
||||||
border-radius: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#export {
|
|
||||||
position: absolute;
|
|
||||||
right: 10px;
|
|
||||||
top: 10px;
|
|
||||||
background-color: rgb(228,225,218);
|
|
||||||
border: 1px solid rgb(196, 196, 196);
|
|
||||||
padding: 10px;
|
|
||||||
z-index: 3000;
|
|
||||||
}
|
|
||||||
|
|
||||||
#search {
|
|
||||||
position: relative;
|
|
||||||
margin: 10px auto;
|
|
||||||
background-color: rgb(228,225,218);
|
|
||||||
border: 1px solid rgb(196, 196, 196);
|
|
||||||
padding: 10px;
|
|
||||||
z-index: 3000;
|
|
||||||
width: 300px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#search input {
|
|
||||||
width: 240px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.typeahead {
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tt-dropdown-menu {
|
|
||||||
width: 240px;
|
|
||||||
padding: 8px 0;
|
|
||||||
background-color: #fff;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tt-suggestion {
|
|
||||||
padding: 3px 20px;
|
|
||||||
font-size: 18px;
|
|
||||||
line-height: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tt-suggestion.tt-is-under-cursor {
|
|
||||||
color: #fff;
|
|
||||||
background-color: #0097cf;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.tt-suggestion p {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#export input {
|
|
||||||
width: 70px;
|
|
||||||
}
|
|
||||||
228
bower_components/leaflet-routing/app.js
vendored
|
|
@ -1,228 +0,0 @@
|
||||||
/*
|
|
||||||
Routing capability using the Leaflet framework
|
|
||||||
Copyright (c) 2013, Turistforeningen, Hans Kristian Flaatten
|
|
||||||
|
|
||||||
https://github.com/Turistforeningen/leaflet-routing
|
|
||||||
*/
|
|
||||||
|
|
||||||
var routing, data;
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
"use strict";
|
|
||||||
jQuery(function($) {
|
|
||||||
var api, apiKey, rUrl, sUrl, topo, map, snapping, inport, myRouter;
|
|
||||||
|
|
||||||
api = window.location.hash.substr(1).split('@');
|
|
||||||
if (api.length === 2) {
|
|
||||||
rUrl = 'http://' + api[1] + '/route/?coords='
|
|
||||||
sUrl = 'http://' + api[1] + '/bbox/?bbox=';
|
|
||||||
apiKey = api[0];
|
|
||||||
} else {
|
|
||||||
throw new Error('API auth failed');
|
|
||||||
}
|
|
||||||
|
|
||||||
topo = L.tileLayer('http://opencache.statkart.no/gatekeeper/gk/gk.open_gmaps?layers=topo2&zoom={z}&x={x}&y={y}', {
|
|
||||||
maxZoom: 16,
|
|
||||||
attribution: '<a href="http://www.statkart.no/">Statens kartverk</a>'
|
|
||||||
});
|
|
||||||
|
|
||||||
var summer = L.tileLayer('http://mt3.turistforeningen.no/prod/trail_summer/{z}/{x}/{y}.png', {
|
|
||||||
maxZoom: 16,
|
|
||||||
attribution: '<a href="http://www.turistforeningen.no/">DNT</a>'
|
|
||||||
});
|
|
||||||
var winter = L.tileLayer('http://mt3.turistforeningen.no/prod/trail_winter/{z}/{x}/{y}.png', {
|
|
||||||
maxZoom: 16,
|
|
||||||
attribution: '<a href="http://www.turistforeningen.no/">DNT</a>'
|
|
||||||
});
|
|
||||||
var cabin = L.tileLayer('http://mt3.turistforeningen.no/prod/cabin/{z}/{x}/{y}.png', {
|
|
||||||
maxZoom: 16,
|
|
||||||
attribution: '<a href="http://www.turistforeningen.no/">DNT</a>'
|
|
||||||
});
|
|
||||||
|
|
||||||
map = new L.Map('map', {
|
|
||||||
layers: [topo]
|
|
||||||
,center: new L.LatLng(61.5, 9)
|
|
||||||
,zoom: 13
|
|
||||||
});
|
|
||||||
cabin.addTo(map);
|
|
||||||
summer.addTo(map);
|
|
||||||
|
|
||||||
L.control.layers({'Topo 2': topo}, {
|
|
||||||
'DNTs merkede stier': summer
|
|
||||||
,'DNTs merkede vinterruter': winter
|
|
||||||
,'DNTs turisthytter': cabin
|
|
||||||
}, {
|
|
||||||
position: 'topleft'
|
|
||||||
}).addTo(map);
|
|
||||||
|
|
||||||
// Import Layer
|
|
||||||
inport = new L.layerGroup(null, {
|
|
||||||
style: {
|
|
||||||
opacity:0.5
|
|
||||||
,clickable:false
|
|
||||||
}
|
|
||||||
}).addTo(map);
|
|
||||||
|
|
||||||
// Snapping Layer
|
|
||||||
snapping = new L.geoJson(null, {
|
|
||||||
style: {
|
|
||||||
opacity:0
|
|
||||||
,clickable:false
|
|
||||||
}
|
|
||||||
}).addTo(map);
|
|
||||||
map.on('moveend', function() {
|
|
||||||
if (map.getZoom() > 12) {
|
|
||||||
var url;
|
|
||||||
url = sUrl + map.getBounds().toBBoxString() + '&callback=?';
|
|
||||||
$.getJSON(url).always(function(data, status) {
|
|
||||||
if (status === 'success') {
|
|
||||||
data = JSON.parse(data);
|
|
||||||
if (data.geometries && data.geometries.length > 0) {
|
|
||||||
snapping.clearLayers();
|
|
||||||
snapping.addData(data);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.error('Could not load snapping data');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
snapping.clearLayers();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
map.fire('moveend');
|
|
||||||
|
|
||||||
// Routing Function
|
|
||||||
// @todo speed up geometryToLayer()
|
|
||||||
myRouter = function(l1, l2, cb) {
|
|
||||||
var req = $.getJSON(rUrl + [l1.lng, l1.lat, l2.lng, l2.lat].join(',') + '&callback=?');
|
|
||||||
req.always(function(data, status) {
|
|
||||||
if (status === 'success') {
|
|
||||||
try {
|
|
||||||
L.GeoJSON.geometryToLayer(JSON.parse(data)).eachLayer(function (layer) {
|
|
||||||
// 14026
|
|
||||||
var d1 = l1.distanceTo(layer._latlngs[0]);
|
|
||||||
var d2 = l2.distanceTo(layer._latlngs[layer._latlngs.length-1]);
|
|
||||||
|
|
||||||
if (d1 < 10 && d2 < 10) {
|
|
||||||
return cb(null, layer);
|
|
||||||
} else {
|
|
||||||
return cb(new Error('This has been discarded'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch(e) {
|
|
||||||
return cb(new Error('Invalid JSON'));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return cb(new Error('Routing failed'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Leaflet Routing Module
|
|
||||||
routing = new L.Routing({
|
|
||||||
position: 'topleft'
|
|
||||||
,routing: {
|
|
||||||
router: myRouter
|
|
||||||
}
|
|
||||||
,snapping: {
|
|
||||||
layers: [snapping]
|
|
||||||
,sensitivity: 15
|
|
||||||
,vertexonly: false
|
|
||||||
}
|
|
||||||
});
|
|
||||||
map.addControl(routing);
|
|
||||||
routing.draw(true); // enable drawing mode
|
|
||||||
|
|
||||||
$('#eta-export').hide();
|
|
||||||
$('#eta-export').on('click', function() {
|
|
||||||
var id = $('#eta-id').val();
|
|
||||||
if (!id) { alert('Ingen tp_id definert!'); return; }
|
|
||||||
if (confirm('Eksport til ETA vil overskrive eksisterende geometri!')) {
|
|
||||||
var coords = routing.toGeoJSON().coordinates;
|
|
||||||
var data = [];
|
|
||||||
for (var i = 0; i < coords.length; i++) {
|
|
||||||
data.push(coords[i][0] + ' ' + coords[i][1]);
|
|
||||||
}
|
|
||||||
data = 'LINESTRING(' + data.join(',') + ')';
|
|
||||||
$.post('http://mintur.ut.no/lib/ajax/post_geom.php?api_key=' + apiKey + '&tp_id=' + id, {coords: data}, function(data) {
|
|
||||||
if (data.error) {
|
|
||||||
alert('Eksport feilet med feilkode ' + data.error);
|
|
||||||
} else if (data.success) {
|
|
||||||
window.location.href = 'http://mintur.ut.no/index.php?tp_id=' + id + '&tab=kart';
|
|
||||||
//alert('Eksport suksess!');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#eta-import').on('click', function() {
|
|
||||||
var id = $('#eta-id').val();
|
|
||||||
if (!id) { alert('Ingen tp_id definert!'); return; }
|
|
||||||
$.get('http://mintur.ut.no/lib/ajax/post_geom.php?api_key=' + apiKey + '&tp_id=' + id, function(data) {
|
|
||||||
if (data.error) {
|
|
||||||
alert('Import feilet med feilkode ' + data.error);
|
|
||||||
} else if (typeof data.coords !== 'undefined') {
|
|
||||||
$('#eta-import').hide();
|
|
||||||
$('#eta-export').show();
|
|
||||||
$('#eta-id').attr('readonly', 'readonly');
|
|
||||||
|
|
||||||
if (data.coords) {
|
|
||||||
data.coords = data.coords.replace('LINESTRING(', '').replace(')', '').split(',');
|
|
||||||
for (var i = 0; i < data.coords.length; i++) {
|
|
||||||
data.coords[i] = new L.LatLng(data.coords[i].split(' ')[1], data.coords[i].split(' ')[0]);
|
|
||||||
}
|
|
||||||
inport.clearLayers();
|
|
||||||
var p = new L.Polyline(data.coords, {clickable:false, color: '#000000', opacity: 0.4});
|
|
||||||
inport.addLayer(p);
|
|
||||||
map.fitBounds(p.getBounds());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function fetchSsrAc(search, cb) {
|
|
||||||
var result = [];
|
|
||||||
$.ajax({
|
|
||||||
url: "https://ws.geonorge.no/SKWS3Index/ssr/sok?navn=" + search + "*&epsgKode=4326&antPerSide=10"
|
|
||||||
,type: "GET"
|
|
||||||
,dataType: 'xml'
|
|
||||||
,success: function(xml) {
|
|
||||||
$(xml).find('sokRes > stedsnavn').each(function(){
|
|
||||||
result.push({
|
|
||||||
title: $(this).find('stedsnavn').text()
|
|
||||||
,lat: $(this).find('aust').text()
|
|
||||||
,lng: $(this).find('nord').text()
|
|
||||||
});
|
|
||||||
});
|
|
||||||
cb(null, result);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
$('#ssr-search').typeahead({
|
|
||||||
remote: {
|
|
||||||
url: 'https://ws.geonorge.no/SKWS3Index/ssr/sok?navn=%QUERY*&epsgKode=4326&antPerSide=10',
|
|
||||||
dataType: 'xml',
|
|
||||||
filter: function(xml) {
|
|
||||||
var result = [];
|
|
||||||
$(xml).find('sokRes > stedsnavn').each(function(){
|
|
||||||
result.push({
|
|
||||||
value: $(this).find('stedsnavn').text()
|
|
||||||
,tokens: [$(this).find('stedsnavn').text()]
|
|
||||||
,lat: $(this).find('nord').text()
|
|
||||||
,lng: $(this).find('aust').text()
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#ssr-search').on('typeahead:selected', function(e, object) {
|
|
||||||
var ll = new L.LatLng(object.lat, object.lng);
|
|
||||||
map.panTo(ll);
|
|
||||||
$('#ssr-search').val('');
|
|
||||||
})
|
|
||||||
|
|
||||||
});
|
|
||||||
}).call(this);
|
|
||||||
BIN
bower_components/leaflet-routing/images/promo.gif
vendored
|
Before Width: | Height: | Size: 3.2 MiB |
BIN
bower_components/leaflet-routing/images/promo.png
vendored
|
Before Width: | Height: | Size: 1.6 MiB |
44
bower_components/leaflet-routing/index.html
vendored
|
|
@ -1,44 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>Routing in Leaflet</title>
|
|
||||||
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css" />
|
|
||||||
<!--[if lte IE 8]><link rel="stylesheet" href="libs/leaflet/leaflet.ie.css" /><![endif]-->
|
|
||||||
<link rel="stylesheet" href="app.css" />
|
|
||||||
<script type="text/javascript">
|
|
||||||
var _gaq = _gaq || [];
|
|
||||||
_gaq.push(['_setAccount', 'UA-38558206-1']);
|
|
||||||
_gaq.push(['_trackPageview']);
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
|
||||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
|
||||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
|
||||||
})();
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="search">
|
|
||||||
<strong>Søk:</strong> <input type="text" id="ssr-search">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="export">
|
|
||||||
<strong>tp_id</strong>: <input type="text" id="eta-id">
|
|
||||||
<button id="eta-export">Eksport</button>
|
|
||||||
<button id="eta-import">Import</button>
|
|
||||||
</div>
|
|
||||||
<div id="map"></div>
|
|
||||||
|
|
||||||
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
|
|
||||||
<script src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js"></script>
|
|
||||||
<script src="src/utils/LineUtil.Snapping.js"></script>
|
|
||||||
<script src="src/utils/Marker.Snapping.js"></script>
|
|
||||||
<script src="src/L.Routing.js"></script>
|
|
||||||
<script src="src/L.Routing.Storage.js"></script>
|
|
||||||
<script src="src/L.Routing.Draw.js"></script>
|
|
||||||
<script src="src/L.Routing.Edit.js"></script>
|
|
||||||
<script src="http://twitter.github.io/typeahead.js/releases/0.9.3/typeahead.min.js"></script>
|
|
||||||
<script src="app.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,309 +0,0 @@
|
||||||
/*
|
|
||||||
* L.Routing.Draw class
|
|
||||||
*
|
|
||||||
* Responsible for drawing and contine drawing
|
|
||||||
*
|
|
||||||
* @dependencies L, L.Routing
|
|
||||||
*
|
|
||||||
* @usage new L.Routing.Draw(map, options);
|
|
||||||
*/
|
|
||||||
|
|
||||||
L.Routing.Draw = L.Handler.extend({
|
|
||||||
|
|
||||||
// INCLUDES
|
|
||||||
includes: [L.Mixin.Events]
|
|
||||||
|
|
||||||
// OPTIONS
|
|
||||||
,options: {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Draw Constructor
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*
|
|
||||||
* @param <> parent - parent class instance
|
|
||||||
* @param <Oject> options - routing options
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @todo fetch last waypoint
|
|
||||||
*/
|
|
||||||
,initialize: function (parent, options) {
|
|
||||||
this._parent = parent;
|
|
||||||
this._map = parent._map;
|
|
||||||
|
|
||||||
this._enabled = false;
|
|
||||||
|
|
||||||
L.Util.setOptions(this, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable drawing
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*
|
|
||||||
* @event map.routing:draw-start
|
|
||||||
* @event map.routing:draw-new
|
|
||||||
* @event map.routing:draw-continue
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
,enable: function() {
|
|
||||||
if (this._enabled) { return; }
|
|
||||||
|
|
||||||
this._enabled = true;
|
|
||||||
this._hidden = false;
|
|
||||||
this._dragging = false;
|
|
||||||
this._addHooks();
|
|
||||||
this.fire('enabled');
|
|
||||||
|
|
||||||
this._map.fire('routing:draw-start');
|
|
||||||
if (this._parent._segments._layers.length === 0) {
|
|
||||||
this._map.fire('routing:draw-new');
|
|
||||||
} else {
|
|
||||||
this._map.fire('routing:draw-continue');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Disable drawing
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*
|
|
||||||
* @event map.routing:draw-end
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
,disable: function() {
|
|
||||||
if (!this._enabled) { return; }
|
|
||||||
|
|
||||||
this._enabled = false;
|
|
||||||
this._removeHooks();
|
|
||||||
this.fire('disabled');
|
|
||||||
|
|
||||||
this._map.fire('routing:draw-end');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add hooks
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
,_addHooks: function() {
|
|
||||||
if (!this._map) { return; }
|
|
||||||
|
|
||||||
// Visible Marker
|
|
||||||
if (!this._marker) {
|
|
||||||
this._marker = new L.Marker(this._map.getCenter(), {
|
|
||||||
icon: (this.options.icons.draw ? this.options.icons.draw : new L.Icon.Default())
|
|
||||||
,opacity: (this.options.icons.draw ? 1.0 : 0.0)
|
|
||||||
,zIndexOffset: this.options.zIndexOffset
|
|
||||||
,clickable: false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trailing line
|
|
||||||
if (!this._trailer) {
|
|
||||||
var ll = this._map.getCenter();
|
|
||||||
this._trailerOpacity = this.options.styles.trailer.opacity || 0.2;
|
|
||||||
var style = L.extend({}, this.options.styles.trailer, {
|
|
||||||
opacity: 0.0
|
|
||||||
,clickable: false
|
|
||||||
});
|
|
||||||
this._trailer = new L.Polyline([ll, ll], style);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._parent.on('waypoint:mouseover', this._catchWaypointEvent, this);
|
|
||||||
this._parent.on('waypoint:mouseout' , this._catchWaypointEvent, this);
|
|
||||||
this._parent.on('waypoint:dragstart', this._catchWaypointEvent, this);
|
|
||||||
this._parent.on('waypoint:dragend' , this._catchWaypointEvent, this);
|
|
||||||
|
|
||||||
this._parent.on('segment:mouseover' , this._catchWaypointEvent, this);
|
|
||||||
this._parent.on('segment:mouseout' , this._catchWaypointEvent, this);
|
|
||||||
this._parent.on('segment:dragstart' , this._catchWaypointEvent, this);
|
|
||||||
this._parent.on('segment:dragend' , this._catchWaypointEvent, this);
|
|
||||||
|
|
||||||
this._map.on('mousemove', this._onMouseMove, this);
|
|
||||||
this._map.on('click', this._onMouseClick, this);
|
|
||||||
|
|
||||||
this._marker.addTo(this._map);
|
|
||||||
this._trailer.addTo(this._map);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove hooks
|
|
||||||
*
|
|
||||||
* This method is invoked after the `disable()` has been called and removes
|
|
||||||
* all the hooks set up using the `_addHooks()` method.
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
,_removeHooks: function() {
|
|
||||||
if (!this._map) { return; }
|
|
||||||
|
|
||||||
this._parent.off('waypoint:mouseover', this._catchWaypointEvent, this);
|
|
||||||
this._parent.off('waypoint:mouseout' , this._catchWaypointEvent, this);
|
|
||||||
this._parent.off('waypoint:dragstart', this._catchWaypointEvent, this);
|
|
||||||
this._parent.off('waypoint:dragend' , this._catchWaypointEvent, this);
|
|
||||||
|
|
||||||
this._parent.off('segment:mouseover' , this._catchWaypointEvent, this);
|
|
||||||
this._parent.off('segment:mouseout' , this._catchWaypointEvent, this);
|
|
||||||
this._parent.off('segment:dragstart' , this._catchWaypointEvent, this);
|
|
||||||
this._parent.off('segment:dragend' , this._catchWaypointEvent, this);
|
|
||||||
|
|
||||||
this._map.off('click', this._onMouseClick, this);
|
|
||||||
this._map.off('mousemove', this._onMouseMove, this);
|
|
||||||
|
|
||||||
this._map.removeLayer(this._marker);
|
|
||||||
this._map.removeLayer(this._trailer);
|
|
||||||
|
|
||||||
delete this._marker;
|
|
||||||
delete this._trailer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle waypoint events
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*
|
|
||||||
* @param <L.Event> e - waypoint event
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
,_catchWaypointEvent: function(e) {
|
|
||||||
var type = e.type.split(':')[1];
|
|
||||||
|
|
||||||
if (this._hidden) {
|
|
||||||
if (this._dragging) {
|
|
||||||
if (type === 'dragend') {
|
|
||||||
this._dragging = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (type === 'mouseout') {
|
|
||||||
this._show();
|
|
||||||
} else if (type === 'dragstart') {
|
|
||||||
this._dragging = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (type === 'mouseover') {
|
|
||||||
this._hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hide HUD
|
|
||||||
*
|
|
||||||
* Call this method in order to quickly hide graphical drawing elements for
|
|
||||||
* instance hoovering over draggable objects which should tempoarily disable
|
|
||||||
* dragging.
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
,_hide: function() {
|
|
||||||
this._hidden = true;
|
|
||||||
this._marker.setOpacity(0.0);
|
|
||||||
this._trailer.setStyle({opacity: 0.0});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show HUD
|
|
||||||
*
|
|
||||||
* Call this method to restore graphical drawing elements after they have been
|
|
||||||
* hidden.
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
,_show: function() {
|
|
||||||
this._hidden = false;
|
|
||||||
this._marker.setOpacity(this.options.icons.draw ? 1.0 : 0.0);
|
|
||||||
this._showTrailer();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show trailer when hidden
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
,_showTrailer: function() {
|
|
||||||
if (this._trailer.options.opacity === 0.0) {
|
|
||||||
this._trailer.setStyle({opacity: this._trailerOpacity});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set trailing guide line
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
,_setTrailer: function(fromLatLng, toLatLng) {
|
|
||||||
this._trailer.setLatLngs([fromLatLng, toLatLng]);
|
|
||||||
this._showTrailer();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mouse move handler
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*
|
|
||||||
* @param <L.Event> e - mouse move event
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
,_onMouseMove : function(e) {
|
|
||||||
if (this._hidden) { return; }
|
|
||||||
|
|
||||||
var latlng = e.latlng;
|
|
||||||
var last = this._parent.getLast();
|
|
||||||
|
|
||||||
if (this.options.snapping) {
|
|
||||||
latlng = L.LineUtil.snapToLayers(latlng, null, this.options.snapping);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._marker.setLatLng(latlng);
|
|
||||||
|
|
||||||
|
|
||||||
if (last !== null) {
|
|
||||||
this._setTrailer(last.getLatLng(), latlng);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mouse click handler
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*
|
|
||||||
* @param <L.Event> e - mouse click event
|
|
||||||
*
|
|
||||||
* @event map.routing:new-waypoint
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
,_onMouseClick: function(e) {
|
|
||||||
if (this._hidden) { return; }
|
|
||||||
|
|
||||||
var marker, latlng, last;
|
|
||||||
|
|
||||||
latlng = e.latlng;
|
|
||||||
if (this.options.snapping) {
|
|
||||||
latlng = L.LineUtil.snapToLayers(latlng, null, this.options.snapping);
|
|
||||||
}
|
|
||||||
marker = new L.Marker(latlng, {title: this.options.tooltips.waypoint });
|
|
||||||
last = this._parent.getLast();
|
|
||||||
|
|
||||||
this._setTrailer(latlng, latlng);
|
|
||||||
this._parent.addWaypoint(marker, last, null, function(err, data) {
|
|
||||||
// console.log(err, data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
@ -1,389 +0,0 @@
|
||||||
/*
|
|
||||||
* L.Routing.Edit class
|
|
||||||
*
|
|
||||||
* Responsible handle edits
|
|
||||||
*
|
|
||||||
* @dependencies L, L.Routing
|
|
||||||
*
|
|
||||||
* @usage new L.Routing.Draw(map, options);
|
|
||||||
*/
|
|
||||||
|
|
||||||
L.Routing.Edit = L.Handler.extend({
|
|
||||||
|
|
||||||
// INCLUDES
|
|
||||||
includes: [L.Mixin.Events]
|
|
||||||
|
|
||||||
// OPTIONS
|
|
||||||
,options: {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Edit Constructor
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*
|
|
||||||
* @param <> parent - parent class instance
|
|
||||||
* @param <Oject> options - routing options
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @todo fetch last waypoint
|
|
||||||
*/
|
|
||||||
,initialize: function (parent, options) {
|
|
||||||
this._parent = parent;
|
|
||||||
this._map = parent._map;
|
|
||||||
|
|
||||||
this._enabled = false;
|
|
||||||
|
|
||||||
L.Util.setOptions(this, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable drawing
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*
|
|
||||||
* @event map.routing:edit-start
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
,enable: function() {
|
|
||||||
if (this._enabled) { return; }
|
|
||||||
|
|
||||||
this._enabled = true;
|
|
||||||
this._addHooks();
|
|
||||||
this.fire('enabled');
|
|
||||||
|
|
||||||
this._map.fire('routing:edit-start');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Disable drawing
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*
|
|
||||||
* @event map.draw:edit-end
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
,disable: function() {
|
|
||||||
if (!this._enabled) { return; }
|
|
||||||
|
|
||||||
this._enabled = false;
|
|
||||||
this._removeHooks();
|
|
||||||
this.fire('disabled');
|
|
||||||
|
|
||||||
this._map.fire('routing:edit-end');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add hooks
|
|
||||||
*
|
|
||||||
* This method is invoked when `enable()` is called – and sets up all
|
|
||||||
* necessary hooks such as:
|
|
||||||
* * text selection
|
|
||||||
* * key listeners
|
|
||||||
* * mouse marker
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @todo hide and style the trailer!
|
|
||||||
*/
|
|
||||||
,_addHooks: function() {
|
|
||||||
if (!this._map) { return; }
|
|
||||||
|
|
||||||
if (!this._mouseMarker) {
|
|
||||||
this._mouseMarker = new L.Marker(this._map.getCenter(), {
|
|
||||||
icon: L.divIcon({
|
|
||||||
className: 'line-mouse-marker'
|
|
||||||
,iconAnchor: [5, 5]
|
|
||||||
,iconSize: [10, 10]
|
|
||||||
})
|
|
||||||
,clickable: true
|
|
||||||
,draggable: true
|
|
||||||
,opacity: 0
|
|
||||||
,zIndexOffset: this.options.zIndexOffset
|
|
||||||
,title: this.options.tooltips.segment
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this._mouseMarker.addTo(this._map);
|
|
||||||
|
|
||||||
if (!this._trailer1) {
|
|
||||||
var ll = this._map.getCenter();
|
|
||||||
this._trailerOpacity = this.options.styles.trailer.opacity || 0.2;
|
|
||||||
var style = L.extend({}, this.options.styles.trailer, {opacity: 0.0,clickable: false});
|
|
||||||
this._trailer1 = new L.Polyline([ll, ll], style);
|
|
||||||
this._trailer2 = new L.Polyline([ll, ll], style);
|
|
||||||
}
|
|
||||||
this._trailer1.addTo(this._map);
|
|
||||||
this._trailer2.addTo(this._map);
|
|
||||||
|
|
||||||
this._parent.on('segment:mouseover' , this._segmentOnMouseover, this);
|
|
||||||
|
|
||||||
this._mouseMarker.on('dragstart' , this._segmentOnDragstart, this);
|
|
||||||
this._mouseMarker.on('drag' , this._segmentOnDrag, this);
|
|
||||||
this._mouseMarker.on('dragend' , this._segmentOnDragend, this);
|
|
||||||
|
|
||||||
this._parent.on('waypoint:dragstart', this._waypointOnDragstart, this);
|
|
||||||
this._parent.on('waypoint:drag' , this._waypointOnDrag, this);
|
|
||||||
this._parent.on('waypoint:dragend' , this._waypointOnDragend, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove hooks
|
|
||||||
*
|
|
||||||
* This method is invoked after the `disable()` has been called and removes
|
|
||||||
* all the hooks set up using the `_addHooks()` method.
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
,_removeHooks: function() {
|
|
||||||
if (!this._map) { return; }
|
|
||||||
|
|
||||||
// this._trailer1.addTo(this._map);
|
|
||||||
// this._trailer2.addTo(this._map);
|
|
||||||
|
|
||||||
this._parent.off('segment:mouseover' , this._segmentOnMouseover, this);
|
|
||||||
|
|
||||||
this._mouseMarker.off('dragstart' , this._segmentOnDragstart, this);
|
|
||||||
this._mouseMarker.off('drag' , this._segmentOnDrag, this);
|
|
||||||
this._mouseMarker.off('dragend' , this._segmentOnDragend, this);
|
|
||||||
|
|
||||||
this._parent.off('waypoint:dragstart', this._waypointOnDragstart, this);
|
|
||||||
this._parent.off('waypoint:drag' , this._waypointOnDrag, this);
|
|
||||||
this._parent.off('waypoint:dragend' , this._waypointOnDragend, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fired when the mouse first enters a segment
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*
|
|
||||||
* @param <L.Event> e - mouse over event
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
,_segmentOnMouseover: function(e) {
|
|
||||||
this._mouseMarker.setOpacity(1.0);
|
|
||||||
this._map.on('mousemove', this._segmentOnMousemove, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fired when the mouse leaves a segement
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*
|
|
||||||
* @param <L.Event> e - mouse move event
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
,_segmentOnMouseout: function(e) {
|
|
||||||
if (this._dragging) { return; }
|
|
||||||
|
|
||||||
this._mouseMarker.setOpacity(0.0);
|
|
||||||
this._map.off('mousemove', this._segmentOnMousemove, this);
|
|
||||||
|
|
||||||
this.fire('segment:mouseout');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fired when the mouse is moved
|
|
||||||
*
|
|
||||||
* This method is fired continously when mouse is moved in edition mode.
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*
|
|
||||||
* @param <L.Event> e - mouse move event
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
,_segmentOnMousemove: function(e) {
|
|
||||||
if (this._dragging) { return; }
|
|
||||||
|
|
||||||
var latlng = L.LineUtil.snapToLayers(e.latlng, null, {
|
|
||||||
layers: [this._parent._segments]
|
|
||||||
,sensitivity: 40
|
|
||||||
,vertexonly: false
|
|
||||||
});
|
|
||||||
|
|
||||||
if (latlng._feature === null) {
|
|
||||||
this._segmentOnMouseout(e);
|
|
||||||
} else {
|
|
||||||
this._mouseMarker._snapping = latlng._feature._routing;
|
|
||||||
this._mouseMarker.setLatLng(latlng);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mouse marker dragstart
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*
|
|
||||||
* @param <L.Event> e - mouse dragstart event
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
,_segmentOnDragstart: function(e) {
|
|
||||||
var latlng = e.target.getLatLng();
|
|
||||||
var next = e.target._snapping.nextMarker;
|
|
||||||
var prev = e.target._snapping.prevMarker;
|
|
||||||
|
|
||||||
this._setTrailers(latlng, next, prev, true);
|
|
||||||
|
|
||||||
this._dragging = true;
|
|
||||||
this.fire('segment:dragstart');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fired when a marker is dragged
|
|
||||||
*
|
|
||||||
* This method is fired continously when dragging a marker and snapps the
|
|
||||||
* marker to the snapping layer.
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*
|
|
||||||
* @param <L.Event> e - mouse drag event
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
,_segmentOnDrag: function(e) {
|
|
||||||
var latlng = e.target.getLatLng();
|
|
||||||
var next = e.target._snapping.nextMarker;
|
|
||||||
var prev = e.target._snapping.prevMarker;
|
|
||||||
|
|
||||||
if (this.options.snapping) {
|
|
||||||
latlng = L.LineUtil.snapToLayers(latlng, null, this.options.snapping);
|
|
||||||
}
|
|
||||||
|
|
||||||
e.target.setLatLng(latlng);
|
|
||||||
this._setTrailers(latlng, next, prev);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mouse marker dragend
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*
|
|
||||||
* @param <L.Event> e - mouse dragend event
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
,_segmentOnDragend: function(e) {
|
|
||||||
var next = this._mouseMarker._snapping.nextMarker;
|
|
||||||
var prev = this._mouseMarker._snapping.prevMarker;
|
|
||||||
var latlng = this._mouseMarker.getLatLng();
|
|
||||||
|
|
||||||
this._parent.addWaypoint(latlng, prev, next, function(err, data) {
|
|
||||||
//console.log(err, data);
|
|
||||||
});
|
|
||||||
|
|
||||||
this._dragging = false;
|
|
||||||
this._setTrailers(null, null, null, false);
|
|
||||||
this.fire('segment:dragend');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fired when marker drag start
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*
|
|
||||||
* @param <L.Event> e - mouse dragend event
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
,_waypointOnDragstart: function(e) {
|
|
||||||
var next = e.marker._routing.nextMarker;
|
|
||||||
var prev = e.marker._routing.prevMarker;
|
|
||||||
|
|
||||||
this._setTrailers(e.marker.getLatLng(), next, prev, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fired while dragging marker
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*
|
|
||||||
* @param <L.Event> e - mouse drag event
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
,_waypointOnDrag: function(e) {
|
|
||||||
var latlng = e.marker._latlng;
|
|
||||||
var next = e.marker._routing.nextMarker;
|
|
||||||
var prev = e.marker._routing.prevMarker;
|
|
||||||
|
|
||||||
if (this.options.snapping) {
|
|
||||||
latlng = L.LineUtil.snapToLayers(latlng, null, this.options.snapping);
|
|
||||||
}
|
|
||||||
|
|
||||||
e.marker.setLatLng(latlng);
|
|
||||||
this._setTrailers(latlng, next, prev);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fired when marker drag ends
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*
|
|
||||||
* @param <L.Event> e - mouse dragend event
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
,_waypointOnDragend: function(e) {
|
|
||||||
this._setTrailers(null, null, null, false);
|
|
||||||
this._parent.routeWaypoint(e.marker, function(err, data) {
|
|
||||||
//console.log('_waypointOnDragend.cb', err, data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fired when marker is clicked
|
|
||||||
*
|
|
||||||
* This method is fired when a marker is clicked by the user. It will then
|
|
||||||
* procede to remove the marker and reroute any connected line segments.
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*
|
|
||||||
* @param <L.Event> e - mouse click event
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
,_waypointOnClick: function(e) {
|
|
||||||
this._parent.removeWaypoint(e.layer, function(err, data) {
|
|
||||||
//console.log('_waypointOnDragend.cb', err, data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set trailing guide lines
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
,_setTrailers: function(latlng, next, prev, show) {
|
|
||||||
if (typeof show !== 'undefined') {
|
|
||||||
if (show === false) {
|
|
||||||
this._trailer1.setStyle({opacity: 0.0});
|
|
||||||
this._trailer2.setStyle({opacity: 0.0});
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
if (next !== null) {
|
|
||||||
this._trailer1.setStyle({opacity: this._trailerOpacity});
|
|
||||||
}
|
|
||||||
if (prev !== null) {
|
|
||||||
this._trailer2.setStyle({opacity: this._trailerOpacity});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (next) {
|
|
||||||
this._trailer1.setLatLngs([latlng, next.getLatLng()]);
|
|
||||||
}
|
|
||||||
if (prev) {
|
|
||||||
this._trailer2.setLatLngs([latlng, prev.getLatLng()]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
/*
|
|
||||||
* Leaflet Routing Storage
|
|
||||||
*
|
|
||||||
* Storing routable objects
|
|
||||||
*
|
|
||||||
* @dependencies L, L.Routing
|
|
||||||
*
|
|
||||||
* @usage new L.Routing(options);
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function () {
|
|
||||||
L.Routing.Storage = L.MultiPolyline.extend({
|
|
||||||
/**
|
|
||||||
* Class constructor
|
|
||||||
*/
|
|
||||||
initialize: function (latlngs, options) {
|
|
||||||
this._layers = {};
|
|
||||||
this._options = options;
|
|
||||||
this.setLatLngs(latlngs);
|
|
||||||
|
|
||||||
this.on('layeradd', function() {
|
|
||||||
console.log('layeradd', arguments);
|
|
||||||
}, this);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
L.Routing.storage = function (latlngs, options) {
|
|
||||||
return new L.MultiPolyline(latlngs, options);
|
|
||||||
};
|
|
||||||
|
|
||||||
}());
|
|
||||||
723
bower_components/leaflet-routing/src/L.Routing.js
vendored
|
|
@ -1,723 +0,0 @@
|
||||||
/*
|
|
||||||
* L.Routing main class
|
|
||||||
*
|
|
||||||
* Main clase for the Leaflet routing module
|
|
||||||
*
|
|
||||||
* @dependencies L
|
|
||||||
*
|
|
||||||
* @usage new L.Routing(options);
|
|
||||||
*
|
|
||||||
* @todo use L.Class.extend instead?
|
|
||||||
*/
|
|
||||||
|
|
||||||
L.Routing = L.Control.extend({
|
|
||||||
|
|
||||||
// INCLUDES
|
|
||||||
includes: [L.Mixin.Events]
|
|
||||||
|
|
||||||
// CONSTANTS
|
|
||||||
,statics: {
|
|
||||||
VERSION: '0.1.1-dev'
|
|
||||||
}
|
|
||||||
|
|
||||||
// OPTIONS
|
|
||||||
,options: {
|
|
||||||
position: 'topleft'
|
|
||||||
,tooltips: {
|
|
||||||
waypoint: 'Waypoint. Drag to move; Click to remove.',
|
|
||||||
segment: 'Drag to create a new waypoint'
|
|
||||||
}
|
|
||||||
,icons: {
|
|
||||||
start: new L.Icon.Default()
|
|
||||||
,end: new L.Icon.Default()
|
|
||||||
,normal: new L.Icon.Default()
|
|
||||||
,draw: new L.Icon.Default()
|
|
||||||
}
|
|
||||||
,styles: {
|
|
||||||
trailer: {}
|
|
||||||
,track: {}
|
|
||||||
,nodata: {}
|
|
||||||
}
|
|
||||||
,zIndexOffset: 2000
|
|
||||||
,routing: {
|
|
||||||
router: null // function (<L.Latlng> l1, <L.Latlng> l2, <Function> cb)
|
|
||||||
}
|
|
||||||
,snapping: {
|
|
||||||
layers: [] // layers to snap to
|
|
||||||
,sensitivity: 10 // snapping sensitivity
|
|
||||||
,vertexonly: false // vertex only snapping
|
|
||||||
}
|
|
||||||
,shortcut: {
|
|
||||||
draw: {
|
|
||||||
enable: 68, // char code for 'd'
|
|
||||||
disable: 81 // char code for 'q'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Routing Constructor
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*
|
|
||||||
* @param <Object> options - non-default options
|
|
||||||
*
|
|
||||||
* @todo render display of segments and waypoints
|
|
||||||
*/
|
|
||||||
,initialize: function (options) {
|
|
||||||
this._editing = false;
|
|
||||||
this._drawing = false;
|
|
||||||
|
|
||||||
L.Util.setOptions(this, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when controller is added to map
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*
|
|
||||||
* @param <L.Map> map - map instance
|
|
||||||
*
|
|
||||||
* @return <HTMLElement> container
|
|
||||||
*/
|
|
||||||
,onAdd: function (map) {
|
|
||||||
this._map = map;
|
|
||||||
this._container = this._map._container;
|
|
||||||
this._overlayPane = this._map._panes.overlayPane;
|
|
||||||
this._popupPane = this._map._panes.popupPane;
|
|
||||||
|
|
||||||
this._router = this.options.routing.router;
|
|
||||||
this._segments = new L.FeatureGroup().addTo(map);
|
|
||||||
this._waypoints = new L.FeatureGroup().addTo(map);
|
|
||||||
this._waypoints._first = null;
|
|
||||||
this._waypoints._last = null;
|
|
||||||
|
|
||||||
//L.DomUtil.disableTextSelection();
|
|
||||||
//this._tooltip = new L.Tooltip(this._map);
|
|
||||||
//this._tooltip.updateContent({ text: L.drawLocal.draw.marker.tooltip.start });
|
|
||||||
|
|
||||||
if (this.options.shortcut) {
|
|
||||||
L.DomEvent.addListener(this._container, 'keyup', this._keyupListener, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._draw = new L.Routing.Draw(this, this.options);
|
|
||||||
this._edit = new L.Routing.Edit(this, this.options);
|
|
||||||
this._edit.enable();
|
|
||||||
|
|
||||||
this.on('waypoint:click', this._waypointClickHandler, this)
|
|
||||||
this._segments.on('mouseover' , this._fireSegmentEvent, this);
|
|
||||||
this._edit.on('segment:mouseout' , this._fireSegmentEvent, this);
|
|
||||||
this._edit.on('segment:dragstart', this._fireSegmentEvent, this);
|
|
||||||
this._edit.on('segment:dragend' , this._fireSegmentEvent, this);
|
|
||||||
|
|
||||||
var container = L.DomUtil.create('div', 'leaflet-routing');
|
|
||||||
|
|
||||||
return container;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when controller is removed from map
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*
|
|
||||||
* @param <L.Map> map - map instance
|
|
||||||
*/
|
|
||||||
,onRemove: function(map) {
|
|
||||||
//L.DomUtil.create('div', 'leaflet-routing'); <= delete this
|
|
||||||
|
|
||||||
this.off('waypoint:click', this._waypointClickHandler, this)
|
|
||||||
this._segments.off('mouseover' , this._fireSegmentEvent, this);
|
|
||||||
this._edit.off('segment:mouseout' , this._fireSegmentEvent, this);
|
|
||||||
this._edit.off('segment:dragstart', this._fireSegmentEvent, this);
|
|
||||||
this._edit.off('segment:dragend' , this._fireSegmentEvent, this);
|
|
||||||
|
|
||||||
this._edit.disable();
|
|
||||||
this._draw.disable();
|
|
||||||
|
|
||||||
L.DomUtil.enableTextSelection();
|
|
||||||
// this._tooltip.dispose();
|
|
||||||
// this._tooltip = null;
|
|
||||||
L.DomEvent.removeListener(this._container, 'keyup', this._keyupListener);
|
|
||||||
|
|
||||||
delete this._draw;
|
|
||||||
delete this._edit;
|
|
||||||
delete this._map;
|
|
||||||
delete this._router;
|
|
||||||
delete this._segments;
|
|
||||||
delete this._waypoints;
|
|
||||||
delete this.options;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called whenever a waypoint is clicked
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*
|
|
||||||
* @param <L.Event> e - click event
|
|
||||||
*/
|
|
||||||
,_waypointClickHandler: function(e) {
|
|
||||||
this.removeWaypoint(e.marker, function() {
|
|
||||||
// console.log(arguments);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add new waypoint to path
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*
|
|
||||||
* @param <L.Marker> marker - new waypoint marker (can be ll)
|
|
||||||
* @param <L.Marker> prev - previous waypoint marker
|
|
||||||
* @param <L.Marker> next - next waypoint marker
|
|
||||||
* @param <Function> cb - callback method (err, marker)
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
,addWaypoint: function(marker, prev, next, cb) {
|
|
||||||
if (marker instanceof L.LatLng) {
|
|
||||||
marker = new L.Marker(marker, { title: this.options.tooltips.waypoint });
|
|
||||||
}
|
|
||||||
|
|
||||||
marker._routing = {
|
|
||||||
prevMarker : prev
|
|
||||||
,nextMarker : next
|
|
||||||
,prevLine : null
|
|
||||||
,nextLine : null
|
|
||||||
,timeoutID : null
|
|
||||||
};
|
|
||||||
|
|
||||||
if (this._waypoints._first === null && this._waypoints._last === null) {
|
|
||||||
this._waypoints._first = marker;
|
|
||||||
this._waypoints._last = marker;
|
|
||||||
} else if (next === null) {
|
|
||||||
this._waypoints._last = marker;
|
|
||||||
} else if (prev === null) {
|
|
||||||
this._waypoints._first = marker;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (marker._routing.prevMarker !== null) {
|
|
||||||
marker._routing.prevMarker._routing.nextMarker = marker;
|
|
||||||
marker._routing.prevLine = marker._routing.prevMarker._routing.nextLine;
|
|
||||||
if (marker._routing.prevLine !== null) {
|
|
||||||
marker._routing.prevLine._routing.nextMarker = marker;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (marker._routing.nextMarker !== null) {
|
|
||||||
marker._routing.nextMarker._routing.prevMarker = marker;
|
|
||||||
marker.nextLine = marker._routing.nextMarker._routing.prevLine;
|
|
||||||
if (marker._routing.nextLine !== null) {
|
|
||||||
marker._routing.nextLine._routing.prevMarker = marker;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
marker.on('mouseover', this._fireWaypointEvent, this);
|
|
||||||
marker.on('mouseout' , this._fireWaypointEvent, this);
|
|
||||||
marker.on('dragstart', this._fireWaypointEvent, this);
|
|
||||||
marker.on('dragend' , this._fireWaypointEvent, this);
|
|
||||||
marker.on('drag' , this._fireWaypointEvent, this);
|
|
||||||
marker.on('click' , this._fireWaypointEvent, this);
|
|
||||||
|
|
||||||
this.routeWaypoint(marker, cb);
|
|
||||||
this._waypoints.addLayer(marker);
|
|
||||||
marker.dragging.enable();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove a waypoint from path
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*
|
|
||||||
* @param <L.Marker> marker - new waypoint marker (can be ll)
|
|
||||||
* @param <Function> cb - callback method
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
,removeWaypoint: function(marker, cb) {
|
|
||||||
marker.off('mouseover', this._fireWaypointEvent, this);
|
|
||||||
marker.off('mouseout' , this._fireWaypointEvent, this);
|
|
||||||
marker.off('dragstart', this._fireWaypointEvent, this);
|
|
||||||
marker.off('dragend' , this._fireWaypointEvent, this);
|
|
||||||
marker.off('drag' , this._fireWaypointEvent, this);
|
|
||||||
marker.off('click' , this._fireWaypointEvent, this);
|
|
||||||
|
|
||||||
var prev = marker._routing.prevMarker;
|
|
||||||
var next = marker._routing.nextMarker;
|
|
||||||
|
|
||||||
if (this._waypoints._first && marker._leaflet_id === this._waypoints._first._leaflet_id) {
|
|
||||||
this._waypoints._first = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._waypoints._last && marker._leaflet_id === this._waypoints._last._leaflet_id) {
|
|
||||||
this._waypoints._last = prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prev !== null) {
|
|
||||||
prev._routing.nextMarker = next;
|
|
||||||
prev._routing.nextLine = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (next !== null) {
|
|
||||||
next._routing.prevMarker = prev;
|
|
||||||
next._routing.prevLine = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (marker._routing.nextLine !== null) {
|
|
||||||
this._segments.removeLayer(marker._routing.nextLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (marker._routing.prevLine !== null) {
|
|
||||||
this._segments.removeLayer(marker._routing.prevLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._waypoints.removeLayer(marker);
|
|
||||||
|
|
||||||
if (prev !== null) {
|
|
||||||
this.routeWaypoint(prev, cb);
|
|
||||||
} else if (next !== null) {
|
|
||||||
this.routeWaypoint(next, cb);
|
|
||||||
} else {
|
|
||||||
this._draw.enable();
|
|
||||||
cb(null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Route with respect to waypoint
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*
|
|
||||||
* @param <L.Marker> marker - marker to route on
|
|
||||||
* @param <Function> cb - callback function
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @todo add propper error checking for callback
|
|
||||||
*/
|
|
||||||
,routeWaypoint: function(marker, cb) {
|
|
||||||
var i = 0;
|
|
||||||
var firstErr;
|
|
||||||
var $this = this;
|
|
||||||
var callback = function(err, data) {
|
|
||||||
i++;
|
|
||||||
firstErr = firstErr || err;
|
|
||||||
if (i === 2) {
|
|
||||||
$this.fire('routing:routeWaypointEnd', { err: firstErr });
|
|
||||||
cb(firstErr, marker);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.fire('routing:routeWaypointStart');
|
|
||||||
|
|
||||||
this._routeSegment(marker._routing.prevMarker, marker, callback);
|
|
||||||
this._routeSegment(marker, marker._routing.nextMarker, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Recalculate the complete route by routing each segment
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*
|
|
||||||
* @param <Function> cb - callback function
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @todo add propper error checking for callback
|
|
||||||
*/
|
|
||||||
,rerouteAllSegments: function(cb) {
|
|
||||||
var numSegments = this.getWaypoints().length - 1;
|
|
||||||
var callbackCount = 0;
|
|
||||||
var firstErr;
|
|
||||||
var $this = this;
|
|
||||||
|
|
||||||
var callback = function(err, data) {
|
|
||||||
callbackCount++;
|
|
||||||
firstErr = firstErr || err;
|
|
||||||
if (callbackCount >= numSegments) {
|
|
||||||
$this.fire('routing:rerouteAllSegmentsEnd', { err: firstErr });
|
|
||||||
if (cb) {
|
|
||||||
cb(firstErr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$this.fire('routing:rerouteAllSegmentsStart');
|
|
||||||
|
|
||||||
if (numSegments < 1) {
|
|
||||||
return callback(null, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._eachSegment(function(m1, m2) {
|
|
||||||
this._routeSegment(m1, m2, callback);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Route segment between two markers
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*
|
|
||||||
* @param <L.Marker> m1 - first waypoint marker
|
|
||||||
* @param <L.Marker> m2 - second waypoint marker
|
|
||||||
* @param <Function> cb - callback function (<Error> err, <String> data)
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @todo logic if router fails
|
|
||||||
*/
|
|
||||||
,_routeSegment: function(m1, m2, cb) {
|
|
||||||
var $this = this;
|
|
||||||
|
|
||||||
if (m1 === null || m2 === null) {
|
|
||||||
return cb(null, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._router(m1.getLatLng(), m2.getLatLng(), function(err, layer) {
|
|
||||||
if (typeof layer === 'undefined') {
|
|
||||||
var layer = new L.Polyline([m1.getLatLng(), m2.getLatLng()], $this.options.styles.nodata);
|
|
||||||
} else {
|
|
||||||
layer.setStyle($this.options.styles.track);
|
|
||||||
}
|
|
||||||
|
|
||||||
layer._routing = {
|
|
||||||
prevMarker: m1
|
|
||||||
,nextMarker: m2
|
|
||||||
};
|
|
||||||
|
|
||||||
if (m1._routing.nextLine !== null) {
|
|
||||||
$this._segments.removeLayer(m1._routing.nextLine);
|
|
||||||
}
|
|
||||||
$this._segments.addLayer(layer);
|
|
||||||
|
|
||||||
m1._routing.nextLine = layer;
|
|
||||||
m2._routing.prevLine = layer;
|
|
||||||
|
|
||||||
return cb(err, layer);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Iterate over all segments and execute callback for each segment
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*
|
|
||||||
* @param <function> callback - function to call for each segment
|
|
||||||
* @param <object> context - callback execution context (this). Optional, default: this
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
,_eachSegment: function(callback, context) {
|
|
||||||
var thisArg = context || this;
|
|
||||||
var marker = this.getFirst();
|
|
||||||
|
|
||||||
if (marker === null) { return; }
|
|
||||||
|
|
||||||
while (marker._routing.nextMarker !== null) {
|
|
||||||
var m1 = marker;
|
|
||||||
var m2 = marker._routing.nextMarker;
|
|
||||||
var line = marker._routing.nextLine;
|
|
||||||
|
|
||||||
callback.call(thisArg, m1, m2, line);
|
|
||||||
|
|
||||||
marker = marker._routing.nextMarker;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fire events
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*
|
|
||||||
* @param <L.Event> e - mouse event
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
,_fireWaypointEvent: function(e) {
|
|
||||||
this.fire('waypoint:' + e.type, {marker:e.target});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
,_fireSegmentEvent: function(e) {
|
|
||||||
if (e.type.split(':').length === 2) {
|
|
||||||
this.fire(e.type);
|
|
||||||
} else {
|
|
||||||
this.fire('segment:' + e.type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get first waypoint
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*
|
|
||||||
* @return L.Marker
|
|
||||||
*/
|
|
||||||
,getFirst: function() {
|
|
||||||
return this._waypoints._first;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get last waypoint
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*
|
|
||||||
* @return L.Marker
|
|
||||||
*/
|
|
||||||
,getLast: function() {
|
|
||||||
return this._waypoints._last;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all waypoints
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*
|
|
||||||
* @return <L.LatLng[]> all waypoints or empty array if none
|
|
||||||
*/
|
|
||||||
,getWaypoints: function() {
|
|
||||||
var latLngs = [];
|
|
||||||
|
|
||||||
this._eachSegment(function(m1) {
|
|
||||||
latLngs.push(m1.getLatLng());
|
|
||||||
});
|
|
||||||
|
|
||||||
if (this.getLast()) {
|
|
||||||
latLngs.push(this.getLast().getLatLng());
|
|
||||||
}
|
|
||||||
|
|
||||||
return latLngs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Concatenates all route segments to a single polyline
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*
|
|
||||||
* @return <L.Polyline> polyline, with empty _latlngs when no route segments
|
|
||||||
*/
|
|
||||||
,toPolyline: function() {
|
|
||||||
var latLngs = [];
|
|
||||||
|
|
||||||
this._eachSegment(function(m1, m2, line) {
|
|
||||||
latLngs = latLngs.concat(line.getLatLngs());
|
|
||||||
});
|
|
||||||
|
|
||||||
return L.polyline(latLngs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Export route to GeoJSON
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*
|
|
||||||
* @param <boolean> enforce2d - enforce 2DGeoJSON
|
|
||||||
*
|
|
||||||
* @return <object> GeoJSON object
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
,toGeoJSON: function(enforce2d) {
|
|
||||||
var geojson = {type: "LineString", properties: {waypoints: []}, coordinates: []};
|
|
||||||
var current = this._waypoints._first;
|
|
||||||
|
|
||||||
if (current === null) { return geojson; }
|
|
||||||
|
|
||||||
// First waypoint marker
|
|
||||||
geojson.properties.waypoints.push({
|
|
||||||
coordinates: [current.getLatLng().lng, current.getLatLng().lat],
|
|
||||||
_index: 0
|
|
||||||
});
|
|
||||||
|
|
||||||
while (current._routing.nextMarker) {
|
|
||||||
var next = current._routing.nextMarker;
|
|
||||||
|
|
||||||
// Line segment
|
|
||||||
var tmp = current._routing.nextLine.getLatLngs();
|
|
||||||
for (var i = 0; i < tmp.length; i++) {
|
|
||||||
if (tmp[i].alt && (typeof enforce2d === 'undefined' || enforce2d === false)) {
|
|
||||||
geojson.coordinates.push([tmp[i].lng, tmp[i].lat, tmp[i].alt]);
|
|
||||||
} else {
|
|
||||||
geojson.coordinates.push([tmp[i].lng, tmp[i].lat]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Waypoint marker
|
|
||||||
geojson.properties.waypoints.push({
|
|
||||||
coordinates: [next.getLatLng().lng, next.getLatLng().lat],
|
|
||||||
_index: geojson.coordinates.length-1
|
|
||||||
});
|
|
||||||
|
|
||||||
// Next waypoint marker
|
|
||||||
current = current._routing.nextMarker;
|
|
||||||
}
|
|
||||||
|
|
||||||
return geojson
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Import route from GeoJSON
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*
|
|
||||||
* @param <object> geojson - GeoJSON object with waypoints
|
|
||||||
* @param <object> opts - parsing options
|
|
||||||
* @param <function> cb - callback method (err)
|
|
||||||
*
|
|
||||||
* @return undefined
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
,loadGeoJSON: function(geojson, opts, cb) {
|
|
||||||
var $this, oldRouter, index, waypoints;
|
|
||||||
|
|
||||||
$this = this;
|
|
||||||
|
|
||||||
// Check for optional options parameter
|
|
||||||
if (typeof opts === 'function' || typeof opts === 'undefined') {
|
|
||||||
cb = opts;
|
|
||||||
opts = {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set default options
|
|
||||||
opts.waypointDistance = opts.waypointDistance || 50;
|
|
||||||
opts.fitBounds = opts.fitBounds || true;
|
|
||||||
|
|
||||||
// Check for waypoints before processing geojson
|
|
||||||
if (!geojson.properties || !geojson.properties.waypoints) {
|
|
||||||
if (!geojson.properties) { geojson.properties = {} };
|
|
||||||
geojson.properties.waypoints = [];
|
|
||||||
|
|
||||||
for (var i = 0; i < geojson.coordinates.length; i = i + opts.waypointDistance) {
|
|
||||||
geojson.properties.waypoints.push({
|
|
||||||
_index: i,
|
|
||||||
coordinates: geojson.coordinates[i].slice(0, 2)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i > geojson.coordinates.length-1) {
|
|
||||||
geojson.properties.waypoints.push({
|
|
||||||
_index: geojson.coordinates.length-1,
|
|
||||||
coordinates: geojson.coordinates[geojson.coordinates.length-1].slice(0, 2)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
index = 0;
|
|
||||||
oldRouter = $this._router;
|
|
||||||
waypoints = geojson.properties.waypoints;
|
|
||||||
|
|
||||||
// This is a fake router.
|
|
||||||
//
|
|
||||||
// It is currently not possible to add a waypoint with a known line segment
|
|
||||||
// manually. We are hijacking the router so that we can intercept the
|
|
||||||
// request and return the correct linesegment.
|
|
||||||
//
|
|
||||||
// It you want to fix this; please make a patch and submit a pull request on
|
|
||||||
// GitHub.
|
|
||||||
$this._router = function(m1, m2, cb) { var start =
|
|
||||||
waypoints[index-1]._index; var end = waypoints[index]._index+1;
|
|
||||||
|
|
||||||
return cb(null, L.GeoJSON.geometryToLayer({
|
|
||||||
type: 'LineString',
|
|
||||||
coordinates: geojson.coordinates.slice(start, end)
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
// Clean up
|
|
||||||
end = function() {
|
|
||||||
$this._router = oldRouter; // Restore router
|
|
||||||
// Set map bounds based on loaded geometry
|
|
||||||
setTimeout(function() {
|
|
||||||
if (opts.fitBounds) {
|
|
||||||
$this._map.fitBounds(L.polyline(L.GeoJSON.coordsToLatLngs(geojson.coordinates)).getBounds());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof cb === 'function') { cb(null); }
|
|
||||||
}, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add waypoints
|
|
||||||
add = function() {
|
|
||||||
if (!waypoints[index]) { return end() }
|
|
||||||
|
|
||||||
var coords = waypoints[index].coordinates;
|
|
||||||
var prev = $this._waypoints._last;
|
|
||||||
|
|
||||||
$this.addWaypoint(L.latLng(coords[1], coords[0]), prev, null, function(err, m) {
|
|
||||||
add(++index);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
add();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start (or continue) drawing
|
|
||||||
*
|
|
||||||
* Call this method in order to start or continue drawing. The drawing handler
|
|
||||||
* will be activate and the user can draw on the map.
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @todo check enable
|
|
||||||
*/
|
|
||||||
,draw: function (enable) {
|
|
||||||
if (typeof enable === 'undefined') {
|
|
||||||
var enable = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enable) {
|
|
||||||
this._draw.enable();
|
|
||||||
} else {
|
|
||||||
this._draw.disable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable or disable routing
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @todo check enable
|
|
||||||
*/
|
|
||||||
,routing: function (enable) {
|
|
||||||
throw new Error('Not implemented');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable or disable snapping
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @todo check enable
|
|
||||||
*/
|
|
||||||
,snapping: function (enable) {
|
|
||||||
throw new Error('Not implemented');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Key up listener
|
|
||||||
*
|
|
||||||
* * `ESC` to cancel drawing
|
|
||||||
* * `M` to enable drawing
|
|
||||||
*
|
|
||||||
* @access private
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
,_keyupListener: function (e) {
|
|
||||||
if (e.keyCode === this.options.shortcut.draw.disable) {
|
|
||||||
this._draw.disable();
|
|
||||||
} else if (e.keyCode === this.options.shortcut.draw.enable) {
|
|
||||||
this._draw.enable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
@ -1,191 +0,0 @@
|
||||||
L.Util.extend(L.LineUtil, {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Snap to all layers
|
|
||||||
*
|
|
||||||
* @param <Latlng> latlng - original position
|
|
||||||
* @param <Number> id - leaflet unique id
|
|
||||||
* @param <Object> opts - snapping options
|
|
||||||
*
|
|
||||||
* @return <Latlng> closest point
|
|
||||||
*/
|
|
||||||
snapToLayers: function (latlng, id, opts) {
|
|
||||||
var i, j, keys, feature, res, sensitivity, vertexonly, layers, minDist, minPoint, map;
|
|
||||||
|
|
||||||
sensitivity = opts.sensitivity || 10;
|
|
||||||
vertexonly = opts.vertexonly || false;
|
|
||||||
layers = opts.layers || [];
|
|
||||||
minDist = Infinity;
|
|
||||||
minPoint = latlng;
|
|
||||||
minPoint._feature = null; // containing layer
|
|
||||||
|
|
||||||
if (!opts || !opts.layers || !opts.layers.length) {
|
|
||||||
return minPoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
map = opts.layers[0]._map; // @todo check for undef
|
|
||||||
|
|
||||||
for (i = 0; i < opts.layers.length; i++) {
|
|
||||||
keys = Object.keys(opts.layers[i]._layers);
|
|
||||||
for (j = 0; j < keys.length; j++) {
|
|
||||||
feature = opts.layers[i]._layers[keys[j]];
|
|
||||||
|
|
||||||
// Don't even try snapping to itself!
|
|
||||||
if (id === feature._leaflet_id) { continue; }
|
|
||||||
|
|
||||||
// GeometryCollection
|
|
||||||
if (feature._layers) {
|
|
||||||
var newLatlng = this.snapToLayers(latlng, id, {
|
|
||||||
'sensitivity': sensitivity,
|
|
||||||
'vertexonly': vertexonly,
|
|
||||||
'layers': [feature]
|
|
||||||
});
|
|
||||||
// What if this is the same?
|
|
||||||
res = {'minDist': latlng.distanceTo(newLatlng), 'minPoint': newLatlng};
|
|
||||||
|
|
||||||
// Marker
|
|
||||||
} else if (feature instanceof L.Marker) {
|
|
||||||
res = this._snapToLatlngs(latlng, [feature.getLatLng()], map, sensitivity, vertexonly, minDist);
|
|
||||||
|
|
||||||
// Polyline
|
|
||||||
} else if (feature instanceof L.Polyline) {
|
|
||||||
res = this._snapToLatlngs(latlng, feature.getLatLngs(), map, sensitivity, vertexonly, minDist);
|
|
||||||
|
|
||||||
// MultiPolyline
|
|
||||||
} else if (feature instanceof L.MultiPolyline) {
|
|
||||||
console.error('Snapping to MultiPolyline is currently unsupported', feature);
|
|
||||||
res = {'minDist': minDist, 'minPoint': minPoint};
|
|
||||||
|
|
||||||
// Polygon
|
|
||||||
} else if (feature instanceof L.Polygon) {
|
|
||||||
res = this._snapToPolygon(latlng, feature, map, sensitivity, vertexonly, minDist);
|
|
||||||
|
|
||||||
// MultiPolygon
|
|
||||||
} else if (feature instanceof L.MultiPolygon) {
|
|
||||||
res = this._snapToMultiPolygon(latlng, feature, map, sensitivity, vertexonly, minDist);
|
|
||||||
|
|
||||||
// Unknown
|
|
||||||
} else {
|
|
||||||
console.error('Unsupported snapping feature', feature);
|
|
||||||
res = {'minDist': minDist, 'minPoint': minPoint};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res.minDist < minDist) {
|
|
||||||
minDist = res.minDist;
|
|
||||||
minPoint = res.minPoint;
|
|
||||||
minPoint._feature = feature;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return minPoint;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Snap to Polygon
|
|
||||||
*
|
|
||||||
* @param <Latlng> latlng - original position
|
|
||||||
* @param <L.Polygon> feature -
|
|
||||||
* @param <L.Map> map -
|
|
||||||
* @param <Number> sensitivity -
|
|
||||||
* @param <Boolean> vertexonly -
|
|
||||||
* @param <Number> minDist -
|
|
||||||
*
|
|
||||||
* @return <Object> minDist and minPoint
|
|
||||||
*/
|
|
||||||
_snapToPolygon: function (latlng, polygon, map, sensitivity, vertexonly, minDist) {
|
|
||||||
var res, keys, latlngs, i, minPoint;
|
|
||||||
|
|
||||||
minPoint = null;
|
|
||||||
|
|
||||||
latlngs = polygon.getLatLngs();
|
|
||||||
latlngs.push(latlngs[0]);
|
|
||||||
res = this._snapToLatlngs(latlng, polygon.getLatLngs(), map, sensitivity, vertexonly, minDist);
|
|
||||||
if (res.minDist < minDist) {
|
|
||||||
minDist = res.minDist;
|
|
||||||
minPoint = res.minPoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
keys = Object.keys(polygon._holes);
|
|
||||||
for (i = 0; i < keys.length; i++) {
|
|
||||||
latlngs = polygon._holes[keys[i]];
|
|
||||||
latlngs.push(latlngs[0]);
|
|
||||||
res = this._snapToLatlngs(latlng, polygon._holes[keys[i]], map, sensitivity, vertexonly, minDist);
|
|
||||||
if (res.minDist < minDist) {
|
|
||||||
minDist = res.minDist;
|
|
||||||
minPoint = res.minPoint;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {'minDist': minDist, 'minPoint': minPoint};
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Snap to MultiPolygon
|
|
||||||
*
|
|
||||||
* @param <Latlng> latlng - original position
|
|
||||||
* @param <L.Polygon> feature -
|
|
||||||
* @param <L.Map> map -
|
|
||||||
* @param <Number> sensitivity -
|
|
||||||
* @param <Boolean> vertexonly -
|
|
||||||
* @param <Number> minDist -
|
|
||||||
*
|
|
||||||
* @return <Object> minDist and minPoint
|
|
||||||
*/
|
|
||||||
_snapToMultiPolygon: function (latlng, multipolygon, map, sensitivity, vertexonly, minDist) {
|
|
||||||
var i, keys, res, minPoint;
|
|
||||||
|
|
||||||
minPoint = null;
|
|
||||||
|
|
||||||
keys = Object.keys(multipolygon._layers);
|
|
||||||
for (i = 0; i < keys.length; i++) {
|
|
||||||
res = this._snapToPolygon(latlng, multipolygon._layers[keys[i]], map, sensitivity, vertexonly, minDist);
|
|
||||||
|
|
||||||
if (res.minDist < minDist) {
|
|
||||||
minDist = res.minDist;
|
|
||||||
minPoint = res.minPoint;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {'minDist': minDist, 'minPoint': minPoint};
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Snap to <Array> of <Latlang>
|
|
||||||
*
|
|
||||||
* @param <LatLng> latlng - cursor click
|
|
||||||
* @param <Array> latlngs - array of <L.LatLngs> to snap to
|
|
||||||
* @param <Object> opts - snapping options
|
|
||||||
* @param <Boolean> isPolygon - if feature is a polygon
|
|
||||||
*
|
|
||||||
* @return <Object> minDist and minPoint
|
|
||||||
*/
|
|
||||||
_snapToLatlngs: function (latlng, latlngs, map, sensitivity, vertexonly, minDist) {
|
|
||||||
var i, tmpDist, minPoint, p, p1, p2, d2;
|
|
||||||
|
|
||||||
p = map.latLngToLayerPoint(latlng);
|
|
||||||
p1 = minPoint = null;
|
|
||||||
|
|
||||||
for (i = 0; i < latlngs.length; i++) {
|
|
||||||
p2 = map.latLngToLayerPoint(latlngs[i]);
|
|
||||||
|
|
||||||
if (!vertexonly && p1 !== null) {
|
|
||||||
tmpDist = L.LineUtil.pointToSegmentDistance(p, p1, p2);
|
|
||||||
if (tmpDist < minDist && tmpDist <= sensitivity) {
|
|
||||||
minDist = tmpDist;
|
|
||||||
minPoint = map.layerPointToLatLng(L.LineUtil.closestPointOnSegment(p, p1, p2));
|
|
||||||
}
|
|
||||||
} else if ((d2 = p.distanceTo(p2)) && d2 <= sensitivity && d2 < minDist) {
|
|
||||||
minDist = d2;
|
|
||||||
minPoint = latlngs[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
p1 = p2;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {'minDist': minDist, 'minPoint': minPoint};
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
L.Marker.include({
|
|
||||||
/**
|
|
||||||
* Snap to function
|
|
||||||
*
|
|
||||||
* @param <LatLng> latlng - original position
|
|
||||||
*
|
|
||||||
* @return <LatLng> - new position
|
|
||||||
*/
|
|
||||||
snapTo: function (latlng) {
|
|
||||||
return L.LineUtil.snapToLayers(latlng, this._leaflet_id, this.options.snapping);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
L.Polyline.include({
|
|
||||||
/**
|
|
||||||
* Snap to function
|
|
||||||
*
|
|
||||||
* @param <LatLng> latlng - original position
|
|
||||||
*
|
|
||||||
* @return <LatLng> - new position
|
|
||||||
*/
|
|
||||||
snapTo: function (latlng) {
|
|
||||||
return L.LineUtil.snapToLayers(latlng, this._leaflet_id, this.options.snapping);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
22
bower_components/leaflet-search/.bower.json
vendored
|
|
@ -1,22 +0,0 @@
|
||||||
{
|
|
||||||
"name": "leaflet-search",
|
|
||||||
"version": "1.5.1",
|
|
||||||
"main": "leaflet-search.js",
|
|
||||||
"ignore": [
|
|
||||||
"**/.*",
|
|
||||||
"node_modules",
|
|
||||||
"components",
|
|
||||||
"bower_components",
|
|
||||||
"examples"
|
|
||||||
],
|
|
||||||
"homepage": "https://github.com/stefanocudini/leaflet-search",
|
|
||||||
"_release": "1.5.1",
|
|
||||||
"_resolution": {
|
|
||||||
"type": "version",
|
|
||||||
"tag": "v1.5.1",
|
|
||||||
"commit": "75ab103b838a966692cfb6cb3dc78c3b0f306eee"
|
|
||||||
},
|
|
||||||
"_source": "git://github.com/stefanocudini/leaflet-search.git",
|
|
||||||
"_target": "*",
|
|
||||||
"_originalSource": "leaflet-search"
|
|
||||||
}
|
|
||||||
12
bower_components/leaflet-search/BUGS
vendored
|
|
@ -1,12 +0,0 @@
|
||||||
. option condition problem {autoCollapse: true, markerLocation: true} not show location, row 61
|
|
||||||
|
|
||||||
. option condition problem {autoCollapse:false }, row 62
|
|
||||||
|
|
||||||
. problem with jsonp/ajax when remote filter has different behavior of this._filterRecords, row 322
|
|
||||||
|
|
||||||
. _handleAutoresize Should resize max search box size when map is resized., row 616
|
|
||||||
|
|
||||||
. if collapse in _handleSubmit hide _markerLoc!, row 684
|
|
||||||
|
|
||||||
. autoCollapse option hide this._markerLoc before that visualized!!, row 714
|
|
||||||
|
|
||||||
115
bower_components/leaflet-search/Gruntfile.js
vendored
|
|
@ -1,115 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
module.exports = function(grunt) {
|
|
||||||
|
|
||||||
grunt.loadNpmTasks('grunt-contrib-uglify');
|
|
||||||
grunt.loadNpmTasks('grunt-contrib-concat');
|
|
||||||
grunt.loadNpmTasks('grunt-contrib-clean');
|
|
||||||
grunt.loadNpmTasks('grunt-contrib-cssmin');
|
|
||||||
grunt.loadNpmTasks('grunt-contrib-jshint');
|
|
||||||
grunt.loadNpmTasks('grunt-contrib-watch');
|
|
||||||
grunt.loadNpmTasks('grunt-todos');
|
|
||||||
|
|
||||||
grunt.initConfig({
|
|
||||||
pkg: grunt.file.readJSON('package.json'),
|
|
||||||
meta: {
|
|
||||||
banner:
|
|
||||||
'/* \n'+
|
|
||||||
' * Leaflet Search Control v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %> \n'+
|
|
||||||
' * \n'+
|
|
||||||
' * Copyright 2014 <%= pkg.author.name %> \n'+
|
|
||||||
' * <%= pkg.author.email %> \n'+
|
|
||||||
' * <%= pkg.author.url %> \n'+
|
|
||||||
' * \n'+
|
|
||||||
' * Licensed under the <%= pkg.license %> license. \n'+
|
|
||||||
' * \n'+
|
|
||||||
' * Demo: \n'+
|
|
||||||
' * <%= pkg.homepage %> \n'+
|
|
||||||
' * \n'+
|
|
||||||
' * Source: \n'+
|
|
||||||
' * <%= pkg.repository.url %> \n'+
|
|
||||||
' * \n'+
|
|
||||||
' */\n'
|
|
||||||
},
|
|
||||||
clean: {
|
|
||||||
dist: {
|
|
||||||
src: ['dist/*']
|
|
||||||
}
|
|
||||||
},
|
|
||||||
jshint: {
|
|
||||||
options: {
|
|
||||||
globals: {
|
|
||||||
console: true,
|
|
||||||
module: true
|
|
||||||
},
|
|
||||||
"-W099": true, //ignora tabs e space warning
|
|
||||||
"-W033": true,
|
|
||||||
"-W044": true //ignore regexp
|
|
||||||
},
|
|
||||||
files: ['src/*.js']
|
|
||||||
},
|
|
||||||
concat: {
|
|
||||||
//TODO cut out SearchMarker
|
|
||||||
options: {
|
|
||||||
banner: '<%= meta.banner %>'
|
|
||||||
},
|
|
||||||
dist: {
|
|
||||||
files: {
|
|
||||||
'dist/leaflet-search.src.js': ['src/leaflet-search.js'],
|
|
||||||
'dist/leaflet-search.src.css': ['src/leaflet-search.css'],
|
|
||||||
'dist/leaflet-search.mobile.src.css': ['src/leaflet-search.mobile.css']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
uglify: {
|
|
||||||
options: {
|
|
||||||
banner: '<%= meta.banner %>'
|
|
||||||
},
|
|
||||||
dist: {
|
|
||||||
files: {
|
|
||||||
'dist/leaflet-search.min.js': ['dist/leaflet-search.src.js']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
cssmin: {
|
|
||||||
combine: {
|
|
||||||
files: {
|
|
||||||
'dist/leaflet-search.min.css': ['src/leaflet-search.css'],
|
|
||||||
'dist/leaflet-search.mobile.min.css': ['src/leaflet-search.mobile.css']
|
|
||||||
}
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
banner: '<%= meta.banner %>'
|
|
||||||
},
|
|
||||||
minify: {
|
|
||||||
expand: true,
|
|
||||||
cwd: 'dist/',
|
|
||||||
files: {
|
|
||||||
'dist/leaflet-search.min.css': ['src/leaflet-search.css'],
|
|
||||||
'dist/leaflet-search.mobile.min.css': ['src/leaflet-search.mobile.css']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
todos: {
|
|
||||||
options: { verbose: false },
|
|
||||||
TODO: ['src/*.js'],
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
dist: {
|
|
||||||
options: { livereload: true },
|
|
||||||
files: ['src/*'],
|
|
||||||
tasks: ['clean','concat','cssmin','jshint']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
grunt.registerTask('default', [
|
|
||||||
'clean',
|
|
||||||
'concat',
|
|
||||||
'cssmin',
|
|
||||||
'jshint',
|
|
||||||
'uglify',
|
|
||||||
'todos'
|
|
||||||
]);
|
|
||||||
|
|
||||||
};
|
|
||||||
21
bower_components/leaflet-search/LICENSE.txt
vendored
|
|
@ -1,21 +0,0 @@
|
||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2013 Stefano Cudini
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
98
bower_components/leaflet-search/README.md
vendored
|
|
@ -1,98 +0,0 @@
|
||||||
Leaflet.Control.Search
|
|
||||||
============
|
|
||||||
|
|
||||||
A leaflet control that search markers/features location by custom property.<br />
|
|
||||||
With ajax/jsonp autocompletion and JSON fields filter/remap
|
|
||||||
|
|
||||||
Copyright 2014 [Stefano Cudini](http://labs.easyblog.it/stefano-cudini/)
|
|
||||||
|
|
||||||
Tested in Leaflet 0.7.2
|
|
||||||
|
|
||||||
|
|
||||||
#Where
|
|
||||||
|
|
||||||
**Demo online:**
|
|
||||||
[labs.easyblog.it/maps/leaflet-search](http://labs.easyblog.it/maps/leaflet-search/)
|
|
||||||
|
|
||||||
**Source code:**
|
|
||||||
[Github](https://github.com/stefanocudini/leaflet-search)
|
|
||||||
[Bitbucket](https://bitbucket.org/zakis_/leaflet-search)
|
|
||||||
[NPM](https://npmjs.org/package/leaflet-search)
|
|
||||||
[Atmosphere](https://atmosphere.meteor.com/package/leaflet-search)
|
|
||||||
|
|
||||||
#Build
|
|
||||||
|
|
||||||
Since Version 1.4.7 this plugin support [Grunt](http://gruntjs.com/) for building process.
|
|
||||||
Therefore the deployment require [NPM](https://npmjs.org/) installed in your system.
|
|
||||||
After you've made sure to have npm working, run this in command line:
|
|
||||||
```bash
|
|
||||||
npm install
|
|
||||||
grunt
|
|
||||||
```
|
|
||||||
|
|
||||||
#Examples
|
|
||||||
(require src/leaflet-search.css)
|
|
||||||
|
|
||||||
Adding the search control to the map:
|
|
||||||
```javascript
|
|
||||||
map.addControl( new L.Control.Search({layer: searchLayer}) );
|
|
||||||
//searchLayer is a L.LayerGroup contains searched markers
|
|
||||||
```
|
|
||||||
|
|
||||||
Short way:
|
|
||||||
```javascript
|
|
||||||
var map = new L.Map('map', { searchControl: {layer: searchLayer} });
|
|
||||||
```
|
|
||||||
|
|
||||||
#Advanced Examples
|
|
||||||
|
|
||||||
Ajax request to search.php for retrieve elements locations:
|
|
||||||
```javascript
|
|
||||||
map.addControl( new L.Control.Search({url: 'search.php?q={s}'}) );
|
|
||||||
```
|
|
||||||
|
|
||||||
Request to third party JSONP service, implements Geocode Searching using OSM API:
|
|
||||||
```javascript
|
|
||||||
map.addControl( new L.Control.Search({
|
|
||||||
url: 'http://nominatim.openstreetmap.org/search?format=json&q={s}',
|
|
||||||
jsonpParam: 'json_callback',
|
|
||||||
propertyName: 'display_name',
|
|
||||||
propertyLoc: ['lat','lon']
|
|
||||||
}) );
|
|
||||||
```
|
|
||||||
|
|
||||||
Search and color features vector in GeoJSON layer:
|
|
||||||
```javascript
|
|
||||||
var searchControl = new L.Control.Search({layer: geojsonLayer, circleLocation:false});
|
|
||||||
searchControl.on('search_locationfound', function(e) {
|
|
||||||
|
|
||||||
e.layer.setStyle({fillColor: '#3f0'});
|
|
||||||
|
|
||||||
}).on('search_collapsed', function(e) {
|
|
||||||
|
|
||||||
featuresLayer.eachLayer(function(layer) {
|
|
||||||
featuresLayer.resetStyle(layer);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
map.addControl(searchControl);
|
|
||||||
```
|
|
||||||
|
|
||||||
Static data source:
|
|
||||||
```
|
|
||||||
var data = [
|
|
||||||
{"loc":[41.575330,13.102411], "title":"aquamarine"},
|
|
||||||
{"loc":[41.575730,13.002411], "title":"black"},
|
|
||||||
{"loc":[41.219190,13.062145], "title":"cyan"}
|
|
||||||
];
|
|
||||||
|
|
||||||
map.addControl(new L.Control.Search({
|
|
||||||
markerLocation: true,
|
|
||||||
callData: function(text, callResponse) {
|
|
||||||
|
|
||||||
//here can use custom criteria or merge data from multiple layers
|
|
||||||
|
|
||||||
callResponse(data);
|
|
||||||
}
|
|
||||||
}) );
|
|
||||||
```
|
|
||||||
|
|
||||||
59
bower_components/leaflet-search/TODO
vendored
|
|
@ -1,59 +0,0 @@
|
||||||
Tasks found in: src/leaflet-search.js
|
|
||||||
[Line: 22] [low] //TODO important! implements uniq option 'sourceData' that recognizes source type: url,array,callback or layer
|
|
||||||
[Line: 23] [low] //TODO implement can do research on multiple sources
|
|
||||||
[Line: 38] [low] //TODO add option for persist markerLoc after collapse!
|
|
||||||
[Line: 48] [low] //TODO add option collapsed, like control.layers
|
|
||||||
[Line: 53] [low] //TODO important optimization!!! always append data in this._recordsCache
|
|
||||||
[Line: 57] [low] //TODO here insert function that search inputText FIRST in _recordsCache keys and if not find results..
|
|
||||||
[Line: 60] [low] //TODO change structure of _recordsCache
|
|
||||||
[Line: 342] [low] //TODO add option for case sesitive search, also showLocation
|
|
||||||
[Line: 345] [low] //TODO use .filter or .map
|
|
||||||
[Line: 407] [low] //TODO throw new Error("propertyName '"+propName+"' not found in JSON data");
|
|
||||||
[Line: 412] [low] //TODO remove script node after call run
|
|
||||||
[Line: 421] [low] //TODO add rnd param or randomize callback name! in recordsFromJsonp
|
|
||||||
[Line: 441] [low] //TODO add rnd param or randomize callback name! in recordsFromAjax
|
|
||||||
[Line: 504] [low] //TODO implements autype without selection(useful for mobile device)
|
|
||||||
[Line: 604] [low] //TODO important optimization!!! always append data in this._recordsCache
|
|
||||||
[Line: 608] [low] //TODO here insert function that search inputText FIRST in _recordsCache keys and if not find results..
|
|
||||||
[Line: 611] [low] //TODO change structure of _recordsCache
|
|
||||||
[Line: 662] [low] //TODO refact _handleAutoresize now is not accurate
|
|
||||||
[Line: 758] [low] //TODO showLocation: start animation after setView or panTo, maybe with map.on('moveend')...
|
|
||||||
[Line: 779] [low] //TODO add custom icon!
|
|
||||||
[Line: 787] [low] //TODO add inner circle
|
|
||||||
[Line: 843] [low] //TODO refact animate() more smooth! like this: http://goo.gl/DDlRs
|
|
||||||
[Line: 865] [low] //TODO use create event 'animateEnd' in SearchMarker
|
|
||||||
[Line: 50] [med] //FIXME option condition problem {autoCollapse: true, markerLocation: true} not show location
|
|
||||||
[Line: 51] [med] //FIXME option condition problem {autoCollapse: false }
|
|
||||||
[Line: 358] [med] //FIXME problem with jsonp/ajax when remote filter has different behavior of this._filterRecords
|
|
||||||
[Line: 731] [med] //FIXME if collapse in _handleSubmit hide _markerLoc!
|
|
||||||
[Line: 761] [med] //FIXME autoCollapse option hide this._markerLoc before that visualized!!
|
|
||||||
Tasks found in: src/leaflet-search_collapsed.js
|
|
||||||
[Line: 22] [low] //TODO important! implements uniq option 'sourceData' that recognizes source type: url,array,callback or layer
|
|
||||||
[Line: 23] [low] //TODO implement can do research on multiple sources
|
|
||||||
[Line: 37] [low] //TODO add option for persist markerLoc after collapse!
|
|
||||||
[Line: 47] [low] //TODO add option collapsed, like control.layers
|
|
||||||
[Line: 52] [low] //TODO important optimization!!! always append data in this._recordsCache
|
|
||||||
[Line: 56] [low] //TODO here insert function that search inputText FIRST in _recordsCache keys and if not find results..
|
|
||||||
[Line: 59] [low] //TODO change structure of _recordsCache
|
|
||||||
[Line: 87] [low] // TODO: touch
|
|
||||||
[Line: 358] [low] //TODO add option for case sesitive search, also showLocation
|
|
||||||
[Line: 361] [low] //TODO use .filter or .map
|
|
||||||
[Line: 423] [low] //TODO throw new Error("propertyName '"+propName+"' not found in JSON data");
|
|
||||||
[Line: 428] [low] //TODO remove script node after call run
|
|
||||||
[Line: 437] [low] //TODO add rnd param or randomize callback name! in recordsFromJsonp
|
|
||||||
[Line: 457] [low] //TODO add rnd param or randomize callback name! in recordsFromAjax
|
|
||||||
[Line: 520] [low] //TODO implements autype without selection(useful for mobile device)
|
|
||||||
[Line: 620] [low] //TODO important optimization!!! always append data in this._recordsCache
|
|
||||||
[Line: 624] [low] //TODO here insert function that search inputText FIRST in _recordsCache keys and if not find results..
|
|
||||||
[Line: 627] [low] //TODO change structure of _recordsCache
|
|
||||||
[Line: 678] [low] //TODO refact _handleAutoresize now is not accurate
|
|
||||||
[Line: 774] [low] //TODO showLocation: start animation after setView or panTo, maybe with map.on('moveend')...
|
|
||||||
[Line: 795] [low] //TODO add custom icon!
|
|
||||||
[Line: 803] [low] //TODO add inner circle
|
|
||||||
[Line: 859] [low] //TODO refact animate() more smooth! like this: http://goo.gl/DDlRs
|
|
||||||
[Line: 881] [low] //TODO use create event 'animateEnd' in SearchMarker
|
|
||||||
[Line: 49] [med] //FIXME option condition problem {autoCollapse: true, markerLocation: true} not show location
|
|
||||||
[Line: 50] [med] //FIXME option condition problem {autoCollapse: false }
|
|
||||||
[Line: 374] [med] //FIXME problem with jsonp/ajax when remote filter has different behavior of this._filterRecords
|
|
||||||
[Line: 747] [med] //FIXME if collapse in _handleSubmit hide _markerLoc!
|
|
||||||
[Line: 777] [med] //FIXME autoCollapse option hide this._markerLoc before that visualized!!
|
|
||||||
12
bower_components/leaflet-search/bower.json
vendored
|
|
@ -1,12 +0,0 @@
|
||||||
{
|
|
||||||
"name": "leaflet-search",
|
|
||||||
"version": "1.5.1",
|
|
||||||
"main": "leaflet-search.js",
|
|
||||||
"ignore": [
|
|
||||||
"**/.*",
|
|
||||||
"node_modules",
|
|
||||||
"components",
|
|
||||||
"bower_components",
|
|
||||||
"examples"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
/*
|
|
||||||
* Leaflet Search Control v1.5.1 - 2014-05-12
|
|
||||||
*
|
|
||||||
* Copyright 2014 Stefano Cudini
|
|
||||||
* stefano.cudini@gmail.com
|
|
||||||
* http://labs.easyblog.it/
|
|
||||||
*
|
|
||||||
* Licensed under the MIT license.
|
|
||||||
*
|
|
||||||
* Demo:
|
|
||||||
* http://labs.easyblog.it/maps/leaflet-search/
|
|
||||||
*
|
|
||||||
* Source:
|
|
||||||
* git@github.com:stefanocudini/leaflet-search.git
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
.leaflet-container .leaflet-control-search{position:relative;float:left;background:#fff;color:#1978cf;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;background-color:rgba(255,255,255,.8);z-index:1000;box-shadow:0 1px 7px rgba(0,0,0,.65);margin-left:10px;margin-top:10px}.leaflet-control-search.search-exp{box-shadow:0 1px 7px #999;background:#fff}.leaflet-control-search .search-input{display:block;float:left;background:#fff;border:1px solid #666;border-radius:2px;height:18px;padding:0 18px 0 2px;margin:3px 0 3px 3px}.leaflet-control-search.search-load .search-input{background:url(../images/loader.gif) no-repeat center right #fff}.leaflet-control-search.search-load .search-cancel{visibility:hidden}.leaflet-control-search .search-cancel{display:block;width:22px;height:18px;position:absolute;right:22px;margin:3px 0;background:url(../images/search-icon.png) no-repeat 0 -46px;text-decoration:none;filter:alpha(opacity=80);opacity:.8}.leaflet-control-search .search-cancel:hover{filter:alpha(opacity=100);opacity:1}.leaflet-control-search .search-cancel span{display:none;font-size:18px;line-height:20px;color:#ccc;font-weight:700}.leaflet-control-search .search-cancel:hover span{color:#aaa}.leaflet-control-search .search-button{display:block;float:left;width:26px;height:26px;background:url(../images/search-icon.png) no-repeat 2px 2px;border-radius:4px}.leaflet-control-search .search-button:hover{background:url(../images/search-icon.png) no-repeat 2px -22px}.leaflet-control-search .search-tooltip{position:absolute;top:100%;left:0;float:left;min-width:80px;max-height:106px;box-shadow:0 0 8px rgba(0,0,0,.4);-webkit-border-radius:5px;-webkit-border-top-left-radius:0;-moz-border-radius:5px;-moz-border-radius-topleft:0;border-radius:5px;border-top-left-radius:0;background-color:rgba(0,0,0,.25);z-index:1010;overflow-y:auto;overflow-x:hidden}.leaflet-control-search .search-tip{margin:2px;padding:2px;display:block;color:#000;background:#ddd;border-radius:.25em;text-decoration:none;white-space:nowrap;font-size:.85em;vertical-align:center}.leaflet-control-search .search-button:hover,.leaflet-control-search .search-tip-select,.leaflet-control-search .search-tip:hover{background-color:#fff}.leaflet-control-search .search-alert{cursor:pointer;clear:both;font-size:.75em;margin-bottom:5px;padding:0 .25em;color:#e00;font-weight:700;border-radius:.25em}
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
/*
|
|
||||||
* Leaflet Search Control v1.5.1 - 2014-05-12
|
|
||||||
*
|
|
||||||
* Copyright 2014 Stefano Cudini
|
|
||||||
* stefano.cudini@gmail.com
|
|
||||||
* http://labs.easyblog.it/
|
|
||||||
*
|
|
||||||
* Licensed under the MIT license.
|
|
||||||
*
|
|
||||||
* Demo:
|
|
||||||
* http://labs.easyblog.it/maps/leaflet-search/
|
|
||||||
*
|
|
||||||
* Source:
|
|
||||||
* git@github.com:stefanocudini/leaflet-search.git
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
.leaflet-control.leaflet-control-search{z-index:2000}.leaflet-control-search .search-input{display:block;float:left;background:#fff;border:1px solid #666;border-radius:2px;height:24px;font-size:1.25em;padding:0 .125em;margin:3px;padding-right:30px}.leaflet-control-search .search-button,.leaflet-control-search .search-button:hover{background-image:url(../images/search-icon-mobile.png);-webkit-border-radius:4px;border-radius:4px;background-position:1px 1px;width:32px;height:32px}.leaflet-control-search.search-load .search-input{background:url(../images/loader.gif) no-repeat center right #fff}.leaflet-control-search .search-cancel{background-image:url(../images/search-icon-mobile.png);-webkit-border-radius:4px;border-radius:4px;background-position:0 -62px;width:26px;height:26px;right:34px;margin:3px}.leaflet-control-search .search-tooltip{max-height:142px}.leaflet-control-search .search-tip{font-size:1em;margin:2px;padding:2px;display:block;color:#000;background:rgba(255,255,255,.8);border-radius:.25em;text-decoration:none;white-space:nowrap;vertical-align:center}.leaflet-control-search .search-tip .climbo-icon-mini{float:right;display:block;white-space:nowrap}.leaflet-control-search .search-button:hover,.leaflet-control-search .search-tip-select,.leaflet-control-search .search-tip:hover{background-color:#fff}.leaflet-control-search .search-alert{font-size:1.2em}
|
|
||||||
|
|
@ -1,83 +0,0 @@
|
||||||
/*
|
|
||||||
* Leaflet Search Control v1.5.1 - 2014-05-12
|
|
||||||
*
|
|
||||||
* Copyright 2014 Stefano Cudini
|
|
||||||
* stefano.cudini@gmail.com
|
|
||||||
* http://labs.easyblog.it/
|
|
||||||
*
|
|
||||||
* Licensed under the MIT license.
|
|
||||||
*
|
|
||||||
* Demo:
|
|
||||||
* http://labs.easyblog.it/maps/leaflet-search/
|
|
||||||
*
|
|
||||||
* Source:
|
|
||||||
* git@github.com:stefanocudini/leaflet-search.git
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* SEARCH */
|
|
||||||
.leaflet-control.leaflet-control-search {
|
|
||||||
z-index:2000;
|
|
||||||
}
|
|
||||||
.leaflet-control-search .search-input {
|
|
||||||
display:block;
|
|
||||||
float:left;
|
|
||||||
background: #fff;
|
|
||||||
border:1px solid #666;
|
|
||||||
border-radius:2px;
|
|
||||||
height:24px;
|
|
||||||
font-size:1.25em;
|
|
||||||
padding:0 .125em;
|
|
||||||
margin:3px;
|
|
||||||
padding-right:30px;
|
|
||||||
}
|
|
||||||
.leaflet-control-search .search-button:hover,
|
|
||||||
.leaflet-control-search .search-button {
|
|
||||||
background-image: url('../images/search-icon-mobile.png');
|
|
||||||
-webkit-border-radius: 4px;
|
|
||||||
border-radius: 4px;
|
|
||||||
background-position: 1px 1px;
|
|
||||||
width:32px;
|
|
||||||
height:32px;
|
|
||||||
}
|
|
||||||
.leaflet-control-search.search-load .search-input {
|
|
||||||
background: url('../images/loader.gif') no-repeat center right #fff;
|
|
||||||
}
|
|
||||||
.leaflet-control-search .search-cancel {
|
|
||||||
background-image: url('../images/search-icon-mobile.png');
|
|
||||||
-webkit-border-radius: 4px;
|
|
||||||
border-radius: 4px;
|
|
||||||
background-position: 0px -62px;
|
|
||||||
width:26px;
|
|
||||||
height:26px;
|
|
||||||
right:34px;
|
|
||||||
margin:3px;
|
|
||||||
}
|
|
||||||
.leaflet-control-search .search-tooltip {
|
|
||||||
max-height:142px;/*(.search-tip height * 5)*/
|
|
||||||
}
|
|
||||||
.leaflet-control-search .search-tip {
|
|
||||||
font-size:1em;
|
|
||||||
margin:2px;
|
|
||||||
padding:2px;
|
|
||||||
display:block;
|
|
||||||
color:black;
|
|
||||||
background: rgba(255,255,255,0.8);
|
|
||||||
border-radius:.25em;
|
|
||||||
text-decoration:none;
|
|
||||||
white-space:nowrap;
|
|
||||||
vertical-align:center;
|
|
||||||
}
|
|
||||||
.leaflet-control-search .search-tip .climbo-icon-mini {
|
|
||||||
float:right;
|
|
||||||
display:block;
|
|
||||||
white-space:nowrap;
|
|
||||||
}
|
|
||||||
.leaflet-control-search .search-button:hover,
|
|
||||||
.leaflet-control-search .search-tip-select,
|
|
||||||
.leaflet-control-search .search-tip:hover {
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
.leaflet-control-search .search-alert {
|
|
||||||
font-size:1.2em;
|
|
||||||
}
|
|
||||||
|
|
@ -1,137 +0,0 @@
|
||||||
/*
|
|
||||||
* Leaflet Search Control v1.5.1 - 2014-05-12
|
|
||||||
*
|
|
||||||
* Copyright 2014 Stefano Cudini
|
|
||||||
* stefano.cudini@gmail.com
|
|
||||||
* http://labs.easyblog.it/
|
|
||||||
*
|
|
||||||
* Licensed under the MIT license.
|
|
||||||
*
|
|
||||||
* Demo:
|
|
||||||
* http://labs.easyblog.it/maps/leaflet-search/
|
|
||||||
*
|
|
||||||
* Source:
|
|
||||||
* git@github.com:stefanocudini/leaflet-search.git
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
.leaflet-container .leaflet-control-search {
|
|
||||||
position:relative;
|
|
||||||
float:left;
|
|
||||||
background:#fff;
|
|
||||||
color:#1978cf;
|
|
||||||
-moz-border-radius: 4px;
|
|
||||||
-webkit-border-radius: 4px;
|
|
||||||
border-radius: 4px;
|
|
||||||
background-color: rgba(255, 255, 255, 0.8);
|
|
||||||
z-index:1000;
|
|
||||||
box-shadow: 0 1px 7px rgba(0,0,0,0.65);
|
|
||||||
margin-left: 10px;
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
.leaflet-control-search.search-exp {/*expanded*/
|
|
||||||
box-shadow: 0 1px 7px #999;
|
|
||||||
background: #fff;
|
|
||||||
}
|
|
||||||
.leaflet-control-search .search-input {
|
|
||||||
display:block;
|
|
||||||
float:left;
|
|
||||||
background: #fff;
|
|
||||||
border:1px solid #666;
|
|
||||||
border-radius:2px;
|
|
||||||
height:18px;
|
|
||||||
padding:0 18px 0 2px;
|
|
||||||
margin:3px 0 3px 3px;
|
|
||||||
}
|
|
||||||
.leaflet-control-search.search-load .search-input {
|
|
||||||
background: url('../images/loader.gif') no-repeat center right #fff;
|
|
||||||
}
|
|
||||||
.leaflet-control-search.search-load .search-cancel {
|
|
||||||
visibility:hidden;
|
|
||||||
}
|
|
||||||
.leaflet-control-search .search-cancel {
|
|
||||||
display:block;
|
|
||||||
width:22px;
|
|
||||||
height:18px;
|
|
||||||
position:absolute;
|
|
||||||
right:22px;
|
|
||||||
margin:3px 0;
|
|
||||||
background: url('../images/search-icon.png') no-repeat 0 -46px;
|
|
||||||
text-decoration:none;
|
|
||||||
filter: alpha(opacity=80);
|
|
||||||
opacity: 0.8;
|
|
||||||
}
|
|
||||||
.leaflet-control-search .search-cancel:hover {
|
|
||||||
filter: alpha(opacity=100);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
.leaflet-control-search .search-cancel span {
|
|
||||||
display:none;/* comment for cancel button imageless */
|
|
||||||
font-size:18px;
|
|
||||||
line-height:20px;
|
|
||||||
color:#ccc;
|
|
||||||
font-weight:bold;
|
|
||||||
}
|
|
||||||
.leaflet-control-search .search-cancel:hover span {
|
|
||||||
color:#aaa;
|
|
||||||
}
|
|
||||||
.leaflet-control-search .search-button {
|
|
||||||
display:block;
|
|
||||||
float:left;
|
|
||||||
width:26px;
|
|
||||||
height:26px;
|
|
||||||
background: url('../images/search-icon.png') no-repeat 2px 2px;
|
|
||||||
border-radius:4px;
|
|
||||||
}
|
|
||||||
.leaflet-control-search .search-button:hover {
|
|
||||||
background: url('../images/search-icon.png') no-repeat 2px -22px;
|
|
||||||
}
|
|
||||||
.leaflet-control-search .search-tooltip {
|
|
||||||
position:absolute;
|
|
||||||
top:100%;
|
|
||||||
left:0;
|
|
||||||
float:left;
|
|
||||||
min-width:80px;
|
|
||||||
max-height:106px;/*(.search-tip height * 5)*/
|
|
||||||
box-shadow: 0 0 8px rgba(0,0,0,0.4);
|
|
||||||
-webkit-border-radius: 5px;
|
|
||||||
-webkit-border-top-left-radius: 0;
|
|
||||||
-moz-border-radius: 5px;
|
|
||||||
-moz-border-radius-topleft: 0;
|
|
||||||
border-radius: 5px;
|
|
||||||
border-top-left-radius: 0;
|
|
||||||
background-color: rgba(0, 0, 0, 0.25);
|
|
||||||
z-index:1010;
|
|
||||||
overflow-y:auto;
|
|
||||||
overflow-x:hidden;
|
|
||||||
}
|
|
||||||
.leaflet-control-search .search-tip {
|
|
||||||
font-size:.85em;
|
|
||||||
margin:2px;
|
|
||||||
padding:2px;
|
|
||||||
display:block;
|
|
||||||
color:black;
|
|
||||||
background: #ddd;
|
|
||||||
border-radius:.25em;
|
|
||||||
text-decoration:none;
|
|
||||||
white-space:nowrap;
|
|
||||||
font-size:.85em;
|
|
||||||
vertical-align:center;
|
|
||||||
}
|
|
||||||
.leaflet-control-search .search-tip-select,
|
|
||||||
.leaflet-control-search .search-tip:hover,
|
|
||||||
.leaflet-control-search .search-button:hover {
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
.leaflet-control-search .search-alert {
|
|
||||||
cursor:pointer;
|
|
||||||
clear:both;
|
|
||||||
font-size:.75em;
|
|
||||||
margin-bottom:5px;
|
|
||||||
padding:0 .25em;
|
|
||||||
color:#e00;
|
|
||||||
font-weight:bold;
|
|
||||||
border-radius:.25em;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,901 +0,0 @@
|
||||||
/*
|
|
||||||
* Leaflet Search Control v1.5.1 - 2014-05-12
|
|
||||||
*
|
|
||||||
* Copyright 2014 Stefano Cudini
|
|
||||||
* stefano.cudini@gmail.com
|
|
||||||
* http://labs.easyblog.it/
|
|
||||||
*
|
|
||||||
* Licensed under the MIT license.
|
|
||||||
*
|
|
||||||
* Demo:
|
|
||||||
* http://labs.easyblog.it/maps/leaflet-search/
|
|
||||||
*
|
|
||||||
* Source:
|
|
||||||
* git@github.com:stefanocudini/leaflet-search.git
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
(function() {
|
|
||||||
|
|
||||||
L.Control.Search = L.Control.extend({
|
|
||||||
includes: L.Mixin.Events,
|
|
||||||
//
|
|
||||||
// Name Data passed Description
|
|
||||||
//
|
|
||||||
//Managed Events:
|
|
||||||
// search_locationfound {latlng, title, layer} fired after moved and show markerLocation
|
|
||||||
// search_collapsed {} fired after control was collapsed
|
|
||||||
//
|
|
||||||
//Public methods:
|
|
||||||
// setLayer() L.LayerGroup() set layer search at runtime
|
|
||||||
// showAlert() 'Text message' Show alert message
|
|
||||||
//
|
|
||||||
options: {
|
|
||||||
wrapper: '', //container id to insert Search Control
|
|
||||||
url: '', //url for search by ajax request, ex: "search.php?q={s}"
|
|
||||||
jsonpParam: null, //jsonp param name for search by jsonp service, ex: "callback"
|
|
||||||
layer: null, //layer where search markers(is a L.LayerGroup)
|
|
||||||
callData: null, //function that fill _recordsCache, passed searching text by first param and callback in second
|
|
||||||
//TODO important! implements uniq option 'sourceData' that recognizes source type: url,array,callback or layer
|
|
||||||
//TODO implement can do research on multiple sources
|
|
||||||
propertyName: 'title', //property in marker.options(or feature.properties for vector layer) trough filter elements in layer,
|
|
||||||
propertyLoc: 'loc', //field for remapping location, using array: ['latname','lonname'] for select double fields(ex. ['lat','lon'] )
|
|
||||||
// support dotted format: 'prop.subprop.title'
|
|
||||||
callTip: null, //function that return row tip html node(or html string), receive text tooltip in first param
|
|
||||||
filterJSON: null, //callback for filtering data to _recordsCache
|
|
||||||
minLength: 1, //minimal text length for autocomplete
|
|
||||||
initial: true, //search elements only by initial text
|
|
||||||
autoType: true, //complete input with first suggested result and select this filled-in text.
|
|
||||||
delayType: 400, //delay while typing for show tooltip
|
|
||||||
tooltipLimit: -1, //limit max results to show in tooltip. -1 for no limit.
|
|
||||||
tipAutoSubmit: true, //auto map panTo when click on tooltip
|
|
||||||
autoResize: true, //autoresize on input change
|
|
||||||
collapsed: true, //collapse search control at startup
|
|
||||||
autoCollapse: false, //collapse search control after submit(on button or on tips if enabled tipAutoSubmit)
|
|
||||||
//TODO add option for persist markerLoc after collapse!
|
|
||||||
autoCollapseTime: 1200, //delay for autoclosing alert and collapse after blur
|
|
||||||
animateLocation: true, //animate a circle over location found
|
|
||||||
circleLocation: true, //draw a circle in location found
|
|
||||||
markerLocation: false, //draw a marker in location found
|
|
||||||
zoom: null, //zoom after pan to location found, default: map.getZoom()
|
|
||||||
text: 'Search...', //placeholder value
|
|
||||||
textCancel: 'Cancel', //title in cancel button
|
|
||||||
textErr: 'Location not found', //error message
|
|
||||||
position: 'topleft'
|
|
||||||
//TODO add option collapsed, like control.layers
|
|
||||||
},
|
|
||||||
//FIXME option condition problem {autoCollapse: true, markerLocation: true} not show location
|
|
||||||
//FIXME option condition problem {autoCollapse: false }
|
|
||||||
//
|
|
||||||
//TODO important optimization!!! always append data in this._recordsCache
|
|
||||||
// now _recordsCache content is emptied and replaced with new data founded
|
|
||||||
// always appending data on _recordsCache give the possibility of caching ajax, jsonp and layersearch!
|
|
||||||
//
|
|
||||||
//TODO here insert function that search inputText FIRST in _recordsCache keys and if not find results..
|
|
||||||
// run one of callbacks search(callData,jsonpUrl or options.layer) and run this.showTooltip
|
|
||||||
//
|
|
||||||
//TODO change structure of _recordsCache
|
|
||||||
// like this: _recordsCache = {"text-key1": {loc:[lat,lng], ..other attributes.. }, {"text-key2": {loc:[lat,lng]}...}, ...}
|
|
||||||
// in this mode every record can have a free structure of attributes, only 'loc' is required
|
|
||||||
|
|
||||||
initialize: function(options) {
|
|
||||||
L.Util.setOptions(this, options || {});
|
|
||||||
this._inputMinSize = this.options.text ? this.options.text.length : 10;
|
|
||||||
this._layer = this.options.layer || new L.LayerGroup();
|
|
||||||
this._filterJSON = this.options.filterJSON || this._defaultFilterJSON;
|
|
||||||
this._autoTypeTmp = this.options.autoType; //useful for disable autoType temporarily in delete/backspace keydown
|
|
||||||
this._countertips = 0; //number of tips items
|
|
||||||
this._recordsCache = {}; //key,value table! that store locations! format: key,latlng
|
|
||||||
},
|
|
||||||
|
|
||||||
onAdd: function (map) {
|
|
||||||
this._map = map;
|
|
||||||
this._container = L.DomUtil.create('div', 'leaflet-control-search');
|
|
||||||
this._input = this._createInput(this.options.text, 'search-input');
|
|
||||||
this._tooltip = this._createTooltip('search-tooltip');
|
|
||||||
this._cancel = this._createCancel(this.options.textCancel, 'search-cancel');
|
|
||||||
this._button = this._createButton(this.options.text, 'search-button');
|
|
||||||
this._alert = this._createAlert('search-alert');
|
|
||||||
|
|
||||||
if(this.options.collapsed===false)
|
|
||||||
this.expand();
|
|
||||||
|
|
||||||
if(this.options.circleLocation || this.options.markerLocation)
|
|
||||||
this._markerLoc = new SearchMarker([0,0], {marker: this.options.markerLocation});//see below
|
|
||||||
|
|
||||||
this.setLayer( this._layer );
|
|
||||||
map.on({
|
|
||||||
// 'layeradd': this._onLayerAddRemove,
|
|
||||||
// 'layerremove': this._onLayerAddRemove
|
|
||||||
'resize': this._handleAutoresize
|
|
||||||
}, this);
|
|
||||||
return this._container;
|
|
||||||
},
|
|
||||||
addTo: function (map) {
|
|
||||||
|
|
||||||
if(this.options.wrapper) {
|
|
||||||
this._container = this.onAdd(map);
|
|
||||||
this._wrapper = L.DomUtil.get(this.options.wrapper);
|
|
||||||
this._wrapper.style.position = 'relative';
|
|
||||||
this._wrapper.appendChild(this._container);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
L.Control.prototype.addTo.call(this, map);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
onRemove: function(map) {
|
|
||||||
this._recordsCache = {};
|
|
||||||
// map.off({
|
|
||||||
// 'layeradd': this._onLayerAddRemove,
|
|
||||||
// 'layerremove': this._onLayerAddRemove
|
|
||||||
// }, this);
|
|
||||||
},
|
|
||||||
|
|
||||||
// _onLayerAddRemove: function(e) {
|
|
||||||
// //console.info('_onLayerAddRemove');
|
|
||||||
// //without this, run setLayer also for each Markers!! to optimize!
|
|
||||||
// if(e.layer instanceof L.LayerGroup)
|
|
||||||
// if( L.stamp(e.layer) != L.stamp(this._layer) )
|
|
||||||
// this.setLayer(e.layer);
|
|
||||||
// },
|
|
||||||
|
|
||||||
_getPath: function(obj, prop) {
|
|
||||||
var parts = prop.split('.'),
|
|
||||||
last = parts.pop(),
|
|
||||||
len = parts.length,
|
|
||||||
cur = parts[0],
|
|
||||||
i = 1;
|
|
||||||
|
|
||||||
if(len > 0)
|
|
||||||
while((obj = obj[cur]) && i < len)
|
|
||||||
cur = parts[i++];
|
|
||||||
|
|
||||||
if(obj)
|
|
||||||
return obj[last];
|
|
||||||
},
|
|
||||||
|
|
||||||
setLayer: function(layer) { //set search layer at runtime
|
|
||||||
//this.options.layer = layer; //setting this, run only this._recordsFromLayer()
|
|
||||||
this._layer = layer;
|
|
||||||
this._layer.addTo(this._map);
|
|
||||||
if(this._markerLoc)
|
|
||||||
this._layer.addLayer(this._markerLoc);
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
showAlert: function(text) {
|
|
||||||
text = text || this.options.textErr;
|
|
||||||
this._alert.style.display = 'block';
|
|
||||||
this._alert.innerHTML = text;
|
|
||||||
clearTimeout(this.timerAlert);
|
|
||||||
var that = this;
|
|
||||||
this.timerAlert = setTimeout(function() {
|
|
||||||
that.hideAlert();
|
|
||||||
},this.options.autoCollapseTime);
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
hideAlert: function() {
|
|
||||||
this._alert.style.display = 'none';
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
cancel: function() {
|
|
||||||
this._input.value = '';
|
|
||||||
this._handleKeypress({keyCode:8});//simulate backspace keypress
|
|
||||||
this._input.size = this._inputMinSize;
|
|
||||||
this._input.focus();
|
|
||||||
this._cancel.style.display = 'none';
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
expand: function() {
|
|
||||||
this._input.style.display = 'block';
|
|
||||||
L.DomUtil.addClass(this._container, 'search-exp');
|
|
||||||
this._input.focus();
|
|
||||||
this._map.on('dragstart', this.collapse, this);
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
collapse: function() {
|
|
||||||
this._hideTooltip();
|
|
||||||
this.cancel();
|
|
||||||
this._alert.style.display = 'none';
|
|
||||||
this._input.blur();
|
|
||||||
if(this.options.collapsed)
|
|
||||||
{
|
|
||||||
this._input.style.display = 'none';
|
|
||||||
this._cancel.style.display = 'none';
|
|
||||||
L.DomUtil.removeClass(this._container, 'search-exp');
|
|
||||||
//this._markerLoc.hide();//maybe unuseful
|
|
||||||
this._map.off('dragstart', this.collapse, this);
|
|
||||||
}
|
|
||||||
this.fire('search_collapsed');
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
collapseDelayed: function() { //collapse after delay, used on_input blur
|
|
||||||
if (!this.options.autoCollapse) return this;
|
|
||||||
var that = this;
|
|
||||||
clearTimeout(this.timerCollapse);
|
|
||||||
this.timerCollapse = setTimeout(function() {
|
|
||||||
that.collapse();
|
|
||||||
}, this.options.autoCollapseTime);
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
collapseDelayedStop: function() {
|
|
||||||
clearTimeout(this.timerCollapse);
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
////start DOM creations
|
|
||||||
_createAlert: function(className) {
|
|
||||||
var alert = L.DomUtil.create('div', className, this._container);
|
|
||||||
alert.style.display = 'none';
|
|
||||||
|
|
||||||
L.DomEvent
|
|
||||||
.on(alert, 'click', L.DomEvent.stop, this)
|
|
||||||
.on(alert, 'click', this.hideAlert, this);
|
|
||||||
|
|
||||||
return alert;
|
|
||||||
},
|
|
||||||
|
|
||||||
_createInput: function (text, className) {
|
|
||||||
var input = L.DomUtil.create('input', className, this._container);
|
|
||||||
input.type = 'text';
|
|
||||||
input.size = this._inputMinSize;
|
|
||||||
input.value = '';
|
|
||||||
input.autocomplete = 'off';
|
|
||||||
input.placeholder = text;
|
|
||||||
input.style.display = 'none';
|
|
||||||
|
|
||||||
L.DomEvent
|
|
||||||
.disableClickPropagation(input)
|
|
||||||
.on(input, 'keyup', this._handleKeypress, this)
|
|
||||||
.on(input, 'keydown', this._handleAutoresize, this)
|
|
||||||
.on(input, 'blur', this.collapseDelayed, this)
|
|
||||||
.on(input, 'focus', this.collapseDelayedStop, this);
|
|
||||||
|
|
||||||
return input;
|
|
||||||
},
|
|
||||||
|
|
||||||
_createCancel: function (title, className) {
|
|
||||||
var cancel = L.DomUtil.create('a', className, this._container);
|
|
||||||
cancel.href = '#';
|
|
||||||
cancel.title = title;
|
|
||||||
cancel.style.display = 'none';
|
|
||||||
cancel.innerHTML = "<span>⊗</span>";//imageless(see css)
|
|
||||||
|
|
||||||
L.DomEvent
|
|
||||||
.on(cancel, 'click', L.DomEvent.stop, this)
|
|
||||||
.on(cancel, 'click', this.cancel, this);
|
|
||||||
|
|
||||||
return cancel;
|
|
||||||
},
|
|
||||||
|
|
||||||
_createButton: function (title, className) {
|
|
||||||
var button = L.DomUtil.create('a', className, this._container);
|
|
||||||
button.href = '#';
|
|
||||||
button.title = title;
|
|
||||||
|
|
||||||
L.DomEvent
|
|
||||||
.on(button, 'click', L.DomEvent.stop, this)
|
|
||||||
.on(button, 'click', this._handleSubmit, this)
|
|
||||||
.on(button, 'focus', this.collapseDelayedStop, this)
|
|
||||||
.on(button, 'blur', this.collapseDelayed, this);
|
|
||||||
|
|
||||||
return button;
|
|
||||||
},
|
|
||||||
|
|
||||||
_createTooltip: function(className) {
|
|
||||||
var tool = L.DomUtil.create('div', className, this._container);
|
|
||||||
tool.style.display = 'none';
|
|
||||||
|
|
||||||
var that = this;
|
|
||||||
L.DomEvent
|
|
||||||
.disableClickPropagation(tool)
|
|
||||||
.on(tool, 'blur', this.collapseDelayed, this)
|
|
||||||
.on(tool, 'mousewheel', function(e) {
|
|
||||||
that.collapseDelayedStop();
|
|
||||||
L.DomEvent.stopPropagation(e);//disable zoom map
|
|
||||||
}, this)
|
|
||||||
.on(tool, 'mouseover', function(e) {
|
|
||||||
that.collapseDelayedStop();
|
|
||||||
}, this);
|
|
||||||
return tool;
|
|
||||||
},
|
|
||||||
|
|
||||||
_createTip: function(text, val) {//val is object in recordCache, usually is Latlng
|
|
||||||
var tip;
|
|
||||||
|
|
||||||
if(this.options.callTip)
|
|
||||||
{
|
|
||||||
tip = this.options.callTip(text,val); //custom tip node or html string
|
|
||||||
if(typeof tip === 'string')
|
|
||||||
{
|
|
||||||
var tmpNode = L.DomUtil.create('div');
|
|
||||||
tmpNode.innerHTML = tip;
|
|
||||||
tip = tmpNode.firstChild;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tip = L.DomUtil.create('a', '');
|
|
||||||
tip.href = '#';
|
|
||||||
tip.innerHTML = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
L.DomUtil.addClass(tip, 'search-tip');
|
|
||||||
tip._text = text; //value replaced in this._input and used by _autoType
|
|
||||||
|
|
||||||
L.DomEvent
|
|
||||||
.disableClickPropagation(tip)
|
|
||||||
.on(tip, 'click', L.DomEvent.stop, this)
|
|
||||||
.on(tip, 'click', function(e) {
|
|
||||||
this._input.value = text;
|
|
||||||
this._handleAutoresize();
|
|
||||||
this._input.focus();
|
|
||||||
this._hideTooltip();
|
|
||||||
if(this.options.tipAutoSubmit)//go to location at once
|
|
||||||
this._handleSubmit();
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
return tip;
|
|
||||||
},
|
|
||||||
|
|
||||||
//////end DOM creations
|
|
||||||
|
|
||||||
_filterRecords: function(text) { //Filter this._recordsCache case insensitive and much more..
|
|
||||||
|
|
||||||
var regFilter = new RegExp("^[.]$|[\[\]|()*]",'g'), //remove . * | ( ) ] [
|
|
||||||
I, regSearch,
|
|
||||||
frecords = {};
|
|
||||||
|
|
||||||
text = text.replace(regFilter,''); //sanitize text
|
|
||||||
I = this.options.initial ? '^' : ''; //search only initial text
|
|
||||||
//TODO add option for case sesitive search, also showLocation
|
|
||||||
regSearch = new RegExp(I + text,'i');
|
|
||||||
|
|
||||||
//TODO use .filter or .map
|
|
||||||
for(var key in this._recordsCache)
|
|
||||||
if( regSearch.test(key) )
|
|
||||||
frecords[key]= this._recordsCache[key];
|
|
||||||
|
|
||||||
return frecords;
|
|
||||||
},
|
|
||||||
|
|
||||||
showTooltip: function() {
|
|
||||||
var filteredRecords, newTip;
|
|
||||||
|
|
||||||
this._countertips = 0;
|
|
||||||
|
|
||||||
//FIXME problem with jsonp/ajax when remote filter has different behavior of this._filterRecords
|
|
||||||
if(this.options.layer)
|
|
||||||
filteredRecords = this._filterRecords( this._input.value );
|
|
||||||
else
|
|
||||||
filteredRecords = this._recordsCache;
|
|
||||||
|
|
||||||
this._tooltip.innerHTML = '';
|
|
||||||
this._tooltip.currentSelection = -1; //inizialized for _handleArrowSelect()
|
|
||||||
|
|
||||||
for(var key in filteredRecords)//fill tooltip
|
|
||||||
{
|
|
||||||
if(++this._countertips == this.options.tooltipLimit) break;
|
|
||||||
|
|
||||||
newTip = this._createTip(key, filteredRecords[key] );
|
|
||||||
|
|
||||||
this._tooltip.appendChild(newTip);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(this._countertips > 0)
|
|
||||||
{
|
|
||||||
this._tooltip.style.display = 'block';
|
|
||||||
if(this._autoTypeTmp)
|
|
||||||
this._autoType();
|
|
||||||
this._autoTypeTmp = this.options.autoType;//reset default value
|
|
||||||
}
|
|
||||||
else
|
|
||||||
this._hideTooltip();
|
|
||||||
|
|
||||||
this._tooltip.scrollTop = 0;
|
|
||||||
return this._countertips;
|
|
||||||
},
|
|
||||||
|
|
||||||
_hideTooltip: function() {
|
|
||||||
this._tooltip.style.display = 'none';
|
|
||||||
this._tooltip.innerHTML = '';
|
|
||||||
return 0;
|
|
||||||
},
|
|
||||||
|
|
||||||
_defaultFilterJSON: function(json) { //default callback for filter data
|
|
||||||
var jsonret = {}, i,
|
|
||||||
propName = this.options.propertyName,
|
|
||||||
propLoc = this.options.propertyLoc;
|
|
||||||
|
|
||||||
if( L.Util.isArray(propLoc) )
|
|
||||||
for(i in json)
|
|
||||||
jsonret[ this._getPath(json[i],propName) ]= L.latLng( json[i][ propLoc[0] ], json[i][ propLoc[1] ] );
|
|
||||||
else
|
|
||||||
for(i in json)
|
|
||||||
jsonret[ this._getPath(json[i],propName) ]= L.latLng( this._getPath(json[i],propLoc) );
|
|
||||||
//TODO throw new Error("propertyName '"+propName+"' not found in JSON data");
|
|
||||||
return jsonret;
|
|
||||||
},
|
|
||||||
|
|
||||||
_recordsFromJsonp: function(text, callAfter) { //extract searched records from remote jsonp service
|
|
||||||
//TODO remove script node after call run
|
|
||||||
var that = this;
|
|
||||||
L.Control.Search.callJsonp = function(data) { //jsonp callback
|
|
||||||
var fdata = that._filterJSON(data);//_filterJSON defined in inizialize...
|
|
||||||
callAfter(fdata);
|
|
||||||
}
|
|
||||||
var script = L.DomUtil.create('script','search-jsonp', document.getElementsByTagName('body')[0] ),
|
|
||||||
url = L.Util.template(this.options.url+'&'+this.options.jsonpParam+'=L.Control.Search.callJsonp', {s: text}); //parsing url
|
|
||||||
//rnd = '&_='+Math.floor(Math.random()*10000);
|
|
||||||
//TODO add rnd param or randomize callback name! in recordsFromJsonp
|
|
||||||
script.type = 'text/javascript';
|
|
||||||
script.src = url;
|
|
||||||
return this;
|
|
||||||
//may be return {abort: function() { script.parentNode.removeChild(script); } };
|
|
||||||
},
|
|
||||||
|
|
||||||
_recordsFromAjax: function(text, callAfter) { //Ajax request
|
|
||||||
if (window.XMLHttpRequest === undefined) {
|
|
||||||
window.XMLHttpRequest = function() {
|
|
||||||
try { return new ActiveXObject("Microsoft.XMLHTTP.6.0"); }
|
|
||||||
catch (e1) {
|
|
||||||
try { return new ActiveXObject("Microsoft.XMLHTTP.3.0"); }
|
|
||||||
catch (e2) { throw new Error("XMLHttpRequest is not supported"); }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
var request = new XMLHttpRequest(),
|
|
||||||
url = L.Util.template(this.options.url, {s: text}), //parsing url
|
|
||||||
//rnd = '&_='+Math.floor(Math.random()*10000);
|
|
||||||
//TODO add rnd param or randomize callback name! in recordsFromAjax
|
|
||||||
response = {};
|
|
||||||
|
|
||||||
request.open("GET", url);
|
|
||||||
var that = this;
|
|
||||||
request.onreadystatechange = function() {
|
|
||||||
if(request.readyState === 4 && request.status === 200) {
|
|
||||||
response = JSON.parse(request.responseText);
|
|
||||||
var fdata = that._filterJSON(response);//_filterJSON defined in inizialize...
|
|
||||||
callAfter(fdata);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
request.send();
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
_recordsFromLayer: function() { //return table: key,value from layer
|
|
||||||
var that = this,
|
|
||||||
retRecords = {},
|
|
||||||
propName = this.options.propertyName,
|
|
||||||
loc;
|
|
||||||
|
|
||||||
this._layer.eachLayer(function(layer) {
|
|
||||||
|
|
||||||
if(layer instanceof SearchMarker) return;
|
|
||||||
|
|
||||||
if(layer instanceof L.Marker)
|
|
||||||
{
|
|
||||||
if(that._getPath(layer.options,propName))
|
|
||||||
{
|
|
||||||
loc = layer.getLatLng();
|
|
||||||
loc.layer = layer;
|
|
||||||
retRecords[ that._getPath(layer.options,propName) ] = loc;
|
|
||||||
|
|
||||||
}else if(that._getPath(layer.feature.properties,propName)){
|
|
||||||
|
|
||||||
loc = layer.getLatLng();
|
|
||||||
loc.layer = layer;
|
|
||||||
retRecords[ that._getPath(layer.feature.properties,propName) ] = loc;
|
|
||||||
|
|
||||||
}else{
|
|
||||||
console.log("propertyName '"+propName+"' not found in marker", layer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(layer.hasOwnProperty('feature'))//GeoJSON layer
|
|
||||||
{
|
|
||||||
if(layer.feature.properties.hasOwnProperty(propName))
|
|
||||||
{
|
|
||||||
loc = layer.getBounds().getCenter();
|
|
||||||
loc.layer = layer;
|
|
||||||
retRecords[ layer.feature.properties[propName] ] = loc;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
console.log("propertyName '"+propName+"' not found in feature", layer);
|
|
||||||
}
|
|
||||||
|
|
||||||
},this);
|
|
||||||
|
|
||||||
return retRecords;
|
|
||||||
},
|
|
||||||
|
|
||||||
_autoType: function() {
|
|
||||||
|
|
||||||
//TODO implements autype without selection(useful for mobile device)
|
|
||||||
|
|
||||||
var start = this._input.value.length,
|
|
||||||
firstRecord = this._tooltip.firstChild._text,
|
|
||||||
end = firstRecord.length;
|
|
||||||
|
|
||||||
if (firstRecord.indexOf(this._input.value) === 0) { // If prefix match
|
|
||||||
this._input.value = firstRecord;
|
|
||||||
this._handleAutoresize();
|
|
||||||
|
|
||||||
if (this._input.createTextRange) {
|
|
||||||
var selRange = this._input.createTextRange();
|
|
||||||
selRange.collapse(true);
|
|
||||||
selRange.moveStart('character', start);
|
|
||||||
selRange.moveEnd('character', end);
|
|
||||||
selRange.select();
|
|
||||||
}
|
|
||||||
else if(this._input.setSelectionRange) {
|
|
||||||
this._input.setSelectionRange(start, end);
|
|
||||||
}
|
|
||||||
else if(this._input.selectionStart) {
|
|
||||||
this._input.selectionStart = start;
|
|
||||||
this._input.selectionEnd = end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_hideAutoType: function() { // deselect text:
|
|
||||||
|
|
||||||
var sel;
|
|
||||||
if ((sel = this._input.selection) && sel.empty) {
|
|
||||||
sel.empty();
|
|
||||||
}
|
|
||||||
else if (this._input.createTextRange) {
|
|
||||||
sel = this._input.createTextRange();
|
|
||||||
sel.collapse(true);
|
|
||||||
var end = this._input.value.length;
|
|
||||||
sel.moveStart('character', end);
|
|
||||||
sel.moveEnd('character', end);
|
|
||||||
sel.select();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (this._input.getSelection) {
|
|
||||||
this._input.getSelection().removeAllRanges();
|
|
||||||
}
|
|
||||||
this._input.selectionStart = this._input.selectionEnd;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_handleKeypress: function (e) { //run _input keyup event
|
|
||||||
|
|
||||||
switch(e.keyCode)
|
|
||||||
{
|
|
||||||
case 27: //Esc
|
|
||||||
this.collapse();
|
|
||||||
break;
|
|
||||||
case 13: //Enter
|
|
||||||
if(this._countertips == 1)
|
|
||||||
this._handleArrowSelect(1);
|
|
||||||
this._handleSubmit(); //do search
|
|
||||||
break;
|
|
||||||
case 38://Up
|
|
||||||
this._handleArrowSelect(-1);
|
|
||||||
break;
|
|
||||||
case 40://Down
|
|
||||||
this._handleArrowSelect(1);
|
|
||||||
break;
|
|
||||||
case 37://Left
|
|
||||||
case 39://Right
|
|
||||||
case 16://Shift
|
|
||||||
case 17://Ctrl
|
|
||||||
//case 32://Space
|
|
||||||
break;
|
|
||||||
case 8://backspace
|
|
||||||
case 46://delete
|
|
||||||
this._autoTypeTmp = false;//disable temporarily autoType
|
|
||||||
break;
|
|
||||||
default://All keys
|
|
||||||
|
|
||||||
if(this._input.value.length)
|
|
||||||
this._cancel.style.display = 'block';
|
|
||||||
else
|
|
||||||
this._cancel.style.display = 'none';
|
|
||||||
|
|
||||||
if(this._input.value.length >= this.options.minLength)
|
|
||||||
{
|
|
||||||
var that = this;
|
|
||||||
clearTimeout(this.timerKeypress); //cancel last search request while type in
|
|
||||||
this.timerKeypress = setTimeout(function() { //delay before request, for limit jsonp/ajax request
|
|
||||||
|
|
||||||
that._fillRecordsCache();
|
|
||||||
|
|
||||||
}, this.options.delayType);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
this._hideTooltip();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_fillRecordsCache: function() {
|
|
||||||
//TODO important optimization!!! always append data in this._recordsCache
|
|
||||||
// now _recordsCache content is emptied and replaced with new data founded
|
|
||||||
// always appending data on _recordsCache give the possibility of caching ajax, jsonp and layersearch!
|
|
||||||
//
|
|
||||||
//TODO here insert function that search inputText FIRST in _recordsCache keys and if not find results..
|
|
||||||
// run one of callbacks search(callData,jsonpUrl or options.layer) and run this.showTooltip
|
|
||||||
//
|
|
||||||
//TODO change structure of _recordsCache
|
|
||||||
// like this: _recordsCache = {"text-key1": {loc:[lat,lng], ..other attributes.. }, {"text-key2": {loc:[lat,lng]}...}, ...}
|
|
||||||
// in this mode every record can have a free structure of attributes, only 'loc' is required
|
|
||||||
|
|
||||||
var inputText = this._input.value,
|
|
||||||
that;
|
|
||||||
|
|
||||||
L.DomUtil.addClass(this._container, 'search-load');
|
|
||||||
|
|
||||||
if(this.options.callData) //CUSTOM SEARCH CALLBACK
|
|
||||||
{
|
|
||||||
that = this;
|
|
||||||
this.options.callData(inputText, function(jsonraw) {
|
|
||||||
|
|
||||||
that._recordsCache = that._filterJSON(jsonraw);
|
|
||||||
|
|
||||||
that.showTooltip();
|
|
||||||
|
|
||||||
L.DomUtil.removeClass(that._container, 'search-load');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else if(this.options.url) //JSONP/AJAX REQUEST
|
|
||||||
{
|
|
||||||
if(this.options.jsonpParam)
|
|
||||||
{
|
|
||||||
that = this;
|
|
||||||
this._recordsFromJsonp(inputText, function(data) {// is async request then it need callback
|
|
||||||
that._recordsCache = data;
|
|
||||||
that.showTooltip();
|
|
||||||
L.DomUtil.removeClass(that._container, 'search-load');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
that = this;
|
|
||||||
this._recordsFromAjax(inputText, function(data) {// is async request then it need callback
|
|
||||||
that._recordsCache = data;
|
|
||||||
that.showTooltip();
|
|
||||||
L.DomUtil.removeClass(that._container, 'search-load');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(this.options.layer) //SEARCH ELEMENTS IN PRELOADED LAYER
|
|
||||||
{
|
|
||||||
this._recordsCache = this._recordsFromLayer(); //fill table key,value from markers into layer
|
|
||||||
this.showTooltip();
|
|
||||||
L.DomUtil.removeClass(this._container, 'search-load');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_handleAutoresize: function() { //autoresize this._input
|
|
||||||
//TODO refact _handleAutoresize now is not accurate
|
|
||||||
if (this._input.style.maxWidth != this._map._container.offsetWidth) //If maxWidth isn't the same as when first set, reset to current Map width
|
|
||||||
this._input.style.maxWidth = L.DomUtil.getStyle(this._map._container, 'width');
|
|
||||||
|
|
||||||
if(this.options.autoResize && (this._container.offsetWidth + 45 < this._map._container.offsetWidth))
|
|
||||||
this._input.size = this._input.value.length<this._inputMinSize ? this._inputMinSize : this._input.value.length;
|
|
||||||
},
|
|
||||||
|
|
||||||
_handleArrowSelect: function(velocity) {
|
|
||||||
|
|
||||||
var searchTips = this._tooltip.hasChildNodes() ? this._tooltip.childNodes : [];
|
|
||||||
|
|
||||||
for (i=0; i<searchTips.length; i++)
|
|
||||||
L.DomUtil.removeClass(searchTips[i], 'search-tip-select');
|
|
||||||
|
|
||||||
if ((velocity == 1 ) && (this._tooltip.currentSelection >= (searchTips.length - 1))) {// If at end of list.
|
|
||||||
L.DomUtil.addClass(searchTips[this._tooltip.currentSelection], 'search-tip-select');
|
|
||||||
}
|
|
||||||
else if ((velocity == -1 ) && (this._tooltip.currentSelection <= 0)) { // Going back up to the search box.
|
|
||||||
this._tooltip.currentSelection = -1;
|
|
||||||
}
|
|
||||||
else if (this._tooltip.style.display != 'none') { // regular up/down
|
|
||||||
this._tooltip.currentSelection += velocity;
|
|
||||||
|
|
||||||
L.DomUtil.addClass(searchTips[this._tooltip.currentSelection], 'search-tip-select');
|
|
||||||
|
|
||||||
this._input.value = searchTips[this._tooltip.currentSelection]._text;
|
|
||||||
|
|
||||||
// scroll:
|
|
||||||
var tipOffsetTop = searchTips[this._tooltip.currentSelection].offsetTop;
|
|
||||||
|
|
||||||
if (tipOffsetTop + searchTips[this._tooltip.currentSelection].clientHeight >= this._tooltip.scrollTop + this._tooltip.clientHeight) {
|
|
||||||
this._tooltip.scrollTop = tipOffsetTop - this._tooltip.clientHeight + searchTips[this._tooltip.currentSelection].clientHeight;
|
|
||||||
}
|
|
||||||
else if (tipOffsetTop <= this._tooltip.scrollTop) {
|
|
||||||
this._tooltip.scrollTop = tipOffsetTop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_handleSubmit: function() { //button and tooltip click and enter submit
|
|
||||||
|
|
||||||
this._hideAutoType();
|
|
||||||
|
|
||||||
this.hideAlert();
|
|
||||||
this._hideTooltip();
|
|
||||||
|
|
||||||
if(this._input.style.display == 'none') //on first click show _input only
|
|
||||||
this.expand();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(this._input.value === '') //hide _input only
|
|
||||||
this.collapse();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var loc = this._getLocation(this._input.value);
|
|
||||||
|
|
||||||
if(loc===false)
|
|
||||||
this.showAlert();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.showLocation(loc, this._input.value);
|
|
||||||
this.fire('search_locationfound', {
|
|
||||||
latlng: loc,
|
|
||||||
text: this._input.value,
|
|
||||||
layer: loc.layer ? loc.layer : null
|
|
||||||
});
|
|
||||||
}
|
|
||||||
//this.collapse();
|
|
||||||
//FIXME if collapse in _handleSubmit hide _markerLoc!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_getLocation: function(key) { //extract latlng from _recordsCache
|
|
||||||
|
|
||||||
if( this._recordsCache.hasOwnProperty(key) )
|
|
||||||
return this._recordsCache[key];//then after use .loc attribute
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
showLocation: function(latlng, title) { //set location on map from _recordsCache
|
|
||||||
|
|
||||||
if(this.options.zoom)
|
|
||||||
this._map.setView(latlng, this.options.zoom);
|
|
||||||
else
|
|
||||||
this._map.panTo(latlng);
|
|
||||||
|
|
||||||
if(this._markerLoc)
|
|
||||||
{
|
|
||||||
this._markerLoc.setLatLng(latlng); //show circle/marker in location found
|
|
||||||
this._markerLoc.setTitle(title);
|
|
||||||
this._markerLoc.show();
|
|
||||||
if(this.options.animateLocation)
|
|
||||||
this._markerLoc.animate();
|
|
||||||
//TODO showLocation: start animation after setView or panTo, maybe with map.on('moveend')...
|
|
||||||
}
|
|
||||||
|
|
||||||
//FIXME autoCollapse option hide this._markerLoc before that visualized!!
|
|
||||||
if(this.options.autoCollapse)
|
|
||||||
this.collapse();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var SearchMarker = L.Marker.extend({
|
|
||||||
|
|
||||||
includes: L.Mixin.Events,
|
|
||||||
|
|
||||||
options: {
|
|
||||||
radius: 10,
|
|
||||||
weight: 3,
|
|
||||||
color: '#e03',
|
|
||||||
stroke: true,
|
|
||||||
fill: false,
|
|
||||||
title: '',
|
|
||||||
//TODO add custom icon!
|
|
||||||
marker: false //show icon optional, show only circleLoc
|
|
||||||
},
|
|
||||||
|
|
||||||
initialize: function (latlng, options) {
|
|
||||||
L.setOptions(this, options);
|
|
||||||
L.Marker.prototype.initialize.call(this, latlng, options);
|
|
||||||
this._circleLoc = new L.CircleMarker(latlng, this.options);
|
|
||||||
//TODO add inner circle
|
|
||||||
},
|
|
||||||
|
|
||||||
onAdd: function (map) {
|
|
||||||
L.Marker.prototype.onAdd.call(this, map);
|
|
||||||
map.addLayer(this._circleLoc);
|
|
||||||
this.hide();
|
|
||||||
},
|
|
||||||
|
|
||||||
onRemove: function (map) {
|
|
||||||
L.Marker.prototype.onRemove.call(this, map);
|
|
||||||
map.removeLayer(this._circleLoc);
|
|
||||||
},
|
|
||||||
|
|
||||||
setLatLng: function (latlng) {
|
|
||||||
L.Marker.prototype.setLatLng.call(this, latlng);
|
|
||||||
this._circleLoc.setLatLng(latlng);
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
setTitle: function(title) {
|
|
||||||
title = title || '';
|
|
||||||
this.options.title = title;
|
|
||||||
if(this._icon)
|
|
||||||
this._icon.title = title;
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
show: function() {
|
|
||||||
if(this.options.marker)
|
|
||||||
{
|
|
||||||
if(this._icon)
|
|
||||||
this._icon.style.display = 'block';
|
|
||||||
if(this._shadow)
|
|
||||||
this._shadow.style.display = 'block';
|
|
||||||
//this._bringToFront();
|
|
||||||
}
|
|
||||||
if(this._circleLoc)
|
|
||||||
{
|
|
||||||
this._circleLoc.setStyle({fill: this.options.fill, stroke: this.options.stroke});
|
|
||||||
//this._circleLoc.bringToFront();
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
hide: function() {
|
|
||||||
if(this._icon)
|
|
||||||
this._icon.style.display = 'none';
|
|
||||||
if(this._shadow)
|
|
||||||
this._shadow.style.display = 'none';
|
|
||||||
if(this._circleLoc)
|
|
||||||
this._circleLoc.setStyle({fill: false, stroke: false});
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
animate: function() {
|
|
||||||
//TODO refact animate() more smooth! like this: http://goo.gl/DDlRs
|
|
||||||
var circle = this._circleLoc,
|
|
||||||
tInt = 200, //time interval
|
|
||||||
ss = 10, //frames
|
|
||||||
mr = parseInt(circle._radius/ss),
|
|
||||||
oldrad = this.options.radius,
|
|
||||||
newrad = circle._radius * 2.5,
|
|
||||||
acc = 0;
|
|
||||||
|
|
||||||
circle._timerAnimLoc = setInterval(function() {
|
|
||||||
acc += 0.5;
|
|
||||||
mr += acc; //adding acceleration
|
|
||||||
newrad -= mr;
|
|
||||||
|
|
||||||
circle.setRadius(newrad);
|
|
||||||
|
|
||||||
if(newrad<oldrad)
|
|
||||||
{
|
|
||||||
clearInterval(circle._timerAnimLoc);
|
|
||||||
circle.setRadius(oldrad);//reset radius
|
|
||||||
//if(typeof afterAnimCall == 'function')
|
|
||||||
//afterAnimCall();
|
|
||||||
//TODO use create event 'animateEnd' in SearchMarker
|
|
||||||
}
|
|
||||||
}, tInt);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
L.Map.addInitHook(function () {
|
|
||||||
if (this.options.searchControl) {
|
|
||||||
this.searchControl = L.control.search(this.options.searchControl);
|
|
||||||
this.addControl(this.searchControl);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
L.control.search = function (options) {
|
|
||||||
return new L.Control.Search(options);
|
|
||||||
};
|
|
||||||
|
|
||||||
}).call(this);
|
|
||||||
|
|
||||||
104
bower_components/leaflet-search/index.html
vendored
|
|
@ -1,104 +0,0 @@
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
||||||
<head>
|
|
||||||
<title>Leaflet.Control.Search</title>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
||||||
<link rel="stylesheet" href="style.css" />
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body id="home">
|
|
||||||
|
|
||||||
<h2>Leaflet.Control.Search</h2>
|
|
||||||
|
|
||||||
<div id="desc">
|
|
||||||
A Leaflet Control for search markers/features location by attribute<br />
|
|
||||||
and much more.
|
|
||||||
<div style="position:absolute;top:0;right:-120px">
|
|
||||||
<iframe src="http://ghbtns.com/github-btn.html?user=stefanocudini&repo=leaflet-search&type=watch&count=true" allowtransparency="true" frameborder="0" scrolling="0" width="104px" height="20px"></iframe>
|
|
||||||
</div>
|
|
||||||
<br />
|
|
||||||
Other useful stuff for <a href="http://labs.easyblog.it/maps/">Web Mapping...</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style="clear:both"></div>
|
|
||||||
|
|
||||||
<div class="contents">
|
|
||||||
<h4>Features</h4>
|
|
||||||
<ul id="ff">
|
|
||||||
<li>Autocomplete</li>
|
|
||||||
<li>No require external Ajax libs</li>
|
|
||||||
<li>Retrieve data locations by Ajax/Jsonp</li>
|
|
||||||
<li>Pre-filtering data from Ajax/Jsonp</li>
|
|
||||||
<li>Complete fields remapping for remote Jsonp service</li>
|
|
||||||
<li>Data source callback support</li>
|
|
||||||
<li>Localization placeholder and text alert</li>
|
|
||||||
<li>Autozoom on location founded</li>
|
|
||||||
<li>Autoresize textbox</li>
|
|
||||||
<li>Customize tooltip menu</li>
|
|
||||||
<li>Many options to customize the behavior</li>
|
|
||||||
<li>Support search in features collection</li>
|
|
||||||
<li>Render Search Box Outside the Leaflet Map</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="contents">
|
|
||||||
<h4>Examples</h4>
|
|
||||||
<ul id="examples">
|
|
||||||
<li><a href="examples/simple.html">Simple</a></li>
|
|
||||||
<li><a href="examples/outside.html">Outside the Map</a></li>
|
|
||||||
<li><a href="examples/geojson-layer.html">GeoJSON features</a></li>
|
|
||||||
<li><a href="examples/ajax.html">Ajax</a></li>
|
|
||||||
<li><a href="examples/jsonp.html">Jsonp</a></li>
|
|
||||||
<li><a href="examples/ajax-jquery.html">Ajax by jQuery</a></li>
|
|
||||||
<li><a href="examples/calldata.html">Static data</a></li>
|
|
||||||
<li><a href="examples/jsonp-filtered.html">Jsonp Filtered</a></li>
|
|
||||||
<li><a href="examples/ajax-bulk.html">Bulk data</a></li>
|
|
||||||
<li><a href="examples/custom-tip.html">Custom Tip Item</a></li>
|
|
||||||
<li><a href="examples/google-geocoding.html">GeoCode Search - Google Geocoding API</a></li>
|
|
||||||
<li><a href="examples/nominatim.html">GeoCode Search - OSM Nominatim API</a></li>
|
|
||||||
<li><a href="examples/cloudmade.html">GeoCode Search - Cloudmade API</a></li>
|
|
||||||
<li><a href="examples/mobile.html">Mobile styled</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="contents">
|
|
||||||
<h4>Code repositories</h4>
|
|
||||||
<a target="_blank" href="https://github.com/stefanocudini/leaflet-search">Github.com</a>
|
|
||||||
<br />
|
|
||||||
<a target="_blank" href="https://bitbucket.org/zakis_/leaflet-search">Bitbucket.org</a>
|
|
||||||
<br />
|
|
||||||
<a target="_blank" href="https://npmjs.org/package/leaflet-search">Node Packaged Module</a>
|
|
||||||
<br />
|
|
||||||
<a target="_blank" href="https://atmosphere.meteor.com/package/leaflet-search">Atmosphere Meteor JS</a>
|
|
||||||
<br />
|
|
||||||
|
|
||||||
<h4>Website</h4>
|
|
||||||
<a href="http://labs.easyblog.it/maps/leaflet-search/">labs.easyblog.it/maps/leaflet-search</a>
|
|
||||||
<br />
|
|
||||||
|
|
||||||
<h4>Download</h4>
|
|
||||||
<ul>
|
|
||||||
<li><a href="https://github.com/stefanocudini/leaflet-search/archive/master.zip">Dev Pack (.zip)</a></li>
|
|
||||||
<li><a href="dist/leaflet-search.src.js">Source Code (.js)</a></li>
|
|
||||||
<li><a href="dist/leaflet-search.min.js">Compressed (.min.js)</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="copy"><a href="http://labs.easyblog.it/">Labs</a> • <a rel="author" href="http://labs.easyblog.it/stefano-cudini/">Stefano Cudini</a></div>
|
|
||||||
|
|
||||||
<a href="https://github.com/stefanocudini/leaflet-search"><img id="ribbon" src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub"></a>
|
|
||||||
|
|
||||||
<div style="clear:both;font-size:.85em;margin-bottom:1em">
|
|
||||||
<b>For questions and bugs</b> I recommend you to <a href="https://github.com/stefanocudini/leaflet-search/issues">create New Issue</a> on Github repository.</strong><br />
|
|
||||||
Or to obtain a fast response consult <a href="https://groups.google.com/forum/?hl=it&fromgroups=#!forum/leaflet-js">Official Leaflet community forum</a>.<br />
|
|
||||||
<br />
|
|
||||||
This is a micro discussion area for methods of implementation.<br />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="comments">
|
|
||||||
<div id="disqus_thread"></div>
|
|
||||||
</div>
|
|
||||||
<script>var disqus_shortname = 'easyblog-it'</script>
|
|
||||||
|
|
||||||
<script type="text/javascript" src="/labs-common.js"></script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
11
bower_components/leaflet-search/package.js
vendored
|
|
@ -1,11 +0,0 @@
|
||||||
Package.describe({
|
|
||||||
summary: "Leaflet Control Search"
|
|
||||||
});
|
|
||||||
|
|
||||||
Package.on_use(function (api, where) {
|
|
||||||
api.add_files('dist/leaflet-search.min.js', 'client');
|
|
||||||
api.add_files('dist/leaflet-search.min.css', 'client');
|
|
||||||
api.add_files('images/search-icon.png', 'client');
|
|
||||||
api.add_files('images/loader.gif', 'client');
|
|
||||||
//TODO server-side searching...
|
|
||||||
});
|
|
||||||
35
bower_components/leaflet-search/package.json
vendored
|
|
@ -1,35 +0,0 @@
|
||||||
{
|
|
||||||
"name": "leaflet-search",
|
|
||||||
"version": "1.5.1",
|
|
||||||
"description": "Leaflet Control for searching markers/features by attribute on map or remote searching in jsonp/ajax",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git@github.com:stefanocudini/leaflet-search.git"
|
|
||||||
},
|
|
||||||
"homepage": "http://labs.easyblog.it/maps/leaflet-search/",
|
|
||||||
"author": {
|
|
||||||
"name": "Stefano Cudini",
|
|
||||||
"email": "stefano.cudini@gmail.com",
|
|
||||||
"url": "http://labs.easyblog.it/"
|
|
||||||
},
|
|
||||||
"license": "MIT",
|
|
||||||
"keywords": [
|
|
||||||
"gis",
|
|
||||||
"map",
|
|
||||||
"leaflet"
|
|
||||||
],
|
|
||||||
"dependencies": {
|
|
||||||
"leaflet": "*"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"grunt": "~0.4.2",
|
|
||||||
"grunt-cli": "~0.1.11",
|
|
||||||
"grunt-contrib-uglify": "~0.2.7",
|
|
||||||
"grunt-contrib-concat": "~0.3.0",
|
|
||||||
"grunt-contrib-clean": "~0.5.0",
|
|
||||||
"grunt-contrib-cssmin": "~0.7.0",
|
|
||||||
"grunt-contrib-jshint": "~0.7.2",
|
|
||||||
"grunt-contrib-watch": "~0.5.3",
|
|
||||||
"grunt-todos": "~0.2.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
8
bower_components/leaflet-search/smart.json
vendored
|
|
@ -1,8 +0,0 @@
|
||||||
{
|
|
||||||
"name": "leaflet-search",
|
|
||||||
"description": "Leaflet Control for searching markers/features by attribute on map or remote searching in jsonp/ajax",
|
|
||||||
"homepage": "http://labs.easyblog.it/maps/leaflet-search/",
|
|
||||||
"author": "Stefano Cudini <stefano.cudini@gmail.com>",
|
|
||||||
"version": "1.5.1",
|
|
||||||
"git": "https://github.com/stefanocudini/leaflet-search.git"
|
|
||||||
}
|
|
||||||
|
|
@ -1,121 +0,0 @@
|
||||||
|
|
||||||
.leaflet-container .leaflet-control-search {
|
|
||||||
position:relative;
|
|
||||||
float:left;
|
|
||||||
background:#fff;
|
|
||||||
color:#1978cf;
|
|
||||||
-moz-border-radius: 4px;
|
|
||||||
-webkit-border-radius: 4px;
|
|
||||||
border-radius: 4px;
|
|
||||||
background-color: rgba(255, 255, 255, 0.8);
|
|
||||||
z-index:1000;
|
|
||||||
box-shadow: 0 1px 7px rgba(0,0,0,0.65);
|
|
||||||
margin-left: 10px;
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
.leaflet-control-search.search-exp {/*expanded*/
|
|
||||||
box-shadow: 0 1px 7px #999;
|
|
||||||
background: #fff;
|
|
||||||
}
|
|
||||||
.leaflet-control-search .search-input {
|
|
||||||
display:block;
|
|
||||||
float:left;
|
|
||||||
background: #fff;
|
|
||||||
border:1px solid #666;
|
|
||||||
border-radius:2px;
|
|
||||||
height:18px;
|
|
||||||
padding:0 18px 0 2px;
|
|
||||||
margin:3px 0 3px 3px;
|
|
||||||
}
|
|
||||||
.leaflet-control-search.search-load .search-input {
|
|
||||||
background: url('../images/loader.gif') no-repeat center right #fff;
|
|
||||||
}
|
|
||||||
.leaflet-control-search.search-load .search-cancel {
|
|
||||||
visibility:hidden;
|
|
||||||
}
|
|
||||||
.leaflet-control-search .search-cancel {
|
|
||||||
display:block;
|
|
||||||
width:22px;
|
|
||||||
height:18px;
|
|
||||||
position:absolute;
|
|
||||||
right:22px;
|
|
||||||
margin:3px 0;
|
|
||||||
background: url('../images/search-icon.png') no-repeat 0 -46px;
|
|
||||||
text-decoration:none;
|
|
||||||
filter: alpha(opacity=80);
|
|
||||||
opacity: 0.8;
|
|
||||||
}
|
|
||||||
.leaflet-control-search .search-cancel:hover {
|
|
||||||
filter: alpha(opacity=100);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
.leaflet-control-search .search-cancel span {
|
|
||||||
display:none;/* comment for cancel button imageless */
|
|
||||||
font-size:18px;
|
|
||||||
line-height:20px;
|
|
||||||
color:#ccc;
|
|
||||||
font-weight:bold;
|
|
||||||
}
|
|
||||||
.leaflet-control-search .search-cancel:hover span {
|
|
||||||
color:#aaa;
|
|
||||||
}
|
|
||||||
.leaflet-control-search .search-button {
|
|
||||||
display:block;
|
|
||||||
float:left;
|
|
||||||
width:26px;
|
|
||||||
height:26px;
|
|
||||||
background: url('../images/search-icon.png') no-repeat 2px 2px;
|
|
||||||
border-radius:4px;
|
|
||||||
}
|
|
||||||
.leaflet-control-search .search-button:hover {
|
|
||||||
background: url('../images/search-icon.png') no-repeat 2px -22px;
|
|
||||||
}
|
|
||||||
.leaflet-control-search .search-tooltip {
|
|
||||||
position:absolute;
|
|
||||||
top:100%;
|
|
||||||
left:0;
|
|
||||||
float:left;
|
|
||||||
min-width:80px;
|
|
||||||
max-height:106px;/*(.search-tip height * 5)*/
|
|
||||||
box-shadow: 0 0 8px rgba(0,0,0,0.4);
|
|
||||||
-webkit-border-radius: 5px;
|
|
||||||
-webkit-border-top-left-radius: 0;
|
|
||||||
-moz-border-radius: 5px;
|
|
||||||
-moz-border-radius-topleft: 0;
|
|
||||||
border-radius: 5px;
|
|
||||||
border-top-left-radius: 0;
|
|
||||||
background-color: rgba(0, 0, 0, 0.25);
|
|
||||||
z-index:1010;
|
|
||||||
overflow-y:auto;
|
|
||||||
overflow-x:hidden;
|
|
||||||
}
|
|
||||||
.leaflet-control-search .search-tip {
|
|
||||||
font-size:.85em;
|
|
||||||
margin:2px;
|
|
||||||
padding:2px;
|
|
||||||
display:block;
|
|
||||||
color:black;
|
|
||||||
background: #ddd;
|
|
||||||
border-radius:.25em;
|
|
||||||
text-decoration:none;
|
|
||||||
white-space:nowrap;
|
|
||||||
font-size:.85em;
|
|
||||||
vertical-align:center;
|
|
||||||
}
|
|
||||||
.leaflet-control-search .search-tip-select,
|
|
||||||
.leaflet-control-search .search-tip:hover,
|
|
||||||
.leaflet-control-search .search-button:hover {
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
.leaflet-control-search .search-alert {
|
|
||||||
cursor:pointer;
|
|
||||||
clear:both;
|
|
||||||
font-size:.75em;
|
|
||||||
margin-bottom:5px;
|
|
||||||
padding:0 .25em;
|
|
||||||
color:#e00;
|
|
||||||
font-weight:bold;
|
|
||||||
border-radius:.25em;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||