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 55 .getLonLatFromViewPortPx(this.handlers.feature.evt.xy); 56 } catch (anErr) { 57 console 58 .warn("unable to get event position; reverting to boundingbox center."); 59 pPos = selectedFeature.geometry.getBounds().getCenterLonLat(); 60 } 61 } 62 63 var pContent = ""; 64 if (feature.data.description != undefined) { 65 pContent += "<div style=''>" + feature.data.id + ": </div>"; 66 } 67 if (feature.data.name != undefined) { 68 pContent += "<div style=''>" + feature.data.name + "<br /></div>"; 69 } 70 if (feature.data.ele != undefined) { 71 pContent += "<div style=''>elevation: " + feature.data.ele 72 + "<br /></div>"; 73 } 74 if (feature.data.type != undefined) { 75 pContent += "<div style=''>" + feature.data.type + "<br /></div>"; 76 } 77 if (feature.data.time != undefined) { 78 pContent += "<div style=''>time: " + feature.data.time + "<br /></div>"; 79 } 80 if (feature.data.description != undefined) { 81 pContent += "<div style=''>" + feature.data.description + "</div>"; 82 } 83 84 if (pContent.length > 0) { 85 var popup = new OpenLayers.Popup.FramedCloud("olPopup", pPos, null, 86 pContent, null, true, function() { 87 selectControl.unselect(selectedFeature); 88 }); 89 feature.popup = popup; 90 feature.layer.map.addPopup(popup); 91 } 92} 93 94/** 95 * handle feature unselect event. remove & destroy the popup. 96 * 97 * @param {OpenLayers.Feature.Vector} 98 * the un-selected feature 99 */ 100function onFeatureUnselect(feature) { 101 if (feature.popup != null) { 102 feature.layer.map.removePopup(feature.popup); 103 feature.popup.destroy(); 104 feature.popup = null; 105 } 106} 107 108// TODO IE7 and lower don't have document.getElementsByClassName so we make one; seems to conflict with openlayers prototypes? 109// Object.prototype.getElementsByClassName = document.getElementsByClassName = 110// document.getElementsByClassName 111// || function(className) { 112// className = className.replace(/\s+/g, ' ').replace( 113// /^\s|![A-Za-z0-9-_\s]|\s$/g, '').split(' '); 114// for ( var i = 0, elements = this.getElementsByTagName('*'), elementsLength = 115// elements.length, b = [], classNameLength = className.length, passed = true; i 116// < elementsLength; i++, passed = true) { 117// for ( var j = 0; j < classNameLength && passed; j++) { 118// passed = (new RegExp( 119// '(^|\\\s)' + className[j] + '(\\\s|$)', 'i')) 120// .test(elements[i].className); 121// } 122// if (passed) { 123// b.push(elements[i]); 124// } 125// } 126// return b; 127// }; 128 129/** init. */ 130function olInit() { 131 // hide the table with POI 132 // var tbls = getElementsByClass('olPOItable', document, 'table'); 133 var tbls = getElementsByClass('olPOItable', null, null); 134 // var tbls = getElementsByClassName('olPOItable'); 135 // console.log(tbls); 136 for (i = 0; i < tbls.length; i++) { 137 tbls[i].className = 'olPOItable olPrintOnly'; 138 } 139} 140 141/** 142 * create the map based on the params given. 143 * 144 * @param {Object}mapOpts 145 * MapOptions hash {id:'olmap', lat:6710200, lon:506500, zoom:13, 146 * toolbar:1, statusbar:1, controls:1, poihoverstyle:1, baselyr:'', 147 * kmlfile:'', gpxfile:'', summary:''} 148 * @param {Array}OLmapPOI 149 * array with POI's [ {lat:6710300,lon:506000,txt:'instap 150 * punt',angle:180,opacity:.9,img:'', rowId:n},... ]); 151 * 152 */ 153function createMap(mapOpts, OLmapPOI) { 154 if (!olEnable) { 155 return; 156 } 157 OpenLayers.IMAGE_RELOAD_ATTEMPTS = 3; 158 OpenLayers.Util.onImageLoadErrorColor = "transparent"; 159 // http://mapbox.com/documentation/adding-tiles-your-site/openlayers-themes 160 // OpenLayers.ImgPath = ''; 161 162 var extent = new OpenLayers.Bounds(); 163 164 var mOpts = { 165 projection : new OpenLayers.Projection("EPSG:900913"), 166 displayProjection : new OpenLayers.Projection("EPSG:4326"), 167 units : "m", 168 maxResolution : 156543.0339, 169 maxExtent : new OpenLayers.Bounds(-20037508.3392, -20037508.3392, 170 20037508.3392, 20037508.3392), 171 controls : [], 172 numZoomLevels : 19 173 }; 174 var m = new OpenLayers.Map(mapOpts.id, mOpts); 175 /* OSM maps */ 176 m.addLayer(new OpenLayers.Layer.OSM("OpenStreetMap"), { 177 transitionEffect : "resize" 178 }); 179 m.addLayer(new OpenLayers.Layer.OSM("t@h", 180 "http://tah.openstreetmap.org/Tiles/tile/${z}/${x}/${y}.png"), { 181 transitionEffect : "resize" 182 }); 183 m 184 .addLayer( 185 new OpenLayers.Layer.OSM("cycle map", 186 "http://andy.sandbox.cloudmade.com/tiles/cycle/${z}/${x}/${y}.png"), 187 { 188 transitionEffect : "resize" 189 }); 190 m 191 .addLayer(new OpenLayers.Layer.OSM( 192 "cloudmade map", 193 "http://tile.cloudmade.com/2f59745a6b525b4ebdb100891d5b6711/3/256/${z}/${x}/${y}.png", 194 { 195 transitionEffect : "resize" 196 })); 197 m.addLayer(new OpenLayers.Layer.OSM("hike and bike map", 198 "http://toolserver.org/tiles/hikebike/${z}/${x}/${y}.png", { 199 transitionEffect : "resize" 200 })); 201 /* open aerial map */ 202 /* 203 * turn this off; project is asleep: 204 * https://sourceforge.net/tracker/?func=detail&aid=2897327&group_id=239475&atid=1110186 205 * m.addLayer(new OpenLayers.Layer.XYZ("OpenAerialMap", 206 * "http://tile.openaerialmap.org/tiles/1.0.0/openaerialmap-900913/${z}/${x}/${y}.jpg", 207 * {name: "OpenStreetMap", attribution: "Data CC-By by <a 208 * href='http://www.openaerialmap.org/licensing/'>OpenAerialMap</a>", 209 * sphericalMercator: true, transitionEffect: "resize"} )); 210 */ 211 212 /* controle of google/yahoo/ve api's beschikbaar zijn.. */ 213 if (gEnable) { 214 try { 215 m.addLayer(new OpenLayers.Layer.Google("google relief", { 216 type : G_PHYSICAL_MAP, 217 'sphericalMercator' : true, 218 transitionEffect : "resize" 219 })); 220 m.addLayer(new OpenLayers.Layer.Google("google sat", { 221 type : G_SATELLITE_MAP, 222 'sphericalMercator' : true, 223 transitionEffect : "resize" 224 })); 225 m.addLayer(new OpenLayers.Layer.Google("google hybrid", { 226 type : G_HYBRID_MAP, 227 'sphericalMercator' : true, 228 transitionEffect : "resize" 229 })); 230 m.addLayer(new OpenLayers.Layer.Google("google normal", { 231 type : G_NORMAL_MAP, 232 'sphericalMercator' : true, 233 transitionEffect : "resize" 234 })); 235 } catch (ol_err1) { 236 } 237 } 238 239 if (yEnable) { 240 try { 241 m.addLayer(new OpenLayers.Layer.Yahoo("yahoo", { 242 'type' : YAHOO_MAP_HYB, 243 'sphericalMercator' : true, 244 transitionEffect : resize 245 })); 246 } catch (ol_err2) { 247 } 248 } 249 250 if (veEnable) { 251 try { 252 m.addLayer(new OpenLayers.Layer.VirtualEarth("ve", { 253 'type' : VEMapStyle.Hybrid, 254 'sphericalMercator' : true, 255 transitionEffect : resize 256 })); 257 } catch (ol_err3) { 258 } 259 } 260 m.setCenter(new OpenLayers.LonLat(mapOpts.lon, mapOpts.lat).transform( 261 m.displayProjection, m.projection), mapOpts.zoom); 262 extent.extend(m.getExtent()); 263 264 m.addControl(new OpenLayers.Control.KeyboardDefaults()); 265 m.addControl(new OpenLayers.Control.Navigation()); 266 if (mapOpts.controls === 1) { 267 /* add base controls to map */ 268 m.addControl(new OpenLayers.Control.LayerSwitcher()); 269 m.addControl(new OpenLayers.Control.ScaleLine({ 270 geodesic : true 271 })); 272 m.addControl(new OpenLayers.Control.PanZoomBar()); 273 m.addControl(new OpenLayers.Control.Graticule({ 274 visible : false 275 })); 276 // TODO optioneel overzichts kaart toevoegen 277 // var overViewOpts = {layers: [wms.clone()],size: new 278 // OpenLayers.Size(120,120),projection: new 279 // OpenLayers.Projection("EPSG:900913"),opacity: 0.0,mapOptions: { 280 // /* Available resolutions are: [156543.03390000001, 281 // 78271.516950000005, 282 // 39135.758475000002, 19567.879237500001, 9783.9396187500006, 283 // 4891.9698093750003, 2445.9849046875001, 1222.9924523437501, 284 // 611.49622617187504, 305.74811308593752, 152.87405654296876, 285 // 76.43702827148438, 38.21851413574219, 19.109257067871095, 286 // 9.5546285339355475, 287 // 4.7773142669677737, 2.3886571334838869, 1.1943285667419434, 288 // 0.59716428337097172, 0.29858214168548586]*/ 289 // maxResolution: 78271.51695,maxExtent: new 290 // OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34), 291 // /* 292 // minExtent: new OpenLayers.Bounds(1000,400000,400000,515000),*/ 293 // numZoomLevels: 5},'div':OpenLayers.Util.getElement('overview')}; 294 // map.addControl(new OpenLayers.Control.OverviewMap(overViewOpts)); 295 } 296 297 if (mapOpts.statusbar === 1) { 298 // statusbar control: permalink 299 m.addControl(new OpenLayers.Control.Permalink(mapOpts.id 300 + '-statusbar-link-ref')); 301 // statusbar control: mouse pos. 302 // TODO kijken naar afronding met aNumber.toFixed(0) 303 m.addControl(new OpenLayers.Control.MousePosition({ 304 'div' : OpenLayers.Util.getElement(mapOpts.id 305 + '-statusbar-mouseposition') 306 })); 307 // statusbar control: scale 308 m.addControl(new OpenLayers.Control.Scale(mapOpts.id 309 + '-statusbar-scale')); 310 // statusbar control: attribution 311 m.addControl(new OpenLayers.Control.Attribution({ 312 'div' : OpenLayers.Util.getElement(mapOpts.id + '-statusbar-text') 313 })); 314 // statusbar control: projection 315 OpenLayers.Util.getElement(mapOpts.id + '-statusbar-projection').innerHTML = m.displayProjection; 316 } else { 317 OpenLayers.Util.getElement(mapOpts.id + '-olStatusBar').display = 'none'; 318 } 319 320 if (mapOpts.toolbar === 1) { 321 // buttons + panel 322 var zoomin = new OpenLayers.Control.ZoomBox({ 323 title : "Zoom in" 324 }); 325 var zoomout = new OpenLayers.Control.ZoomBox({ 326 out : true, 327 title : "Zoom uit", 328 displayClass : "olControlZoomOut" 329 }); 330 var pan = new OpenLayers.Control.DragPan({ 331 title : "Verschuif" 332 }); 333 // icon_query.png 334 var nav = new OpenLayers.Control.NavigationHistory(); 335 m.addControl(nav); 336 var panel = new OpenLayers.Control.Panel({ 337 defaultControl : zoomin, 338 displayClass : "olToolbar", 339 "div" : OpenLayers.Util.getElement(mapOpts.id + "-olToolbar") 340 }); 341 panel.addControls([ zoomin, zoomout, pan ]); 342 panel.addControls([ nav.next, nav.previous ]); 343 m.addControl(panel); 344 } else { 345 OpenLayers.Util.getElement(mapOpts.id + '-olToolbar').display = 'none'; 346 } 347 348 // add overlays 349 m.addLayer(new OpenLayers.Layer.OSM("Hillshade", 350 "http://toolserver.org/~cmarqu/hill/${z}/${x}/${y}.png", { 351 transitionEffect : "resize", 352 isBaseLayer : false, 353 transparent : true, 354 visibility : false 355 })); 356 357 var DocBase = DOKU_BASE; 358 if (OLmapPOI.length > 0) { 359 var markers = new OpenLayers.Layer.Vector( 360 "POI", 361 { 362 styleMap : new OpenLayers.StyleMap( 363 { 364 "default" : { 365 externalGraphic : "${img}", 366 graphicHeight : 16, 367 graphicWidth : 16, 368 graphicXOffset : 0, 369 graphicYOffset : -8, 370 graphicOpacity : "${opacity}", 371 rotation : "${angle}", 372 backgroundGraphic : DocBase 373 + "lib/plugins/openlayersmap/icons/marker_shadow.png", 374 backgroundXOffset : 0, 375 backgroundYOffset : -4, 376 backgroundRotation : "${angle}", 377 pointRadius : 10 378 }, 379 "select" : { 380 cursor : "crosshair", 381 externalGraphic : DocBase 382 + "lib/plugins/openlayersmap/icons/marker-red.png", 383 graphicHeight : 16, 384 graphicWidth : 16, 385 graphicXOffset : 0, 386 graphicYOffset : -8, 387 graphicOpacity : 1.0, 388 rotation : "${angle}" 389 } 390 }), 391 isBaseLayer : false, 392 rendererOptions : { 393 yOrdering : true 394 } 395 }); 396 397 m.addLayer(markers); 398 var features = []; 399 var lonLat; 400 for ( var j = 0; j < OLmapPOI.length; j++) { 401 var feat = new OpenLayers.Feature.Vector( 402 new OpenLayers.Geometry.Point(OLmapPOI[j].lon, 403 OLmapPOI[j].lat).transform(m.displayProjection, 404 m.projection), { 405 angle : OLmapPOI[j].angle, 406 opacity : OLmapPOI[j].opacity, 407 img : DocBase + "lib/plugins/openlayersmap/icons/" 408 + OLmapPOI[j].img 409 }); 410 feat.data = { 411 name : OLmapPOI[j].txt, 412 id : OLmapPOI[j].rowId 413 }; 414 features.push(feat); 415 } 416 markers.addFeatures(features); 417 extent.extend(markers.getDataExtent()); 418 m.zoomToExtent(extent); 419 } 420 421 /* GPX layer */ 422 if (mapOpts.gpxfile.length > 0) { 423 var layerGPX = new OpenLayers.Layer.GML("GPS route", DocBase 424 + "lib/exe/fetch.php?media=" + mapOpts.gpxfile, { 425 format : OpenLayers.Format.GPX, 426 formatOptions : { 427 extractWaypoints : true, 428 extractTracks : true, 429 extractStyles : true, 430 extractAttributes : true, 431 handleHeight : true, 432 maxDepth : 3 433 }, 434 style : { 435 strokeColor : "#0000FF", 436 strokeWidth : 3, 437 strokeOpacity : 0.7, 438 pointRadius : 4, 439 fillColor : "#0099FF", 440 fillOpacity : 0.7 441 /* 442 * , label:"${name}" 443 */}, 444 projection : new OpenLayers.Projection("EPSG:4326") 445 }); 446 m.addLayer(layerGPX); 447 layerGPX.events.register('loadend', m, function() { 448 extent.extend(layerGPX.getDataExtent()); 449 m.zoomToExtent(extent); 450 }); 451 452 } 453 454 /* KML layer */ 455 if (mapOpts.kmlfile.length > 0) { 456 var layerKML = new OpenLayers.Layer.GML("KML file", DocBase 457 + "lib/exe/fetch.php?media=" + mapOpts.kmlfile, { 458 format : OpenLayers.Format.KML, 459 formatOptions : { 460 extractStyles : true, 461 extractAttributes : true, 462 maxDepth : 3 463 }, 464 style : { 465 label : "${name}" 466 }, 467 projection : new OpenLayers.Projection("EPSG:4326") 468 }); 469 m.addLayer(layerKML); 470 layerKML.events.register('loadend', m, function() { 471 extent.extend(layerKML.getDataExtent()); 472 m.zoomToExtent(extent); 473 }); 474 } 475 476 // selectcontrol for layers 477 if ((m.getLayersByClass('OpenLayers.Layer.GML').length > 0) 478 || m.getLayersByClass('OpenLayers.Layer.Vector').length > 0) { 479 selectControl = new OpenLayers.Control.SelectFeature((m 480 .getLayersByClass('OpenLayers.Layer.Vector')).concat(m 481 .getLayersByClass('OpenLayers.Layer.GML')), { 482 multiple : true, 483 hover : mapOpts.poihoverstyle, 484 onSelect : onFeatureSelect, 485 onUnselect : onFeatureUnselect 486 }); 487 m.addControl(selectControl); 488 selectControl.activate(); 489 } 490 491 // change/set alternative baselyr 492 try { 493 m.setBaseLayer(m.getLayersByName(mapOpts.baselyr)[0]); 494 } catch (ol_err4) { 495 m.setBaseLayer(m.layers[0]); 496 } 497 return m; 498} 499 500/** 501 * ol api flag. 502 * 503 * @type {Boolean} 504 */ 505var olEnable = false; 506/** 507 * google map api flag. 508 * 509 * @type {Boolean} 510 */ 511var gEnable = false; 512/** 513 * virtual earth map api flag. 514 * 515 * @type {Boolean} 516 */ 517var veEnable = false; 518/** 519 * yahoo map api flag. 520 * 521 * @type {Boolean} 522 */ 523var yEnable = false; 524 525/* register olInit to run with onload event. */ 526addInitEvent(olInit); 527 528