Subversion Repositories eFlore/Applications.moissonnage

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4 delphine 1
/*global L: true */
2
 
3
L.KML = L.FeatureGroup.extend({
4
	options: {
5
		async: true
6
	},
7
 
8
	initialize: function(kml, options) {
9
		L.Util.setOptions(this, options);
10
		this._kml = kml;
11
		this._layers = {};
12
 
13
		if (kml) {
14
			this.addKML(kml, options, this.options.async);
15
		}
16
	},
17
 
18
	loadXML: function(url, cb, options, async) {
19
		if (async == undefined) async = this.options.async;
20
		if (options == undefined) options = this.options;
21
 
22
		var req = new window.XMLHttpRequest();
23
		req.open('GET', url, async);
24
		try {
25
			req.overrideMimeType('text/xml'); // unsupported by IE
26
		} catch(e) {}
27
		req.onreadystatechange = function() {
28
			if (req.readyState != 4) return;
29
			if(req.status == 200) cb(req.responseXML, options);
30
		};
31
		req.send(null);
32
	},
33
 
34
	addKML: function(url, options, async) {
35
		var _this = this;
36
		var cb = function(gpx, options) { _this._addKML(gpx, options) };
37
		this.loadXML(url, cb, options, async);
38
	},
39
 
40
	_addKML: function(xml, options) {
41
		var layers = L.KML.parseKML(xml);
42
		if (!layers || !layers.length) return;
43
		for (var i = 0; i < layers.length; i++)
44
		{
45
			this.fire('addlayer', {
46
				layer: layers[i]
47
			});
48
			this.addLayer(layers[i]);
49
		}
50
		this.latLngs = L.KML.getLatLngs(xml);
51
		this.fire("loaded");
52
	},
53
 
54
	latLngs: []
55
});
56
 
