Subversion Repositories eFlore/Applications.moissonnage

Rev

Rev 28 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 28 Rev 31
1
/*
1
/*
2
 * 
2
 * 
3
 * Copyright (c) 2011-2012, Pavel Shramov
3
 * Copyright (c) 2011-2012, Pavel Shramov
4
 * All rights reserved. 
4
 * All rights reserved. 
5
 * 
5
 * 
6
 * Redistribution and use in source and binary forms, with or without modification, are 
6
 * Redistribution and use in source and binary forms, with or without modification, are 
7
 * permitted provided that the following conditions are met: 
7
 * permitted provided that the following conditions are met: 
8
 * 
8
 * 
9
 *    1. Redistributions of source code must retain the above copyright notice, this list of 
9
 *    1. Redistributions of source code must retain the above copyright notice, this list of 
10
 *       conditions and the following disclaimer. 
10
 *       conditions and the following disclaimer. 
11
 * 	  
11
 * 	  
12
 *    2. Redistributions in binary form must reproduce the above copyright notice, this list 
12
 *    2. Redistributions in binary form must reproduce the above copyright notice, this list 
13
 *       of conditions and the following disclaimer in the documentation and/or other materials
13
 *       of conditions and the following disclaimer in the documentation and/or other materials
14
 *       provided with the distribution. 
14
 *       provided with the distribution. 
15
 * 
15
 * 
16
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
16
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
17
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
17
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
18
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
18
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
19
 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
19
 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
20
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
20
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
21
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
21
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
22
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 
22
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 
23
 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
23
 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
24
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 * 
25
 * 
26
 */
26
 */
-
 
27
 
-
 
28
// Adaptation Alexandre GALIBERT :
-
 
29
//   - Define fill opacity for polygons at 0 for transparent rendering
-
 
30
//   - Disable creation of icons for KML elements
-
 
31
//   - Specific beahaviour to add an array of files by their urls. A variable will define
-
 
32
//     the status of the processing (BUSY or READY) and managed with a counter for the number
-
 
33
//     of files remaining to parse. Once all files parsed, the map zooms on KML spatial elements
-
 
34
 
-
 
35
const KML_READY = 0;
-
 
36
const KML_BUSY = 1;
27
 
37
 
28
 
38
 
29
L.KML = L.FeatureGroup.extend({
39
L.KML = L.FeatureGroup.extend({
30
	options: {
40
	options: {
31
		async: true
41
		async: true
32
	},
42
	},
33
 
43
 
34
	initialize: function(kml, options) {
44
	initialize: function(kml, options) {
35
		L.Util.setOptions(this, options);
45
		L.Util.setOptions(this, options);
36
		this._kml = kml;
46
		this._kml = kml;
-
 
47
		this._status = KML_READY;
-
 
48
		this._onWaiting = 0;
37
		this._layers = {};
49
		this._layers = {};
38
 
50
 
39
		if (kml) {
51
		if (kml) {
40
			this.addKML(kml, options, this.options.async);
52
			this.addKML(kml, options, this.options.async);
41
		}
53
		}
42
	},
54
	},
43
 
55
 
44
	loadXML: function(url, cb, options, async) {
56
	loadXML: function(url, cb, options, async) {
45
		if (async == undefined) async = this.options.async;
57
		if (async == undefined) async = this.options.async;
46
		if (options == undefined) options = this.options;
58
		if (options == undefined) options = this.options;
47
 
59
 
48
		var req = new window.XMLHttpRequest();
60
		var req = new window.XMLHttpRequest();
49
		req.open('GET', url, async);
61
		req.open('GET', url, async);
50
		try {
62
		try {
51
			req.overrideMimeType('text/xml'); // unsupported by IE
63
			req.overrideMimeType('text/xml'); // unsupported by IE
52
		} catch(e) {}
64
		} catch(e) {}
53
		req.onreadystatechange = function() {
65
		req.onreadystatechange = function() {
54
			if (req.readyState != 4) return;
66
			if (req.readyState != 4) return;
55
			if(req.status == 200) cb(req.responseXML, options);
67
			if(req.status == 200) cb(req.responseXML, options);
56
		};
68
		};
57
		req.send(null);
69
		req.send(null);
58
	},
70
	},
-
 
71
 
-
 
72
	addKMLFiles: function(urlList, options, async) {
-
 
73
		this._status = KML_BUSY;
-
 
74
		this._onWaiting = urlList.length;
-
 
75
		for (var index = 0; index < urlList.length; index ++) {
-
 
76
			this.addKML(urlList[index], options, async);
-
 
77
		}
-
 
78
	},
59
 
79
	
60
	addKML: function(url, options, async) {
80
	addKML: function(url, options, async) {
61
		var _this = this;
81
		var _this = this;
62
		var cb = function(gpx, options) { _this._addKML(gpx, options) };
82
		var cb = function(gpx, options) { _this._addKML(gpx, options) };
63
		this.loadXML(url, cb, options, async);
83
		this.loadXML(url, cb, options, async);
64
	},
84
	},
65
 
85
 
66
	_addKML: function(xml, options) {
86
	_addKML: function(xml, options) {
67
		var layers = L.KML.parseKML(xml);
87
		var layers = L.KML.parseKML(xml);
68
		if (!layers || !layers.length) return;
88
		if (!layers || !layers.length) return;
69
		for (var i = 0; i < layers.length; i++)
89
		for (var i = 0; i < layers.length; i++)
70
		{
90
		{
71
			this.fire('addlayer', {
91
			this.fire('addlayer', {
72
				layer: layers[i]
92
				layer: layers[i]
73
			});
93
			});
74
			this.addLayer(layers[i]);
94
			this.addLayer(layers[i]);
75
		}
95
		}
76
		this.latLngs = L.KML.getLatLngs(xml);
96
		this.latLngs = L.KML.getLatLngs(xml);
77
		this.fire("loaded");
97
		this.fire("loaded");
-
 
98
		this._onWaiting --;
-
 
99
		if (this._onWaiting == 0) {
-
 
100
			this._status = KML_READY;
-
 
101
			this._map.fitBounds(this.getBounds());
-
 
102
		}
-
 
103
	},
-
 
104
	
-
 
105
	getStatus: function() {
-
 
106
		return this._status;
78
	},
107
	},
79
 
108
 
80
	latLngs: []
109
	latLngs: []
81
});
110
});
82
 
