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