57
L.Util.extend(L.KML, {
58
 
59
	parseKML: function (xml) {
60
		var style = this.parseStyle(xml);
61
		var el = xml.getElementsByTagName("Folder");
62
		var layers = [], l;
63
		for (var i = 0; i < el.length; i++) {
64
			if (!this._check_folder(el[i])) { continue; }
65
			l = this.parseFolder(el[i], style);
66
			if (l) { layers.push(l); }
67
		}
68
		el = xml.getElementsByTagName('Placemark');
69
		for (var j = 0; j < el.length; j++) {
70
			if (!this._check_folder(el[j])) { continue; }
71
			l = this.parsePlacemark(el[j], xml, style);
72
			if (l) { layers.push(l); }
73
		}
74
		return layers;
75
	},
76
 
77
	// Return false if e's first parent Folder is not [folder]
78
	// - returns true if no parent Folders
79
	_check_folder: function (e, folder) {
80
		e = e.parentElement;
81
		while (e && e.tagName !== "Folder")
82
		{
83
			e = e.parentElement;
84
		}
85
		return !e || e === folder;
86
	},
87
 
88
	parseStyle: function (xml) {
89
		var style = {};
90
		var sl = xml.getElementsByTagName("Style");
91
 
92
		//for (var i = 0; i < sl.length; i++) {
93
		var attributes = {color: true, width: true, Icon: true, href: true,
94
						  hotSpot: true};
95
 
96
		function _parse(xml) {
97
			var options = {};
98
			for (var i = 0; i < xml.childNodes.length; i++) {
99
				var e = xml.childNodes[i];
100
				var key = e.tagName;
101
				if (!attributes[key]) { continue; }
102
				if (key === 'hotSpot')
103
				{
104
					for (var j = 0; j < e.attributes.length; j++) {
105
						options[e.attributes[j].name] = e.attributes[j].nodeValue;
106
					}
107
				} else {
108
					var value = e.childNodes[0].nodeValue;
109
					if (key === 'color') {
110
						options.opacity = parseInt(value.substring(0, 2), 16) / 255.0;
111
						options.color = "#" + value.substring(2, 8);
112
					} else if (key === 'width') {
113
						options.weight = value;
114
					} else if (key === 'Icon') {
115
						ioptions = _parse(e);
116
						if (ioptions.href) { options.href = ioptions.href; }
117
					} else if (key === 'href') {
118
						options.href = value;
119
					}
120
				}
121
			}
122
			return options;
123
		}
124
 
125
		for (var i = 0; i < sl.length; i++) {
126
			var e = sl[i], el;
127
			var options = {}, poptions = {}, ioptions = {};
128
			el = e.getElementsByTagName("LineStyle");
129
			if (el && el[0]) { options = _parse(el[0]); }
130
			el = e.getElementsByTagName("PolyStyle");
131
			if (el && el[0]) { poptions = _parse(el[0]); }
132
			if (poptions.color) { options.fillColor = poptions.color; }
133
			if (poptions.opacity) { options.fillOpacity = poptions.opacity; }
134
			el = e.getElementsByTagName("IconStyle");
135
			if (el && el[0]) { ioptions = _parse(el[0]); }
136
			if (ioptions.href) {
137
				// save anchor info until the image is loaded
138
				options.icon = new L.KMLIcon({
139
					iconUrl: ioptions.href,
140
					shadowUrl: null,
141
					iconAnchorRef: {x: ioptions.x, y: ioptions.y},
142
					iconAnchorType:	{x: ioptions.xunits, y: ioptions.yunits}
143
				});
144
			}
145
			style['#' + e.getAttribute('id')] = options;
146
		}
147
		return style;
148
	},
149
 
150
	parseFolder: function (xml, style) {
151
		var el, layers = [], l;
152
		el = xml.getElementsByTagName('Folder');
153
		for (var i = 0; i < el.length; i++) {
154
			if (!this._check_folder(el[i], xml)) { continue; }
155
			l = this.parseFolder(el[i], style);
156
			if (l) { layers.push(l); }
157
		}
158
		el = xml.getElementsByTagName('Placemark');
159
		for (var j = 0; j < el.length; j++) {
160
			if (!this._check_folder(el[j], xml)) { continue; }
161
			l = this.parsePlacemark(el[j], xml, style);
162
			if (l) { layers.push(l); }
163
		}
164
		if (!layers.length) { return; }
165
		if (layers.length === 1) { return layers[0]; }
166
		return new L.FeatureGroup(layers);
167
	},
168
 
169
	parsePlacemark: function (place, xml, style) {
170
		var i, j, el, options = {};
171
		el = place.getElementsByTagName('styleUrl');
172
		for (i = 0; i < el.length; i++) {
173
			var url = el[i].childNodes[0].nodeValue;
174
			for (var a in style[url])
175
			{
176
				// for jshint
177
				if (true)
178
				{
179
					options[a] = style[url][a];
180
				}
181
			}
182
		}
183
		var layers = [];
184
 
185
		var parse = ['LineString', 'Polygon', 'Point'];
186
		for (j in parse) {
187
			// for jshint
188
			if (true)
189
			{
190
				var tag = parse[j];
191
				el = place.getElementsByTagName(tag);
192
				for (i = 0; i < el.length; i++) {
193
					var l = this["parse" + tag](el[i], xml, options);
194
					if (l) { layers.push(l); }
195
				}
196
			}
197
		}
198
 
199
		if (!layers.length) {
200
			return;
201
		}
202
		var layer = layers[0];
203
		if (layers.length > 1) {
204
			layer = new L.FeatureGroup(layers);
205
		}
206
 
207
		var name, descr = "";
208
		el = place.getElementsByTagName('name');
209
		if (el.length) {
210
			name = el[0].childNodes[0].nodeValue;
211
		}
212
		el = place.getElementsByTagName('description');
213
		for (i = 0; i < el.length; i++) {
214
			for (j = 0; j < el[i].childNodes.length; j++) {
215
				descr = descr + el[i].childNodes[j].nodeValue;
216
			}
217
		}
218
 
219
		if (name) {
220
			layer.bindPopup("<h2>" + name + "</h2>" + descr);
221
		}
222
 
223
		return layer;
224
	},
225
 
226
	parseCoords: function (xml) {
227
		var el = xml.getElementsByTagName('coordinates');
228
		return this._read_coords(el[0]);
229
	},
230
 
231
	parseLineString: function (line, xml, options) {
232
		var coords = this.parseCoords(line);
233
		if (!coords.length) { return; }
234
		return new L.Polyline(coords, options);
235
	},
236
 
237
	parsePoint: function (line, xml, options) {
238
		var el = line.getElementsByTagName('coordinates');
239
		if (!el.length) {
240
			return;
241
		}
242
		var ll = el[0].childNodes[0].nodeValue.split(',');
243
		return new L.KMLMarker(new L.LatLng(ll[1], ll[0]), options);
244
	},
245
 
246
	parsePolygon: function (line, xml, options) {
247
		var el, polys = [], inner = [], i, coords;
248
		el = line.getElementsByTagName('outerBoundaryIs');
249
		for (i = 0; i < el.length; i++) {
250
			coords = this.parseCoords(el[i]);
251
			if (coords) {
252
				polys.push(coords);
253
			}
254
		}
255
		el = line.getElementsByTagName('innerBoundaryIs');
256
		for (i = 0; i < el.length; i++) {
257
			coords = this.parseCoords(el[i]);
258
			if (coords) {
259
				inner.push(coords);
260
			}
261
		}
262
		if (!polys.length) {
263
			return;
264
		}
265
		if (options.fillColor) {
266
			options.fill = true;
267
		}
268
		if (polys.length === 1) {
269
			return new L.Polygon(polys.concat(inner), options);
270
		}
271
		return new L.MultiPolygon(polys, options);
272
	},
273
 
274
	getLatLngs: function (xml) {
275
		var el = xml.getElementsByTagName('coordinates');
276
		var coords = [];
277
		for (var j = 0; j < el.length; j++) {
278
			// text might span many childnodes
279
			coords = coords.concat(this._read_coords(el[j]));
280
		}
281
		return coords;
282
	},
283
 
284
	_read_coords: function (el) {
285
		var text = "", coords = [], i;
286
		for (i = 0; i < el.childNodes.length; i++) {
287
			text = text + el.childNodes[i].nodeValue;
288
		}
289
		text = text.split(/[\s\n]+/);
290
		for (i = 0; i < text.length; i++) {
291
			var ll = text[i].split(',');
292
			if (ll.length < 2) {
293
				continue;
294
			}
295
			coords.push(new L.LatLng(ll[1], ll[0]));
296
		}
297
		return coords;
298
	}
299
 
300
});
301
 