111
 
83
L.Util.extend(L.KML, {
112
L.Util.extend(L.KML, {
84
 
113
 
85
	parseKML: function (xml) {
114
	parseKML: function (xml) {
86
		var style = this.parseStyle(xml);
115
		var style = this.parseStyle(xml);
87
		var el = xml.getElementsByTagName("Folder");
116
		var el = xml.getElementsByTagName("Folder");
88
		var layers = [], l;
117
		var layers = [], l;
89
		for (var i = 0; i < el.length; i++) {
118
		for (var i = 0; i < el.length; i++) {
90
			if (!this._check_folder(el[i])) { continue; }
119
			if (!this._check_folder(el[i])) { continue; }
91
			l = this.parseFolder(el[i], style);
120
			l = this.parseFolder(el[i], style);
92
			if (l) { layers.push(l); }
121
			if (l) { layers.push(l); }
93
		}
122
		}
94
		el = xml.getElementsByTagName('Placemark');
123
		el = xml.getElementsByTagName('Placemark');
95
		for (var j = 0; j < el.length; j++) {
124
		for (var j = 0; j < el.length; j++) {
96
			if (!this._check_folder(el[j])) { continue; }
125
			if (!this._check_folder(el[j])) { continue; }
97
			l = this.parsePlacemark(el[j], xml, style);
126
			l = this.parsePlacemark(el[j], xml, style);
98
			if (l) { layers.push(l); }
127
			if (l) { layers.push(l); }
99
		}
128
		}
100
		return layers;
129
		return layers;
101
	},
130
	},
102
 
131
 
103
	// Return false if e's first parent Folder is not [folder]
132
	// Return false if e's first parent Folder is not [folder]
104
	// - returns true if no parent Folders
133
	// - returns true if no parent Folders
105
	_check_folder: function (e, folder) {
134
	_check_folder: function (e, folder) {
106
		e = e.parentElement;
135
		e = e.parentElement;
107
		while (e && e.tagName !== "Folder")
136
		while (e && e.tagName !== "Folder")
108
		{
137
		{
109
			e = e.parentElement;
138
			e = e.parentElement;
110
		}
139
		}
111
		return !e || e === folder;
140
		return !e || e === folder;
112
	},
141
	},
113
 
142
 
114
	parseStyle: function (xml) {
143
	parseStyle: function (xml) {
115
		var style = {};
144
		var style = {};
116
		var sl = xml.getElementsByTagName("Style");
145
		var sl = xml.getElementsByTagName("Style");
117
 
146
 
118
		//for (var i = 0; i < sl.length; i++) {
147
		//for (var i = 0; i < sl.length; i++) {
119
		var attributes = {color: true, width: true, Icon: true, href: true,
148
		var attributes = {color: true, width: true, Icon: true, href: true,
120
						  hotSpot: true};
149
						  hotSpot: true};
121
 
150
 
122
		function _parse(xml) {
151
		function _parse(xml) {
123
			var options = {};
152
			var options = {};
124
			for (var i = 0; i < xml.childNodes.length; i++) {
153
			for (var i = 0; i < xml.childNodes.length; i++) {
125
				var e = xml.childNodes[i];
154
				var e = xml.childNodes[i];
126
				var key = e.tagName;
155
				var key = e.tagName;
127
				if (!attributes[key]) { continue; }
156
				if (!attributes[key]) { continue; }
128
				if (key === 'hotSpot')
157
				if (key === 'hotSpot')
129
				{
158
				{
130
					for (var j = 0; j < e.attributes.length; j++) {
159
					for (var j = 0; j < e.attributes.length; j++) {
131
						options[e.attributes[j].name] = e.attributes[j].nodeValue;
160
						options[e.attributes[j].name] = e.attributes[j].nodeValue;
132
					}
161
					}
133
				} else {
162
				} else {
134
					var value = e.childNodes[0].nodeValue;
163
					var value = e.childNodes[0].nodeValue;
135
					if (key === 'color') {
164
					if (key === 'color') {
136
						options.opacity = parseInt(value.substring(0, 2), 16) / 255.0;
165
						options.opacity = parseInt(value.substring(0, 2), 16) / 255.0;
137
						options.color = "#" + value.substring(2, 8);
166
						options.color = "#" + value.substring(2, 8);
138
					} else if (key === 'width') {
167
					} else if (key === 'width') {
139
						options.weight = value;
168
						options.weight = value;
140
					} else if (key === 'Icon') {
169
					} /*else if (key === 'Icon') {
141
						ioptions = _parse(e);
170
						ioptions = _parse(e);
142
						if (ioptions.href) { options.href = ioptions.href; }
171
						if (ioptions.href) { options.href = ioptions.href; }
143
					} else if (key === 'href') {
172
					}*/ else if (key === 'href') {
144
						options.href = value;
173
						options.href = value;
145
					}
174
					}
146
				}
175
				}
147
			}
176
			}
-
 
177
			options.fillOpacity = 0;
148
			return options;
178
			return options;
149
		}
179
		}
150
 
180
 
151
		for (var i = 0; i < sl.length; i++) {
181
		for (var i = 0; i < sl.length; i++) {
152
			var e = sl[i], el;
182
			var e = sl[i], el;
153
			var options = {}, poptions = {}, ioptions = {};
183
			var options = {}, poptions = {}, ioptions = {};
154
			el = e.getElementsByTagName("LineStyle");
184
			el = e.getElementsByTagName("LineStyle");
155
			if (el && el[0]) { options = _parse(el[0]); }
185
			if (el && el[0]) { options = _parse(el[0]); }
156
			el = e.getElementsByTagName("PolyStyle");
186
			el = e.getElementsByTagName("PolyStyle");
157
			if (el && el[0]) { poptions = _parse(el[0]); }
187
			if (el && el[0]) { poptions = _parse(el[0]); }
158
			if (poptions.color) { options.fillColor = poptions.color; }
188
			if (poptions.color) { options.fillColor = poptions.color; }
159
			if (poptions.opacity) { options.fillOpacity = poptions.opacity; }
189
			if (poptions.opacity) { options.fillOpacity = poptions.opacity; }
160
			el = e.getElementsByTagName("IconStyle");
190
			el = e.getElementsByTagName("IconStyle");
161
			if (el && el[0]) { ioptions = _parse(el[0]); }
191
			if (el && el[0]) { ioptions = _parse(el[0]); }
162
			if (ioptions.href) {
192
			if (ioptions.href) {
163
				// save anchor info until the image is loaded
193
				// save anchor info until the image is loaded
164
				options.icon = new L.KMLIcon({
194
				options.icon = new L.KMLIcon({
165
					iconUrl: ioptions.href,
195
					iconUrl: ioptions.href,
166
					shadowUrl: null,
196
					shadowUrl: null,
167
					iconAnchorRef: {x: ioptions.x, y: ioptions.y},
197
					iconAnchorRef: {x: ioptions.x, y: ioptions.y},
168
					iconAnchorType:	{x: ioptions.xunits, y: ioptions.yunits}
198
					iconAnchorType:	{x: ioptions.xunits, y: ioptions.yunits}
169
				});
199
				});
170
			}
200
			}
171
			style['#' + e.getAttribute('id')] = options;
201
			style['#' + e.getAttribute('id')] = options;
172
		}
202
		}
173
		return style;
203
		return style;
174
	},
204
	},
175
 
205
 
176
	parseFolder: function (xml, style) {
206
	parseFolder: function (xml, style) {
177
		var el, layers = [], l;
207
		var el, layers = [], l;
178
		el = xml.getElementsByTagName('Folder');
208
		el = xml.getElementsByTagName('Folder');
179
		for (var i = 0; i < el.length; i++) {
209
		for (var i = 0; i < el.length; i++) {
180
			if (!this._check_folder(el[i], xml)) { continue; }
210
			if (!this._check_folder(el[i], xml)) { continue; }
181
			l = this.parseFolder(el[i], style);
211
			l = this.parseFolder(el[i], style);
182
			if (l) { layers.push(l); }
212
			if (l) { layers.push(l); }
183
		}
213
		}
184
		el = xml.getElementsByTagName('Placemark');
214
		el = xml.getElementsByTagName('Placemark');
185
		for (var j = 0; j < el.length; j++) {
215
		for (var j = 0; j < el.length; j++) {
186
			if (!this._check_folder(el[j], xml)) { continue; }
216
			if (!this._check_folder(el[j], xml)) { continue; }
187
			l = this.parsePlacemark(el[j], xml, style);
217
			l = this.parsePlacemark(el[j], xml, style);
188
			if (l) { layers.push(l); }
218
			if (l) { layers.push(l); }
189
		}
219
		}
190
		if (!layers.length) { return; }
220
		if (!layers.length) { return; }
191
		if (layers.length === 1) { return layers[0]; }
221
		if (layers.length === 1) { return layers[0]; }
192
		return new L.FeatureGroup(layers);
222
		return new L.FeatureGroup(layers);
193
	},
223
	},
194
 
224
 
195
	parsePlacemark: function (place, xml, style) {
225
	parsePlacemark: function (place, xml, style) {
196
		var i, j, el, options = {};
226
		var i, j, el, options = {};
197
		el = place.getElementsByTagName('styleUrl');
227
		el = place.getElementsByTagName('styleUrl');
198
		for (i = 0; i < el.length; i++) {
228
		for (i = 0; i < el.length; i++) {
199
			var url = el[i].childNodes[0].nodeValue;
229
			var url = el[i].childNodes[0].nodeValue;
200
			for (var a in style[url])
230
			for (var a in style[url])
201
			{
231
			{
202
				// for jshint
232
				// for jshint
203
				if (true)
233
				if (true)
204
				{
234
				{
205
					options[a] = style[url][a];
235
					options[a] = style[url][a];
206
				}
236
				}
207
			}
237
			}
208
		}
238
		}
209
		var layers = [];
239
		var layers = [];
210
 
240
 
211
		var parse = ['LineString', 'Polygon', 'Point'];
241
		var parse = ['LineString', 'Polygon', 'Point'];
212
		for (j in parse) {
242
		for (j in parse) {
213
			// for jshint
243
			// for jshint
214
			if (true)
244
			if (true)
215
			{
245
			{
216
				var tag = parse[j];
246
				var tag = parse[j];
217
				el = place.getElementsByTagName(tag);
247
				el = place.getElementsByTagName(tag);
218
				for (i = 0; i < el.length; i++) {
248
				for (i = 0; i < el.length; i++) {
219
					var l = this["parse" + tag](el[i], xml, options);
249
					var l = this["parse" + tag](el[i], xml, options);
220
					if (l) { layers.push(l); }
250
					if (l) { layers.push(l); }
221
				}
251
				}
222
			}
252
			}
223
		}
253
		}
224
 
254
 
225
		if (!layers.length) {
255
		if (!layers.length) {
226
			return;
256
			return;
227
		}
257
		}
228
		var layer = layers[0];
258
		var layer = layers[0];
229
		if (layers.length > 1) {
259
		if (layers.length > 1) {
230
			layer = new L.FeatureGroup(layers);
260
			layer = new L.FeatureGroup(layers);
231
		}
261
		}
232
 
262
 
233
		var name, descr = "";
263
		var name, descr = "";
234
		el = place.getElementsByTagName('name');
264
		el = place.getElementsByTagName('name');
235
		if (el.length) {
265
		if (el.length) {
236
			name = el[0].childNodes[0].nodeValue;
266
			name = el[0].childNodes[0].nodeValue;
237
		}
267
		}
238
		el = place.getElementsByTagName('description');
268
		el = place.getElementsByTagName('description');
239
		for (i = 0; i < el.length; i++) {
269
		for (i = 0; i < el.length; i++) {
240
			for (j = 0; j < el[i].childNodes.length; j++) {
270
			for (j = 0; j < el[i].childNodes.length; j++) {
241
				descr = descr + el[i].childNodes[j].nodeValue;
271
				descr = descr + el[i].childNodes[j].nodeValue;
242
			}
272
			}
243
		}
273
		}
244
 
274
 
245
		if (name) {
275
		if (name) {
246
			layer.bindPopup("<h2>" + name + "</h2>" + descr);
276
			layer.bindPopup("<h2>" + name + "</h2>" + descr);
247
		}
277
		}
248
 
278
 
249
		return layer;
279
		return layer;
250
	},
280
	},
251
 
281
 
252
	parseCoords: function (xml) {
282
	parseCoords: function (xml) {
253
		var el = xml.getElementsByTagName('coordinates');
283
		var el = xml.getElementsByTagName('coordinates');
254
		return this._read_coords(el[0]);
284
		return this._read_coords(el[0]);
255
	},
285
	},
256
 
286
 
257
	parseLineString: function (line, xml, options) {
287
	parseLineString: function (line, xml, options) {
258
		var coords = this.parseCoords(line);
288
		var coords = this.parseCoords(line);
259
		if (!coords.length) { return; }
289
		if (!coords.length) { return; }
260
		return new L.Polyline(coords, options);
290
		return new L.Polyline(coords, options);
261
	},
291
	},
262
 
292
 
263
	parsePoint: function (line, xml, options) {
293
	parsePoint: function (line, xml, options) {
264
		var el = line.getElementsByTagName('coordinates');
294
		var el = line.getElementsByTagName('coordinates');
265
		if (!el.length) {
295
		if (!el.length) {
266
			return;
296
			return;
267
		}
297
		}
268
		var ll = el[0].childNodes[0].nodeValue.split(',');
298
		var ll = el[0].childNodes[0].nodeValue.split(',');
269
		return new L.KMLMarker(new L.LatLng(ll[1], ll[0]), options);
299
		return new L.KMLMarker(new L.LatLng(ll[1], ll[0]), options);
270
	},
300
	},
271
 
301
 
272
	parsePolygon: function (line, xml, options) {
302
	parsePolygon: function (line, xml, options) {
273
		var el, polys = [], inner = [], i, coords;
303
		var el, polys = [], inner = [], i, coords;
274
		el = line.getElementsByTagName('outerBoundaryIs');
304
		el = line.getElementsByTagName('outerBoundaryIs');
275
		for (i = 0; i < el.length; i++) {
305
		for (i = 0; i < el.length; i++) {
276
			coords = this.parseCoords(el[i]);
306
			coords = this.parseCoords(el[i]);
277
			if (coords) {
307
			if (coords) {
278
				polys.push(coords);
308
				polys.push(coords);
279
			}
309
			}
280
		}
310
		}
281
		el = line.getElementsByTagName('innerBoundaryIs');
311
		el = line.getElementsByTagName('innerBoundaryIs');
282
		for (i = 0; i < el.length; i++) {
312
		for (i = 0; i < el.length; i++) {
283
			coords = this.parseCoords(el[i]);
313
			coords = this.parseCoords(el[i]);
284
			if (coords) {
314
			if (coords) {
285
				inner.push(coords);
315
				inner.push(coords);
286
			}
316
			}
287
		}
317
		}
288
		if (!polys.length) {
318
		if (!polys.length) {
289
			return;
319
			return;
290
		}
320
		}
291
		if (options.fillColor) {
321
		if (options.fillColor) {
292
			options.fill = true;
322
			options.fill = true;
293
		}
323
		}
294
		if (polys.length === 1) {
324
		if (polys.length === 1) {
295
			return new L.Polygon(polys.concat(inner), options);
325
			return new L.Polygon(polys.concat(inner), options);
296
		}
326
		}
297
		return new L.MultiPolygon(polys, options);
327
		return new L.MultiPolygon(polys, options);
298
	},
328
	},
299
 
329
 
300
	getLatLngs: function (xml) {
330
	getLatLngs: function (xml) {
301
		var el = xml.getElementsByTagName('coordinates');
331
		var el = xml.getElementsByTagName('coordinates');
302
		var coords = [];
332
		var coords = [];
303
		for (var j = 0; j < el.length; j++) {
333
		for (var j = 0; j < el.length; j++) {
304
			// text might span many childnodes
334
			// text might span many childnodes
305
			coords = coords.concat(this._read_coords(el[j]));
335
			coords = coords.concat(this._read_coords(el[j]));
306
		}
336
		}
307
		return coords;
337
		return coords;
308
	},
338
	},
309
 
339
 
310
	_read_coords: function (el) {
340
	_read_coords: function (el) {
311
		var text = "", coords = [], i;
341
		var text = "", coords = [], i;
312
		for (i = 0; i < el.childNodes.length; i++) {
342
		for (i = 0; i < el.childNodes.length; i++) {
313
			text = text + el.childNodes[i].nodeValue;
343
			text = text + el.childNodes[i].nodeValue;
314
		}
344
		}
315
		text = text.split(/[\s\n]+/);
345
		text = text.split(/[\s\n]+/);
316
		for (i = 0; i < text.length; i++) {
346
		for (i = 0; i < text.length; i++) {
317
			var ll = text[i].split(',');
347
			var ll = text[i].split(',');
318
			if (ll.length < 2) {
348
			if (ll.length < 2) {
319
				continue;
349
				continue;
320
			}
350
			}
321
			coords.push(new L.LatLng(ll[1], ll[0]));
351
			coords.push(new L.LatLng(ll[1], ll[0]));
322
		}
352
		}
323
		return coords;
353
		return coords;
324
	}
354
	}
325
 
355
 
326
});
356
});
327
 
