]> git.openstreetmap.org Git - rails.git/blob - vendor/assets/leaflet/leaflet.osm.js
Merge remote-tracking branch 'upstream/pull/5113'
[rails.git] / vendor / assets / leaflet / leaflet.osm.js
1 L.OSM = {};
2
3 L.OSM.TileLayer = L.TileLayer.extend({
4   options: {
5     url: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
6     attribution: '© <a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a> contributors'
7   },
8
9   initialize: function (options) {
10     options = L.Util.setOptions(this, options);
11     L.TileLayer.prototype.initialize.call(this, options.url);
12   }
13 });
14
15 L.OSM.Mapnik = L.OSM.TileLayer.extend({
16   options: {
17     url: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
18     maxZoom: 19
19   }
20 });
21
22 L.OSM.CyclOSM = L.OSM.TileLayer.extend({
23   options: {
24     url: 'https://{s}.tile-cyclosm.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png',
25     maxZoom: 20,
26     subdomains: 'abc',
27     attribution: '© <a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a> contributors. Tiles courtesy of <a href="https://www.openstreetmap.fr" target="_blank">OpenStreetMap France</a>'
28   }
29 });
30
31 L.OSM.CycleMap = L.OSM.TileLayer.extend({
32   options: {
33     url: 'https://{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}{r}.png?apikey={apikey}',
34     maxZoom: 21,
35     attribution: '© <a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a> contributors. Tiles courtesy of <a href="http://www.thunderforest.com/" target="_blank">Andy Allan</a>'
36   }
37 });
38
39 L.OSM.TransportMap = L.OSM.TileLayer.extend({
40   options: {
41     url: 'https://{s}.tile.thunderforest.com/transport/{z}/{x}/{y}{r}.png?apikey={apikey}',
42     maxZoom: 21,
43     attribution: '© <a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a> contributors. Tiles courtesy of <a href="http://www.thunderforest.com/" target="_blank">Andy Allan</a>'
44   }
45 });
46
47 L.OSM.OPNVKarte = L.OSM.TileLayer.extend({
48   options: {
49     url: 'https://tileserver.memomaps.de/tilegen/{z}/{x}/{y}.png',
50     maxZoom: 18,
51     attribution: '© <a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a> contributors. Tiles courtesy of <a href="http://memomaps.de/" target="_blank">MeMoMaps</a>'
52   }
53 });
54
55 L.OSM.HOT = L.OSM.TileLayer.extend({
56   options: {
57     url: 'https://tile-{s}.openstreetmap.fr/hot/{z}/{x}/{y}.png',
58     maxZoom: 20,
59     subdomains: 'abc',
60     attribution: '© <a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a> contributors. Tiles courtesy of <a href="http://hot.openstreetmap.org/" target="_blank">Humanitarian OpenStreetMap Team</a>'
61   }
62 });
63
64 L.OSM.TracestrackTopo = L.OSM.TileLayer.extend({
65   options: {
66     url: 'https://tile.tracestrack.com/topo__/{z}/{x}/{y}.png?key={apikey}',
67     maxZoom: 19,
68     attribution: '© <a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a> contributors. Tiles courtesy of <a href="https://www.tracestrack.com/" target="_blank">Tracestrack Maps</a>'
69   }
70 });
71
72 L.OSM.GPS = L.OSM.TileLayer.extend({
73   options: {
74     url: 'https://gps.tile.openstreetmap.org/lines/{z}/{x}/{y}.png',
75     maxZoom: 21,
76     maxNativeZoom: 20,
77     subdomains: 'abc'
78   }
79 });
80
81 L.OSM.DataLayer = L.FeatureGroup.extend({
82   options: {
83     areaTags: ['area', 'building', 'leisure', 'tourism', 'ruins', 'historic', 'landuse', 'military', 'natural', 'sport'],
84     uninterestingTags: ['source', 'source_ref', 'source:ref', 'history', 'attribution', 'created_by', 'tiger:county', 'tiger:tlid', 'tiger:upload_uuid'],
85     styles: {}
86   },
87
88   initialize: function (xml, options) {
89     L.Util.setOptions(this, options);
90
91     L.FeatureGroup.prototype.initialize.call(this);
92
93     if (xml) {
94       this.addData(xml);
95     }
96   },
97
98   addData: function (features) {
99     if (!(features instanceof Array)) {
100       features = this.buildFeatures(features);
101     }
102
103     for (var i = 0; i < features.length; i++) {
104       var feature = features[i], layer;
105
106       if (feature.type === "changeset") {
107         layer = L.rectangle(feature.latLngBounds, this.options.styles.changeset);
108       } else if (feature.type === "node") {
109         layer = L.circleMarker(feature.latLng, this.options.styles.node);
110       } else {
111         var latLngs = new Array(feature.nodes.length);
112
113         for (var j = 0; j < feature.nodes.length; j++) {
114           latLngs[j] = feature.nodes[j].latLng;
115         }
116
117         if (this.isWayArea(feature)) {
118           latLngs.pop(); // Remove last == first.
119           layer = L.polygon(latLngs, this.options.styles.area);
120         } else {
121           layer = L.polyline(latLngs, this.options.styles.way);
122         }
123       }
124
125       layer.addTo(this);
126       layer.feature = feature;
127     }
128   },
129
130   buildFeatures: function (xml) {
131     var features = L.OSM.getChangesets(xml),
132       nodes = L.OSM.getNodes(xml),
133       ways = L.OSM.getWays(xml, nodes),
134       relations = L.OSM.getRelations(xml, nodes, ways);
135
136     for (var node_id in nodes) {
137       var node = nodes[node_id];
138       if (this.interestingNode(node, ways, relations)) {
139         features.push(node);
140       }
141     }
142
143     for (var i = 0; i < ways.length; i++) {
144       var way = ways[i];
145       features.push(way);
146     }
147
148     return features;
149   },
150
151   isWayArea: function (way) {
152     if (way.nodes[0] != way.nodes[way.nodes.length - 1]) {
153       return false;
154     }
155
156     for (var key in way.tags) {
157       if (~this.options.areaTags.indexOf(key)) {
158         return true;
159       }
160     }
161
162     return false;
163   },
164
165   interestingNode: function (node, ways, relations) {
166     var used = false;
167
168     for (var i = 0; i < ways.length; i++) {
169       if (ways[i].nodes.indexOf(node) >= 0) {
170         used = true;
171         break;
172       }
173     }
174
175     if (!used) {
176       return true;
177     }
178
179     for (var i = 0; i < relations.length; i++) {
180       if (relations[i].members.indexOf(node) >= 0)
181         return true;
182     }
183
184     for (var key in node.tags) {
185       if (this.options.uninterestingTags.indexOf(key) < 0) {
186         return true;
187       }
188     }
189
190     return false;
191   }
192 });
193
194 L.Util.extend(L.OSM, {
195   getChangesets: function (xml) {
196     var result = [];
197
198     var nodes = xml.getElementsByTagName("changeset");
199     for (var i = 0; i < nodes.length; i++) {
200       var node = nodes[i], id = node.getAttribute("id");
201       result.push({
202         id: id,
203         type: "changeset",
204         latLngBounds: L.latLngBounds(
205           [node.getAttribute("min_lat"), node.getAttribute("min_lon")],
206           [node.getAttribute("max_lat"), node.getAttribute("max_lon")]),
207         tags: this.getTags(node)
208       });
209     }
210
211     return result;
212   },
213
214   getNodes: function (xml) {
215     var result = {};
216
217     var nodes = xml.getElementsByTagName("node");
218     for (var i = 0; i < nodes.length; i++) {
219       var node = nodes[i], id = node.getAttribute("id");
220       result[id] = {
221         id: id,
222         type: "node",
223         latLng: L.latLng(node.getAttribute("lat"),
224                          node.getAttribute("lon"),
225                          true),
226         tags: this.getTags(node)
227       };
228     }
229
230     return result;
231   },
232
233   getWays: function (xml, nodes) {
234     var result = [];
235
236     var ways = xml.getElementsByTagName("way");
237     for (var i = 0; i < ways.length; i++) {
238       var way = ways[i], nds = way.getElementsByTagName("nd");
239
240       var way_object = {
241         id: way.getAttribute("id"),
242         type: "way",
243         nodes: new Array(nds.length),
244         tags: this.getTags(way)
245       };
246
247       for (var j = 0; j < nds.length; j++) {
248         way_object.nodes[j] = nodes[nds[j].getAttribute("ref")];
249       }
250
251       result.push(way_object);
252     }
253
254     return result;
255   },
256
257   getRelations: function (xml, nodes, ways) {
258     var result = [];
259
260     var rels = xml.getElementsByTagName("relation");
261     for (var i = 0; i < rels.length; i++) {
262       var rel = rels[i], members = rel.getElementsByTagName("member");
263
264       var rel_object = {
265         id: rel.getAttribute("id"),
266         type: "relation",
267         members: new Array(members.length),
268         tags: this.getTags(rel)
269       };
270
271       for (var j = 0; j < members.length; j++) {
272         if (members[j].getAttribute("type") === "node")
273           rel_object.members[j] = nodes[members[j].getAttribute("ref")];
274         else // relation-way and relation-relation membership not implemented
275           rel_object.members[j] = null;
276       }
277
278       result.push(rel_object);
279     }
280
281     return result;
282   },
283
284   getTags: function (xml) {
285     var result = {};
286
287     var tags = xml.getElementsByTagName("tag");
288     for (var j = 0; j < tags.length; j++) {
289       result[tags[j].getAttribute("k")] = tags[j].getAttribute("v");
290     }
291
292     return result;
293   }
294 });