302
L.KMLIcon = L.Icon.extend({
303
 
304
	createIcon: function () {
305
		var img = this._createIcon('icon');
306
		img.onload = function () {
307
			var i = new Image();
308
			i.src = this.src;
309
			this.style.width = i.width + 'px';
310
			this.style.height = i.height + 'px';
311
 
312
			if (this.anchorType.x === 'UNITS_FRACTION' || this.anchorType.x === 'fraction') {
313
				img.style.marginLeft = (-this.anchor.x * i.width) + 'px';
314
			}
315
			if (this.anchorType.y === 'UNITS_FRACTION' || this.anchorType.x === 'fraction') {
316
				img.style.marginTop  = (-(1 - this.anchor.y) * i.height) + 'px';
317
			}
318
			this.style.display = "";
319
		};
320
		return img;
321
	},
322
 
323
	_setIconStyles: function (img, name) {
324
		L.Icon.prototype._setIconStyles.apply(this, [img, name])
325
		// save anchor information to the image
326
		img.anchor = this.options.iconAnchorRef;
327
		img.anchorType = this.options.iconAnchorType;
328
	}
329
});
330
 
331
 
332
L.KMLMarker = L.Marker.extend({
333
	options: {
334
		icon: new L.KMLIcon.Default()
335
	}
336
});
337