357
 
328
L.KMLIcon = L.Icon.extend({
358
L.KMLIcon = L.Icon.extend({
329
 
359
 
330
	createIcon: function () {
360
	createIcon: function () {
331
		var img = this._createIcon('icon');
361
		var img = this._createIcon('icon');
332
		img.onload = function () {
362
		img.onload = function () {
333
			var i = new Image();
363
			var i = new Image();
334
			i.src = this.src;
364
			i.src = this.src;
335
			this.style.width = i.width + 'px';
365
			this.style.width = i.width + 'px';
336
			this.style.height = i.height + 'px';
366
			this.style.height = i.height + 'px';
337
 
367
 
338
			if (this.anchorType.x === 'UNITS_FRACTION' || this.anchorType.x === 'fraction') {
368
			if (this.anchorType.x === 'UNITS_FRACTION' || this.anchorType.x === 'fraction') {
339
				img.style.marginLeft = (-this.anchor.x * i.width) + 'px';
369
				img.style.marginLeft = (-this.anchor.x * i.width) + 'px';
340
			}
370
			}
341
			if (this.anchorType.y === 'UNITS_FRACTION' || this.anchorType.x === 'fraction') {
371
			if (this.anchorType.y === 'UNITS_FRACTION' || this.anchorType.x === 'fraction') {
342
				img.style.marginTop  = (-(1 - this.anchor.y) * i.height) + 'px';
372
				img.style.marginTop  = (-(1 - this.anchor.y) * i.height) + 'px';
343
			}
373
			}
344
			this.style.display = "";
374
			this.style.display = "";
345
		};
375
		};
346
		return img;
376
		return img;
347
	},
377
	},
348
 
378
 
349
	_setIconStyles: function (img, name) {
379
	_setIconStyles: function (img, name) {
350
		L.Icon.prototype._setIconStyles.apply(this, [img, name])
380
		L.Icon.prototype._setIconStyles.apply(this, [img, name])
351
		// save anchor information to the image
381
		// save anchor information to the image
352
		img.anchor = this.options.iconAnchorRef;
382
		img.anchor = this.options.iconAnchorRef;
353
		img.anchorType = this.options.iconAnchorType;
383
		img.anchorType = this.options.iconAnchorType;
354
	}
384
	}
355
});
385
});
356
 
386
 
357
 
387
 
358
L.KMLMarker = L.Marker.extend({
388
L.KMLMarker = L.Marker.extend({
359
	options: {
389
	options: {
360
		icon: new L.KMLIcon.Default()
390
		icon: new L.KMLIcon.Default()
361
	}
391
	}
362
});
392
});
363
 
393