xref: /plugin/openlayersmap/script.js (revision 38a47c60cc6e07c37451d90f3ec54a36e64048ad)
1/*
2 * Copyright (c) 2008-2011 Mark C. Prins <mc.prins@gmail.com>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17/**
18 * @fileoverview Javascript voor OpenLayers plugin.
19 *
20 * @requires {lib/OpenLayers.js} or other full openlayers build
21 * @author Mark C. Prins <mc.prins@gmail.com>
22 *
23 */
24
25/**
26 * Openlayers selectcontrol.
27 *
28 * @type {OpenLayers.Control.SelectFeature}
29 * @private
30 */
31var selectControl;
32/**
33 * Openlayers bounds used for managing the map extent.
34 *
35 * @type {OpenLayers.Bounds}
36 * @private
37 */
38var extent;
39
40/**
41 * handle feature select event.
42 *
43 * @param {OpenLayers.Feature.Vector}
44 *            the selected feature
45 */
46function onFeatureSelect(feature) {
47	var selectedFeature = feature;
48	// 'this' is selectFeature control
49	var pPos = selectedFeature.geometry.getBounds().getCenterLonLat();
50	// != OpenLayers.Geometry.Point
51	if (selectedFeature.geometry.CLASS_NAME == "OpenLayers.Geometry.LineString"){
52		try{
53			// for lines make the popup show at the cursor position
54			pPos = feature.layer.map.getLonLatFromViewPortPx(this.handlers.feature.evt.xy);
55		} catch (anErr){
56			console.warn("unable to get event position; reverting to boundingbox center.");
57			pPos = selectedFeature.geometry.getBounds().getCenterLonLat();
58		}
59	}
60
61	var pContent="";
62	if (feature.data.name !=undefined) {
63		pContent+="<div style=''>" + feature.data.name + "<br /></div>";		}
64	if (feature.data.ele !=undefined) {
65		pContent+="<div style=''>elevation: " + feature.data.ele + "<br /></div>";}
66	if (feature.data.type !=undefined) {
67		pContent+="<div style=''>" + feature.data.type + "<br /></div>";}
68	if (feature.data.time !=undefined) {
69		pContent+="<div style=''>time: " + feature.data.time + "<br /></div>";}
70	if (feature.data.description !=undefined) {
71		pContent+="<div style=''>" + feature.data.description + "</div>";}
72	if(pContent.length>0){
73		var popup = new OpenLayers.Popup.FramedCloud(
74				"olPopup", pPos, null, pContent, null, true,
75				function() {
76					selectControl.unselect(selectedFeature);
77				});
78		feature.popup = popup;
79		feature.layer.map.addPopup(popup);
80	}
81}
82
83/**
84 * handle feature unselect event. remove & destroy the popup.
85 *
86 * @param {OpenLayers.Feature.Vector}
87 *            the un-selected feature
88 */
89function onFeatureUnselect(feature) {
90	if(feature.popup!=null){
91		feature.layer.map.removePopup(feature.popup);
92		feature.popup.destroy();
93		feature.popup = null;
94	}
95}
96
97/** init. */
98function olInit() {
99	if (!olEnable) {
100		return;
101	}
102}
103
104/**
105 * create the map based on the params given.
106 *
107 * @param {Object}mapOpts
108 *            MapOptions hash {id:'olmap', lat:6710200, lon:506500, zoom:13,
109 *            toolbar:1, statusbar:1, controls:1, poihoverstyle:1, baselyr:'',
110 *            kmlfile:'', gpxfile:''}
111 * @param {Array}OLmapPOI
112 *            array with POI's [ {lat:6710300,lon:506000,txt:'instap
113 *            punt',angle:180,opacity:.9,img:''},... ]);
114 *
115 */
116function createMap(mapOpts, OLmapPOI) {
117	if (!olEnable) {
118		return;
119	}
120	OpenLayers.IMAGE_RELOAD_ATTEMPTS = 3;
121	OpenLayers.Util.onImageLoadErrorColor = "transparent";
122	var extent = new OpenLayers.Bounds();
123
124	var mOpts = {
125			projection :new OpenLayers.Projection("EPSG:900913"),
126			displayProjection :new OpenLayers.Projection("EPSG:4326"),
127			units :"m",
128			maxResolution :156543.0339,
129			maxExtent :new OpenLayers.Bounds(-20037508.3392, -20037508.3392,
130					20037508.3392, 20037508.3392),
131					controls : [],
132					numZoomLevels :19
133	};
134	var m = new OpenLayers.Map(mapOpts.id, mOpts);
135	/* OSM maps */
136	m.addLayer(new OpenLayers.Layer.OSM("OpenStreetMap"),
137			{transitionEffect: "resize"});
138	m.addLayer(new OpenLayers.Layer.OSM("t@h",
139	"http://tah.openstreetmap.org/Tiles/tile/${z}/${x}/${y}.png"),
140	{transitionEffect: "resize"});
141	m.addLayer(new OpenLayers.Layer.OSM("cycle map",
142	"http://andy.sandbox.cloudmade.com/tiles/cycle/${z}/${x}/${y}.png"),
143	{transitionEffect: "resize"});
144	m.addLayer(new OpenLayers.Layer.OSM("cloudmade map",
145			"http://tile.cloudmade.com/2f59745a6b525b4ebdb100891d5b6711/3/256/${z}/${x}/${y}.png",
146			{transitionEffect: "resize"}));
147	m.addLayer(new OpenLayers.Layer.OSM("hike and bike map",
148			"http://toolserver.org/tiles/hikebike/${z}/${x}/${y}.png",
149			{transitionEffect: "resize"}));
150	/* open aerial map */
151	/*
152	 * turn this off; project is asleep:
153	 * https://sourceforge.net/tracker/?func=detail&aid=2897327&group_id=239475&atid=1110186
154	 * m.addLayer(new OpenLayers.Layer.XYZ("OpenAerialMap",
155	 * "http://tile.openaerialmap.org/tiles/1.0.0/openaerialmap-900913/${z}/${x}/${y}.jpg",
156	 * {name: "OpenStreetMap", attribution: "Data CC-By by <a
157	 * href='http://www.openaerialmap.org/licensing/'>OpenAerialMap</a>",
158	 * sphericalMercator: true, transitionEffect: "resize"} ));
159	 */
160
161	/* controle of google/yahoo/ve api's beschikbaar zijn.. */
162	if (gEnable) {
163		try {
164			m.addLayer(new OpenLayers.Layer.Google("google relief", {
165				type :G_PHYSICAL_MAP,
166				'sphericalMercator' :true,
167				transitionEffect: "resize"
168			}));
169			m.addLayer(new OpenLayers.Layer.Google("google sat", {
170				type :G_SATELLITE_MAP,
171				'sphericalMercator' :true,
172				transitionEffect: "resize"
173			}));
174			m.addLayer(new OpenLayers.Layer.Google("google hybrid", {
175				type :G_HYBRID_MAP,
176				'sphericalMercator' :true,
177				transitionEffect: "resize"
178			}));
179			m.addLayer(new OpenLayers.Layer.Google("google normal", {
180				type :G_NORMAL_MAP,
181				'sphericalMercator' :true,
182				transitionEffect: "resize"
183			}));
184		} catch (ol_err1) {
185		}
186	}
187
188	if (yEnable) {
189		try {
190			m.addLayer(new OpenLayers.Layer.Yahoo("yahoo", {
191				'type' :YAHOO_MAP_HYB,
192				'sphericalMercator' :true,
193				transitionEffect: resize
194			}));
195		} catch (ol_err2) {
196		}
197	}
198
199	if (veEnable) {
200		try {
201			m.addLayer(new OpenLayers.Layer.VirtualEarth("ve", {
202				'type' :VEMapStyle.Hybrid,
203				'sphericalMercator' :true,
204				transitionEffect: resize
205			}));
206		} catch (ol_err3) {
207		}
208	}
209	m.setCenter(new OpenLayers.LonLat(mapOpts.lon, mapOpts.lat).transform(
210			m.displayProjection, m.projection), mapOpts.zoom);
211	extent.extend(m.getExtent());
212
213	m.addControl(new OpenLayers.Control.KeyboardDefaults());
214	m.addControl(new OpenLayers.Control.Navigation());
215	if (mapOpts.controls === 1) {
216		/* add base controls to map */
217		m.addControl(new OpenLayers.Control.LayerSwitcher());
218		m.addControl(new OpenLayers.Control.ScaleLine({geodesic: true}));
219		m.addControl(new OpenLayers.Control.PanZoomBar());
220		m.addControl(new OpenLayers.Control.Graticule({visible:false}));
221		// TODO optioneel overzichts kaart toevoegen
222		// var overViewOpts = {layers: [wms.clone()],size: new
223		// OpenLayers.Size(120,120),projection: new
224		// OpenLayers.Projection("EPSG:900913"),opacity: 0.0,mapOptions: {
225		// /* Available resolutions are: [156543.03390000001,
226		// 78271.516950000005,
227		// 39135.758475000002, 19567.879237500001, 9783.9396187500006,
228		// 4891.9698093750003, 2445.9849046875001, 1222.9924523437501,
229		// 611.49622617187504, 305.74811308593752, 152.87405654296876,
230		// 76.43702827148438, 38.21851413574219, 19.109257067871095,
231		// 9.5546285339355475,
232		// 4.7773142669677737, 2.3886571334838869, 1.1943285667419434,
233		// 0.59716428337097172, 0.29858214168548586]*/
234		// maxResolution: 78271.51695,maxExtent: new
235		// OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34),
236		// /*
237		// minExtent: new OpenLayers.Bounds(1000,400000,400000,515000),*/
238		// numZoomLevels: 5},'div':OpenLayers.Util.getElement('overview')};
239		// map.addControl(new OpenLayers.Control.OverviewMap(overViewOpts));
240	}
241
242	if (mapOpts.statusbar === 1) {
243		// statusbar control: permalink
244		m.addControl(new OpenLayers.Control.Permalink(
245				mapOpts.id + '-statusbar-link-ref'));
246		// statusbar control: mouse pos.
247		// TODO kijken naar afronding met aNumber.toFixed(0)
248		m.addControl(new OpenLayers.Control.MousePosition( {
249			'div' :OpenLayers.Util
250			.getElement(mapOpts.id + '-statusbar-mouseposition')
251		}));
252		// statusbar control: scale
253		m.addControl(new OpenLayers.Control.Scale(
254				mapOpts.id + '-statusbar-scale'));
255		// statusbar control: attribution
256		m.addControl(new OpenLayers.Control.Attribution( {
257			'div' :OpenLayers.Util.getElement(mapOpts.id + '-statusbar-text')
258		}));
259		// statusbar control: projection
260		OpenLayers.Util.getElement(mapOpts.id + '-statusbar-projection').innerHTML = m.displayProjection;
261	} else {
262		OpenLayers.Util.getElement(mapOpts.id + '-olStatusBar').display = 'none';
263	}
264
265	if (mapOpts.toolbar === 1) {
266		// buttons + panel
267		var zoomin = new OpenLayers.Control.ZoomBox( {
268			title :"Zoom in"
269		});
270		var zoomout = new OpenLayers.Control.ZoomBox( {
271			out :true,
272			title :"Zoom uit",
273			displayClass :"olControlZoomOut"
274		});
275		var pan = new OpenLayers.Control.DragPan( {
276			title :"Verschuif"
277		});
278		// icon_query.png
279		var nav = new OpenLayers.Control.NavigationHistory();
280		m.addControl(nav);
281		var panel = new OpenLayers.Control.Panel( {
282			defaultControl :zoomin,
283			displayClass :"olToolbar",
284			"div" :OpenLayers.Util.getElement(mapOpts.id + "-olToolbar")
285		});
286		panel.addControls( [ zoomin, zoomout, pan ]);
287		panel.addControls( [ nav.next, nav.previous ]);
288		m.addControl(panel);
289	} else {
290		OpenLayers.Util.getElement(mapOpts.id + '-olToolbar').display = 'none';
291	}
292
293	// add overlays
294	m.addLayer(new OpenLayers.Layer.OSM("Hillshade",
295			"http://toolserver.org/~cmarqu/hill/${z}/${x}/${y}.png",
296			{transitionEffect: "resize",isBaseLayer: false,
297        transparent: true, visibility: false}));
298
299	var DocBase = DOKU_BASE;
300	if (OLmapPOI.length > 0) {
301		var markers = new OpenLayers.Layer.Vector(
302				"POI",
303				{
304					styleMap :new OpenLayers.StyleMap({
305						"default" : {
306						externalGraphic:"${img}",
307						graphicHeight:16,
308						graphicWidth:16,
309						graphicXOffset:0,
310						graphicYOffset:-8,
311						graphicOpacity:"${opacity}",
312						rotation:"${angle}",
313						backgroundGraphic:DocBase + "lib/plugins/openlayersmap/icons/marker_shadow.png",
314						backgroundXOffset:0,
315						backgroundYOffset:-4,
316						backgroundRotation:"${angle}",
317						pointRadius:10
318					},
319					"select":{
320						cursor:"crosshair",
321						externalGraphic:DocBase	+ "lib/plugins/openlayersmap/icons/marker-red.png",
322						graphicHeight:16,
323						graphicWidth:16,
324						graphicXOffset:0,
325						graphicYOffset:-8,
326						graphicOpacity:1.0,
327						rotation:"${angle}"
328					}
329					}),
330					isBaseLayer:false,
331					rendererOptions:{yOrdering :true}
332				});
333
334		m.addLayer(markers);
335		var features = [];
336		var lonLat;
337		for ( var j = 0; j < OLmapPOI.length; j++) {
338			var feat = new OpenLayers.Feature.Vector(
339					new OpenLayers.Geometry.Point(OLmapPOI[j].lon,
340							OLmapPOI[j].lat).transform(m.displayProjection,
341									m.projection), {
342						angle:OLmapPOI[j].angle,
343						opacity:OLmapPOI[j].opacity,
344						img:DocBase + "lib/plugins/openlayersmap/icons/" + OLmapPOI[j].img
345					});
346			feat.data = {name:OLmapPOI[j].txt};
347			features.push(feat);
348		}
349		markers.addFeatures(features);
350		extent.extend(markers.getDataExtent());
351		m.zoomToExtent(extent);
352	}
353
354	/* GPX layer */
355	if (mapOpts.gpxfile.length > 0) {
356		var layerGPX = new OpenLayers.Layer.GML("GPS route",
357				DocBase + "lib/exe/fetch.php?media=" + mapOpts.gpxfile, {
358			format : OpenLayers.Format.GPX,
359			formatOptions: {
360			extractWaypoints:true,
361			extractTracks:true,
362			extractStyles: true,
363			extractAttributes: true,
364			handleHeight:true,
365			maxDepth: 3
366		},
367		style : {strokeColor:"#0000FF", strokeWidth:3, strokeOpacity:0.7,
368			pointRadius:4, fillColor: "#0099FF", fillOpacity:0.7 /*
369																	 * ,
370																	 * label:"${name}"
371																	 */},
372			 projection : new OpenLayers.Projection("EPSG:4326")
373		});
374		m.addLayer(layerGPX);
375		layerGPX.events.register('loadend', m, function() {
376			extent.extend(layerGPX.getDataExtent());
377			m.zoomToExtent(extent);
378		});
379
380	}
381
382	/* KML layer */
383	if (mapOpts.kmlfile.length > 0) {
384		var layerKML = new OpenLayers.Layer.GML("KML file",
385				DocBase + "lib/exe/fetch.php?media=" + mapOpts.kmlfile, {
386			format : OpenLayers.Format.KML,
387			formatOptions: {
388			extractStyles: true,
389			extractAttributes: true,
390			maxDepth: 3
391		},
392		style:{label:"${name}"},
393		projection : new OpenLayers.Projection("EPSG:4326")
394		});
395		m.addLayer(layerKML);
396		layerKML.events.register('loadend', m, function() {
397			extent.extend(layerKML.getDataExtent());
398			m.zoomToExtent(extent);
399		});
400	}
401
402	// selectcontrol for layers
403	if((m.getLayersByClass('OpenLayers.Layer.GML').length > 0)
404			|| m.getLayersByClass('OpenLayers.Layer.Vector').length > 0){
405		selectControl = new OpenLayers.Control.SelectFeature(
406				(m.getLayersByClass('OpenLayers.Layer.Vector')).concat(m.getLayersByClass('OpenLayers.Layer.GML')),
407				{
408					multiple: true,
409					hover :mapOpts.poihoverstyle,
410					onSelect :onFeatureSelect,
411					onUnselect :onFeatureUnselect
412				});
413		m.addControl(selectControl);
414		selectControl.activate();
415	}
416
417	// change/set alternative baselyr
418	try{
419		m.setBaseLayer(m.getLayersByName(mapOpts.baselyr)[0]);
420	}catch(ol_err4){
421		m.setBaseLayer(m.layers[0]);
422	}
423	return m;
424}
425
426/**
427 * ol api flag.
428 *
429 * @type {Boolean}
430 */
431var olEnable = false;
432/**
433 * google map api flag.
434 *
435 * @type {Boolean}
436 */
437var gEnable = false;
438/**
439 * virtual earth map api flag.
440 *
441 * @type {Boolean}
442 */
443var veEnable = false;
444/**
445 * yahoo map api flag.
446 *
447 * @type {Boolean}
448 */
449var yEnable = false;
450
451/* register olInit to run with onload event. */
452addInitEvent(olInit);
453