├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── app.css
├── app.js
├── examples
├── load-geojson.html
├── load-waypoints.html
├── osm.html
├── route.geojson
└── styling.html
├── images
├── promo.gif
└── promo.png
├── index.html
├── libs
└── leaflet
│ ├── images
│ ├── layers.png
│ ├── marker-icon.png
│ ├── marker-icon@2x.png
│ └── marker-shadow.png
│ ├── leaflet.css
│ ├── leaflet.ie.css
│ └── leaflet.js
└── src
├── L.Routing.Draw.js
├── L.Routing.Edit.js
├── L.Routing.Storage.js
├── L.Routing.js
└── utils
├── LineUtil.Snapping.js
├── Marker.Snapping.js
└── Polyline.Snapping.js
/.gitignore:
--------------------------------------------------------------------------------
1 | *.swp
2 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | Changelog
2 | =========
3 |
4 | ### 0.2.0 (Unreadlesed)
5 |
6 | **Features**
7 |
8 | * Add option for overriding draw shortcuts (#23)
9 | * Add option for disabling drawing marker (#18)
10 | * Add options for tooltips (waypoint, segment)
11 | * Disable shortcuts by setting `options.shortcut` to `false`.
12 | * Add support for loading GeoJSON without waypoints (#16).
13 | * Add option to #loadGeoJSON() to disable map fit bounds.
14 | * Add [OSM demo](http://turistforeningen.github.io/leaflet-routing/examples/osm.html)
15 | * …as well as countless updates to the readme and code readability.
16 |
17 | **Breaking changes**
18 |
19 | * Default shortcut key for draw enable is `d`
20 | * Default shortcut key for draw disable is `q`
21 |
22 | ### 0.1.1 March 11, 2014
23 |
24 | **Features**
25 |
26 | * Add changelog overview (#14)
27 | * Add Change map bounds when loading GeoJSON (#13)
28 |
29 | **Bugfixes**
30 |
31 | * Fix undefined evaluation when snapping layer is not avaiable (#15)
32 | * Fail gracefully when loading invalid GeoJSON (#12)
33 |
34 | ### 0.1.0 March 10, 2014
35 |
36 | * Implements `#loadGeoJSON()` method (#3)
37 |
38 | #### Backwards compability note
39 |
40 | * Format of `properties.waypoints` in `#toGeoJSON()` is changed according to #3.
41 |
42 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013-2015, Den Norske Turistforening (DNT), Hans Kristian Flaatten
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification, are
5 | permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this list of
8 | conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 | of conditions and the following disclaimer in the documentation and/or other materials
12 | provided with the distribution.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
15 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
17 | COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
21 | TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Leaflet.Routing
2 | ===============
3 | [](https://gitter.im/Turistforeningen/leaflet-routing?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
4 |
5 | Leaflet.Routing is a routing controller for the popular Leaflet mapping
6 | framework. The module provides an intuitive interface for routing paths between
7 | waypoints using any user specified routing service. A demo using the OSM data
8 | can be found
9 | [here](http://turistforeningen.github.io/leaflet-routing/examples/osm.html).
10 |
11 | 
12 |
13 | ## Features
14 |
15 | * Route handling interface for Leaflet
16 | * Use your own routing backend, or OSM
17 |
18 | ## Usage
19 |
20 | ```javascript
21 | var routing = new L.Routing({
22 | position: 'topright'
23 | ,routing: {
24 | router: myRouterFunction
25 | }
26 | ,tooltips: {
27 | waypoint: 'Waypoint. Drag to move; Click to remove.',
28 | segment: 'Drag to create a new waypoint'
29 | }
30 | ,styles: { // see http://leafletjs.com/reference.html#polyline-options
31 | trailer: {} // drawing line
32 | ,track: {} // calculated route result
33 | ,nodata: {} // line when no result (error)
34 | }
35 | ,snapping: {
36 | layers: [mySnappingLayer]
37 | ,sensitivity: 15
38 | ,vertexonly: false
39 | }
40 | ,shortcut: {
41 | draw: {
42 | enable: 68 // 'd'
43 | ,disable: 81 // 'q'
44 | }
45 | }
46 | });
47 | map.addControl(routing);
48 | ```
49 |
50 | ### Enable Drawing
51 |
52 | ```javascript
53 | routing.draw(true);
54 | ```
55 |
56 | ### Enable Routing `NOT IMPLEMENTED`
57 |
58 | ```javascript
59 | routing.routing(true);
60 | ```
61 |
62 | ### Enable Snapping `NOT IMPLEMETED`
63 |
64 | ```javascript
65 | routing.snapping(true);
66 | ```
67 |
68 | ### Recalculate the complete route by routing each segment
69 |
70 | ```javascript
71 | routing.rerouteAllSegments(callback);
72 | ```
73 |
74 | ### Get first waypoint
75 |
76 | ```javascript
77 | var first = routing.getFirst();
78 | ```
79 |
80 | ### Get last waypoint
81 |
82 | ```javascript
83 | var last = routing.getLast();
84 | ```
85 |
86 | ### Get all waypoints
87 |
88 | ```javascript
89 | var waypointsArray = routing.getWaypoints();
90 | ```
91 |
92 | ### Routing to Polyline
93 |
94 | ```javascript
95 | var polyline = routing.toPolyline();
96 | ```
97 |
98 | ### To GeoJSON
99 |
100 | ```javascript
101 | var geoJSON3D = routing.toGeoJSON();
102 | var geoJSON2D = routing.toGeoJSON(false);
103 | ```
104 |
105 | ### Load GeoJSON
106 |
107 | Load GeoJSON with and without `properties.waypoints`.
108 |
109 | #### Options
110 |
111 | * `number` waypointDistance - distance between inserted waypoints for GeoJSON without waypoints.
112 | * `boolean` fitBounds - fit map arround loaded GeoJSON.
113 |
114 | ```javascript
115 | routing.loadGeoJSON(geojson, [options], function(err) {
116 | if (err) {
117 | console.log(err);
118 | } else {
119 | console.log('Finished loading GeoJSON');
120 | }
121 | });
122 | ```
123 |
124 | ## Events
125 |
126 | All events form Leaflet.Routing is prefixed with `routing:`.
127 |
128 | ### Usage
129 |
130 | ```javascript
131 | routing.on('routing:someEvent', function() {
132 | console.log('routing:someEvent triggered');
133 | });
134 | ```
135 |
136 | ### L.Routing Events
137 |
138 | | Event name | Description |
139 | |------------|-------------|
140 | | `routing:draw-start` | Fired when drawing mode is started |
141 | | `routing:draw-new` | Fired when drawing mode is started for a new route |
142 | | `routing:draw-continue` | Fired when drawing mode is started for an existing route |
143 | | `routing:draw-stop` | Fired when drawing mode ends |
144 | | `routing:edit-start` | Fired when editing mode starts |
145 | | `routing:edit-end` | Fired when editing mode ends |
146 |
147 | ### Waypoint Events
148 |
149 | | Event name | Description |
150 | |------------|-------------|
151 | | `routing:routeWaypointStart` | Fired when a new or existing waypoint is created or moved |
152 | | `routing:routeWaypointEnd` | Fired when routing is finished for new or moved waypoint |
153 |
154 | ### Segment Events
155 |
156 | | Event name | Description |
157 | |------------|-------------|
158 | | `routing:rerouteAllSegmentsStart` | Fired when rerouting of all segments starts |
159 | | `routing:rerouteAllSegmentsEnd` | Fired when rerouting of all segments completes |
160 |
161 | ## Copyright
162 |
163 | Copyright (c) 2014, Den Norske Turistforening
164 |
165 | All rights reserved.
166 |
167 | Redistribution and use in source and binary forms, with or without modification, are permitted
168 | provided that the following conditions are met:
169 |
170 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions
171 | and the following disclaimer.
172 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
173 | and the following disclaimer in the documentation and/or other materials provided with the
174 | distribution.
175 |
176 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
177 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
178 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
179 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
180 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
181 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
182 | IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
183 | THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
184 |
185 |
--------------------------------------------------------------------------------
/app.css:
--------------------------------------------------------------------------------
1 | #map {
2 | position: absolute;
3 | top: 0;
4 | left: 0;
5 | width: 100%;
6 | height: 100%;
7 | }
8 |
9 | div.line-mouse-marker {
10 | background-color: #ffffff;
11 | border: 2px solid black;
12 | border-radius: 10px;
13 | }
14 |
15 | #export {
16 | position: absolute;
17 | right: 10px;
18 | top: 10px;
19 | background-color: rgb(228,225,218);
20 | border: 1px solid rgb(196, 196, 196);
21 | padding: 10px;
22 | z-index: 3000;
23 | }
24 |
25 | #search {
26 | position: relative;
27 | margin: 10px auto;
28 | background-color: rgb(228,225,218);
29 | border: 1px solid rgb(196, 196, 196);
30 | padding: 10px;
31 | z-index: 3000;
32 | width: 300px;
33 | }
34 |
35 | #search input {
36 | width: 240px;
37 | }
38 |
39 | .typeahead {
40 | background-color: #fff;
41 | }
42 |
43 | .tt-dropdown-menu {
44 | width: 240px;
45 | padding: 8px 0;
46 | background-color: #fff;
47 | border: 1px solid #ccc;
48 | }
49 |
50 | .tt-suggestion {
51 | padding: 3px 20px;
52 | font-size: 18px;
53 | line-height: 24px;
54 | }
55 |
56 | .tt-suggestion.tt-is-under-cursor {
57 | color: #fff;
58 | background-color: #0097cf;
59 |
60 | }
61 |
62 | .tt-suggestion p {
63 | margin: 0;
64 | }
65 |
66 | #export input {
67 | width: 70px;
68 | }
--------------------------------------------------------------------------------
/app.js:
--------------------------------------------------------------------------------
1 | /*
2 | Routing capability using the Leaflet framework
3 | Copyright (c) 2013, Turistforeningen, Hans Kristian Flaatten
4 |
5 | https://github.com/Turistforeningen/leaflet-routing
6 | */
7 |
8 | var routing, data;
9 |
10 | (function() {
11 | "use strict";
12 | jQuery(function($) {
13 | var api, apiKey, rUrl, sUrl, topo, map, snapping, inport, myRouter;
14 |
15 | api = window.location.hash.substr(1).split('@');
16 | if (api.length === 2) {
17 | rUrl = 'http://' + api[1] + '/route/?coords='
18 | sUrl = 'http://' + api[1] + '/bbox/?bbox=';
19 | apiKey = api[0];
20 | } else {
21 | throw new Error('API auth failed');
22 | }
23 |
24 | topo = L.tileLayer('http://opencache.statkart.no/gatekeeper/gk/gk.open_gmaps?layers=topo2&zoom={z}&x={x}&y={y}', {
25 | maxZoom: 16,
26 | attribution: 'Statens kartverk'
27 | });
28 |
29 | var summer = L.tileLayer('http://mt3.turistforeningen.no/prod/trail_summer/{z}/{x}/{y}.png', {
30 | maxZoom: 16,
31 | attribution: 'DNT'
32 | });
33 | var winter = L.tileLayer('http://mt3.turistforeningen.no/prod/trail_winter/{z}/{x}/{y}.png', {
34 | maxZoom: 16,
35 | attribution: 'DNT'
36 | });
37 | var cabin = L.tileLayer('http://mt3.turistforeningen.no/prod/cabin/{z}/{x}/{y}.png', {
38 | maxZoom: 16,
39 | attribution: 'DNT'
40 | });
41 |
42 | map = new L.Map('map', {
43 | layers: [topo]
44 | ,center: new L.LatLng(61.5, 9)
45 | ,zoom: 13
46 | });
47 | cabin.addTo(map);
48 | summer.addTo(map);
49 |
50 | L.control.layers({'Topo 2': topo}, {
51 | 'DNTs merkede stier': summer
52 | ,'DNTs merkede vinterruter': winter
53 | ,'DNTs turisthytter': cabin
54 | }, {
55 | position: 'topleft'
56 | }).addTo(map);
57 |
58 | // Import Layer
59 | inport = new L.layerGroup(null, {
60 | style: {
61 | opacity:0.5
62 | ,clickable:false
63 | }
64 | }).addTo(map);
65 |
66 | // Snapping Layer
67 | snapping = new L.geoJson(null, {
68 | style: {
69 | opacity:0
70 | ,clickable:false
71 | }
72 | }).addTo(map);
73 | map.on('moveend', function() {
74 | if (map.getZoom() > 12) {
75 | var url;
76 | url = sUrl + map.getBounds().toBBoxString() + '&callback=?';
77 | $.getJSON(url).always(function(data, status) {
78 | if (status === 'success') {
79 | data = JSON.parse(data);
80 | if (data.geometries && data.geometries.length > 0) {
81 | snapping.clearLayers();
82 | snapping.addData(data);
83 | }
84 | } else {
85 | console.error('Could not load snapping data');
86 | }
87 | });
88 | } else {
89 | snapping.clearLayers();
90 | }
91 | });
92 | map.fire('moveend');
93 |
94 | // Routing Function
95 | // @todo speed up geometryToLayer()
96 | myRouter = function(l1, l2, cb) {
97 | var req = $.getJSON(rUrl + [l1.lng, l1.lat, l2.lng, l2.lat].join(',') + '&callback=?');
98 | req.always(function(data, status) {
99 | if (status === 'success') {
100 | try {
101 | L.GeoJSON.geometryToLayer(JSON.parse(data)).eachLayer(function (layer) {
102 | // 14026
103 | var d1 = l1.distanceTo(layer._latlngs[0]);
104 | var d2 = l2.distanceTo(layer._latlngs[layer._latlngs.length-1]);
105 |
106 | if (d1 < 10 && d2 < 10) {
107 | return cb(null, layer);
108 | } else {
109 | return cb(new Error('This has been discarded'));
110 | }
111 | });
112 | } catch(e) {
113 | return cb(new Error('Invalid JSON'));
114 | }
115 | } else {
116 | return cb(new Error('Routing failed'));
117 | }
118 | });
119 | }
120 |
121 | // Leaflet Routing Module
122 | routing = new L.Routing({
123 | position: 'topleft'
124 | ,routing: {
125 | router: myRouter
126 | }
127 | ,snapping: {
128 | layers: [snapping]
129 | ,sensitivity: 15
130 | ,vertexonly: false
131 | }
132 | });
133 | map.addControl(routing);
134 | routing.draw(true); // enable drawing mode
135 |
136 | $('#eta-export').hide();
137 | $('#eta-export').on('click', function() {
138 | var id = $('#eta-id').val();
139 | if (!id) { alert('Ingen tp_id definert!'); return; }
140 | if (confirm('Eksport til ETA vil overskrive eksisterende geometri!')) {
141 | var coords = routing.toGeoJSON().coordinates;
142 | var data = [];
143 | for (var i = 0; i < coords.length; i++) {
144 | data.push(coords[i][0] + ' ' + coords[i][1]);
145 | }
146 | data = 'LINESTRING(' + data.join(',') + ')';
147 | $.post('http://mintur.ut.no/lib/ajax/post_geom.php?api_key=' + apiKey + '&tp_id=' + id, {coords: data}, function(data) {
148 | if (data.error) {
149 | alert('Eksport feilet med feilkode ' + data.error);
150 | } else if (data.success) {
151 | window.location.href = 'http://mintur.ut.no/index.php?tp_id=' + id + '&tab=kart';
152 | //alert('Eksport suksess!');
153 | }
154 | });
155 | }
156 | });
157 |
158 | $('#eta-import').on('click', function() {
159 | var id = $('#eta-id').val();
160 | if (!id) { alert('Ingen tp_id definert!'); return; }
161 | $.get('http://mintur.ut.no/lib/ajax/post_geom.php?api_key=' + apiKey + '&tp_id=' + id, function(data) {
162 | if (data.error) {
163 | alert('Import feilet med feilkode ' + data.error);
164 | } else if (typeof data.coords !== 'undefined') {
165 | $('#eta-import').hide();
166 | $('#eta-export').show();
167 | $('#eta-id').attr('readonly', 'readonly');
168 |
169 | if (data.coords) {
170 | data.coords = data.coords.replace('LINESTRING(', '').replace(')', '').split(',');
171 | for (var i = 0; i < data.coords.length; i++) {
172 | data.coords[i] = new L.LatLng(data.coords[i].split(' ')[1], data.coords[i].split(' ')[0]);
173 | }
174 | inport.clearLayers();
175 | var p = new L.Polyline(data.coords, {clickable:false, color: '#000000', opacity: 0.4});
176 | inport.addLayer(p);
177 | map.fitBounds(p.getBounds());
178 | }
179 | }
180 | });
181 | });
182 |
183 | function fetchSsrAc(search, cb) {
184 | var result = [];
185 | $.ajax({
186 | url: "https://ws.geonorge.no/SKWS3Index/ssr/sok?navn=" + search + "*&epsgKode=4326&antPerSide=10"
187 | ,type: "GET"
188 | ,dataType: 'xml'
189 | ,success: function(xml) {
190 | $(xml).find('sokRes > stedsnavn').each(function(){
191 | result.push({
192 | title: $(this).find('stedsnavn').text()
193 | ,lat: $(this).find('aust').text()
194 | ,lng: $(this).find('nord').text()
195 | });
196 | });
197 | cb(null, result);
198 | }
199 | });
200 | }
201 |
202 | $('#ssr-search').typeahead({
203 | remote: {
204 | url: 'https://ws.geonorge.no/SKWS3Index/ssr/sok?navn=%QUERY*&epsgKode=4326&antPerSide=10',
205 | dataType: 'xml',
206 | filter: function(xml) {
207 | var result = [];
208 | $(xml).find('sokRes > stedsnavn').each(function(){
209 | result.push({
210 | value: $(this).find('stedsnavn').text()
211 | ,tokens: [$(this).find('stedsnavn').text()]
212 | ,lat: $(this).find('nord').text()
213 | ,lng: $(this).find('aust').text()
214 | });
215 | });
216 | return result;
217 | }
218 | }
219 | });
220 |
221 | $('#ssr-search').on('typeahead:selected', function(e, object) {
222 | var ll = new L.LatLng(object.lat, object.lng);
223 | map.panTo(ll);
224 | $('#ssr-search').val('');
225 | })
226 |
227 | });
228 | }).call(this);
229 |
--------------------------------------------------------------------------------
/examples/load-geojson.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Load Leaflet Route
6 |
7 |
8 |
9 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/examples/load-waypoints.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Load Leaflet Route
6 |
7 |
8 |
9 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/examples/osm.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Load Leaflet Route
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
146 |
147 |
148 |
153 |
154 |
155 |
--------------------------------------------------------------------------------
/examples/route.geojson:
--------------------------------------------------------------------------------
1 | {
2 | "type": "LineString",
3 | "properties": {
4 | "waypoints":[
5 | {"coordinates":[8.906856536865227,61.498998536981695],"_index":0},
6 | {"coordinates":[8.949394226074219,61.507221451655326],"_index":77},
7 | {"coordinates":[8.991113039526608,61.49597606714658],"_index":196},
8 | {"coordinates":[9.03364562988282,61.48669286650201],"_index":380}
9 | ]
10 | },
11 | "coordinates": [
12 | [8.9069297439802,61.4989743830191,1132.92067320133],
13 | [8.90724154784554,61.4991902326406,1136],
14 | [8.9073347415908,61.4993519090339,1139],
15 | [8.90740820891501,61.4995996899242,1140],
16 | [8.90740822323507,61.4996284167131,1140],
17 | [8.90740780822136,61.5000001270589,1145],
18 | [8.90740761622789,61.5001508631871,1149],
19 | [8.90755689802269,61.5004741730185,1156],
20 | [8.907706829915,61.5006357808669,1158],
21 | [8.90793506333067,61.5007613660566,1162],
22 | [8.908719614027,61.5011930223032,1170],
23 | [8.90911379871622,61.5012920935566,1169],
24 | [8.90935782548616,61.5013372483362,1169],
25 | [8.91016542493687,61.5014364714851,1177],
26 | [8.91086731277077,61.5014626956094,1188],
27 | [8.9108980004749,61.5014638002919,1188],
28 | [8.91125484094649,61.5014910427938,1194],
29 | [8.91179070416959,61.501642198231,1202],
30 | [8.91189303108492,61.501671005317,1213],
31 | [8.91234342784011,61.5018419232006,1227],
32 | [8.9124679384612,61.5018652398011,1227],
33 | [8.91300322716584,61.5019655760685,1242],
34 | [8.91354506932991,61.5020671040829,1249],
35 | [8.91437101405918,61.5023189469589,1248],
36 | [8.91493379544784,61.5025617044141,1264],
37 | [8.91513540753681,61.5026127836712,1264],
38 | [8.91508019114435,61.5029472785175,1272],
39 | [8.91493041961669,61.5032027087888,1276],
40 | [8.91522847444286,61.5037163693465,1279],
41 | [8.91528011038667,61.5037557814443,1281],
42 | [8.91579240151426,61.5041466573161,1290],
43 | [8.91661543668598,61.5043675569542,1302],
44 | [8.91664498447798,61.5043754530057,1302],
45 | [8.91749314806559,61.5046278183029,1306],
46 | [8.91849269666844,61.5051252223107,1312],
47 | [8.91902719035745,61.5054973564794,1321],
48 | [8.9193703042181,61.5057362986623,1325],
49 | [8.92024312438816,61.5063710172345,1341],
50 | [8.92046413153294,61.5064261967684,1341],
51 | [8.92128904277547,61.5066322008265,1350],
52 | [8.92248007666191,61.5066615935927,1361],
53 | [8.92272053249859,61.5066540640505,1361],
54 | [8.9237344862281,61.5066223997986,1380],
55 | [8.92419130783537,61.5065667275886,1386],
56 | [8.92444964747572,61.5065352308777,1394],
57 | [8.92495656187703,61.506508629673,1397],
58 | [8.92537003649824,61.5064818131266,1400],
59 | [8.92587523724855,61.5065140239652,1408],
60 | [8.92636556218724,61.5065452080322,1409],
61 | [8.92666608289049,61.5066082521347,1411],
62 | [8.92741771891687,61.506617789008,1415],
63 | [8.92822832190934,61.5068470630479,1419],
64 | [8.92896243525351,61.5069452267982,1425],
65 | [8.92929743165783,61.5069900838579,1429],
66 | [8.93058732915021,61.5070238198913,1440],
67 | [8.93071179269098,61.5070369410871,1443],
68 | [8.9317599045293,61.5071476675804,1452],
69 | [8.93304929793769,61.50720522022,1468],
70 | [8.93373725069322,61.5072359222206,1479],
71 | [8.93467202440819,61.5072776337074,1488],
72 | [8.93551692928634,61.5073153294592,1497],
73 | [8.93632780418334,61.5073400658517,1510],
74 | [8.93720239957265,61.5073666487621,1518],
75 | [8.93808841675107,61.5073859011643,1528],
76 | [8.93928803122822,61.5074120158237,1540],
77 | [8.93983582061693,61.5074038401956,1548],
78 | [8.94168863572099,61.5073761179655,1568],
79 | [8.94175476380828,61.5073752830476,1568],
80 | [8.94370094794695,61.5073519646437,1588],
81 | [8.94463757742485,61.5073407418929,1601],
82 | [8.94544017714414,61.5073219224119,1612],
83 | [8.94604018516534,61.5073078533028,1618],
84 | [8.94679433749858,61.5073122615528,1629],
85 | [8.94788323011605,61.5073185120465,1644],
86 | [8.94832097471587,61.507299549956,1649],
87 | [8.94924110289473,61.5072598265395,1664],
88 | [8.94927970373115,61.5072561418717,1664],
89 | [8.94940374245659,61.5072444228199,1665.55374551147],
90 | [8.94940374245659,61.5072444228199,1665.55374551147],
91 | [8.94999819117708,61.5071882582123,1673],
92 | [8.95061278931188,61.5071302452717,1682],
93 | [8.95068189820639,61.507127647697,1682],
94 | [8.95176764196467,61.5070861825043,1694],
95 | [8.95245746916518,61.5069863951584,1698],
96 | [8.95254279612833,61.5069740727506,1703],
97 | [8.95335750699792,61.5068746138703,1713],
98 | [8.9538248354617,61.5068488460621,1719],
99 | [8.95390312540864,61.5068445841548,1719],
100 | [8.95460058478887,61.5067790732135,1729],
101 | [8.95515028531726,61.5066564724723,1737],
102 | [8.95558540447445,61.5067089573853,1742],
103 | [8.95585462754512,61.5067413683642,1746],
104 | [8.95670478398229,61.5067520615147,1754],
105 | [8.95733546052668,61.5065765031147,1756],
106 | [8.95772479110708,61.5063521252765,1755],
107 | [8.95823224561218,61.5062624826857,1756],
108 | [8.95847658131743,61.5061816751737,1756],
109 | [8.95873983801271,61.5060472303528,1757],
110 | [8.95904072003225,61.5058588988233,1758],
111 | [8.95937929292895,61.5056792651961,1758],
112 | [8.95982134428754,61.5054791961039,1759],
113 | [8.96012183764927,61.505248253627,1761],
114 | [8.96027919659453,61.505147550545,1761],
115 | [8.9604787516479,61.5050198173819,1763],
116 | [8.96119760554611,61.5045360620929,1768],
117 | [8.96201145966002,61.5040462583682,1770],
118 | [8.96242535267018,61.5038308841753,1770],
119 | [8.96285744769709,61.503660439633,1769],
120 | [8.96312079917417,61.5033731845482,1771],
121 | [8.96325262502132,61.503014174679,1775],
122 | [8.96334712155468,61.5026281141329,1771],
123 | [8.96327233723375,61.5022869421441,1770],
124 | [8.96314107116482,61.5021073244907,1769],
125 | [8.96306225960671,61.5018517868017,1758],
126 | [8.96299133902331,61.5016225326134,1745],
127 | [8.96302924592967,61.5014431346624,1741],
128 | [8.96302923850336,61.5014247650448,1741],
129 | [8.9630294152674,61.5012097441754,1734],
130 | [8.96308595383206,61.5010750259196,1726],
131 | [8.9629938246816,61.5009490123951,1717],
132 | [8.9627108498035,61.5005632049287,1701],
133 | [8.96270773014781,61.50053371151,1701],
134 | [8.96269226185313,61.5003836388653,1693],
135 | [8.96255402212372,61.500044239831,1676],
136 | [8.96254245731751,61.5000155418674,1676],
137 | [8.96254003538683,61.5000018374058,1676],
138 | [8.96253963542417,61.5000000187283,1676],
139 | [8.96250501189147,61.4998089348361,1670],
140 | [8.96261796648882,61.4996001840432,1667],
141 | [8.96282519625632,61.4992167002429,1661],
142 | [8.96283372368003,61.4991883544859,1661],
143 | [8.96291946575032,61.4989024864642,1656],
144 | [8.96308886073253,61.498660224215,1651],
145 | [8.96297617504252,61.4985973197726,1654],
146 | [8.96297633160079,61.4984715331226,1654],
147 | [8.96306571320519,61.4982764125692,1653],
148 | [8.96320230410041,61.497978035623,1660],
149 | [8.96344669816698,61.4977715207258,1661],
150 | [8.96365350281189,61.4976459077086,1664],
151 | [8.96408565297273,61.4974843791342,1669],
152 | [8.96431144884736,61.4972959465643,1671],
153 | [8.96440582874866,61.4969907418607,1663],
154 | [8.96425563239032,61.4968291036206,1656],
155 | [8.96425283879386,61.4968269985583,1656],
156 | [8.96378643829354,61.4964699651978,1647],
157 | [8.96376799470904,61.4962993203228,1645],
158 | [8.9636178715126,61.4960569136346,1645],
159 | [8.96358039014819,61.4958863235788,1648],
160 | [8.96376881563027,61.4954375317511,1650],
161 | [8.96395694343983,61.495213119839,1644],
162 | [8.96406986082974,61.4949617755454,1643],
163 | [8.96416598406799,61.4948520471465,1633],
164 | [8.96444597698707,61.4945310439627,1630],
165 | [8.96445960906351,61.4945200335177,1630],
166 | [8.96502873943452,61.4940644656725,1599],
167 | [8.96516033590238,61.4939786432603,1599],
168 | [8.96544222234442,61.4937951318045,1592],
169 | [8.96647572634666,61.4933878221411,1575],
170 | [8.96662626123677,61.4933285922549,1575],
171 | [8.96736268323587,61.4930472068955,1556],
172 | [8.9673775661897,61.4930413843098,1556],
173 | [8.96822295992948,61.4927274633143,1547],
174 | [8.96878643743225,61.4926467590212,1541],
175 | [8.96948151676365,61.492503368239,1540],
176 | [8.97003419578306,61.4924374874363,1540],
177 | [8.97053345689313,61.4923779687801,1538],
178 | [8.97143490997508,61.4922882968022,1534],
179 | [8.97203602426383,61.4921717905464,1524],
180 | [8.9724681373013,61.4920282463389,1520],
181 | [8.9725936394155,61.4919998659466,1520],
182 | [8.9731442368169,61.4918757118332,1514],
183 | [8.97370783105705,61.4917796855988,1503],
184 | [8.97445923987694,61.4916515548802,1496],
185 | [8.9754541414524,61.4916965650061,1491],
186 | [8.97611152387083,61.4917685675796,1490],
187 | [8.9766185405275,61.4918942319263,1485],
188 | [8.97736981296426,61.4921727189933,1482],
189 | [8.97757320874444,61.4922846533096,1477],
190 | [8.97825192466734,61.4926576174232,1468],
191 | [8.9788715417362,61.4928283315364,1465],
192 | [8.97971674998501,61.4929451050428,1462],
193 | [8.98054290031764,61.4931067712706,1459],
194 | [8.98112500430261,61.493250510534,1461],
195 | [8.9813092968433,61.4933065757615,1455],
196 | [8.98195127195717,61.4935020366105,1450],
197 | [8.98328446087164,61.4941036694874,1441],
198 | [8.9834258400851,61.4941712482235,1435],
199 | [8.98448616053739,61.4946783075007,1427],
200 | [8.98487475671412,61.4949235872721,1419],
201 | [8.98536864531148,61.4952351152447,1412],
202 | [8.98604474531648,61.49547744676,1403],
203 | [8.98654780110099,61.4955598548621,1401],
204 | [8.98741570074812,61.4957019829283,1391],
205 | [8.98812684499371,61.4958052960784,1381],
206 | [8.98846767599249,61.4958547684471,1378],
207 | [8.9898761468938,61.4959177799776,1367],
208 | [8.99111582069343,61.4959548894561,1362.18762779351],
209 | [8.99111582069343,61.4959548894561,1362.18762779351],
210 | [8.99167935785628,61.4959717551128,1360],
211 | [8.99243382083955,61.4960109586499,1359],
212 | [8.99254331421909,61.4960166087958,1359],
213 | [8.99425268914357,61.4961963333471,1355],
214 | [8.99599951240412,61.4963130395054,1350],
215 | [8.9971449808589,61.4962592765983,1354],
216 | [8.99797150133284,61.4962503072953,1356],
217 | [8.9991360734623,61.4963130756719,1357],
218 | [9.00000003545876,61.4963579715502,1357],
219 | [9.00080775011647,61.4963400509417,1356],
220 | [9.00167165493822,61.4963940278008,1354],
221 | [9.00298636787146,61.496420798981,1349],
222 | [9.00377527983553,61.4964387681443,1343],
223 | [9.00436472052291,61.4964721548143,1337],
224 | [9.00456428570176,61.4964835692779,1337],
225 | [9.00516540583799,61.4965374568704,1335],
226 | [9.00664927527571,61.4965643597726,1331],
227 | [9.00824578509538,61.4965552432164,1331],
228 | [9.00916617652415,61.4965371977445,1330],
229 | [9.00999264888937,61.4964923165785,1324],
230 | [9.01029562605648,61.4964686618512,1320],
231 | [9.01080017900536,61.4964293978947,1312],
232 | [9.01234019745649,61.4965548766363,1305],
233 | [9.01241178614437,61.4965548789287,1305],
234 | [9.01296037800935,61.4965549140421,1296],
235 | [9.01380557623777,61.4965907009653,1287],
236 | [9.01427522413097,61.4966445198037,1285],
237 | [9.01478227288738,61.4967251953681,1287],
238 | [9.01564634234743,61.4967970075535,1281],
239 | [9.01566291413554,61.4967989977618,1281],
240 | [9.01675473491036,61.4969315230601,1276],
241 | [9.01778773735423,61.4969850961455,1272],
242 | [9.01827604274259,61.4967338542882,1262],
243 | [9.01847051344314,61.4966641675251,1262],
244 | [9.01865165634138,61.4965991163435,1257],
245 | [9.01895196766046,61.4964464772665,1255],
246 | [9.01978541602949,61.4958918552821,1239],
247 | [9.01981566137008,61.495871756441,1239],
248 | [9.02094206628705,61.4952072930575,1222],
249 | [9.02126033418766,61.4949690909886,1220],
250 | [9.02137391390197,61.4948840469901,1220],
251 | [9.02216247813233,61.4943722786557,1206],
252 | [9.02246349743775,61.4941531245024,1200],
253 | [9.02259409399383,61.4940579332442,1198],
254 | [9.02311958534234,61.4935102794243,1183],
255 | [9.02340169744097,61.4932943439793,1182],
256 | [9.0234951269874,61.4932229089196,1175],
257 | [9.02375771843558,61.4929175151101,1173],
258 | [9.02451933645731,61.4923632226201,1162],
259 | [9.0246211896173,61.492289095962,1151],
260 | [9.0246774437181,61.4922081922972,1151],
261 | [9.02462091107483,61.4919479224007,1145],
262 | [9.02475227227038,61.4918222396476,1145],
263 | [9.02492127792592,61.4917593489546,1143],
264 | [9.02517309735208,61.4917065817505,1138],
265 | [9.02552204448995,61.491633593125,1132],
266 | [9.02590912825821,61.4914837653528,1120],
267 | [9.02591647065884,61.4914808466782,1120],
268 | [9.0259445049688,61.4914584885809,1120],
269 | [9.02602921951723,61.4913911710275,1118],
270 | [9.02610395963496,61.4911935775949,1105],
271 | [9.02602864575644,61.4910769068783,1107],
272 | [9.02580321624447,61.490906366262,1099],
273 | [9.02581210263078,61.4908572349989,1099],
274 | [9.02584068526527,61.4906998413066,1094],
275 | [9.02600939573414,61.4904484832224,1089],
276 | [9.02629106027278,61.4903227434567,1085],
277 | [9.02663171245015,61.4901977951476,1083],
278 | [9.02717333392733,61.4899993825843,1070],
279 | [9.02769916942535,61.4899633361514,1068],
280 | [9.02826113521727,61.4898481098484,1068],
281 | [9.02825647363774,61.4898037856006,1065],
282 | [9.02822482664488,61.489752873164,1065],
283 | [9.0282138337161,61.4897316809934,1065],
284 | [9.028204729297,61.4897006674511,1065],
285 | [9.02820479168934,61.4896709571215,1065],
286 | [9.02822984160589,61.4896288388768,1061],
287 | [9.02826371486735,61.4895898095393,1061],
288 | [9.02828139023279,61.4895742890728,1061],
289 | [9.02829773895371,61.4895597907838,1061],
290 | [9.02833225724867,61.4895369969063,1061],
291 | [9.02839090447766,61.4895062593334,1061],
292 | [9.0284458162216,61.4894753575962,1058],
293 | [9.02853183316076,61.4894296155074,1058],
294 | [9.02857603287845,61.4894054461961,1058],
295 | [9.02860290841044,61.4893832168296,1058],
296 | [9.02863491324676,61.4893441053231,1058],
297 | [9.02867906493025,61.4892614081555,1055],
298 | [9.02872287304177,61.4891804966756,1055],
299 | [9.02874643526866,61.4891265178187,1055],
300 | [9.0287582009055,61.4890947105932,1052],
301 | [9.02877779764652,61.489061356631,1052],
302 | [9.02880265400124,61.4890300345618,1052],
303 | [9.02882987235117,61.4890060194378,1052],
304 | [9.02885623237053,61.488986468573,1052],
305 | [9.02888546938413,61.488971546093,1052],
306 | [9.02892166202282,61.4889596304132,1052],
307 | [9.02896345759772,61.4889479609074,1052],
308 | [9.02901220879953,61.4889392981907,1049],
309 | [9.02904294952789,61.4889361468897,1049],
310 | [9.02906961164012,61.488934617169,1049],
311 | [9.02910069565913,61.488929680148,1049],
312 | [9.02913757476507,61.4889141929952,1047],
313 | [9.02917784584361,61.4889006556557,1047],
314 | [9.02925293614005,61.4888823453624,1047],
315 | [9.02930883491131,61.4888658930248,1047],
316 | [9.0293808763159,61.4888438471305,1047],
317 | [9.02944697139463,61.4888233407414,1047],
318 | [9.02957184199715,61.4887910102477,1045],
319 | [9.0296523834307,61.48876393529,1045],
320 | [9.02973361124804,61.4887332888647,1042],
321 | [9.02986648690137,61.4886887042791,1041],
322 | [9.02994992520257,61.4886563540584,1041],
323 | [9.03001637992197,61.4886339723871,1041],
324 | [9.03008142726403,61.488618912094,1041],
325 | [9.03015108507102,61.4885994622968,1041],
326 | [9.03016989367177,61.4885937156726,1041],
327 | [9.030195090584,61.4885860887344,1041],
328 | [9.03024012574954,61.488567358025,1038],
329 | [9.0302778619343,61.4885474062729,1038],
330 | [9.03030591667515,61.4885288300084,1038],
331 | [9.03033837299908,61.4885167498527,1038],
332 | [9.03037166726626,61.4885101088642,1038],
333 | [9.03044130458946,61.4885005623663,1038],
334 | [9.03053539270067,61.4884911894903,1038],
335 | [9.03060876520009,61.4884818069842,1036],
336 | [9.03067331430337,61.4884693356826,1036],
337 | [9.03074110378604,61.4884498035366,1036],
338 | [9.03078324121043,61.4884363477413,1036],
339 | [9.03082267292329,61.4884173707237,1036],
340 | [9.03093727232565,61.4883404686195,1034],
341 | [9.03102686598209,61.4882858783304,1032],
342 | [9.03106782179698,61.488268768983,1032],
343 | [9.0311165713794,61.4882601054907,1032],
344 | [9.03121490857689,61.4882482176244,1032],
345 | [9.03127112856868,61.4882398821951,1032],
346 | [9.03132142228705,61.488223182914,1032],
347 | [9.03135915736476,61.4882032308473,1029],
348 | [9.03139929449998,61.4881707787671,1028],
349 | [9.03144488255307,61.4881295621534,1028],
350 | [9.03150337218976,61.4880898125615,1028],
351 | [9.03158821916261,61.4880305115147,1025],
352 | [9.03165078677971,61.4879891401881,1025],
353 | [9.03168255574634,61.4879806311284,1025],
354 | [9.03177189696688,61.487966547013,1023],
355 | [9.03185681664275,61.4879558702285,1023],
356 | [9.03194446167625,61.4879408111188,1023],
357 | [9.03201173454633,61.4879239568888,1023],
358 | [9.03209259523647,61.4879049981729,1023],
359 | [9.03215578963742,61.4878897655514,1020],
360 | [9.03221099891167,61.4878768834121,1020],
361 | [9.03222673276473,61.4878714516966,1020],
362 | [9.0322714873087,61.4878561295512,1019],
363 | [9.03231278498131,61.4878372340949,1019],
364 | [9.03237159662007,61.487805601852,1019],
365 | [9.03243721175155,61.4877679656072,1019],
366 | [9.03252274223738,61.4877050925057,1016],
367 | [9.03257696052088,61.4876777604409,1016],
368 | [9.03263135024885,61.4876495354937,1016],
369 | [9.03267554424689,61.4876253647743,1016],
370 | [9.03270698881937,61.4876087377221,1016],
371 | [9.03275356489388,61.487581970406,1016],
372 | [9.03279299432366,61.4875629927868,1016],
373 | [9.03283394822221,61.4875458828823,1016],
374 | [9.03288949967581,61.4875312147364,1014],
375 | [9.03294062979272,61.4875199539955,1014],
376 | [9.03300586211729,61.4875039101091,1014],
377 | [9.03306871221606,61.4874904627669,1013],
378 | [9.0331082936697,61.4874804956577,1013],
379 | [9.03315094334507,61.4874643605175,1013],
380 | [9.03319395518804,61.4874365361769,1013],
381 | [9.03330618208695,61.4873523250632,1012],
382 | [9.03333068942883,61.4873227878082,1010],
383 | [9.03334267651434,61.4872701910336,1010],
384 | [9.03336083812757,61.4871854512745,1010],
385 | [9.03337558843776,61.4871086652578,1008],
386 | [9.03338673687268,61.4870506293131,1008],
387 | [9.03339868554567,61.4870178394641,1008],
388 | [9.03342355462943,61.4869766129986,1008],
389 | [9.0334815821988,61.4869098306729,1005],
390 | [9.03351001656723,61.4868774945332,1005],
391 | [9.03358759381415,61.4867893308682,1005],
392 | [9.03367368215039,61.4866989705824,1002.04090700385]
393 | ]
394 | }
395 |
396 |
--------------------------------------------------------------------------------
/examples/styling.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Styling example
6 |
7 |
8 |
9 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/images/promo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Turistforeningen/leaflet-routing/b7368272b0e32cd43f74e52cd47684297394f79e/images/promo.gif
--------------------------------------------------------------------------------
/images/promo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Turistforeningen/leaflet-routing/b7368272b0e32cd43f74e52cd47684297394f79e/images/promo.png
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Routing in Leaflet
6 |
7 |
8 |
9 |
20 |
21 |
22 |
23 | Søk:
24 |
25 |
26 |
27 | tp_id:
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/libs/leaflet/images/layers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Turistforeningen/leaflet-routing/b7368272b0e32cd43f74e52cd47684297394f79e/libs/leaflet/images/layers.png
--------------------------------------------------------------------------------
/libs/leaflet/images/marker-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Turistforeningen/leaflet-routing/b7368272b0e32cd43f74e52cd47684297394f79e/libs/leaflet/images/marker-icon.png
--------------------------------------------------------------------------------
/libs/leaflet/images/marker-icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Turistforeningen/leaflet-routing/b7368272b0e32cd43f74e52cd47684297394f79e/libs/leaflet/images/marker-icon@2x.png
--------------------------------------------------------------------------------
/libs/leaflet/images/marker-shadow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Turistforeningen/leaflet-routing/b7368272b0e32cd43f74e52cd47684297394f79e/libs/leaflet/images/marker-shadow.png
--------------------------------------------------------------------------------
/libs/leaflet/leaflet.css:
--------------------------------------------------------------------------------
1 | /* required styles */
2 |
3 | .leaflet-map-pane,
4 | .leaflet-tile,
5 | .leaflet-marker-icon,
6 | .leaflet-marker-shadow,
7 | .leaflet-tile-pane,
8 | .leaflet-tile-container,
9 | .leaflet-overlay-pane,
10 | .leaflet-shadow-pane,
11 | .leaflet-marker-pane,
12 | .leaflet-popup-pane,
13 | .leaflet-overlay-pane svg,
14 | .leaflet-zoom-box,
15 | .leaflet-image-layer,
16 | .leaflet-layer {
17 | position: absolute;
18 | left: 0;
19 | top: 0;
20 | }
21 | .leaflet-container {
22 | overflow: hidden;
23 | -ms-touch-action: none;
24 | }
25 | .leaflet-tile,
26 | .leaflet-marker-icon,
27 | .leaflet-marker-shadow {
28 | -webkit-user-select: none;
29 | -moz-user-select: none;
30 | user-select: none;
31 | -webkit-user-drag: none;
32 | }
33 | .leaflet-marker-icon,
34 | .leaflet-marker-shadow {
35 | display: block;
36 | }
37 | /* map is broken in FF if you have max-width: 100% on tiles */
38 | .leaflet-container img {
39 | max-width: none !important;
40 | }
41 | /* stupid Android 2 doesn't understand "max-width: none" properly */
42 | .leaflet-container img.leaflet-image-layer {
43 | max-width: 15000px !important;
44 | }
45 | .leaflet-tile {
46 | filter: inherit;
47 | visibility: hidden;
48 | }
49 | .leaflet-tile-loaded {
50 | visibility: inherit;
51 | }
52 | .leaflet-zoom-box {
53 | width: 0;
54 | height: 0;
55 | }
56 |
57 | .leaflet-tile-pane { z-index: 2; }
58 | .leaflet-objects-pane { z-index: 3; }
59 | .leaflet-overlay-pane { z-index: 4; }
60 | .leaflet-shadow-pane { z-index: 5; }
61 | .leaflet-marker-pane { z-index: 6; }
62 | .leaflet-popup-pane { z-index: 7; }
63 |
64 |
65 | /* control positioning */
66 |
67 | .leaflet-control {
68 | position: relative;
69 | z-index: 7;
70 | pointer-events: auto;
71 | }
72 | .leaflet-top,
73 | .leaflet-bottom {
74 | position: absolute;
75 | z-index: 1000;
76 | pointer-events: none;
77 | }
78 | .leaflet-top {
79 | top: 0;
80 | }
81 | .leaflet-right {
82 | right: 0;
83 | }
84 | .leaflet-bottom {
85 | bottom: 0;
86 | }
87 | .leaflet-left {
88 | left: 0;
89 | }
90 | .leaflet-control {
91 | float: left;
92 | clear: both;
93 | }
94 | .leaflet-right .leaflet-control {
95 | float: right;
96 | }
97 | .leaflet-top .leaflet-control {
98 | margin-top: 10px;
99 | }
100 | .leaflet-bottom .leaflet-control {
101 | margin-bottom: 10px;
102 | }
103 | .leaflet-left .leaflet-control {
104 | margin-left: 10px;
105 | }
106 | .leaflet-right .leaflet-control {
107 | margin-right: 10px;
108 | }
109 |
110 |
111 | /* zoom and fade animations */
112 |
113 | .leaflet-fade-anim .leaflet-tile,
114 | .leaflet-fade-anim .leaflet-popup {
115 | opacity: 0;
116 | -webkit-transition: opacity 0.2s linear;
117 | -moz-transition: opacity 0.2s linear;
118 | -o-transition: opacity 0.2s linear;
119 | transition: opacity 0.2s linear;
120 | }
121 | .leaflet-fade-anim .leaflet-tile-loaded,
122 | .leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
123 | opacity: 1;
124 | }
125 |
126 | .leaflet-zoom-anim .leaflet-zoom-animated {
127 | -webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
128 | -moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
129 | -o-transition: -o-transform 0.25s cubic-bezier(0,0,0.25,1);
130 | transition: transform 0.25s cubic-bezier(0,0,0.25,1);
131 | }
132 | .leaflet-zoom-anim .leaflet-tile,
133 | .leaflet-pan-anim .leaflet-tile,
134 | .leaflet-touching .leaflet-zoom-animated {
135 | -webkit-transition: none;
136 | -moz-transition: none;
137 | -o-transition: none;
138 | transition: none;
139 | }
140 |
141 | .leaflet-zoom-anim .leaflet-zoom-hide {
142 | visibility: hidden;
143 | }
144 |
145 |
146 | /* cursors */
147 |
148 | .leaflet-clickable {
149 | cursor: pointer;
150 | }
151 | .leaflet-container {
152 | cursor: -webkit-grab;
153 | cursor: -moz-grab;
154 | }
155 | .leaflet-popup-pane,
156 | .leaflet-control {
157 | cursor: auto;
158 | }
159 | .leaflet-dragging,
160 | .leaflet-dragging .leaflet-clickable,
161 | .leaflet-dragging .leaflet-container {
162 | cursor: move;
163 | cursor: -webkit-grabbing;
164 | cursor: -moz-grabbing;
165 | }
166 |
167 |
168 | /* visual tweaks */
169 |
170 | .leaflet-container {
171 | background: #ddd;
172 | outline: 0;
173 | }
174 | .leaflet-container a {
175 | color: #0078A8;
176 | }
177 | .leaflet-container a.leaflet-active {
178 | outline: 2px solid orange;
179 | }
180 | .leaflet-zoom-box {
181 | border: 2px dotted #05f;
182 | background: white;
183 | opacity: 0.5;
184 | }
185 |
186 |
187 | /* general typography */
188 | .leaflet-container {
189 | font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
190 | }
191 |
192 |
193 | /* general toolbar styles */
194 |
195 | .leaflet-bar {
196 | box-shadow: 0 1px 7px rgba(0,0,0,0.65);
197 | -webkit-border-radius: 4px;
198 | border-radius: 4px;
199 | }
200 | .leaflet-bar a {
201 | background-color: #fff;
202 | border-bottom: 1px solid #ccc;
203 | width: 26px;
204 | height: 26px;
205 | line-height: 26px;
206 | display: block;
207 | text-align: center;
208 | text-decoration: none;
209 | color: black;
210 | }
211 | .leaflet-bar a,
212 | .leaflet-control-layers-toggle {
213 | background-position: 50% 50%;
214 | background-repeat: no-repeat;
215 | display: block;
216 | }
217 | .leaflet-bar a:hover {
218 | background-color: #f4f4f4;
219 | }
220 | .leaflet-bar a:first-child {
221 | -webkit-border-top-left-radius: 4px;
222 | border-top-left-radius: 4px;
223 | -webkit-border-top-right-radius: 4px;
224 | border-top-right-radius: 4px;
225 | }
226 | .leaflet-bar a:last-child {
227 | -webkit-border-bottom-left-radius: 4px;
228 | border-bottom-left-radius: 4px;
229 | -webkit-border-bottom-right-radius: 4px;
230 | border-bottom-right-radius: 4px;
231 | border-bottom: none;
232 | }
233 | .leaflet-bar a.leaflet-disabled {
234 | cursor: default;
235 | background-color: #f4f4f4;
236 | color: #bbb;
237 | }
238 |
239 | .leaflet-touch .leaflet-bar {
240 | -webkit-border-radius: 10px;
241 | border-radius: 10px;
242 | }
243 | .leaflet-touch .leaflet-bar a {
244 | width: 30px;
245 | height: 30px;
246 | }
247 | .leaflet-touch .leaflet-bar a:first-child {
248 | -webkit-border-top-left-radius: 7px;
249 | border-top-left-radius: 7px;
250 | -webkit-border-top-right-radius: 7px;
251 | border-top-right-radius: 7px;
252 | }
253 | .leaflet-touch .leaflet-bar a:last-child {
254 | -webkit-border-bottom-left-radius: 7px;
255 | border-bottom-left-radius: 7px;
256 | -webkit-border-bottom-right-radius: 7px;
257 | border-bottom-right-radius: 7px;
258 | border-bottom: none;
259 | }
260 |
261 |
262 | /* zoom control */
263 |
264 | .leaflet-control-zoom-in {
265 | font: bold 18px 'Lucida Console', Monaco, monospace;
266 | }
267 | .leaflet-control-zoom-out {
268 | font: bold 22px 'Lucida Console', Monaco, monospace;
269 | }
270 |
271 | .leaflet-touch .leaflet-control-zoom-in {
272 | font-size: 22px;
273 | line-height: 30px;
274 | }
275 | .leaflet-touch .leaflet-control-zoom-out {
276 | font-size: 28px;
277 | line-height: 30px;
278 | }
279 |
280 |
281 | /* layers control */
282 |
283 | .leaflet-control-layers {
284 | box-shadow: 0 1px 7px rgba(0,0,0,0.4);
285 | background: #f8f8f9;
286 | -webkit-border-radius: 8px;
287 | border-radius: 8px;
288 | }
289 | .leaflet-control-layers-toggle {
290 | background-image: url(images/layers.png);
291 | width: 36px;
292 | height: 36px;
293 | }
294 | .leaflet-touch .leaflet-control-layers-toggle {
295 | width: 44px;
296 | height: 44px;
297 | }
298 | .leaflet-control-layers .leaflet-control-layers-list,
299 | .leaflet-control-layers-expanded .leaflet-control-layers-toggle {
300 | display: none;
301 | }
302 | .leaflet-control-layers-expanded .leaflet-control-layers-list {
303 | display: block;
304 | position: relative;
305 | }
306 | .leaflet-control-layers-expanded {
307 | padding: 6px 10px 6px 6px;
308 | color: #333;
309 | background: #fff;
310 | }
311 | .leaflet-control-layers-selector {
312 | margin-top: 2px;
313 | position: relative;
314 | top: 1px;
315 | }
316 | .leaflet-control-layers label {
317 | display: block;
318 | }
319 | .leaflet-control-layers-separator {
320 | height: 0;
321 | border-top: 1px solid #ddd;
322 | margin: 5px -10px 5px -6px;
323 | }
324 |
325 |
326 | /* attribution and scale controls */
327 |
328 | .leaflet-container .leaflet-control-attribution {
329 | background-color: rgba(255, 255, 255, 0.7);
330 | box-shadow: 0 0 5px #bbb;
331 | margin: 0;
332 | }
333 | .leaflet-control-attribution,
334 | .leaflet-control-scale-line {
335 | padding: 0 5px;
336 | color: #333;
337 | }
338 | .leaflet-container .leaflet-control-attribution,
339 | .leaflet-container .leaflet-control-scale {
340 | font-size: 11px;
341 | }
342 | .leaflet-left .leaflet-control-scale {
343 | margin-left: 5px;
344 | }
345 | .leaflet-bottom .leaflet-control-scale {
346 | margin-bottom: 5px;
347 | }
348 | .leaflet-control-scale-line {
349 | border: 2px solid #777;
350 | border-top: none;
351 | color: black;
352 | line-height: 1.1;
353 | padding: 2px 5px 1px;
354 | font-size: 11px;
355 | text-shadow: 1px 1px 1px #fff;
356 | background-color: rgba(255, 255, 255, 0.5);
357 | box-shadow: 0 -1px 5px rgba(0, 0, 0, 0.2);
358 | white-space: nowrap;
359 | overflow: hidden;
360 | }
361 | .leaflet-control-scale-line:not(:first-child) {
362 | border-top: 2px solid #777;
363 | border-bottom: none;
364 | margin-top: -2px;
365 | box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
366 | }
367 | .leaflet-control-scale-line:not(:first-child):not(:last-child) {
368 | border-bottom: 2px solid #777;
369 | }
370 |
371 | .leaflet-touch .leaflet-control-attribution,
372 | .leaflet-touch .leaflet-control-layers,
373 | .leaflet-touch .leaflet-control-zoom {
374 | box-shadow: none;
375 | }
376 | .leaflet-touch .leaflet-control-layers,
377 | .leaflet-touch .leaflet-control-zoom {
378 | border: 4px solid rgba(0,0,0,0.3);
379 | }
380 |
381 |
382 | /* popup */
383 |
384 | .leaflet-popup {
385 | position: absolute;
386 | text-align: center;
387 | }
388 | .leaflet-popup-content-wrapper {
389 | padding: 1px;
390 | text-align: left;
391 | -webkit-border-radius: 20px;
392 | border-radius: 20px;
393 | }
394 | .leaflet-popup-content {
395 | margin: 14px 20px;
396 | line-height: 1.4;
397 | }
398 | .leaflet-popup-content p {
399 | margin: 18px 0;
400 | }
401 | .leaflet-popup-tip-container {
402 | margin: 0 auto;
403 | width: 40px;
404 | height: 20px;
405 | position: relative;
406 | overflow: hidden;
407 | }
408 | .leaflet-popup-tip {
409 | width: 15px;
410 | height: 15px;
411 | padding: 1px;
412 |
413 | margin: -8px auto 0;
414 |
415 | -webkit-transform: rotate(45deg);
416 | -moz-transform: rotate(45deg);
417 | -ms-transform: rotate(45deg);
418 | -o-transform: rotate(45deg);
419 | transform: rotate(45deg);
420 | }
421 | .leaflet-popup-content-wrapper, .leaflet-popup-tip {
422 | background: white;
423 |
424 | box-shadow: 0 3px 14px rgba(0,0,0,0.4);
425 | }
426 | .leaflet-container a.leaflet-popup-close-button {
427 | position: absolute;
428 | top: 0;
429 | right: 0;
430 | padding: 4px 5px 0 0;
431 | text-align: center;
432 | width: 18px;
433 | height: 14px;
434 | font: 16px/14px Tahoma, Verdana, sans-serif;
435 | color: #c3c3c3;
436 | text-decoration: none;
437 | font-weight: bold;
438 | background: transparent;
439 | }
440 | .leaflet-container a.leaflet-popup-close-button:hover {
441 | color: #999;
442 | }
443 | .leaflet-popup-scrolled {
444 | overflow: auto;
445 | border-bottom: 1px solid #ddd;
446 | border-top: 1px solid #ddd;
447 | }
448 |
449 |
450 | /* div icon */
451 |
452 | .leaflet-div-icon {
453 | background: #fff;
454 | border: 1px solid #666;
455 | }
456 | .leaflet-editing-icon {
457 | -webkit-border-radius: 2px;
458 | border-radius: 2px;
459 | }
460 |
--------------------------------------------------------------------------------
/libs/leaflet/leaflet.ie.css:
--------------------------------------------------------------------------------
1 | .leaflet-vml-shape {
2 | width: 1px;
3 | height: 1px;
4 | }
5 | .lvml {
6 | behavior: url(#default#VML);
7 | display: inline-block;
8 | position: absolute;
9 | }
10 |
11 | .leaflet-control {
12 | display: inline;
13 | }
14 |
15 | .leaflet-popup-tip {
16 | width: 21px;
17 | _width: 27px;
18 | margin: 0 auto;
19 | _margin-top: -3px;
20 |
21 | filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
22 | -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
23 | }
24 | .leaflet-popup-tip-container {
25 | margin-top: -1px;
26 | }
27 | .leaflet-popup-content-wrapper, .leaflet-popup-tip {
28 | border: 1px solid #999;
29 | }
30 | .leaflet-popup-content-wrapper {
31 | zoom: 1;
32 | }
33 |
34 | .leaflet-control-zoom,
35 | .leaflet-control-layers {
36 | border: 3px solid #999;
37 | }
38 | .leaflet-control-layers-toggle {
39 | }
40 | .leaflet-control-attribution,
41 | .leaflet-control-layers,
42 | .leaflet-control-scale-line {
43 | background: white;
44 | }
45 | .leaflet-zoom-box {
46 | filter: alpha(opacity=50);
47 | }
48 | .leaflet-control-attribution {
49 | border-top: 1px solid #bbb;
50 | border-left: 1px solid #bbb;
51 | }
52 |
--------------------------------------------------------------------------------
/src/L.Routing.Draw.js:
--------------------------------------------------------------------------------
1 | /*
2 | * L.Routing.Draw class
3 | *
4 | * Responsible for drawing and contine drawing
5 | *
6 | * @dependencies L, L.Routing
7 | *
8 | * @usage new L.Routing.Draw(map, options);
9 | */
10 |
11 | L.Routing.Draw = L.Handler.extend({
12 |
13 | // INCLUDES
14 | includes: [L.Mixin.Events]
15 |
16 | // OPTIONS
17 | ,options: {}
18 |
19 | /**
20 | * Draw Constructor
21 | *
22 | * @access public
23 | *
24 | * @param <> parent - parent class instance
25 | * @param options - routing options
26 | *
27 | * @return void
28 | *
29 | * @todo fetch last waypoint
30 | */
31 | ,initialize: function (parent, options) {
32 | this._parent = parent;
33 | this._map = parent._map;
34 |
35 | this._enabled = false;
36 |
37 | L.Util.setOptions(this, options);
38 | }
39 |
40 | /**
41 | * Enable drawing
42 | *
43 | * @access public
44 | *
45 | * @event map.routing:draw-start
46 | * @event map.routing:draw-new
47 | * @event map.routing:draw-continue
48 | *
49 | * @return void
50 | */
51 | ,enable: function() {
52 | if (this._enabled) { return; }
53 |
54 | this._enabled = true;
55 | this._hidden = false;
56 | this._dragging = false;
57 | this._addHooks();
58 | this.fire('enabled');
59 |
60 | this._map.fire('routing:draw-start');
61 | if (this._parent._segments._layers.length === 0) {
62 | this._map.fire('routing:draw-new');
63 | } else {
64 | this._map.fire('routing:draw-continue');
65 | }
66 | }
67 |
68 | /**
69 | * Disable drawing
70 | *
71 | * @access public
72 | *
73 | * @event map.routing:draw-end
74 | *
75 | * @return void
76 | */
77 | ,disable: function() {
78 | if (!this._enabled) { return; }
79 |
80 | this._enabled = false;
81 | this._removeHooks();
82 | this.fire('disabled');
83 |
84 | this._map.fire('routing:draw-end');
85 | }
86 |
87 | /**
88 | * Add hooks
89 | *
90 | * @access private
91 | *
92 | * @return void
93 | */
94 | ,_addHooks: function() {
95 | if (!this._map) { return; }
96 |
97 | // Visible Marker
98 | if (!this._marker) {
99 | this._marker = new L.Marker(this._map.getCenter(), {
100 | icon: (this.options.icons.draw ? this.options.icons.draw : new L.Icon.Default())
101 | ,opacity: (this.options.icons.draw ? 1.0 : 0.0)
102 | ,zIndexOffset: this.options.zIndexOffset
103 | ,clickable: false
104 | });
105 | }
106 |
107 | // Trailing line
108 | if (!this._trailer) {
109 | var ll = this._map.getCenter();
110 | this._trailerOpacity = this.options.styles.trailer.opacity || 0.2;
111 | var style = L.extend({}, this.options.styles.trailer, {
112 | opacity: 0.0
113 | ,clickable: false
114 | });
115 | this._trailer = new L.Polyline([ll, ll], style);
116 | }
117 |
118 | this._parent.on('waypoint:mouseover', this._catchWaypointEvent, this);
119 | this._parent.on('waypoint:mouseout' , this._catchWaypointEvent, this);
120 | this._parent.on('waypoint:dragstart', this._catchWaypointEvent, this);
121 | this._parent.on('waypoint:dragend' , this._catchWaypointEvent, this);
122 |
123 | this._parent.on('segment:mouseover' , this._catchWaypointEvent, this);
124 | this._parent.on('segment:mouseout' , this._catchWaypointEvent, this);
125 | this._parent.on('segment:dragstart' , this._catchWaypointEvent, this);
126 | this._parent.on('segment:dragend' , this._catchWaypointEvent, this);
127 |
128 | this._map.on('mousemove', this._onMouseMove, this);
129 | this._map.on('click', this._onMouseClick, this);
130 |
131 | this._marker.addTo(this._map);
132 | this._trailer.addTo(this._map);
133 | }
134 |
135 | /**
136 | * Remove hooks
137 | *
138 | * This method is invoked after the `disable()` has been called and removes
139 | * all the hooks set up using the `_addHooks()` method.
140 | *
141 | * @access private
142 | *
143 | * @return void
144 | */
145 | ,_removeHooks: function() {
146 | if (!this._map) { return; }
147 |
148 | this._parent.off('waypoint:mouseover', this._catchWaypointEvent, this);
149 | this._parent.off('waypoint:mouseout' , this._catchWaypointEvent, this);
150 | this._parent.off('waypoint:dragstart', this._catchWaypointEvent, this);
151 | this._parent.off('waypoint:dragend' , this._catchWaypointEvent, this);
152 |
153 | this._parent.off('segment:mouseover' , this._catchWaypointEvent, this);
154 | this._parent.off('segment:mouseout' , this._catchWaypointEvent, this);
155 | this._parent.off('segment:dragstart' , this._catchWaypointEvent, this);
156 | this._parent.off('segment:dragend' , this._catchWaypointEvent, this);
157 |
158 | this._map.off('click', this._onMouseClick, this);
159 | this._map.off('mousemove', this._onMouseMove, this);
160 |
161 | this._map.removeLayer(this._marker);
162 | this._map.removeLayer(this._trailer);
163 |
164 | delete this._marker;
165 | delete this._trailer;
166 | }
167 |
168 | /**
169 | * Handle waypoint events
170 | *
171 | * @access private
172 | *
173 | * @param e - waypoint event
174 | *
175 | * @return void
176 | */
177 | ,_catchWaypointEvent: function(e) {
178 | var type = e.type.split(':')[1];
179 |
180 | if (this._hidden) {
181 | if (this._dragging) {
182 | if (type === 'dragend') {
183 | this._dragging = false;
184 | }
185 | } else {
186 | if (type === 'mouseout') {
187 | this._show();
188 | } else if (type === 'dragstart') {
189 | this._dragging = true;
190 | }
191 | }
192 | } else {
193 | if (type === 'mouseover') {
194 | this._hide();
195 | }
196 | }
197 | }
198 |
199 | /**
200 | * Hide HUD
201 | *
202 | * Call this method in order to quickly hide graphical drawing elements for
203 | * instance hoovering over draggable objects which should tempoarily disable
204 | * dragging.
205 | *
206 | * @access private
207 | *
208 | * @return void
209 | */
210 | ,_hide: function() {
211 | this._hidden = true;
212 | this._marker.setOpacity(0.0);
213 | this._trailer.setStyle({opacity: 0.0});
214 | }
215 |
216 | /**
217 | * Show HUD
218 | *
219 | * Call this method to restore graphical drawing elements after they have been
220 | * hidden.
221 | *
222 | * @access private
223 | *
224 | * @return void
225 | */
226 | ,_show: function() {
227 | this._hidden = false;
228 | this._marker.setOpacity(this.options.icons.draw ? 1.0 : 0.0);
229 | this._showTrailer();
230 | }
231 |
232 | /**
233 | * Show trailer when hidden
234 | *
235 | * @access private
236 | *
237 | * @return void
238 | */
239 | ,_showTrailer: function() {
240 | if (this._trailer.options.opacity === 0.0) {
241 | this._trailer.setStyle({opacity: this._trailerOpacity});
242 | }
243 | }
244 |
245 | /**
246 | * Set trailing guide line
247 | *
248 | */
249 | ,_setTrailer: function(fromLatLng, toLatLng) {
250 | this._trailer.setLatLngs([fromLatLng, toLatLng]);
251 | this._showTrailer();
252 | }
253 |
254 | /**
255 | * Mouse move handler
256 | *
257 | * @access private
258 | *
259 | * @param e - mouse move event
260 | *
261 | * @return void
262 | */
263 | ,_onMouseMove : function(e) {
264 | if (this._hidden) { return; }
265 |
266 | var latlng = e.latlng;
267 | var last = this._parent.getLast();
268 |
269 | if (this.options.snapping) {
270 | latlng = L.LineUtil.snapToLayers(latlng, null, this.options.snapping);
271 | }
272 |
273 | this._marker.setLatLng(latlng);
274 |
275 |
276 | if (last !== null) {
277 | this._setTrailer(last.getLatLng(), latlng);
278 | };
279 | }
280 |
281 | /**
282 | * Mouse click handler
283 | *
284 | * @access private
285 | *
286 | * @param e - mouse click event
287 | *
288 | * @event map.routing:new-waypoint
289 | *
290 | * @return void
291 | */
292 | ,_onMouseClick: function(e) {
293 | if (this._hidden) { return; }
294 |
295 | var marker, latlng, last;
296 |
297 | latlng = e.latlng;
298 | if (this.options.snapping) {
299 | latlng = L.LineUtil.snapToLayers(latlng, null, this.options.snapping);
300 | }
301 | marker = new L.Marker(latlng, {title: this.options.tooltips.waypoint });
302 | last = this._parent.getLast();
303 |
304 | this._setTrailer(latlng, latlng);
305 | this._parent.addWaypoint(marker, last, null, function(err, data) {
306 | // console.log(err, data);
307 | });
308 | }
309 | });
310 |
--------------------------------------------------------------------------------
/src/L.Routing.Edit.js:
--------------------------------------------------------------------------------
1 | /*
2 | * L.Routing.Edit class
3 | *
4 | * Responsible handle edits
5 | *
6 | * @dependencies L, L.Routing
7 | *
8 | * @usage new L.Routing.Draw(map, options);
9 | */
10 |
11 | L.Routing.Edit = L.Handler.extend({
12 |
13 | // INCLUDES
14 | includes: [L.Mixin.Events]
15 |
16 | // OPTIONS
17 | ,options: {}
18 |
19 | /**
20 | * Edit Constructor
21 | *
22 | * @access public
23 | *
24 | * @param <> parent - parent class instance
25 | * @param options - routing options
26 | *
27 | * @return void
28 | *
29 | * @todo fetch last waypoint
30 | */
31 | ,initialize: function (parent, options) {
32 | this._parent = parent;
33 | this._map = parent._map;
34 |
35 | this._enabled = false;
36 |
37 | L.Util.setOptions(this, options);
38 | }
39 |
40 | /**
41 | * Enable drawing
42 | *
43 | * @access public
44 | *
45 | * @event map.routing:edit-start
46 | *
47 | * @return void
48 | */
49 | ,enable: function() {
50 | if (this._enabled) { return; }
51 |
52 | this._enabled = true;
53 | this._addHooks();
54 | this.fire('enabled');
55 |
56 | this._map.fire('routing:edit-start');
57 | }
58 |
59 | /**
60 | * Disable drawing
61 | *
62 | * @access public
63 | *
64 | * @event map.draw:edit-end
65 | *
66 | * @return void
67 | */
68 | ,disable: function() {
69 | if (!this._enabled) { return; }
70 |
71 | this._enabled = false;
72 | this._removeHooks();
73 | this.fire('disabled');
74 |
75 | this._map.fire('routing:edit-end');
76 | }
77 |
78 | /**
79 | * Add hooks
80 | *
81 | * This method is invoked when `enable()` is called – and sets up all
82 | * necessary hooks such as:
83 | * * text selection
84 | * * key listeners
85 | * * mouse marker
86 | *
87 | * @access private
88 | *
89 | * @return void
90 | *
91 | * @todo hide and style the trailer!
92 | */
93 | ,_addHooks: function() {
94 | if (!this._map) { return; }
95 |
96 | if (!this._mouseMarker) {
97 | this._mouseMarker = new L.Marker(this._map.getCenter(), {
98 | icon: L.divIcon({
99 | className: 'line-mouse-marker'
100 | ,iconAnchor: [5, 5]
101 | ,iconSize: [10, 10]
102 | })
103 | ,clickable: true
104 | ,draggable: true
105 | ,opacity: 0
106 | ,zIndexOffset: this.options.zIndexOffset
107 | ,title: this.options.tooltips.segment
108 | });
109 | }
110 | this._mouseMarker.addTo(this._map);
111 |
112 | if (!this._trailer1) {
113 | var ll = this._map.getCenter();
114 | this._trailerOpacity = this.options.styles.trailer.opacity || 0.2;
115 | var style = L.extend({}, this.options.styles.trailer, {opacity: 0.0,clickable: false});
116 | this._trailer1 = new L.Polyline([ll, ll], style);
117 | this._trailer2 = new L.Polyline([ll, ll], style);
118 | }
119 | this._trailer1.addTo(this._map);
120 | this._trailer2.addTo(this._map);
121 |
122 | this._parent.on('segment:mouseover' , this._segmentOnMouseover, this);
123 |
124 | this._mouseMarker.on('dragstart' , this._segmentOnDragstart, this);
125 | this._mouseMarker.on('drag' , this._segmentOnDrag, this);
126 | this._mouseMarker.on('dragend' , this._segmentOnDragend, this);
127 |
128 | this._parent.on('waypoint:dragstart', this._waypointOnDragstart, this);
129 | this._parent.on('waypoint:drag' , this._waypointOnDrag, this);
130 | this._parent.on('waypoint:dragend' , this._waypointOnDragend, this);
131 | }
132 |
133 | /**
134 | * Remove hooks
135 | *
136 | * This method is invoked after the `disable()` has been called and removes
137 | * all the hooks set up using the `_addHooks()` method.
138 | *
139 | * @access private
140 | *
141 | * @return void
142 | */
143 | ,_removeHooks: function() {
144 | if (!this._map) { return; }
145 |
146 | // this._trailer1.addTo(this._map);
147 | // this._trailer2.addTo(this._map);
148 |
149 | this._parent.off('segment:mouseover' , this._segmentOnMouseover, this);
150 |
151 | this._mouseMarker.off('dragstart' , this._segmentOnDragstart, this);
152 | this._mouseMarker.off('drag' , this._segmentOnDrag, this);
153 | this._mouseMarker.off('dragend' , this._segmentOnDragend, this);
154 |
155 | this._parent.off('waypoint:dragstart', this._waypointOnDragstart, this);
156 | this._parent.off('waypoint:drag' , this._waypointOnDrag, this);
157 | this._parent.off('waypoint:dragend' , this._waypointOnDragend, this);
158 | }
159 |
160 | /**
161 | * Fired when the mouse first enters a segment
162 | *
163 | * @access private
164 | *
165 | * @param e - mouse over event
166 | *
167 | * @return void
168 | */
169 | ,_segmentOnMouseover: function(e) {
170 | this._mouseMarker.setOpacity(1.0);
171 | this._map.on('mousemove', this._segmentOnMousemove, this);
172 | }
173 |
174 | /**
175 | * Fired when the mouse leaves a segement
176 | *
177 | * @access private
178 | *
179 | * @param e - mouse move event
180 | *
181 | * @return void
182 | */
183 | ,_segmentOnMouseout: function(e) {
184 | if (this._dragging) { return; }
185 |
186 | this._mouseMarker.setOpacity(0.0);
187 | this._map.off('mousemove', this._segmentOnMousemove, this);
188 |
189 | this.fire('segment:mouseout');
190 | }
191 |
192 | /**
193 | * Fired when the mouse is moved
194 | *
195 | * This method is fired continously when mouse is moved in edition mode.
196 | *
197 | * @access private
198 | *
199 | * @param e - mouse move event
200 | *
201 | * @return void
202 | */
203 | ,_segmentOnMousemove: function(e) {
204 | if (this._dragging) { return; }
205 |
206 | var latlng = L.LineUtil.snapToLayers(e.latlng, null, {
207 | layers: [this._parent._segments]
208 | ,sensitivity: 40
209 | ,vertexonly: false
210 | });
211 |
212 | if (latlng._feature === null) {
213 | this._segmentOnMouseout(e);
214 | } else {
215 | this._mouseMarker._snapping = latlng._feature._routing;
216 | this._mouseMarker.setLatLng(latlng);
217 | }
218 | }
219 |
220 | /**
221 | * Mouse marker dragstart
222 | *
223 | * @access private
224 | *
225 | * @param e - mouse dragstart event
226 | *
227 | * @return void
228 | */
229 | ,_segmentOnDragstart: function(e) {
230 | var latlng = e.target.getLatLng();
231 | var next = e.target._snapping.nextMarker;
232 | var prev = e.target._snapping.prevMarker;
233 |
234 | this._setTrailers(latlng, next, prev, true);
235 |
236 | this._dragging = true;
237 | this.fire('segment:dragstart');
238 | }
239 |
240 | /**
241 | * Fired when a marker is dragged
242 | *
243 | * This method is fired continously when dragging a marker and snapps the
244 | * marker to the snapping layer.
245 | *
246 | * @access private
247 | *
248 | * @param e - mouse drag event
249 | *
250 | * @return void
251 | */
252 | ,_segmentOnDrag: function(e) {
253 | var latlng = e.target.getLatLng();
254 | var next = e.target._snapping.nextMarker;
255 | var prev = e.target._snapping.prevMarker;
256 |
257 | if (this.options.snapping) {
258 | latlng = L.LineUtil.snapToLayers(latlng, null, this.options.snapping);
259 | }
260 |
261 | e.target.setLatLng(latlng);
262 | this._setTrailers(latlng, next, prev);
263 | }
264 |
265 | /**
266 | * Mouse marker dragend
267 | *
268 | * @access private
269 | *
270 | * @param e - mouse dragend event
271 | *
272 | * @return void
273 | */
274 | ,_segmentOnDragend: function(e) {
275 | var next = this._mouseMarker._snapping.nextMarker;
276 | var prev = this._mouseMarker._snapping.prevMarker;
277 | var latlng = this._mouseMarker.getLatLng();
278 |
279 | this._parent.addWaypoint(latlng, prev, next, function(err, data) {
280 | //console.log(err, data);
281 | });
282 |
283 | this._dragging = false;
284 | this._setTrailers(null, null, null, false);
285 | this.fire('segment:dragend');
286 | }
287 |
288 | /**
289 | * Fired when marker drag start
290 | *
291 | * @access private
292 | *
293 | * @param e - mouse dragend event
294 | *
295 | * @return void
296 | */
297 | ,_waypointOnDragstart: function(e) {
298 | var next = e.marker._routing.nextMarker;
299 | var prev = e.marker._routing.prevMarker;
300 |
301 | this._setTrailers(e.marker.getLatLng(), next, prev, true);
302 | }
303 |
304 | /**
305 | * Fired while dragging marker
306 | *
307 | * @access private
308 | *
309 | * @access private
310 | *
311 | * @param e - mouse drag event
312 | *
313 | * @return void
314 | */
315 | ,_waypointOnDrag: function(e) {
316 | var latlng = e.marker._latlng;
317 | var next = e.marker._routing.nextMarker;
318 | var prev = e.marker._routing.prevMarker;
319 |
320 | if (this.options.snapping) {
321 | latlng = L.LineUtil.snapToLayers(latlng, null, this.options.snapping);
322 | }
323 |
324 | e.marker.setLatLng(latlng);
325 | this._setTrailers(latlng, next, prev);
326 | }
327 |
328 | /**
329 | * Fired when marker drag ends
330 | *
331 | * @access private
332 | *
333 | * @param e - mouse dragend event
334 | *
335 | * @return void
336 | */
337 | ,_waypointOnDragend: function(e) {
338 | this._setTrailers(null, null, null, false);
339 | this._parent.routeWaypoint(e.marker, function(err, data) {
340 | //console.log('_waypointOnDragend.cb', err, data);
341 | });
342 | }
343 |
344 | /**
345 | * Fired when marker is clicked
346 | *
347 | * This method is fired when a marker is clicked by the user. It will then
348 | * procede to remove the marker and reroute any connected line segments.
349 | *
350 | * @access private
351 | *
352 | * @param e - mouse click event
353 | *
354 | * @return void
355 | */
356 | ,_waypointOnClick: function(e) {
357 | this._parent.removeWaypoint(e.layer, function(err, data) {
358 | //console.log('_waypointOnDragend.cb', err, data);
359 | });
360 | }
361 |
362 | /**
363 | * Set trailing guide lines
364 | *
365 | */
366 | ,_setTrailers: function(latlng, next, prev, show) {
367 | if (typeof show !== 'undefined') {
368 | if (show === false) {
369 | this._trailer1.setStyle({opacity: 0.0});
370 | this._trailer2.setStyle({opacity: 0.0});
371 | return;
372 | } else {
373 | if (next !== null) {
374 | this._trailer1.setStyle({opacity: this._trailerOpacity});
375 | }
376 | if (prev !== null) {
377 | this._trailer2.setStyle({opacity: this._trailerOpacity});
378 | }
379 | }
380 | }
381 | if (next) {
382 | this._trailer1.setLatLngs([latlng, next.getLatLng()]);
383 | }
384 | if (prev) {
385 | this._trailer2.setLatLngs([latlng, prev.getLatLng()]);
386 | }
387 | }
388 | });
389 |
390 |
--------------------------------------------------------------------------------
/src/L.Routing.Storage.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Leaflet Routing Storage
3 | *
4 | * Storing routable objects
5 | *
6 | * @dependencies L, L.Routing
7 | *
8 | * @usage new L.Routing(options);
9 | */
10 |
11 | (function () {
12 | L.Routing.Storage = L.MultiPolyline.extend({
13 | /**
14 | * Class constructor
15 | */
16 | initialize: function (latlngs, options) {
17 | this._layers = {};
18 | this._options = options;
19 | this.setLatLngs(latlngs);
20 |
21 | this.on('layeradd', function() {
22 | console.log('layeradd', arguments);
23 | }, this);
24 | }
25 | });
26 |
27 | L.Routing.storage = function (latlngs, options) {
28 | return new L.MultiPolyline(latlngs, options);
29 | };
30 |
31 | }());
32 |
--------------------------------------------------------------------------------
/src/L.Routing.js:
--------------------------------------------------------------------------------
1 | /*
2 | * L.Routing main class
3 | *
4 | * Main clase for the Leaflet routing module
5 | *
6 | * @dependencies L
7 | *
8 | * @usage new L.Routing(options);
9 | *
10 | * @todo use L.Class.extend instead?
11 | */
12 |
13 | L.Routing = L.Control.extend({
14 |
15 | // INCLUDES
16 | includes: [L.Mixin.Events]
17 |
18 | // CONSTANTS
19 | ,statics: {
20 | VERSION: '0.1.1-dev'
21 | }
22 |
23 | // OPTIONS
24 | ,options: {
25 | position: 'topleft'
26 | ,tooltips: {
27 | waypoint: 'Waypoint. Drag to move; Click to remove.',
28 | segment: 'Drag to create a new waypoint'
29 | }
30 | ,icons: {
31 | start: new L.Icon.Default()
32 | ,end: new L.Icon.Default()
33 | ,normal: new L.Icon.Default()
34 | ,draw: new L.Icon.Default()
35 | }
36 | ,styles: {
37 | trailer: {}
38 | ,track: {}
39 | ,nodata: {}
40 | }
41 | ,zIndexOffset: 2000
42 | ,routing: {
43 | router: null // function ( l1, l2, cb)
44 | }
45 | ,snapping: {
46 | layers: [] // layers to snap to
47 | ,sensitivity: 10 // snapping sensitivity
48 | ,vertexonly: false // vertex only snapping
49 | }
50 | ,shortcut: {
51 | draw: {
52 | enable: 68, // char code for 'd'
53 | disable: 81 // char code for 'q'
54 | }
55 | }
56 | }
57 |
58 | /**
59 | * Routing Constructor
60 | *
61 | * @access public
62 | *
63 | * @param