1 /** 2 * @fileOverview 3 * Copyright (c) 2013 Regione Autonoma della Sardegna 4 * Published under the GPL license.<br> 5 * See <a href="https://sardegnageoportale.it/webgis/license.txt">https://sardegnageoportale.it/webgis/license.txt</a> 6 * for the full text of the license. 7 * @version 0.1 8 */ 9 10 /** 11 * @require framework/widgets/control/Compass.js 12 * @require framework/widgets/control/ViewDirection.js 13 */ 14 15 /** 16 * @namespace framework.plugins 17 */ 18 Ext.namespace("framework.plugins"); 19 20 /** 21 * Constant for nearest algorithm type 22 */ 23 var OBLIQUEPHOTOS_ALGORITHMTYPE = {CENTROID_BASED: {value: 0, name: 'Centroid'}, EXTENT_BASED: {value: 1, name: 'Extent'}}; 24 25 /** 26 * Provides control for link to info application. 27 * @name_ ActiveObliquePhotos 28 * @class Provides control for link to info application. 29 * @constructor 30 * @extends <a target="_blank" href="http://gxp.opengeo.org/master/doc/lib/plugins/Tool.html">gxp.plugins.Tool</a> 31 */ 32 framework.plugins.ActiveObliquePhotos = Ext.extend(gxp.plugins.Tool, 33 /** 34 * @lends framework.plugins.ActiveObliquePhotos.prototype 35 */ 36 { 37 /** 38 * plugin type. 39 * @public 40 * @type String 41 */ 42 ptype: "framework_activeobliquephotos", 43 /** 44 * Menu text. 45 * @public 46 * @type String 47 */ 48 menuText: "Attiva modalità foto oblique", 49 /** 50 * Msg no photo. 51 * @public 52 * @type String 53 */ 54 noPhoto: "Foto oblique non presenti in questa zona", 55 /** 56 * Msg no CSV. 57 * @public 58 * @type String 59 */ 60 noCSV: "Foto oblique in fase di elaborazione", 61 /** 62 * Tooltip text. 63 * @public 64 * @type String 65 */ 66 tooltip: "Attiva la modalità foto oblique", 67 /** 68 * Msg tooltip deactivate. 69 * @public 70 * @type String 71 */ 72 tooltipDeactivate: "Disattiva la modalità foto oblique", 73 /** 74 * Class with button is pressed. 75 * @public 76 * @type String 77 */ 78 pressedCls: 'oblBtnPressed', 79 /** 80 * Class with button is unpressed. 81 * @public 82 * @type String 83 */ 84 unpressedCls: 'oblBtn', 85 /** 86 * Css class for icon. 87 * @public 88 * @type String 89 */ 90 iconCls: "gxp-icon-obliquephotos", 91 /** 92 * Compass used for changing direction and switching to orthophone mode 93 * @private 94 * @type framework.widgets.control.Compass 95 */ 96 compass: null, 97 /** 98 * Type of algorithm to use for nearest photogram search 99 * @public 100 * @type ALGORITHMTYPE 101 */ 102 algorithmType: null, 103 /** 104 * Configured map 105 * 106 * @public 107 * @type {Object} OpenLayers.Map 108 */ 109 map: null, 110 /** 111 * Baselayer map 112 * 113 * @public 114 * @type {Object} OpenLayers.Layer 115 */ 116 lastBaseLayer: null, 117 /** 118 * Type of Spatial Reference used for the computation. Per default: 'EPSG:4326' 119 * 120 * @public 121 * @type String 122 */ 123 srs: 'EPSG:3003', 124 /** 125 * Proxy to make the search request. default null. 126 * 127 * @public 128 * @type string 129 */ 130 proxy: null, 131 132 /** 133 * Store for toring the routing results 134 * 135 * @public 136 * @type {Object} Ext.data.Storw 137 */ 138 store: null, 139 /** 140 * Base URL service WMS used for the computation. Per default: '' 141 * 142 * @public 143 * @type string 144 */ 145 baseUrl: '', 146 /** 147 * Type of service WFS used for the computation. Per default: 'http://localhost:8080/geoserver/wfs?' 148 * 149 * @public 150 * @type string 151 */ 152 url: 'http://localhost:8080/geoserver/wfs?', 153 /** 154 * Type of service TMS used for the oblique Photos. Per default: 'http://webgis.regione.sardegna.it/tms/fotooblique/' 155 * 156 * @public 157 * @type string 158 */ 159 tmsUrl: 'http://webgis.regione.sardegna.it/tms/fotooblique/', 160 /** 161 * Type of service for calculate oblique Photos. If is null: dinamic url generated 162 * 163 * @public 164 * @type string 165 */ 166 urlServOPDedicated: false, 167 /** 168 * File name of tilemap source 'http://localhost:8080/geoserver/wfs?' 169 * 170 * @public 171 * @type string 172 */ 173 tilemapResource: 'tilemapresource.xml', 174 /** 175 * Nome del layer che contiene l'inviluppo delle foto oblique' 176 * 177 * @public 178 * @type string 179 */ 180 typename: 'inviluppo_orto_roma40_tot', 181 workspace: 'dbu:', 182 /** 183 * Parametro del servizio WFS. ID del layer che indica la zona delle foto oblique' 184 * 185 * @public 186 * @type string 187 */ 188 propertyName: 'id', 189 /** 190 * Parametro del servizio WFS. Campo per l'ordinamento dei risultati di ricerca' 191 * 192 * @public 193 * @type string 194 */ 195 sortby: 'id', 196 /** 197 * Parametro del servizio WFS. Bounding box della ricerca' 198 * 199 * @public 200 * @type string 201 */ 202 BBOX: null, 203 /** 204 * Tolleranza del boundingbox per la ricerca' 205 * 206 * @public 207 * @type Number 208 */ 209 tollerance: 0, 210 /** 211 * Scala di visualizzazione minima in cui viene attivato il pulsante di 212 * attivazione delle foto oblique' 213 * 214 * @public 215 * @type Number 216 */ 217 minScaleActivate: 100000, 218 /** 219 * Livello di zoom minimo della visualizzazione delle foto oblique' 220 * 221 * @public 222 * @type Number 223 */ 224 minZoomObliquePhoto: 4, 225 /** 226 * Layer dei TMS delle fotooblique visualizzato' 227 * 228 * @public 229 * @type {Object} OpenLayers.Layer.TMS 230 */ 231 tmsLayer: null, 232 /** 233 * Foto Oblique visualizzata in mappa' 234 * 235 * @public 236 * @type {Object} JSON 237 */ 238 obliquePhoto: { 239 /** 240 * Property: extent 241 * {OpenLayers.Bounds} extent of the tile map 242 */ 243 extent: null, 244 /** 245 * Property: extent 246 * {OpenLayers.Bounds} Maximum extent of the tile map 247 */ 248 maxExtent: null, 249 /** 250 * Property: tileOrigin 251 * {OpenLayers.LonLat} origin of the tile map 252 */ 253 tileOrigin: null, 254 /** 255 * Property: maxResolution 256 * {float} max resolution of the zero level 257 */ 258 maxResolution: null, 259 /** 260 * Property: zoom 261 * {int} zooom of the tilemap 262 */ 263 typeImg: null, 264 /** 265 * Property: numLevels 266 * {int} num levels of the tile map 267 */ 268 numLevels: 0, 269 /** 270 * Property: resolutions 271 * {int} resolution of the tile map 272 */ 273 resolutions: null, 274 /** 275 * Property: area 276 * {int} area of the tile map 277 */ 278 projection: 'EPSG:32632', 279 /** 280 * Property: area 281 * {int} area of the tile map 282 */ 283 area: null, 284 /** 285 * Property: initcoordRect 286 * {OpenLayers.LonLat} coordinata "fittizzia" del centro della mappa (rettangolo) 287 */ 288 initcoordRect: null, 289 /** 290 * Property: initcoordTrap 291 * {OpenLayers.LonLat} coordinata "reale" del centro della mappa (trapezio) 292 */ 293 initcoordTrap: null, 294 /** 295 * Property: scale 296 * {string} actual scale of the tile map 297 */ 298 scale: null, 299 /** 300 * Flag to remember if obliquephoto is opened or not 301 * {boolean} flag for opened status 302 */ 303 opened: false, 304 /** 305 * Start direction: fixed North (N) 306 * 307 * @public 308 * @type String 309 */ 310 initDirection: 'N' 311 }, 312 /** 313 * Livello di zoom minimo della visualizzazione dell'ortofoto 314 * 315 * @public 316 * @type Number 317 */ 318 minZoomOrtoPhoto: 4, 319 /** 320 * Layer dei TMS del'ortofoto visualizzata 321 * 322 * @public 323 * @type {Object} OpenLayers.Layer.TMS 324 */ 325 tmsOrtoLayer: null, 326 /** 327 * Ortofoto visualizzata in mappa' 328 * 329 * @public 330 * @type {Object} JSON 331 */ 332 ortoPhoto: { 333 /** 334 * Property: extent 335 * {OpenLayers.Bounds} extent of the tile map 336 */ 337 extent: null, 338 /** 339 * Property: tileOrigin 340 * {OpenLayers.LonLat} origin of the tile map 341 */ 342 tileOrigin: null, 343 /** 344 * Property: maxResolution 345 * {float} max resolution of the zero level 346 */ 347 maxResolution: null, 348 /** 349 * Property: zoom 350 * {int} zooom of the tilemap 351 */ 352 typeImg: null, 353 /** 354 * Property: numLevels 355 * {int} num levels of the tile map 356 */ 357 numLevels: 0, 358 /** 359 * Property: resolutions 360 * {int} resolution of the tile map 361 */ 362 resolutions: null, 363 /** 364 * Property: projection 365 * {string} projection of the tile map 366 */ 367 projection: 'EPSG:32632', 368 /** 369 * Property: area 370 * {int} area of the tile map 371 */ 372 area: null, 373 /** 374 * Property: idmap 375 * {string} type map (map1 or map2) 376 */ 377 idmap: null, 378 /** 379 * Property: scale 380 * {string} actual scale of the tile map 381 */ 382 scale: null 383 }, 384 /** 385 * Classe della mappa doppia' 386 * 387 * @public 388 * @type String 389 */ 390 idDoubleMapComp: null, 391 /** 392 * Configured doublemap 393 * 394 * @public 395 * @type {Object} OpenLayers.Map 396 */ 397 map2: null, 398 /** 399 * Layer dei TMS del'ortofoto visualizzata nella mappa singola 400 * 401 * @public 402 * @type {Object} OpenLayers.Layer.TMS 403 */ 404 tmsOrtoLayer2: null, 405 /** 406 * Indica la direzione della vista nella mappa doppia 407 * 408 * @public 409 * @type string 410 */ 411 viewdirection: null, 412 /** api: config[onlyShowOnFirstLoad] 413 * ``Boolean`` Set this to true to only show the loading indicator on the 414 * first load of the map. Default is false. 415 * 416 * @public 417 * @type boolean 418 */ 419 onlyShowOnFirstLoad: false, 420 /** api: config[loadingMapMessage] 421 * ``String`` Message to show when the map is loading (i18n) 422 * 423 * @public 424 * @type String 425 */ 426 loadingMapMessage: "Loading Map...", 427 428 /** private: property[layerCount] 429 * ``Integer`` The number of layers currently loading. 430 * 431 * @public 432 * @type integer 433 */ 434 layerCount: 0, 435 436 /** 437 * private: property[busyMask] 438 * ``Ext.LoadMask`` The Ext load mask to show when busy. 439 * 440 * @public 441 * @type {Object} Ext.LoadMask 442 */ 443 busyMask: null, 444 445 /** 446 * private: property[busyMask2] 447 * ``Ext.LoadMask`` The Ext load mask to show when busy. 448 * 449 * @public 450 * @type {Object} Ext.LoadMask 451 */ 452 busyMask2: null, 453 454 layer_envelope: null, 455 456 /** 457 * Modalità debug. Visualizzazione estensione e ingombri delle fotooblique 458 * nella mappa doppia. 459 * 460 * @public 461 * @type Boolean 462 */ 463 debug: false, 464 /** 465 * Modalità debug. Layer Vector for extent rectangle 466 * 467 * @public 468 * @type {Object} OpenLayers.Layer.Vector 469 */ 470 debug_rectangle: new OpenLayers.Layer.Vector( "Rectangle", { style: {stroke: true, strokeWidth: 2, strokeColor: '#FFFF00', strokeOpacity: 0.4, fillColor: '#000', fillOpacity: 0}} ), 471 /** 472 * Modalità debug. Feature Vectore for extent rectangle 473 * 474 * @public 475 * @type {Object} OpenLayers.Feature.Vector 476 */ 477 debug_rect: null, 478 /** 479 * Modalità debug. Layer Vector for trapezoid oblique photo 480 * 481 * @public 482 * @type {Object} OpenLayers.Layer.Vector 483 */ 484 debug_trapezoid: new OpenLayers.Layer.Vector( "Trapezoid", { style: {stroke: true, strokeWidth: 2, strokeColor: '#0000FF', fillColor: '#000', fillOpacity: 0}} ), 485 /** 486 * Modalità debug. Feature Vector for trapezoid oblique photo 487 * 488 * @public 489 * @type {Object} OpenLayers.Feature.Vector 490 */ 491 debug_trap: null, 492 /** 493 * Modalità debug. Layer Vector for extent view 494 * 495 * @public 496 * @type {Object} OpenLayers.Layer.Vector 497 */ 498 debug_boxes: new OpenLayers.Layer.Vector( "Boxes", { style: {stroke: true, strokeWidth: 2, strokeColor: '#FF0000', fillColor: '#000', fillOpacity: 0.1}} ), 499 /** 500 * Modalità debug. Feature Vector for extent view 501 * 502 * @public 503 * @type {Object} OpenLayers.Feature.Vector 504 */ 505 debug_box: null, 506 /** 507 * Modalità debug. Inviluppo foto oblique. 508 * 509 * @public 510 * @type {Object} OpenLayers.Layer.WMS 511 */ 512 debug_layer: null, 513 /** 514 * Modalità debug. DSM. 515 * 516 * @public 517 * @type {Object} OpenLayers.Layer.WMS 518 */ 519 debug_layer_dsm: null, 520 521 /** 522 * @private 523 * @param {Object} config configuration object 524 */ 525 constructor: function(config) { 526 if (Ext.isEmpty(config.algorithmType)) { 527 //default value 528 config.algorithmType = OBLIQUEPHOTOS_ALGORITHMTYPE.CENTROID_BASED; 529 } 530 framework.plugins.ActiveObliquePhotos.superclass.constructor.apply(this, arguments); 531 }, 532 /** 533 * Create and append info action 534 * @public 535 * @returns {framework.plugins.ActiveObliquePhotos} Object with info control inside 536 */ 537 addActions: function() { 538 539 if (!this.map) { 540 this.map = this.target.mapPanel.map; 541 } 542 if (this.idDoubleMapComp && !this.map2) { 543 this.map2 = Ext.getCmp(this.idDoubleMapComp).app2.mapPanel.map; 544 } 545 546 if (!this.layer_envelope) { 547 this.layer_envelope = new OpenLayers.Layer.WMS( 548 this.typename, this.baseUrl+"/geoserver/wms", 549 { 550 LAYERS: this.workspace+this.typename, 551 STYLES: '', 552 format: "image/png", 553 transparent: true, 554 tiled: true 555 }, 556 { 557 buffer: 0, 558 displayInLayerSwitcher: false, 559 singleTile: true, 560 ratio: 1, 561 visibility: true, 562 isBaseLayer: false, 563 yx : {'EPSG:3003' : false} 564 } 565 ); 566 } 567 568 569 var self = this; 570 this.map.events.register('zoomend', this, this.enableButton); 571 this.map.events.register('zoom', this, this.verifyMinZoomObliquePhoto); 572 573 //registrazione evento spostamento mappa 574 this.dragcontrol = new OpenLayers.Control.DragPan({'map': this.map, 575 'panMapDone': function(xy) { 576 this.userdragged = true; 577 self.refreshPhotogram(false); 578 }}); 579 580 this.dragcontrol.draw(); 581 this.map.addControl(this.dragcontrol); 582 var sUrl = ""; 583 if (this.proxy) 584 sUrl = this.proxy + escape(this.url); 585 else 586 sUrl = this.url; 587 588 if (!this.store) { 589 this.store = new Ext.data.Store({ 590 proxy: new Ext.data.HttpProxy({ 591 url: sUrl, 592 method: 'POST' 593 }), 594 fields: [this.propertyName], 595 reader: new framework.data.EnvelopesObliquePhotos_XLSReader({ 596 propertyName: this.propertyName 597 }), 598 listeners: { 599 datachanged: function(store) { 600 var center = this.target.mapPanel.map.getCenter(); 601 // trasformazione coordinate in UTM 32N 602 Proj4js.defs["EPSG:32632"] = "+title=UTM 32N +proj=utm +zone=32 +ellps=WGS84 +datum=WGS84 +units=m +no_defs "; 603 new Proj4js.Proj('EPSG:32632'); 604 605 var fromProjection = new OpenLayers.Projection(this.srs); // Transform from ROMA40 606 var toProjection = new OpenLayers.Projection("EPSG:32632"); // to Spherical Mercator Projection 607 var position = new OpenLayers.LonLat(center.lon, center.lat).transform(fromProjection, toProjection); 608 609 if (store.data.items[0].data.msg_error === 1) { 610 this.msgAlert(this.mapInfoText, this.noPhoto, false); 611 } else { 612 var areaId = store.data.items[0].data.id; 613 //verificare la foto obliqua più vicina alla coordinata 614 this.loadPhotogram(areaId, position, true); 615 } 616 }, 617 beforeload: function(store, operation) { 618 619 var center = this.target.mapPanel.map.getCenter(); 620 621 store.baseParams['BBOX'] = (center.lon - this.tollerance) + "," + (center.lat - this.tollerance) + "," + (center.lon + this.tollerance) + "," + (center.lat + this.tollerance); 622 623 }, 624 scope: this 625 }, 626 baseParams: { 627 'typename': this.typename, 628 'SERVICE': 'WFS', 629 'VERSION': '1.0.0', 630 'REQUEST': 'GetFeature', 631 'propertyName': this.propertyName, 632 'SRS': this.srs, 633 'sortby': this.sortby, 634 'BBOX': this.BBOX 635 }, 636 scope: this 637 }); 638 639 } 640 641 this.button = new Ext.Button({ 642 iconCls: this.iconCls, 643 tooltip: this.tooltip, 644 pressedCls: this.pressedCls, 645 enableToggle: true, 646 handler: function() { 647 if (this.button.pressed) { 648 this.store.load(); 649 } 650 else { 651 this.button.addClass(this.unpressedCls); 652 this.button.removeClass(this.pressedCls); 653 this.button.setTooltip(this.tooltip); 654 655 this.closePhotogram(); 656 } 657 }, 658 listeners: { 659 mouseover: function () { 660 this.scope.map.addLayer(this.scope.layer_envelope); 661 self.centroidActiveObliquePhoto(this.scope.map,true); 662 }, 663 mouseout: function () { 664 this.scope.map.removeLayer(this.scope.layer_envelope); 665 self.centroidActiveObliquePhoto(this.scope.map,false); 666 }, 667 beforeshow: function() { 668 this.enableButton(); 669 if (this.button.pressed) { 670 this.button.removeClass('x-btn-pressed'); 671 this.button.removeClass(this.unpressedCls); 672 this.button.addClass(this.pressedCls); 673 this.button.setTooltip(this.button.tooltipDeactivate); 674 } 675 else { 676 this.button.addClass(this.unpressedCls); 677 this.button.setTooltip(this.button.tooltip); 678 } 679 } 680 }, 681 scope: this 682 }); 683 684 this.button.addClass(this.unpressedCls); 685 686 return framework.plugins.ActiveObliquePhotos.superclass.addActions.apply(this, [this.button]); 687 }, 688 689 centroidActiveObliquePhoto: function(map,over) { 690 691 console.log("mouseover"); 692 console.log(over); 693 694 if(!this.layer){ 695 this.layer = new OpenLayers.Layer.Vector('centroidActiveObliquePhoto', { 696 displayInLayerSwitcher: false, 697 visibility: true, 698 styleMap: new OpenLayers.StyleMap({ 699 'default': new OpenLayers.Style({ 700 graphicZIndex: 100, 701 pointRadius: 5, 702 fillColor: "#f29f1e", 703 fillOpacity: 0.5, 704 strokeWidth: 2, 705 strokeColor: "white", 706 graphicName: "circle" 707 })}) 708 }); 709 } 710 var center = map.getCenter(); 711 var point = new OpenLayers.Geometry.Point(center.lon, center.lat); 712 this.layer.removeAllFeatures(); 713 this.layer.addFeatures([new OpenLayers.Feature.Vector(point)]); 714 if (map.getLayersByName("centroidActiveObliquePhoto").length !== 0) { 715 map.removeLayer(this.layer); 716 }; 717 if (over) 718 map.addLayer(this.layer); 719 }, 720 /** 721 * Enable button for activate oblique photos. 722 * @public 723 */ 724 enableButton: function() { 725 726 if (this.map.getScale() <= this.minScaleActivate) { 727 this.actions[0].enable(); 728 } 729 else { 730 this.actions[0].disable(); 731 } 732 733 }, 734 /** 735 * Verifica il livello di zoom durante la navigazione. 736 * @private 737 */ 738 verifyMinZoomObliquePhoto: function() { 739 740 if (this.button) { 741 742 if (this.button.pressed) { 743 744 var x = this.map.getZoom(); 745 746 if (x < this.minZoomObliquePhoto) 747 { 748 //this.closePhotogram(); 749 //this.button.toggle(false); 750 // this.map.zoomTo(this.minZoomObliquePhoto); 751 this.map.setCenter(null,this.minZoomObliquePhoto); 752 } 753 if (this.idDoubleMapComp) { 754 if (!this.debug) this.map2.zoomToScale(this.map.getScale()); 755 this.map2.setCenter(this.obliquePhoto.initcoordTrap); 756 } 757 758 //this.obliquePhoto.scale = this.map.getScale(); 759 } 760 } 761 }, 762 /** 763 * Chiude il fotogramma della fotoobliqua visualizzata. 764 * @private 765 */ 766 closePhotogram: function() { 767 768 var center = this.target.mapPanel.map.getCenter(); 769 770 // trasformazione coordinate in UTM 32N 771 Proj4js.defs["EPSG:32632"] = "+title=UTM 32N +proj=utm +zone=32 +ellps=WGS84 +datum=WGS84 +units=m +no_defs "; 772 new Proj4js.Proj('EPSG:32632'); 773 774 var fromProjection = new OpenLayers.Projection("EPSG:32632"); // to Spherical Mercator Projection 775 var toProjection = new OpenLayers.Projection(this.srs); // Transform from ROMA40 776 var position = new OpenLayers.LonLat(center.lon, center.lat).transform(fromProjection, toProjection); 777 778 if (this.tmsLayer !== null) 779 { 780 this.tmsLayer.destroy(); 781 } 782 783 this.fireEvent('obliquePhotoClosed'); 784 785 this.map.setCenter(position); 786 787 if (this.idDoubleMapComp) 788 this.map2.setCenter(position); 789 790 this.lastBaseLayer = null; 791 this.dragcontrol.deactivate(); 792 this.hideCompass(); 793 794 this.obliquePhoto.initcoordRect = undefined; 795 this.obliquePhoto.initcoordTrap = undefined; 796 }, 797 /** 798 * Finds a photogram using area id and current coordinate and loads it 799 * @param {String} area id of the area of the photogram to find 800 * @param {OpenLayers.LonLat} coord current coordinate (used to find nearest photogram) 801 * @private 802 */ 803 loadPhotogram: function(area, coord, transform) { 804 this.obliquePhoto.initDirection = "N" 805 this.obliquePhoto.area = area; 806 this.obliquePhoto.initcoordTrap = coord; 807 this.obliquePhoto.initcoordRect = coord; 808 Ext.Ajax.request({ 809 url: this.getObliqueServletUrl(), 810 method: 'POST', 811 params: { 812 method: 'nearest', 813 area: area, 814 algorithmType: this.algorithmType.value, 815 photoId: Ext.isEmpty(this.obliquePhoto) ? null : this.obliquePhoto.id, 816 coordinate: Ext.util.JSON.encode(coord), 817 extent: Ext.util.JSON.encode(this.getCurrentExtent(transform)), 818 direction: Ext.isEmpty(this.compass) ? this.obliquePhoto.initDirection : this.compass.getDirection() 819 }, 820 success: function(data) { 821 if (data.responseText) { 822 var record = Ext.util.JSON.decode(data.responseText); 823 824 if (!Ext.isEmpty(record.error)) { 825 if (record.error.indexOf("java.io.FileNotFoundException") != -1) { 826 this.msgAlert(this.mapInfoText, this.noCSV, false); 827 } 828 else 829 Ext.MessageBox.alert('Errore caricamento foto obliqua', record.error); 830 } else { 831 832 // GB: HACK CASO INIZIALE CON NE, SE, NW, SW 833 if (record.direction != this.obliquePhoto.initDirection) 834 this.obliquePhoto.initDirection = record.direction; 835 836 if (this.idDoubleMapComp) { 837 this.openOrtoPhoto(this.obliquePhoto.area, "map2"); 838 } 839 this.openObliquePhoto(record); 840 this.dragcontrol.activate(); 841 if (!this.compass) { 842 this.showCompass(); 843 this.compass.refreshCssClass(); 844 } 845 } 846 } else { 847 Ext.MessageBox.alert('Errore caricamento fotogramma', 'Risposta da servlet errata'); 848 } 849 }, scope: this 850 }); 851 }, 852 /** 853 * Shows Compass control 854 * @public 855 */ 856 showCompass: function() { 857 this.compass = new framework.widgets.control.Compass({ 858 id: this.id + '_pcompass', 859 displayClass: 'panelCompass', 860 initDirection: this.obliquePhoto.initDirection 861 }); 862 this.map.addControl(this.compass); 863 this.compass.activate(); 864 this.compass.events.register('rotateLeft', this, function(evt) { 865 this.refreshPhotogram(true); 866 if (this.viewdirection) 867 this.viewdirection.rotateLeft(); 868 }); 869 this.compass.events.register('rotateRight', this, function(evt) { 870 this.refreshPhotogram(true); 871 if (this.viewdirection) 872 this.viewdirection.rotateRight(); 873 }); 874 this.compass.events.register('modeSwitched', this, function(evt) { 875 if (this.compass.mode === this.compass.MODES.ORTHO) { 876 this.openOrtoPhoto(this.obliquePhoto.area, "map1"); 877 if (this.tmsLayer) this.tmsLayer.destroy(); 878 this.dragcontrol.deactivate(); 879 if (this.viewdirection) 880 this.viewdirection.hide(); 881 } else { 882 var position = this.target.mapPanel.map.getCenter(); 883 if (this.tmsOrtoLayer) this.tmsOrtoLayer.destroy(); 884 this.loadPhotogram(this.obliquePhoto.area,position,false); 885 if (this.viewdirection) 886 this.viewdirection.show(); 887 } 888 889 }); 890 891 if (this.idDoubleMapComp) { 892 this.createViewDirection(0); 893 this.viewdirection.refreshCssClass(); 894 } 895 }, 896 /** 897 * Crea il controllo sulla mappa doppia che indica la vista rispetto alla direzione della foto obliqua 898 * visualizzata in mappa singola 899 * @private 900 */ 901 createViewDirection: function() { 902 this.viewdirection = new framework.widgets.control.ViewDirection({ 903 id: this.id + '_pviewdirection', 904 displayClass: 'panelViewDirection', 905 initDirection: this.obliquePhoto.initDirection 906 }); 907 this.map2.addControl(this.viewdirection); 908 909 }, 910 /** 911 * Hides Compass control 912 * @public 913 */ 914 hideCompass: function() { 915 this.compass.deactivate(); 916 this.map.removeControl(this.compass); 917 this.compass.destroy(); 918 this.compass = null; 919 if (this.viewdirection) { 920 this.viewdirection.destroy(); 921 } 922 }, 923 /** 924 * Method: fillTileMapFailure 925 * on failure load url 926 * 927 * @private 928 * @param data string of the file xml 929 * 930 */ 931 fillCSVFailure: function(data) { 932 Ext.MessageBox.alert('Errore', 'Foto oblique non ancora disponibili. La zona è in fase di elaborazione.'); 933 this.button.toggle(false); 934 }, 935 /** 936 * Method: openObliquePhoto 937 * Apre la foto obliqua 938 * 939 * @private 940 * @param {String } json representation of the file xml 941 * 942 */ 943 openObliquePhoto: function(data) { 944 this.obliquePhoto.id = data.photogramId; 945 this.obliquePhoto.tmsUrl = data.tmsUrl; 946 this.obliquePhoto.direction = data.direction; 947 this.obliquePhoto.maxExtent = new OpenLayers.Bounds( 948 data.areaExtent.minx, 949 data.areaExtent.miny, 950 data.areaExtent.maxx, 951 data.areaExtent.maxy); 952 var deltaX = this.obliquePhoto.maxExtent.getWidth()/14; 953 var deltaY = this.obliquePhoto.maxExtent.getHeight()/14; 954 //computes an extent incremented by deltaX and deltaY (and the same center) 955 this.obliquePhoto.restrictedExtent = new OpenLayers.Bounds( 956 data.viewPort.minx - deltaX, 957 data.viewPort.miny - deltaY, 958 data.viewPort.maxx + deltaX, 959 data.viewPort.maxy + deltaY); 960 this.obliquePhoto.viewPort = new OpenLayers.Bounds( 961 data.viewPort.minx, 962 data.viewPort.miny, 963 data.viewPort.maxx, 964 data.viewPort.maxy); 965 Ext.Ajax.request({ 966 url: data.tmsUrl + '/' + this.tilemapResource, 967 success: function(obj) { 968 if (!Ext.isEmpty(data.coordinate)) { 969 obj.coordinate = data.coordinate; 970 } 971 if (!Ext.isEmpty(data.zoom)) { 972 obj.zoom = data.zoom; 973 } 974 if (!Ext.isEmpty(data.viewPort)) { 975 obj.viewPort = data.viewPort; 976 } 977 this.fillTileMap(obj); 978 }, 979 failure: this.fillTileMapFailure, 980 scope: this 981 }); 982 }, 983 /** 984 * Method: fillTileMap 985 * 986 * fill this object tile map with the information of the tile map 987 * 988 * @private 989 * @param data string of the file xml 990 * 991 */ 992 fillTileMap: function(data) { 993 var doc = data.responseXML; 994 if (!doc || !doc.documentElement) { 995 doc = data.responseText; 996 } 997 998 var xml = new OpenLayers.Format.XML(); 999 if (typeof doc == "string") { 1000 doc = xml.read(doc); 1001 } 1002 1003 var boundingBoxNode = doc.getElementsByTagName('BoundingBox'); 1004 if (boundingBoxNode !== null && boundingBoxNode[0] != null) { 1005 var boundingBox = boundingBoxNode[0]; 1006 var minx = boundingBox.getAttribute('miny'); 1007 var miny = boundingBox.getAttribute('minx'); 1008 var maxx = boundingBox.getAttribute('maxy'); 1009 var maxy = boundingBox.getAttribute('maxx'); 1010 if (minx != null && minx != '' && miny != null && miny != '' && maxx != null && maxx != '' && maxy != null && maxy != '') { 1011 this.obliquePhoto.extent = new OpenLayers.Bounds(minx, miny, maxx, maxy); 1012 } 1013 } 1014 var tileOriginNode = doc.getElementsByTagName('Origin'); 1015 if (tileOriginNode != null && tileOriginNode[0] != null) { 1016 var origin = tileOriginNode[0]; 1017 var x = origin.getAttribute('y'); 1018 var y = origin.getAttribute('x'); 1019 if (x != null && x != '' && y != null && y != '') { 1020 this.obliquePhoto.tileOrigin = new OpenLayers.LonLat(x, y); 1021 } 1022 } 1023 var tileFormat = doc.getElementsByTagName('TileFormat'); 1024 if (tileFormat != null && tileFormat[0] != null) { 1025 var tileType = tileFormat[0]; 1026 this.obliquePhoto.typeImg = tileType.getAttribute('extension'); 1027 } 1028 var tileSet = doc.getElementsByTagName('TileSet'); 1029 if (tileSet != null && tileSet.length > 0) { 1030 this.obliquePhoto.numLevels = tileSet.length; 1031 this.obliquePhoto.resolutions = []; 1032 for (var i = 0; i < tileSet.length; i++) { 1033 var firstTileSet = tileSet[i]; 1034 var order = firstTileSet.getAttribute('order'); 1035 if (order != null && order == '0') { 1036 var unitsperpixel = firstTileSet.getAttribute('units-per-pixel'); 1037 if (unitsperpixel != null) { 1038 this.obliquePhoto.maxResolution = unitsperpixel; 1039 } 1040 //break; 1041 } 1042 this.obliquePhoto.resolutions.push(parseFloat(firstTileSet.getAttribute('units-per-pixel'))); 1043 } 1044 this.obliquePhoto.resolutions = this.obliquePhoto.resolutions.reverse(); 1045 } 1046 this.obliquePhoto.opened = true; 1047 this.updateObliquePhotoLayer(data); 1048 }, 1049 /** 1050 * Method: fillTileMapFailure 1051 * on failure load url 1052 * 1053 * @private 1054 * @param data string of the file xml 1055 * 1056 */ 1057 fillTileMapFailure: function(data) { 1058 Ext.MessageBox.alert('Errore', 'Foto obliqua non esistente.'); 1059 this.button.toggle(false); 1060 }, 1061 /** 1062 * Method: updateFotogrammiLayer 1063 * Update Fotogrammi Layer to show selected fotogramma 1064 * 1065 * @private 1066 * @param data string of the file xml 1067 * 1068 */ 1069 updateObliquePhotoLayer: function(data) { 1070 1071 this.map.events.unregister('zoomend', this, this.verifyMinZoomObliquePhoto); 1072 1073 if (!this.lastBaseLayer) { 1074 this.lastBaseLayer = this.map.baseLayer; 1075 } 1076 1077 var options = { 1078 projection: this.obliquePhoto.projection, 1079 id: "mymap", 1080 units: 'm', 1081 resolutions: this.obliquePhoto.resolutions, 1082 maxResolution: this.obliquePhoto.maxResolution, 1083 maxExtent: this.obliquePhoto.maxExtent, 1084 restrictedExtent: this.obliquePhoto.restrictedExtent, 1085 numZoomLevels: this.obliquePhoto.numLevels, 1086 panMethod: "null", 1087 zoom: this.minZoomObliquePhoto 1088 }; 1089 this.map.setOptions(options); 1090 this.changePhotogram(); 1091 this.map.setBaseLayer(this.tmsLayer); 1092 var zoom = (Ext.isEmpty(data.zoom)) ? 4 : data.zoom; 1093 var center; 1094 if (Ext.isEmpty(data.viewPort)) { 1095 center = data.coordinate; 1096 this.map.setCenter(center, zoom); 1097 } else { 1098 var x = data.viewPort.minx + (data.viewPort.maxx - data.viewPort.minx) / 2; 1099 var y = data.viewPort.miny + (data.viewPort.maxy - data.viewPort.miny) / 2; 1100 center = new OpenLayers.LonLat(x, y); 1101 this.map.setCenter(center, zoom); 1102 } 1103 1104 //per zoomare sul punt corretto della mappa all'apertura delle fotooblique 1105 if (this.obliquePhoto.initcoordRect) { 1106 this.map.setCenter(this.obliquePhoto.initcoordRect, zoom); 1107 } 1108 1109 this.obliquePhoto.scale = this.map.getScale(); 1110 1111 this.fireEvent('obliquePhotoOpened', this.tmsLayer, this.obliquePhoto); 1112 1113 this.map.events.register('zoomend', this, this.verifyMinZoomObliquePhoto); 1114 1115 if (this.button) { 1116 this.button.removeClass('x-btn-pressed'); 1117 this.button.removeClass(this.unpressedCls); 1118 this.button.addClass(this.pressedCls); 1119 this.button.setTooltip(this.tooltipDeactivate); 1120 } 1121 1122 }, 1123 /** 1124 * Method: changePhotogram 1125 * Cambio fotogramma 1126 * 1127 * @private 1128 * 1129 */ 1130 changePhotogram: function() { 1131 this.oldTmsLayer = this.tmsLayer; 1132 var layerName = this.obliquePhoto.id; 1133 if (Ext.isEmpty(this.obliquePhoto.id) || Ext.isEmpty(this.obliquePhoto.area)) { 1134 return; 1135 } 1136 this.tmsLayer = new OpenLayers.Layer.TMS( 1137 this.obliquePhoto.id, 1138 this.tmsUrl + this.obliquePhoto.area, 1139 { 1140 layername: layerName, 1141 type: this.obliquePhoto.typeImg, 1142 format: 'image/png', 1143 maxExtent: this.obliquePhoto.extent, 1144 tileOrigin: this.obliquePhoto.tileOrigin, 1145 candidateBaseLayer: true, 1146 displayInLayerSwitcher: false, 1147 serviceVersion: '' 1148 }); 1149 this.tmsLayer.setIsBaseLayer(true); 1150 this.map.addLayer(this.tmsLayer); 1151 1152 this.tmsLayer.events.register('loadstart', this, this.onloadstart); 1153 this.tmsLayer.events.register('loadend', this, this.onloadend); 1154 1155 var oldLayer = this.oldTmsLayer; 1156 // var destroyTask = new Ext.util.DelayedTask(function() { 1157 if (!Ext.isEmpty(oldLayer)) { 1158 //console.log('Trying to destroy old layer'); 1159 try { 1160 oldLayer.destroy(); 1161 //console.log('Old layer destroyed'); 1162 } catch (err) { 1163 //l'errore può essere solo x oggetto non inizializzato => lo ignoro 1164 console.log('error destroying old layer ' + err); 1165 } 1166 } 1167 // }); 1168 // destroyTask.delay(1000); 1169 }, 1170 /** 1171 * Event handling on map move. 1172 * Here the program will change photogram, if necessary. 1173 * @private 1174 */ 1175 refreshPhotogram: function(compass) { 1176 if (this.obliquePhoto.opened) { 1177 var currentExtent = this.getCurrentExtent(false); 1178 //if (this.obliquePhoto.viewPort.containsBounds(currentExtent) && !compass) { 1179 // continuare perché non la prende! 1180 //return; //skip elaboration 'cause we don't need to change photogram 1181 //} 1182 //console.log(Ext.util.JSON.encode(this.obliquePhoto.viewPort)); 1183 var center = this.target.mapPanel.map.getCenter(); //fittizia 1184 // console.log("center da rettangolo (fittizio)"); 1185 // console.log(center); 1186 this.obliquePhoto.initcoordRect = center; 1187 var zoom = this.target.mapPanel.map.getZoom(); 1188 Ext.Ajax.request({ 1189 url: this.getObliqueServletUrl(), 1190 method: 'POST', 1191 params: { 1192 method: 'convert', 1193 area: this.obliquePhoto.area, 1194 coordinate: Ext.util.JSON.encode(center), 1195 extent: Ext.util.JSON.encode(currentExtent), 1196 photoId: this.obliquePhoto.id 1197 }, 1198 success: function(data) { 1199 if (data.responseText) { 1200 var record = Ext.util.JSON.decode(data.responseText); 1201 if (!Ext.isEmpty(record.coordinate)) { 1202 center = this.toLonLat(record.coordinate); 1203 //console.log("center convertito sul trapezio (reale)"); 1204 //console.log(center); 1205 this.obliquePhoto.initcoordTrap = center; 1206 var viewPort = this.toBounds(record.viewPort); 1207 if (this.idDoubleMapComp && this.debug) this.debugPolygon(viewPort,record.rectangle._coords,record.trapezoid._coords); 1208 this.coordinateConverted(center, viewPort, zoom); 1209 } else { 1210 Ext.MessageBox.alert('Errore conversione', record.error); 1211 } 1212 } else { 1213 Ext.MessageBox.alert('Errore conversione', 'Risposta da servlet errata'); 1214 } 1215 }, 1216 failure: function() { 1217 Ext.MessageBox.alert('Errore conversione', 'Errore in chiamata servizio conversione coordinata.'); 1218 }, 1219 scope: this 1220 }); 1221 } 1222 }, 1223 /** 1224 * Converts a JTS coordinate in a OpenLayers Coordinate 1225 * @param {Object} coordinate JTS coordinate 1226 * @return {OpenLayers.LonLat} LonLat corresponding coordinate 1227 * @private 1228 */ 1229 toLonLat: function(coordinate) { 1230 return new OpenLayers.LonLat(coordinate.x, coordinate.y); 1231 }, 1232 /** 1233 * Converts a JTS envelope to a OpenLayers Bounds 1234 * @param {Object} env JTS envelope 1235 * @return {OpenLayers.Bounds} Bounds corresponding to input envelope 1236 * @private 1237 */ 1238 toBounds: function(env) { 1239 return new OpenLayers.Bounds(env.minx, env.miny, env.maxx, env.maxy); 1240 }, 1241 /** 1242 * Search nearest oblique photos before converting coordinate with extent view 1243 * 1244 * @private 1245 * @param {OpenLayers.LatLon} center 1246 * @param {OpenLayers.Bounds} viewPort 1247 * @param {Integer} zoom 1248 */ 1249 coordinateConverted: function(center, viewPort, zoom) { 1250 var self = this; 1251 Ext.Ajax.request({ 1252 url: self.getObliqueServletUrl(), 1253 method: 'POST', 1254 params: { 1255 method: 'nearest', 1256 area: self.obliquePhoto.area, 1257 extent: Ext.util.JSON.encode(viewPort), 1258 algorithmType: self.algorithmType.value, 1259 photoId: Ext.isEmpty(this.obliquePhoto) ? null : this.obliquePhoto.id, 1260 coordinate: Ext.util.JSON.encode(center), 1261 direction: self.getDirection() 1262 }, 1263 success: function(data) { 1264 if (data.responseText) { 1265 var record = Ext.util.JSON.decode(data.responseText); 1266 if (!Ext.isEmpty(record.error)) { 1267 Ext.MessageBox.alert('Errore cambio mappa', record.error); 1268 //chiusura foto oblique 1269 self.closePhotogram(); 1270 self.button.toggle(false); 1271 } else { 1272 if (self.idDoubleMapComp) 1273 self.onMapObliqueMove(record); 1274 if (Ext.isDefined(record.photogramId) && record.photogramId !== self.obliquePhoto.id) { //otherwise we will use the same photogram 1275 self.obliquePhoto.id = data.photogramId; 1276 self.obliquePhoto.tmsUrl = data.tmsUrl; 1277 self.obliquePhoto.initcoordRect = self.toLonLat(record.coordinate); 1278 //calcolare nuovo extent fotogramma 1279 self.changePhotogram(); 1280 record.zoom = zoom; 1281 self.openObliquePhoto(record); 1282 } 1283 } 1284 } else { 1285 Ext.MessageBox.alert('Errore cambio mappa', 'Risposta da servlet errata'); 1286 } 1287 } 1288 }); 1289 }, 1290 /** 1291 * Returns oblique servlet url 1292 * @private 1293 * @return url servelt obliquephotos 1294 */ 1295 getObliqueServletUrl: function() { 1296 if (this.urlServOPDedicated) { 1297 return this.urlServOPDedicated 1298 } 1299 else { 1300 var current = String(window.location); 1301 current = current.replace("print.jsp", ""); //removes print modality 1302 current = current.replace(/\?.*/g, ""); //removes possible querystring 1303 if (!current.match(/.*\/$/)) { 1304 current += '/'; 1305 } 1306 return current + 'ObliquePhotos'; 1307 } 1308 }, 1309 /** 1310 * Returns current direction 1311 * 1312 * @public 1313 * @return {String} direction 1314 */ 1315 getDirection: function() { 1316 return (Ext.isEmpty(this.compass)) ? this.obliquePhoto.initDirection : this.compass.getDirection(); 1317 }, 1318 /** 1319 * Returns current extent as a coordinate array (of four coordinates) 1320 * 1321 * @private 1322 * @param {Boolean} if trasform coordinate 1323 * @return {OpenLayers.Bounds} extent view optimized 1324 */ 1325 getCurrentExtent: function(trasform) { 1326 var fromProjection = new OpenLayers.Projection(this.srs); // Transform from ROMA40 1327 var toProjection = new OpenLayers.Projection("EPSG:32632"); // to Spherical Mercator Projection 1328 var e = (trasform) ? this.target.mapPanel.map.getExtent().transform(fromProjection, toProjection) : 1329 this.target.mapPanel.map.getExtent(); 1330 var deltaX = e.getWidth()/12; 1331 var deltaY = e.getHeight()/12; 1332 //computes an extent incremented by deltaX and deltaY (and the same center) 1333 var ext_small = new OpenLayers.Bounds( 1334 e.left + deltaX, 1335 e.bottom + deltaY, 1336 e.right - deltaX, 1337 e.top - deltaY); 1338 return ext_small; 1339 }, 1340 /** 1341 * Event handling on map move. 1342 * 1343 * @private 1344 * @param {String} json representation of record coordinate 1345 * 1346 */ 1347 onMapObliqueMove: function(record) { 1348 var map1 = this.map; 1349 var map2 = this.map2; 1350 1351 if (this.idDoubleMapComp) { 1352 map2.setCenter(this.obliquePhoto.initcoordTrap); 1353 } 1354 else { 1355 // per trasformazione coordinate in UTM 32N 1356 Proj4js.defs["EPSG:32632"] = "+title=UTM 32N +proj=utm +zone=32 +ellps=WGS84 +datum=WGS84 +units=m +no_defs "; 1357 new Proj4js.Proj('EPSG:32632'); 1358 1359 var fromProjection = map1.getProjectionObject(); 1360 var toProjection = map2.getProjectionObject(); 1361 1362 map2.setCenter(new OpenLayers.LonLat(record.coordinate.x, record.coordinate.y).transform(fromProjection, toProjection)) 1363 } 1364 1365 if (!this.debug) map2.zoomToScale(map1.getScale()); 1366 }, 1367 1368 openOrtoPhoto: function(area,map) { 1369 1370 this.ortoPhoto.area = area; 1371 this.ortoPhoto.idmap = map; 1372 this.ortoPhoto.scale = this.map.getScale(); 1373 //this.ortoPhoto.position = this.map.getCenter(); 1374 1375 1376 var urlOrto = this.tmsUrl + '/'+ area + '/ORTO/' + this.tilemapResource; 1377 1378 Ext.Ajax.request({ 1379 url: urlOrto, 1380 success: this.fillTileMapOrto, 1381 failure: this.fillTileMapOrtoFailure, 1382 scope: this 1383 }); 1384 1385 }, 1386 1387 /** 1388 * Method: fillTileMap 1389 * 1390 * fill this object tile map with the information of the tile map 1391 * 1392 * @private 1393 * @param data string of the file xml 1394 * 1395 */ 1396 fillTileMapOrto: function(data) { 1397 1398 if (this.ortoPhoto.idmap == "map1") { 1399 var map = this.map; 1400 } 1401 else { 1402 var map = this.map2; 1403 } 1404 1405 this.ortoPhoto = this.configureMap(data,this.ortoPhoto.projection,this.ortoPhoto.area); 1406 1407 if (this.ortoPhoto) { 1408 this.updateOrtoPhotoLayer(map,this.ortoPhoto,'ORTO',"Ortofoto HD"); 1409 1410 } 1411 1412 1413 }, 1414 1415 /** 1416 * Method: fillTileMapFailure 1417 * on failure load url 1418 * 1419 * @private 1420 * @param data string of the file xml 1421 * 1422 */ 1423 fillTileMapOrtoFailure: function(data) { 1424 alert('Ortofoto associata alla foto obliqua non esistente.'); 1425 }, 1426 /** 1427 * Method: fillTileMap 1428 * 1429 * fill this object tile map with the information of the tile map 1430 * 1431 * @private 1432 * @param data string of the file xml 1433 * 1434 */ 1435 configureMap: function(data,projection,area) { 1436 1437 var tilemap = { 1438 extent: null, 1439 tileOrigin:null, 1440 maxResolution:null, 1441 typeImg: null, 1442 numLevels:0, 1443 resolutions: null, 1444 projection: projection, 1445 area: area, 1446 idmap: this.ortoPhoto.idmap 1447 }; 1448 1449 var doc = data.responseXML; 1450 if (!doc || !doc.documentElement) { 1451 doc = data.responseText; 1452 } 1453 1454 var xml = new OpenLayers.Format.XML(); 1455 if (typeof doc == "string") { 1456 doc = xml.read(doc); 1457 } 1458 1459 var boundingBoxNode = doc.getElementsByTagName('BoundingBox'); 1460 if (boundingBoxNode != null && boundingBoxNode[0] != null) { 1461 var boundingBox = boundingBoxNode[0]; 1462 var minx = boundingBox.getAttribute('miny'); 1463 var miny = boundingBox.getAttribute('minx'); 1464 var maxx = boundingBox.getAttribute('maxy'); 1465 var maxy = boundingBox.getAttribute('maxx'); 1466 if (minx != null && minx != '' && miny != null && miny != '' && maxx != null && maxx != '' && maxy != null && maxy != '') { 1467 tilemap.extent = new OpenLayers.Bounds(minx, miny, maxx, maxy); 1468 } 1469 } 1470 var tileOriginNode = doc.getElementsByTagName('Origin'); 1471 if (tileOriginNode != null && tileOriginNode[0] != null) { 1472 var origin = tileOriginNode[0]; 1473 var x = origin.getAttribute('y'); 1474 var y = origin.getAttribute('x'); 1475 if (x != null && x != '' && y != null && y != '') { 1476 tilemap.tileOrigin = new OpenLayers.LonLat(x, y); 1477 } 1478 } 1479 var tileFormat = doc.getElementsByTagName('TileFormat'); 1480 if (tileFormat != null && tileFormat[0] != null) { 1481 var tileType = tileFormat[0]; 1482 tilemap.typeImg = tileType.getAttribute('extension'); 1483 } 1484 var tileSet = doc.getElementsByTagName('TileSet'); 1485 if (tileSet != null && tileSet.length > 0) { 1486 tilemap.numLevels = tileSet.length; 1487 tilemap.resolutions = []; 1488 for (var i = 0; i < tileSet.length; i++) { 1489 var firstTileSet = tileSet[i]; 1490 var order = firstTileSet.getAttribute('order'); 1491 if (order != null && order == '0') { 1492 var unitsperpixel = firstTileSet.getAttribute('units-per-pixel'); 1493 if (unitsperpixel != null) { 1494 tilemap.maxResolution = unitsperpixel; 1495 1496 1497 } 1498 //break; 1499 } 1500 tilemap.resolutions.push(parseFloat(firstTileSet.getAttribute('units-per-pixel'))); 1501 } 1502 tilemap.resolutions = tilemap.resolutions.reverse(); 1503 } 1504 1505 return tilemap; 1506 1507 1508 }, 1509 /** 1510 * Method: updateFotogrammiLayer 1511 * 1512 * Update Fotogrammi Layer to show selected fotogramma 1513 * @private 1514 * @param {OpenLayers.Map} map 1515 * @param {Object} tilemap Ortofoto corrente 1516 * @param {String} layername 1517 * @param {String} namePhoto 1518 * 1519 */ 1520 updateOrtoPhotoLayer: function(map,tilemap,layername,namePhoto) { 1521 1522 var options = { 1523 projection: tilemap.projection, 1524 id:"mymap", 1525 units: 'm', 1526 resolutions: tilemap.resolutions, 1527 maxResolution: tilemap.maxResolution, 1528 maxExtent: tilemap.extent, 1529 restrictedExtent: tilemap.extent, 1530 numZoomLevels: tilemap.numLevels, 1531 panMethod:"null", 1532 zoom: 1 1533 }; 1534 1535 map.setOptions(options); 1536 1537 var layerTemp = new OpenLayers.Layer.TMS( 1538 namePhoto, 1539 this.tmsUrl + '/' + tilemap.area, 1540 { 1541 layername: layername, 1542 type: tilemap.typeImg, 1543 background: "#000000", 1544 maxExtent: tilemap.extent, 1545 tileOrigin: tilemap.tileOrigin, 1546 candidateBaseLayer: true, 1547 displayInLayerSwitcher: false, 1548 serviceVersion: '' 1549 }); 1550 1551 layerTemp.setIsBaseLayer(true); 1552 1553 map.addLayer(layerTemp); 1554 1555 if (this.idDoubleMapComp) { 1556 layerTemp.events.register('loadstart', this, this.onloadstart2); 1557 layerTemp.events.register('loadend', this, this.onloadend2); 1558 } 1559 1560 map.setBaseLayer(layerTemp); 1561 1562 if (!this.debug) map.zoomToScale(this.obliquePhoto.scale); 1563 map.setCenter(this.obliquePhoto.initcoordTrap); 1564 1565 1566 if (tilemap.idmap == "map1") 1567 this.tmsOrtoLayer = layerTemp; 1568 else 1569 this.tmsOrtoLayer2 = layerTemp; 1570 1571 }, 1572 /** 1573 * Method: onloadstart 1574 * 1575 * Avvio esecuzione chiamate layer TMS, 1576 * @private 1577 * @param {Event} evt 1578 * 1579 */ 1580 onloadstart: function(evt) { 1581 this.layerCount++; 1582 if (!this.busyMask) { 1583 this.busyMask = new Ext.LoadMask( 1584 this.map.div, { 1585 msg: this.loadingMapMessage 1586 } 1587 ); 1588 } 1589 this.busyMask.show(); 1590 if (this.onlyShowOnFirstLoad === true) { 1591 this.tmsLayer.events.unregister("loadstart", this, arguments.callee); 1592 } 1593 }, 1594 /** 1595 * Method: onloadend 1596 * 1597 * Fine esecuzione chiamate layer TMS, 1598 * @private 1599 * @param {Event} evt 1600 * 1601 */ 1602 onloadend: function(evt) { 1603 this.layerCount--; 1604 if(this.layerCount === 0) { 1605 this.busyMask.hide(); 1606 } 1607 if (this.onlyShowOnFirstLoad === true) { 1608 this.tmsLayer.events.unregister("loadend", this, arguments.callee); 1609 } 1610 }, 1611 /** 1612 * Method: onloadstart2 1613 * 1614 * Avvio esecuzione chiamate Ajax per i servizi 1615 * @private 1616 * @param {Event} evt 1617 * 1618 */ 1619 onloadstart2: function(evt) { 1620 if (!this.busyMask2) { 1621 this.busyMask2 = new Ext.LoadMask( 1622 this.map2.div, { 1623 msg: this.loadingMapMessage 1624 } 1625 ); 1626 } 1627 this.busyMask2.show(); 1628 evt.object.events.unregister("loadstart", this, arguments.callee); 1629 }, 1630 /** 1631 * Method: onloadend2 1632 * 1633 * Fine esecuzione chiamate Ajax per i servizi 1634 * @private 1635 * @param {Event} evt 1636 * 1637 */ 1638 onloadend2: function(evt) { 1639 this.busyMask2.hide(); 1640 evt.object.events.unregister("loadend", this, arguments.callee); 1641 }, 1642 /** 1643 * Opens an oblique photo but using its json representation 1644 * @param {String} json representation of the photogram 1645 * @param {OpenLayers.LatLon} center position 1646 * @public 1647 */ 1648 openFromJSON: function(json,center) { 1649 if (json) { 1650 1651 if (!this.map) { 1652 this.map = this.target.mapPanel.map; 1653 } 1654 if (this.idDoubleMapComp && !this.map2) { 1655 this.map2 = Ext.getCmp(this.idDoubleMapComp).app2.mapPanel.map; 1656 } 1657 1658 var record = json; 1659 this.obliquePhoto.area = record.area; 1660 var position = new OpenLayers.LonLat(record.initcoordRect.lon, record.initcoordRect.lat); 1661 this.obliquePhoto.initcoordRect = position; 1662 var position = new OpenLayers.LonLat(record.initcoordTrap.lon, record.initcoordTrap.lat); 1663 this.obliquePhoto.initcoordTrap = position; 1664 this.obliquePhoto.scale = record.scale; 1665 this.obliquePhoto.id = record.id; 1666 this.obliquePhoto.tmsUrl = record.tmsUrl; 1667 this.obliquePhoto.direction = record.direction; 1668 this.obliquePhoto.initDirection = record.initDirection; 1669 this.obliquePhoto.maxExtent = new OpenLayers.Bounds( 1670 record.maxExtent.left, 1671 record.maxExtent.bottom, 1672 record.maxExtent.right, 1673 record.maxExtent.top); 1674 this.obliquePhoto.restrictedExtent = new OpenLayers.Bounds( 1675 record.restrictedExtent.left, 1676 record.restrictedExtent.bottom, 1677 record.restrictedExtent.right, 1678 record.restrictedExtent.top); 1679 this.obliquePhoto.viewPort = new OpenLayers.Bounds( 1680 record.viewPort.left, 1681 record.viewPort.bottom, 1682 record.viewPort.right, 1683 record.viewPort.top); 1684 1685 Ext.Ajax.request({ 1686 url: record.tmsUrl + '/' + this.tilemapResource, 1687 success: function(obj) { 1688 if (!Ext.isEmpty(record.coordinate)) { 1689 obj.coordinate = record.coordinate; 1690 } 1691 if (!Ext.isEmpty(record.zoom)) { 1692 obj.zoom = record.zoom; 1693 } 1694 if (!Ext.isEmpty(record.viewPort)) { 1695 obj.viewPort = record.viewPort; 1696 } 1697 this.fillTileMap(obj); 1698 }, 1699 failure: this.fillTileMapFailure, 1700 scope: this 1701 }); 1702 1703 if (this.dragcontrol) 1704 this.dragcontrol.activate(); 1705 1706 if (!this.compass) { 1707 this.showCompass(); 1708 this.compass.setDirection(record.direction); 1709 this.compass.refreshCssClass(); 1710 if (this.viewdirection) { 1711 this.viewdirection.setDirection(record.direction); 1712 this.viewdirection.refreshCssClass(); 1713 } 1714 } 1715 1716 if (this.idDoubleMapComp) { 1717 this.openOrtoPhoto(this.obliquePhoto.area, "map2"); 1718 } 1719 1720 if (this.button) { 1721 this.enableButton(); 1722 this.button.toggle(true); 1723 } 1724 } 1725 }, 1726 /** 1727 * Method: msgAlert 1728 * 1729 * Messaggio di avviso 1730 * 1731 * @private 1732 * @param {String} title 1733 * @param {String} text 1734 * @param {Boolean} toggle 1735 * 1736 */ 1737 msgAlert: function (title, text, toggle) { 1738 var mapInfo = new Ext.Panel({ 1739 title: title, 1740 html: '<div class="gx-info-panel">' + 1741 '<p><b>'+text+'</b>' + 1742 '</p></div>', 1743 height: 'auto', 1744 width: 'auto' 1745 }); 1746 1747 var win = new Ext.Window({ 1748 title: "Avviso", 1749 modal: true, 1750 layout: "fit", 1751 width: 'auto', 1752 height: 'auto', 1753 items: [mapInfo] 1754 }); 1755 win.show(); 1756 this.button.toggle(toggle); 1757 }, 1758 /** 1759 * Method: debugPolygon 1760 * 1761 * Funzione per lanciare la modalità di debug durante la navigazione 1762 * delle foto oblique 1763 * 1764 * @private 1765 * @param {OpenLayers.Bounds} viewBounds 1766 * @param {Object} rectangle (points rectangle) 1767 * @param {Object} trapezoid (points trapezoid) 1768 * 1769 */ 1770 debugPolygon: function(viewBounds,rectangle,trapezoid) { 1771 1772 if (this.debug_box) { 1773 1774 //extent schermo 1775 this.debug_boxes.removeFeatures([this.debug_box]); 1776 this.debug_box = new OpenLayers.Feature.Vector(viewBounds.toGeometry()); 1777 this.debug_boxes.addFeatures(this.debug_box); 1778 1779 //rettangolo 1780 this.debug_rectangle.removeFeatures([this.debug_rect]); 1781 var pointList = []; 1782 var num_point = rectangle.length; 1783 var newPoint = null; 1784 for (var i = 0; i < num_point; i++) { 1785 newPoint = new OpenLayers.Geometry.Point(rectangle[i].x,rectangle[i].y); 1786 pointList.push(newPoint); 1787 } 1788 var ring = new OpenLayers.Geometry.LinearRing(pointList); 1789 var polygon = new OpenLayers.Geometry.Polygon([ring]); 1790 this.debug_rect = new OpenLayers.Feature.Vector(polygon); 1791 this.debug_rectangle.addFeatures(this.debug_rect); 1792 1793 //trapezio 1794 this.debug_trapezoid.removeFeatures([this.debug_trap]); 1795 pointList = []; 1796 num_point = trapezoid.length; 1797 newPoint = null; 1798 for (var i = 0; i < num_point; i++) { 1799 newPoint = new OpenLayers.Geometry.Point(trapezoid[i].x,trapezoid[i].y); 1800 pointList.push(newPoint); 1801 } 1802 ring = new OpenLayers.Geometry.LinearRing(pointList); 1803 polygon = new OpenLayers.Geometry.Polygon([ring]); 1804 this.debug_trap = new OpenLayers.Feature.Vector(polygon); 1805 this.debug_trapezoid.addFeatures(this.debug_trap); 1806 } 1807 else { 1808 1809 if (this.debug_layer) this.map2.addLayer(this.debug_layer); 1810 if (this.debug_layer_dsm) this.map2.addLayer(this.debug_layer_dsm); 1811 1812 // extent schermo 1813 this.debug_box = new OpenLayers.Feature.Vector(viewBounds.toGeometry()); 1814 this.debug_boxes.addFeatures(this.debug_box); 1815 this.map2.addLayer(this.debug_boxes); 1816 1817 //rettangolo 1818 var pointList = []; 1819 var num_point = rectangle.length; 1820 var newPoint = null; 1821 for (var i = 0; i < num_point; i++) { 1822 newPoint = new OpenLayers.Geometry.Point(rectangle[i].x,rectangle[i].y); 1823 pointList.push(newPoint); 1824 } 1825 var ring = new OpenLayers.Geometry.LinearRing(pointList); 1826 var polygon = new OpenLayers.Geometry.Polygon([ring]); 1827 this.debug_rect = new OpenLayers.Feature.Vector(polygon); 1828 // var layer = new OpenLayers.Layer.Vector("Test"); 1829 this.debug_rectangle.addFeatures([this.debug_rect]); 1830 this.map2.addLayer(this.debug_rectangle); 1831 1832 // trapezio 1833 pointList = []; 1834 var num_point = trapezoid.length; 1835 var newPoint = null; 1836 for (var i = 0; i < num_point; i++) { 1837 newPoint = new OpenLayers.Geometry.Point(trapezoid[i].x,trapezoid[i].y); 1838 pointList.push(newPoint); 1839 } 1840 ring = new OpenLayers.Geometry.LinearRing(pointList); 1841 polygon = new OpenLayers.Geometry.Polygon([ring]); 1842 this.debug_trap = new OpenLayers.Feature.Vector(polygon); 1843 // var layer = new OpenLayers.Layer.Vector("Test"); 1844 this.debug_trapezoid.addFeatures([this.debug_trap]); 1845 this.map2.addLayer(this.debug_trapezoid); 1846 1847 // console.log(polygon); 1848 1849 1850 } 1851 1852 } 1853 1854 }); 1855 1856 Ext.preg(framework.plugins.ActiveObliquePhotos.prototype.ptype, framework.plugins.ActiveObliquePhotos); 1857