4 |
delphine |
1 |
/*global L: true */
|
|
|
2 |
|
|
|
3 |
L.OSM = L.FeatureGroup.extend({
|
|
|
4 |
options: {
|
|
|
5 |
async: true,
|
|
|
6 |
forceAll: false
|
|
|
7 |
},
|
|
|
8 |
|
|
|
9 |
initialize: function(url, options) {
|
|
|
10 |
L.Util.setOptions(this, options);
|
|
|
11 |
this._url = url;
|
|
|
12 |
this._layers = {};
|
|
|
13 |
|
|
|
14 |
if (url) {
|
|
|
15 |
this.addXML(url, options, this.options.async);
|
|
|
16 |
}
|
|
|
17 |
},
|
|
|
18 |
|
|
|
19 |
loadXML: function(url, cb, options, async) {
|
|
|
20 |
if (async == undefined) async = this.options.async;
|
|
|
21 |
if (options == undefined) options = this.options;
|
|
|
22 |
|
|
|
23 |
var req = new window.XMLHttpRequest();
|
|
|
24 |
req.open('GET', url, async);
|
|
|
25 |
req.overrideMimeType('text/xml');
|
|
|
26 |
req.onreadystatechange = function() {
|
|
|
27 |
if (req.readyState != 4) return;
|
|
|
28 |
if(req.status == 200) cb(req.responseXML, options);
|
|
|
29 |
};
|
|
|
30 |
req.send(null);
|
|
|
31 |
},
|
|
|
32 |
|
|
|
33 |
addXML: function(url, options, async) {
|
|
|
34 |
var _this = this;
|
|
|
35 |
var cb = function(xml, options) { _this._addXML(xml, options) };
|
|
|
36 |
this.loadXML(url, cb, options, async);
|
|
|
37 |
},
|
|
|
38 |
|
|
|
39 |
_addXML: function(xml, options) {
|
|
|
40 |
var layers = this.parseOSM(xml, options);
|
|
|
41 |
if (!layers) return;
|
|
|
42 |
this.addLayer(layers);
|
|
|
43 |
this.fire("loaded");
|
|
|
44 |
},
|
|
|
45 |
|
|
|
46 |
parseOSM: function(xml, options) {
|
|
|
47 |
var i, el, ll, layers = [];
|
|
|
48 |
var nodes = {};
|
|
|
49 |
var ways = {};
|
|
|
50 |
var named = false;
|
|
|
51 |
|
|
|
52 |
el = xml.getElementsByTagName('node');
|
|
|
53 |
for (i = 0; i < el.length; i++) {
|
|
|
54 |
var l = this.parse_node(el[i], xml, options);
|
|
|
55 |
if (l == undefined) continue;
|
|
|
56 |
nodes[l.osmid] = l;
|
|
|
57 |
if (!this.options.forceAll && !l.tags.length) continue;
|
|
|
58 |
var m = this.named_node(l, options);
|
|
|
59 |
if (!ll) ll = m.getLatLng();
|
|
|
60 |
if (this.parse_name(m, l, "Node")) named = true;
|
|
|
61 |
layers.push(m);
|
|
|
62 |
}
|
|
|
63 |
|
|
|
64 |
el = xml.getElementsByTagName('way');
|
|
|
65 |
for (i = 0; i < el.length; i++) {
|
|
|
66 |
if (i > 10) break;
|
|
|
67 |
var l = this.parse_way(el[i], nodes, options);
|
|
|
68 |
if (!l) continue;
|
|
|
69 |
if (!ll) ll = l.getLatLngs()[0];
|
|
|
70 |
if (this.parse_name(l, l, "Way")) named = true;
|
|
|
71 |
layers.push(l);
|
|
|
72 |
ways[l.osmid] = l;
|
|
|
73 |
}
|
|
|
74 |
|
|
|
75 |
el = xml.getElementsByTagName('relation');
|
|
|
76 |
for (i = 0; i < el.length; i++) {
|
|
|
77 |
if (i > 10) break;
|
|
|
78 |
var l = this.parse_relation(el[i], ways, options);
|
|
|
79 |
if (!l) continue;
|
|
|
80 |
if (!ll) ll = l.getLatLngs()[0];
|
|
|
81 |
if (this.parse_name(l, l, "Relation")) named = true;
|
|
|
82 |
layers.push(l);
|
|
|
83 |
}
|
|
|
84 |
|
|
|
85 |
if (!layers.length) return;
|
|
|
86 |
var layer = layers[0];
|
|
|
87 |
if (layers.length > 1)
|
|
|
88 |
layer = new L.FeatureGroup(layers);
|
|
|
89 |
if (!named) this.parse_name(xml, layer);
|
|
|
90 |
layer.focusPoint = ll;
|
|
|
91 |
return layer;
|
|
|
92 |
},
|
|
|
93 |
|
|
|
94 |
parse_name: function(layer, obj, obj_name) {
|
|
|
95 |
console.info("parse name");
|
|
|
96 |
console.info(this.options);
|
|
|
97 |
if (!this.options.forceAll)
|
|
|
98 |
if (!obj.tags || !obj.tags.length) return;
|
|
|
99 |
var i, txt = "<table>";
|
|
|
100 |
for (i = 0; i < obj.tags.length; i++) {
|
|
|
101 |
var t = obj.tags[i];
|
|
|
102 |
txt += "<tr><td>" + t.k + "</td><td>=</td><td>" + t.v + "</td></tr>";
|
|
|
103 |
}
|
|
|
104 |
txt += "</table>"
|
|
|
105 |
txt = "<h2>" + obj_name + " " + obj.osmid + "</h2>" + txt;
|
|
|
106 |
if (layer) layer.bindPopup(txt);
|
|
|
107 |
return txt;
|
|
|
108 |
},
|
|
|
109 |
|
|
|
110 |
parse_tags: function(line) {
|
|
|
111 |
var tags = [], el = line.getElementsByTagName('tag');
|
|
|
112 |
for (var i = 0; i < el.length; i++)
|
|
|
113 |
tags.push({k: el[i].getAttribute('k'), v: el[i].getAttribute('v')})
|
|
|
114 |
return tags;
|
|
|
115 |
},
|
|
|
116 |
|
|
|
117 |
parse_node: function(e) {
|
|
|
118 |
var n = { osmid: e.getAttribute('id')
|
|
|
119 |
, lat:e.getAttribute('lat')
|
|
|
120 |
, lon:e.getAttribute('lon')
|
|
|
121 |
}
|
|
|
122 |
n.ll = new L.LatLng(n.lat, n.lon);
|
|
|
123 |
n.tags = this.parse_tags(e);
|
|
|
124 |
return n;
|
|
|
125 |
},
|
|
|
126 |
|
|
|
127 |
parse_way: function(line, nodes, options) {
|
|
|
128 |
var el = line.getElementsByTagName('nd');
|
|
|
129 |
if (!el.length) return;
|
|
|
130 |
var coords = [], tags = [];
|
|
|
131 |
for (var i = 0; i < el.length; i++) {
|
|
|
132 |
var ref = el[i].getAttribute('ref'), n = nodes[ref];
|
|
|
133 |
if (!n) return;
|
|
|
134 |
coords.push(n.ll);
|
|
|
135 |
}
|
|
|
136 |
var layer = new L.Polyline(coords, options);
|
|
|
137 |
layer.tags = this.parse_tags(line);
|
|
|
138 |
layer.osmid = line.getAttribute('id')
|
|
|
139 |
return layer;
|
|
|
140 |
},
|
|
|
141 |
|
|
|
142 |
parse_relation: function(line, ways, options) {
|
|
|
143 |
var el = line.getElementsByTagName('member');
|
|
|
144 |
if (!el.length) return;
|
|
|
145 |
var rt, coords = [], tags = this.parse_tags(line);
|
|
|
146 |
for (var i = 0; i < tags.length; i++)
|
|
|
147 |
if (tags[i].k == "type") rt = tags[i].v;
|
|
|
148 |
|
|
|
149 |
if (rt != "multipolygon" && rt != "boundary" && rt != "waterway")
|
|
|
150 |
return;
|
|
|
151 |
|
|
|
152 |
for (var i = 0; i < el.length; i++) {
|
|
|
153 |
var mt = el[i].getAttribute("type"), ref = el[i].getAttribute("ref");
|
|
|
154 |
if (mt != "way") continue;
|
|
|
155 |
var w = ways[ref];
|
|
|
156 |
console.info("Way: " + ref + " " + w);
|
|
|
157 |
if (!w) return;
|
|
|
158 |
coords.push(w);
|
|
|
159 |
}
|
|
|
160 |
console.info("Coords: " + coords.length);
|
|
|
161 |
if (!coords.length) return;
|
|
|
162 |
var layer = new L.MultiPolyline(coords, options);
|
|
|
163 |
layer.tags = this.parse_tags(line);
|
|
|
164 |
layer.osmid = line.getAttribute('id')
|
|
|
165 |
return layer;
|
|
|
166 |
},
|
|
|
167 |
|
|
|
168 |
named_node: function(node, options) {
|
|
|
169 |
var marker = new L.Marker(new L.LatLng(node.lat, node.lon), options);
|
|
|
170 |
return marker;
|
|
|
171 |
}
|
|
|
172 |
});
|