/**
* @fileOverview
* Copyright (c) 2013 Regione Autonoma della Sardegna
* Published under the GPL license.
* See https://sardegnageoportale.it/webgis/license.txt
* for the full text of the license.
* @version 0.1
*/
/**
* @require framework/widgets/control/Compass.js
* @require framework/widgets/control/ViewDirection.js
*/
/**
* @namespace framework.plugins
*/
Ext.namespace("framework.plugins");
/**
* Constant for nearest algorithm type
*/
var OBLIQUEPHOTOS_ALGORITHMTYPE = {CENTROID_BASED: {value: 0, name: 'Centroid'}, EXTENT_BASED: {value: 1, name: 'Extent'}};
/**
* Provides control for link to info application.
* @name_ ActiveObliquePhotos
* @class Provides control for link to info application.
* @constructor
* @extends gxp.plugins.Tool
*/
framework.plugins.ActiveObliquePhotos = Ext.extend(gxp.plugins.Tool,
/**
* @lends framework.plugins.ActiveObliquePhotos.prototype
*/
{
/**
* plugin type.
* @public
* @type String
*/
ptype: "framework_activeobliquephotos",
/**
* Menu text.
* @public
* @type String
*/
menuText: "Attiva modalità foto oblique",
/**
* Msg no photo.
* @public
* @type String
*/
noPhoto: "Foto oblique non presenti in questa zona",
/**
* Msg no CSV.
* @public
* @type String
*/
noCSV: "Foto oblique in fase di elaborazione",
/**
* Tooltip text.
* @public
* @type String
*/
tooltip: "Attiva la modalità foto oblique",
/**
* Msg tooltip deactivate.
* @public
* @type String
*/
tooltipDeactivate: "Disattiva la modalità foto oblique",
/**
* Class with button is pressed.
* @public
* @type String
*/
pressedCls: 'oblBtnPressed',
/**
* Class with button is unpressed.
* @public
* @type String
*/
unpressedCls: 'oblBtn',
/**
* Css class for icon.
* @public
* @type String
*/
iconCls: "gxp-icon-obliquephotos",
/**
* Compass used for changing direction and switching to orthophone mode
* @private
* @type framework.widgets.control.Compass
*/
compass: null,
/**
* Type of algorithm to use for nearest photogram search
* @public
* @type ALGORITHMTYPE
*/
algorithmType: null,
/**
* Configured map
*
* @public
* @type {Object} OpenLayers.Map
*/
map: null,
/**
* Baselayer map
*
* @public
* @type {Object} OpenLayers.Layer
*/
lastBaseLayer: null,
/**
* Type of Spatial Reference used for the computation. Per default: 'EPSG:4326'
*
* @public
* @type String
*/
srs: 'EPSG:3003',
/**
* Proxy to make the search request. default null.
*
* @public
* @type string
*/
proxy: null,
/**
* Store for toring the routing results
*
* @public
* @type {Object} Ext.data.Storw
*/
store: null,
/**
* Base URL service WMS used for the computation. Per default: ''
*
* @public
* @type string
*/
baseUrl: '',
/**
* Type of service WFS used for the computation. Per default: 'http://localhost:8080/geoserver/wfs?'
*
* @public
* @type string
*/
url: 'http://localhost:8080/geoserver/wfs?',
/**
* Type of service TMS used for the oblique Photos. Per default: 'http://webgis.regione.sardegna.it/tms/fotooblique/'
*
* @public
* @type string
*/
tmsUrl: 'http://webgis.regione.sardegna.it/tms/fotooblique/',
/**
* Type of service for calculate oblique Photos. If is null: dinamic url generated
*
* @public
* @type string
*/
urlServOPDedicated: false,
/**
* File name of tilemap source 'http://localhost:8080/geoserver/wfs?'
*
* @public
* @type string
*/
tilemapResource: 'tilemapresource.xml',
/**
* Nome del layer che contiene l'inviluppo delle foto oblique'
*
* @public
* @type string
*/
typename: 'inviluppo_orto_roma40_tot',
workspace: 'dbu:',
/**
* Parametro del servizio WFS. ID del layer che indica la zona delle foto oblique'
*
* @public
* @type string
*/
propertyName: 'id',
/**
* Parametro del servizio WFS. Campo per l'ordinamento dei risultati di ricerca'
*
* @public
* @type string
*/
sortby: 'id',
/**
* Parametro del servizio WFS. Bounding box della ricerca'
*
* @public
* @type string
*/
BBOX: null,
/**
* Tolleranza del boundingbox per la ricerca'
*
* @public
* @type Number
*/
tollerance: 0,
/**
* Scala di visualizzazione minima in cui viene attivato il pulsante di
* attivazione delle foto oblique'
*
* @public
* @type Number
*/
minScaleActivate: 100000,
/**
* Livello di zoom minimo della visualizzazione delle foto oblique'
*
* @public
* @type Number
*/
minZoomObliquePhoto: 4,
/**
* Layer dei TMS delle fotooblique visualizzato'
*
* @public
* @type {Object} OpenLayers.Layer.TMS
*/
tmsLayer: null,
/**
* Foto Oblique visualizzata in mappa'
*
* @public
* @type {Object} JSON
*/
obliquePhoto: {
/**
* Property: extent
* {OpenLayers.Bounds} extent of the tile map
*/
extent: null,
/**
* Property: extent
* {OpenLayers.Bounds} Maximum extent of the tile map
*/
maxExtent: null,
/**
* Property: tileOrigin
* {OpenLayers.LonLat} origin of the tile map
*/
tileOrigin: null,
/**
* Property: maxResolution
* {float} max resolution of the zero level
*/
maxResolution: null,
/**
* Property: zoom
* {int} zooom of the tilemap
*/
typeImg: null,
/**
* Property: numLevels
* {int} num levels of the tile map
*/
numLevels: 0,
/**
* Property: resolutions
* {int} resolution of the tile map
*/
resolutions: null,
/**
* Property: area
* {int} area of the tile map
*/
projection: 'EPSG:32632',
/**
* Property: area
* {int} area of the tile map
*/
area: null,
/**
* Property: initcoordRect
* {OpenLayers.LonLat} coordinata "fittizzia" del centro della mappa (rettangolo)
*/
initcoordRect: null,
/**
* Property: initcoordTrap
* {OpenLayers.LonLat} coordinata "reale" del centro della mappa (trapezio)
*/
initcoordTrap: null,
/**
* Property: scale
* {string} actual scale of the tile map
*/
scale: null,
/**
* Flag to remember if obliquephoto is opened or not
* {boolean} flag for opened status
*/
opened: false,
/**
* Start direction: fixed North (N)
*
* @public
* @type String
*/
initDirection: 'N'
},
/**
* Livello di zoom minimo della visualizzazione dell'ortofoto
*
* @public
* @type Number
*/
minZoomOrtoPhoto: 4,
/**
* Layer dei TMS del'ortofoto visualizzata
*
* @public
* @type {Object} OpenLayers.Layer.TMS
*/
tmsOrtoLayer: null,
/**
* Ortofoto visualizzata in mappa'
*
* @public
* @type {Object} JSON
*/
ortoPhoto: {
/**
* Property: extent
* {OpenLayers.Bounds} extent of the tile map
*/
extent: null,
/**
* Property: tileOrigin
* {OpenLayers.LonLat} origin of the tile map
*/
tileOrigin: null,
/**
* Property: maxResolution
* {float} max resolution of the zero level
*/
maxResolution: null,
/**
* Property: zoom
* {int} zooom of the tilemap
*/
typeImg: null,
/**
* Property: numLevels
* {int} num levels of the tile map
*/
numLevels: 0,
/**
* Property: resolutions
* {int} resolution of the tile map
*/
resolutions: null,
/**
* Property: projection
* {string} projection of the tile map
*/
projection: 'EPSG:32632',
/**
* Property: area
* {int} area of the tile map
*/
area: null,
/**
* Property: idmap
* {string} type map (map1 or map2)
*/
idmap: null,
/**
* Property: scale
* {string} actual scale of the tile map
*/
scale: null
},
/**
* Classe della mappa doppia'
*
* @public
* @type String
*/
idDoubleMapComp: null,
/**
* Configured doublemap
*
* @public
* @type {Object} OpenLayers.Map
*/
map2: null,
/**
* Layer dei TMS del'ortofoto visualizzata nella mappa singola
*
* @public
* @type {Object} OpenLayers.Layer.TMS
*/
tmsOrtoLayer2: null,
/**
* Indica la direzione della vista nella mappa doppia
*
* @public
* @type string
*/
viewdirection: null,
/** api: config[onlyShowOnFirstLoad]
* ``Boolean`` Set this to true to only show the loading indicator on the
* first load of the map. Default is false.
*
* @public
* @type boolean
*/
onlyShowOnFirstLoad: false,
/** api: config[loadingMapMessage]
* ``String`` Message to show when the map is loading (i18n)
*
* @public
* @type String
*/
loadingMapMessage: "Loading Map...",
/** private: property[layerCount]
* ``Integer`` The number of layers currently loading.
*
* @public
* @type integer
*/
layerCount: 0,
/**
* private: property[busyMask]
* ``Ext.LoadMask`` The Ext load mask to show when busy.
*
* @public
* @type {Object} Ext.LoadMask
*/
busyMask: null,
/**
* private: property[busyMask2]
* ``Ext.LoadMask`` The Ext load mask to show when busy.
*
* @public
* @type {Object} Ext.LoadMask
*/
busyMask2: null,
layer_envelope: null,
/**
* Modalità debug. Visualizzazione estensione e ingombri delle fotooblique
* nella mappa doppia.
*
* @public
* @type Boolean
*/
debug: false,
/**
* Modalità debug. Layer Vector for extent rectangle
*
* @public
* @type {Object} OpenLayers.Layer.Vector
*/
debug_rectangle: new OpenLayers.Layer.Vector( "Rectangle", { style: {stroke: true, strokeWidth: 2, strokeColor: '#FFFF00', strokeOpacity: 0.4, fillColor: '#000', fillOpacity: 0}} ),
/**
* Modalità debug. Feature Vectore for extent rectangle
*
* @public
* @type {Object} OpenLayers.Feature.Vector
*/
debug_rect: null,
/**
* Modalità debug. Layer Vector for trapezoid oblique photo
*
* @public
* @type {Object} OpenLayers.Layer.Vector
*/
debug_trapezoid: new OpenLayers.Layer.Vector( "Trapezoid", { style: {stroke: true, strokeWidth: 2, strokeColor: '#0000FF', fillColor: '#000', fillOpacity: 0}} ),
/**
* Modalità debug. Feature Vector for trapezoid oblique photo
*
* @public
* @type {Object} OpenLayers.Feature.Vector
*/
debug_trap: null,
/**
* Modalità debug. Layer Vector for extent view
*
* @public
* @type {Object} OpenLayers.Layer.Vector
*/
debug_boxes: new OpenLayers.Layer.Vector( "Boxes", { style: {stroke: true, strokeWidth: 2, strokeColor: '#FF0000', fillColor: '#000', fillOpacity: 0.1}} ),
/**
* Modalità debug. Feature Vector for extent view
*
* @public
* @type {Object} OpenLayers.Feature.Vector
*/
debug_box: null,
/**
* Modalità debug. Inviluppo foto oblique.
*
* @public
* @type {Object} OpenLayers.Layer.WMS
*/
debug_layer: null,
/**
* Modalità debug. DSM.
*
* @public
* @type {Object} OpenLayers.Layer.WMS
*/
debug_layer_dsm: null,
/**
* @private
* @param {Object} config configuration object
*/
constructor: function(config) {
if (Ext.isEmpty(config.algorithmType)) {
//default value
config.algorithmType = OBLIQUEPHOTOS_ALGORITHMTYPE.CENTROID_BASED;
}
framework.plugins.ActiveObliquePhotos.superclass.constructor.apply(this, arguments);
},
/**
* Create and append info action
* @public
* @returns {framework.plugins.ActiveObliquePhotos} Object with info control inside
*/
addActions: function() {
if (!this.map) {
this.map = this.target.mapPanel.map;
}
if (this.idDoubleMapComp && !this.map2) {
this.map2 = Ext.getCmp(this.idDoubleMapComp).app2.mapPanel.map;
}
if (!this.layer_envelope) {
this.layer_envelope = new OpenLayers.Layer.WMS(
this.typename, this.baseUrl+"/geoserver/wms",
{
LAYERS: this.workspace+this.typename,
STYLES: '',
format: "image/png",
transparent: true,
tiled: true
},
{
buffer: 0,
displayInLayerSwitcher: false,
singleTile: true,
ratio: 1,
visibility: true,
isBaseLayer: false,
yx : {'EPSG:3003' : false}
}
);
}
var self = this;
this.map.events.register('zoomend', this, this.enableButton);
this.map.events.register('zoom', this, this.verifyMinZoomObliquePhoto);
//registrazione evento spostamento mappa
this.dragcontrol = new OpenLayers.Control.DragPan({'map': this.map,
'panMapDone': function(xy) {
this.userdragged = true;
self.refreshPhotogram(false);
}});
this.dragcontrol.draw();
this.map.addControl(this.dragcontrol);
var sUrl = "";
if (this.proxy)
sUrl = this.proxy + escape(this.url);
else
sUrl = this.url;
if (!this.store) {
this.store = new Ext.data.Store({
proxy: new Ext.data.HttpProxy({
url: sUrl,
method: 'POST'
}),
fields: [this.propertyName],
reader: new framework.data.EnvelopesObliquePhotos_XLSReader({
propertyName: this.propertyName
}),
listeners: {
datachanged: function(store) {
var center = this.target.mapPanel.map.getCenter();
// trasformazione coordinate in UTM 32N
Proj4js.defs["EPSG:32632"] = "+title=UTM 32N +proj=utm +zone=32 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ";
new Proj4js.Proj('EPSG:32632');
var fromProjection = new OpenLayers.Projection(this.srs); // Transform from ROMA40
var toProjection = new OpenLayers.Projection("EPSG:32632"); // to Spherical Mercator Projection
var position = new OpenLayers.LonLat(center.lon, center.lat).transform(fromProjection, toProjection);
if (store.data.items[0].data.msg_error === 1) {
this.msgAlert(this.mapInfoText, this.noPhoto, false);
} else {
var areaId = store.data.items[0].data.id;
//verificare la foto obliqua più vicina alla coordinata
this.loadPhotogram(areaId, position, true);
}
},
beforeload: function(store, operation) {
var center = this.target.mapPanel.map.getCenter();
store.baseParams['BBOX'] = (center.lon - this.tollerance) + "," + (center.lat - this.tollerance) + "," + (center.lon + this.tollerance) + "," + (center.lat + this.tollerance);
},
scope: this
},
baseParams: {
'typename': this.typename,
'SERVICE': 'WFS',
'VERSION': '1.0.0',
'REQUEST': 'GetFeature',
'propertyName': this.propertyName,
'SRS': this.srs,
'sortby': this.sortby,
'BBOX': this.BBOX
},
scope: this
});
}
this.button = new Ext.Button({
iconCls: this.iconCls,
tooltip: this.tooltip,
pressedCls: this.pressedCls,
enableToggle: true,
handler: function() {
if (this.button.pressed) {
this.store.load();
}
else {
this.button.addClass(this.unpressedCls);
this.button.removeClass(this.pressedCls);
this.button.setTooltip(this.tooltip);
this.closePhotogram();
}
},
listeners: {
mouseover: function () {
this.scope.map.addLayer(this.scope.layer_envelope);
self.centroidActiveObliquePhoto(this.scope.map,true);
},
mouseout: function () {
this.scope.map.removeLayer(this.scope.layer_envelope);
self.centroidActiveObliquePhoto(this.scope.map,false);
},
beforeshow: function() {
this.enableButton();
if (this.button.pressed) {
this.button.removeClass('x-btn-pressed');
this.button.removeClass(this.unpressedCls);
this.button.addClass(this.pressedCls);
this.button.setTooltip(this.button.tooltipDeactivate);
}
else {
this.button.addClass(this.unpressedCls);
this.button.setTooltip(this.button.tooltip);
}
}
},
scope: this
});
this.button.addClass(this.unpressedCls);
return framework.plugins.ActiveObliquePhotos.superclass.addActions.apply(this, [this.button]);
},
centroidActiveObliquePhoto: function(map,over) {
console.log("mouseover");
console.log(over);
if(!this.layer){
this.layer = new OpenLayers.Layer.Vector('centroidActiveObliquePhoto', {
displayInLayerSwitcher: false,
visibility: true,
styleMap: new OpenLayers.StyleMap({
'default': new OpenLayers.Style({
graphicZIndex: 100,
pointRadius: 5,
fillColor: "#f29f1e",
fillOpacity: 0.5,
strokeWidth: 2,
strokeColor: "white",
graphicName: "circle"
})})
});
}
var center = map.getCenter();
var point = new OpenLayers.Geometry.Point(center.lon, center.lat);
this.layer.removeAllFeatures();
this.layer.addFeatures([new OpenLayers.Feature.Vector(point)]);
if (map.getLayersByName("centroidActiveObliquePhoto").length !== 0) {
map.removeLayer(this.layer);
};
if (over)
map.addLayer(this.layer);
},
/**
* Enable button for activate oblique photos.
* @public
*/
enableButton: function() {
if (this.map.getScale() <= this.minScaleActivate) {
this.actions[0].enable();
}
else {
this.actions[0].disable();
}
},
/**
* Verifica il livello di zoom durante la navigazione.
* @private
*/
verifyMinZoomObliquePhoto: function() {
if (this.button) {
if (this.button.pressed) {
var x = this.map.getZoom();
if (x < this.minZoomObliquePhoto)
{
//this.closePhotogram();
//this.button.toggle(false);
// this.map.zoomTo(this.minZoomObliquePhoto);
this.map.setCenter(null,this.minZoomObliquePhoto);
}
if (this.idDoubleMapComp) {
if (!this.debug) this.map2.zoomToScale(this.map.getScale());
this.map2.setCenter(this.obliquePhoto.initcoordTrap);
}
//this.obliquePhoto.scale = this.map.getScale();
}
}
},
/**
* Chiude il fotogramma della fotoobliqua visualizzata.
* @private
*/
closePhotogram: function() {
var center = this.target.mapPanel.map.getCenter();
// trasformazione coordinate in UTM 32N
Proj4js.defs["EPSG:32632"] = "+title=UTM 32N +proj=utm +zone=32 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ";
new Proj4js.Proj('EPSG:32632');
var fromProjection = new OpenLayers.Projection("EPSG:32632"); // to Spherical Mercator Projection
var toProjection = new OpenLayers.Projection(this.srs); // Transform from ROMA40
var position = new OpenLayers.LonLat(center.lon, center.lat).transform(fromProjection, toProjection);
if (this.tmsLayer !== null)
{
this.tmsLayer.destroy();
}
this.fireEvent('obliquePhotoClosed');
this.map.setCenter(position);
if (this.idDoubleMapComp)
this.map2.setCenter(position);
this.lastBaseLayer = null;
this.dragcontrol.deactivate();
this.hideCompass();
this.obliquePhoto.initcoordRect = undefined;
this.obliquePhoto.initcoordTrap = undefined;
},
/**
* Finds a photogram using area id and current coordinate and loads it
* @param {String} area id of the area of the photogram to find
* @param {OpenLayers.LonLat} coord current coordinate (used to find nearest photogram)
* @private
*/
loadPhotogram: function(area, coord, transform) {
this.obliquePhoto.initDirection = "N"
this.obliquePhoto.area = area;
this.obliquePhoto.initcoordTrap = coord;
this.obliquePhoto.initcoordRect = coord;
Ext.Ajax.request({
url: this.getObliqueServletUrl(),
method: 'POST',
params: {
method: 'nearest',
area: area,
algorithmType: this.algorithmType.value,
photoId: Ext.isEmpty(this.obliquePhoto) ? null : this.obliquePhoto.id,
coordinate: Ext.util.JSON.encode(coord),
extent: Ext.util.JSON.encode(this.getCurrentExtent(transform)),
direction: Ext.isEmpty(this.compass) ? this.obliquePhoto.initDirection : this.compass.getDirection()
},
success: function(data) {
if (data.responseText) {
var record = Ext.util.JSON.decode(data.responseText);
if (!Ext.isEmpty(record.error)) {
if (record.error.indexOf("java.io.FileNotFoundException") != -1) {
this.msgAlert(this.mapInfoText, this.noCSV, false);
}
else
Ext.MessageBox.alert('Errore caricamento foto obliqua', record.error);
} else {
// GB: HACK CASO INIZIALE CON NE, SE, NW, SW
if (record.direction != this.obliquePhoto.initDirection)
this.obliquePhoto.initDirection = record.direction;
if (this.idDoubleMapComp) {
this.openOrtoPhoto(this.obliquePhoto.area, "map2");
}
this.openObliquePhoto(record);
this.dragcontrol.activate();
if (!this.compass) {
this.showCompass();
this.compass.refreshCssClass();
}
}
} else {
Ext.MessageBox.alert('Errore caricamento fotogramma', 'Risposta da servlet errata');
}
}, scope: this
});
},
/**
* Shows Compass control
* @public
*/
showCompass: function() {
this.compass = new framework.widgets.control.Compass({
id: this.id + '_pcompass',
displayClass: 'panelCompass',
initDirection: this.obliquePhoto.initDirection
});
this.map.addControl(this.compass);
this.compass.activate();
this.compass.events.register('rotateLeft', this, function(evt) {
this.refreshPhotogram(true);
if (this.viewdirection)
this.viewdirection.rotateLeft();
});
this.compass.events.register('rotateRight', this, function(evt) {
this.refreshPhotogram(true);
if (this.viewdirection)
this.viewdirection.rotateRight();
});
this.compass.events.register('modeSwitched', this, function(evt) {
if (this.compass.mode === this.compass.MODES.ORTHO) {
this.openOrtoPhoto(this.obliquePhoto.area, "map1");
if (this.tmsLayer) this.tmsLayer.destroy();
this.dragcontrol.deactivate();
if (this.viewdirection)
this.viewdirection.hide();
} else {
var position = this.target.mapPanel.map.getCenter();
if (this.tmsOrtoLayer) this.tmsOrtoLayer.destroy();
this.loadPhotogram(this.obliquePhoto.area,position,false);
if (this.viewdirection)
this.viewdirection.show();
}
});
if (this.idDoubleMapComp) {
this.createViewDirection(0);
this.viewdirection.refreshCssClass();
}
},
/**
* Crea il controllo sulla mappa doppia che indica la vista rispetto alla direzione della foto obliqua
* visualizzata in mappa singola
* @private
*/
createViewDirection: function() {
this.viewdirection = new framework.widgets.control.ViewDirection({
id: this.id + '_pviewdirection',
displayClass: 'panelViewDirection',
initDirection: this.obliquePhoto.initDirection
});
this.map2.addControl(this.viewdirection);
},
/**
* Hides Compass control
* @public
*/
hideCompass: function() {
this.compass.deactivate();
this.map.removeControl(this.compass);
this.compass.destroy();
this.compass = null;
if (this.viewdirection) {
this.viewdirection.destroy();
}
},
/**
* Method: fillTileMapFailure
* on failure load url
*
* @private
* @param data string of the file xml
*
*/
fillCSVFailure: function(data) {
Ext.MessageBox.alert('Errore', 'Foto oblique non ancora disponibili. La zona è in fase di elaborazione.');
this.button.toggle(false);
},
/**
* Method: openObliquePhoto
* Apre la foto obliqua
*
* @private
* @param {String } json representation of the file xml
*
*/
openObliquePhoto: function(data) {
this.obliquePhoto.id = data.photogramId;
this.obliquePhoto.tmsUrl = data.tmsUrl;
this.obliquePhoto.direction = data.direction;
this.obliquePhoto.maxExtent = new OpenLayers.Bounds(
data.areaExtent.minx,
data.areaExtent.miny,
data.areaExtent.maxx,
data.areaExtent.maxy);
var deltaX = this.obliquePhoto.maxExtent.getWidth()/14;
var deltaY = this.obliquePhoto.maxExtent.getHeight()/14;
//computes an extent incremented by deltaX and deltaY (and the same center)
this.obliquePhoto.restrictedExtent = new OpenLayers.Bounds(
data.viewPort.minx - deltaX,
data.viewPort.miny - deltaY,
data.viewPort.maxx + deltaX,
data.viewPort.maxy + deltaY);
this.obliquePhoto.viewPort = new OpenLayers.Bounds(
data.viewPort.minx,
data.viewPort.miny,
data.viewPort.maxx,
data.viewPort.maxy);
Ext.Ajax.request({
url: data.tmsUrl + '/' + this.tilemapResource,
success: function(obj) {
if (!Ext.isEmpty(data.coordinate)) {
obj.coordinate = data.coordinate;
}
if (!Ext.isEmpty(data.zoom)) {
obj.zoom = data.zoom;
}
if (!Ext.isEmpty(data.viewPort)) {
obj.viewPort = data.viewPort;
}
this.fillTileMap(obj);
},
failure: this.fillTileMapFailure,
scope: this
});
},
/**
* Method: fillTileMap
*
* fill this object tile map with the information of the tile map
*
* @private
* @param data string of the file xml
*
*/
fillTileMap: function(data) {
var doc = data.responseXML;
if (!doc || !doc.documentElement) {
doc = data.responseText;
}
var xml = new OpenLayers.Format.XML();
if (typeof doc == "string") {
doc = xml.read(doc);
}
var boundingBoxNode = doc.getElementsByTagName('BoundingBox');
if (boundingBoxNode !== null && boundingBoxNode[0] != null) {
var boundingBox = boundingBoxNode[0];
var minx = boundingBox.getAttribute('miny');
var miny = boundingBox.getAttribute('minx');
var maxx = boundingBox.getAttribute('maxy');
var maxy = boundingBox.getAttribute('maxx');
if (minx != null && minx != '' && miny != null && miny != '' && maxx != null && maxx != '' && maxy != null && maxy != '') {
this.obliquePhoto.extent = new OpenLayers.Bounds(minx, miny, maxx, maxy);
}
}
var tileOriginNode = doc.getElementsByTagName('Origin');
if (tileOriginNode != null && tileOriginNode[0] != null) {
var origin = tileOriginNode[0];
var x = origin.getAttribute('y');
var y = origin.getAttribute('x');
if (x != null && x != '' && y != null && y != '') {
this.obliquePhoto.tileOrigin = new OpenLayers.LonLat(x, y);
}
}
var tileFormat = doc.getElementsByTagName('TileFormat');
if (tileFormat != null && tileFormat[0] != null) {
var tileType = tileFormat[0];
this.obliquePhoto.typeImg = tileType.getAttribute('extension');
}
var tileSet = doc.getElementsByTagName('TileSet');
if (tileSet != null && tileSet.length > 0) {
this.obliquePhoto.numLevels = tileSet.length;
this.obliquePhoto.resolutions = [];
for (var i = 0; i < tileSet.length; i++) {
var firstTileSet = tileSet[i];
var order = firstTileSet.getAttribute('order');
if (order != null && order == '0') {
var unitsperpixel = firstTileSet.getAttribute('units-per-pixel');
if (unitsperpixel != null) {
this.obliquePhoto.maxResolution = unitsperpixel;
}
//break;
}
this.obliquePhoto.resolutions.push(parseFloat(firstTileSet.getAttribute('units-per-pixel')));
}
this.obliquePhoto.resolutions = this.obliquePhoto.resolutions.reverse();
}
this.obliquePhoto.opened = true;
this.updateObliquePhotoLayer(data);
},
/**
* Method: fillTileMapFailure
* on failure load url
*
* @private
* @param data string of the file xml
*
*/
fillTileMapFailure: function(data) {
Ext.MessageBox.alert('Errore', 'Foto obliqua non esistente.');
this.button.toggle(false);
},
/**
* Method: updateFotogrammiLayer
* Update Fotogrammi Layer to show selected fotogramma
*
* @private
* @param data string of the file xml
*
*/
updateObliquePhotoLayer: function(data) {
this.map.events.unregister('zoomend', this, this.verifyMinZoomObliquePhoto);
if (!this.lastBaseLayer) {
this.lastBaseLayer = this.map.baseLayer;
}
var options = {
projection: this.obliquePhoto.projection,
id: "mymap",
units: 'm',
resolutions: this.obliquePhoto.resolutions,
maxResolution: this.obliquePhoto.maxResolution,
maxExtent: this.obliquePhoto.maxExtent,
restrictedExtent: this.obliquePhoto.restrictedExtent,
numZoomLevels: this.obliquePhoto.numLevels,
panMethod: "null",
zoom: this.minZoomObliquePhoto
};
this.map.setOptions(options);
this.changePhotogram();
this.map.setBaseLayer(this.tmsLayer);
var zoom = (Ext.isEmpty(data.zoom)) ? 4 : data.zoom;
var center;
if (Ext.isEmpty(data.viewPort)) {
center = data.coordinate;
this.map.setCenter(center, zoom);
} else {
var x = data.viewPort.minx + (data.viewPort.maxx - data.viewPort.minx) / 2;
var y = data.viewPort.miny + (data.viewPort.maxy - data.viewPort.miny) / 2;
center = new OpenLayers.LonLat(x, y);
this.map.setCenter(center, zoom);
}
//per zoomare sul punt corretto della mappa all'apertura delle fotooblique
if (this.obliquePhoto.initcoordRect) {
this.map.setCenter(this.obliquePhoto.initcoordRect, zoom);
}
this.obliquePhoto.scale = this.map.getScale();
this.fireEvent('obliquePhotoOpened', this.tmsLayer, this.obliquePhoto);
this.map.events.register('zoomend', this, this.verifyMinZoomObliquePhoto);
if (this.button) {
this.button.removeClass('x-btn-pressed');
this.button.removeClass(this.unpressedCls);
this.button.addClass(this.pressedCls);
this.button.setTooltip(this.tooltipDeactivate);
}
},
/**
* Method: changePhotogram
* Cambio fotogramma
*
* @private
*
*/
changePhotogram: function() {
this.oldTmsLayer = this.tmsLayer;
var layerName = this.obliquePhoto.id;
if (Ext.isEmpty(this.obliquePhoto.id) || Ext.isEmpty(this.obliquePhoto.area)) {
return;
}
this.tmsLayer = new OpenLayers.Layer.TMS(
this.obliquePhoto.id,
this.tmsUrl + this.obliquePhoto.area,
{
layername: layerName,
type: this.obliquePhoto.typeImg,
format: 'image/png',
maxExtent: this.obliquePhoto.extent,
tileOrigin: this.obliquePhoto.tileOrigin,
candidateBaseLayer: true,
displayInLayerSwitcher: false,
serviceVersion: ''
});
this.tmsLayer.setIsBaseLayer(true);
this.map.addLayer(this.tmsLayer);
this.tmsLayer.events.register('loadstart', this, this.onloadstart);
this.tmsLayer.events.register('loadend', this, this.onloadend);
var oldLayer = this.oldTmsLayer;
// var destroyTask = new Ext.util.DelayedTask(function() {
if (!Ext.isEmpty(oldLayer)) {
//console.log('Trying to destroy old layer');
try {
oldLayer.destroy();
//console.log('Old layer destroyed');
} catch (err) {
//l'errore può essere solo x oggetto non inizializzato => lo ignoro
console.log('error destroying old layer ' + err);
}
}
// });
// destroyTask.delay(1000);
},
/**
* Event handling on map move.
* Here the program will change photogram, if necessary.
* @private
*/
refreshPhotogram: function(compass) {
if (this.obliquePhoto.opened) {
var currentExtent = this.getCurrentExtent(false);
//if (this.obliquePhoto.viewPort.containsBounds(currentExtent) && !compass) {
// continuare perché non la prende!
//return; //skip elaboration 'cause we don't need to change photogram
//}
//console.log(Ext.util.JSON.encode(this.obliquePhoto.viewPort));
var center = this.target.mapPanel.map.getCenter(); //fittizia
// console.log("center da rettangolo (fittizio)");
// console.log(center);
this.obliquePhoto.initcoordRect = center;
var zoom = this.target.mapPanel.map.getZoom();
Ext.Ajax.request({
url: this.getObliqueServletUrl(),
method: 'POST',
params: {
method: 'convert',
area: this.obliquePhoto.area,
coordinate: Ext.util.JSON.encode(center),
extent: Ext.util.JSON.encode(currentExtent),
photoId: this.obliquePhoto.id
},
success: function(data) {
if (data.responseText) {
var record = Ext.util.JSON.decode(data.responseText);
if (!Ext.isEmpty(record.coordinate)) {
center = this.toLonLat(record.coordinate);
//console.log("center convertito sul trapezio (reale)");
//console.log(center);
this.obliquePhoto.initcoordTrap = center;
var viewPort = this.toBounds(record.viewPort);
if (this.idDoubleMapComp && this.debug) this.debugPolygon(viewPort,record.rectangle._coords,record.trapezoid._coords);
this.coordinateConverted(center, viewPort, zoom);
} else {
Ext.MessageBox.alert('Errore conversione', record.error);
}
} else {
Ext.MessageBox.alert('Errore conversione', 'Risposta da servlet errata');
}
},
failure: function() {
Ext.MessageBox.alert('Errore conversione', 'Errore in chiamata servizio conversione coordinata.');
},
scope: this
});
}
},
/**
* Converts a JTS coordinate in a OpenLayers Coordinate
* @param {Object} coordinate JTS coordinate
* @return {OpenLayers.LonLat} LonLat corresponding coordinate
* @private
*/
toLonLat: function(coordinate) {
return new OpenLayers.LonLat(coordinate.x, coordinate.y);
},
/**
* Converts a JTS envelope to a OpenLayers Bounds
* @param {Object} env JTS envelope
* @return {OpenLayers.Bounds} Bounds corresponding to input envelope
* @private
*/
toBounds: function(env) {
return new OpenLayers.Bounds(env.minx, env.miny, env.maxx, env.maxy);
},
/**
* Search nearest oblique photos before converting coordinate with extent view
*
* @private
* @param {OpenLayers.LatLon} center
* @param {OpenLayers.Bounds} viewPort
* @param {Integer} zoom
*/
coordinateConverted: function(center, viewPort, zoom) {
var self = this;
Ext.Ajax.request({
url: self.getObliqueServletUrl(),
method: 'POST',
params: {
method: 'nearest',
area: self.obliquePhoto.area,
extent: Ext.util.JSON.encode(viewPort),
algorithmType: self.algorithmType.value,
photoId: Ext.isEmpty(this.obliquePhoto) ? null : this.obliquePhoto.id,
coordinate: Ext.util.JSON.encode(center),
direction: self.getDirection()
},
success: function(data) {
if (data.responseText) {
var record = Ext.util.JSON.decode(data.responseText);
if (!Ext.isEmpty(record.error)) {
Ext.MessageBox.alert('Errore cambio mappa', record.error);
//chiusura foto oblique
self.closePhotogram();
self.button.toggle(false);
} else {
if (self.idDoubleMapComp)
self.onMapObliqueMove(record);
if (Ext.isDefined(record.photogramId) && record.photogramId !== self.obliquePhoto.id) { //otherwise we will use the same photogram
self.obliquePhoto.id = data.photogramId;
self.obliquePhoto.tmsUrl = data.tmsUrl;
self.obliquePhoto.initcoordRect = self.toLonLat(record.coordinate);
//calcolare nuovo extent fotogramma
self.changePhotogram();
record.zoom = zoom;
self.openObliquePhoto(record);
}
}
} else {
Ext.MessageBox.alert('Errore cambio mappa', 'Risposta da servlet errata');
}
}
});
},
/**
* Returns oblique servlet url
* @private
* @return url servelt obliquephotos
*/
getObliqueServletUrl: function() {
if (this.urlServOPDedicated) {
return this.urlServOPDedicated
}
else {
var current = String(window.location);
current = current.replace("print.jsp", ""); //removes print modality
current = current.replace(/\?.*/g, ""); //removes possible querystring
if (!current.match(/.*\/$/)) {
current += '/';
}
return current + 'ObliquePhotos';
}
},
/**
* Returns current direction
*
* @public
* @return {String} direction
*/
getDirection: function() {
return (Ext.isEmpty(this.compass)) ? this.obliquePhoto.initDirection : this.compass.getDirection();
},
/**
* Returns current extent as a coordinate array (of four coordinates)
*
* @private
* @param {Boolean} if trasform coordinate
* @return {OpenLayers.Bounds} extent view optimized
*/
getCurrentExtent: function(trasform) {
var fromProjection = new OpenLayers.Projection(this.srs); // Transform from ROMA40
var toProjection = new OpenLayers.Projection("EPSG:32632"); // to Spherical Mercator Projection
var e = (trasform) ? this.target.mapPanel.map.getExtent().transform(fromProjection, toProjection) :
this.target.mapPanel.map.getExtent();
var deltaX = e.getWidth()/12;
var deltaY = e.getHeight()/12;
//computes an extent incremented by deltaX and deltaY (and the same center)
var ext_small = new OpenLayers.Bounds(
e.left + deltaX,
e.bottom + deltaY,
e.right - deltaX,
e.top - deltaY);
return ext_small;
},
/**
* Event handling on map move.
*
* @private
* @param {String} json representation of record coordinate
*
*/
onMapObliqueMove: function(record) {
var map1 = this.map;
var map2 = this.map2;
if (this.idDoubleMapComp) {
map2.setCenter(this.obliquePhoto.initcoordTrap);
}
else {
// per trasformazione coordinate in UTM 32N
Proj4js.defs["EPSG:32632"] = "+title=UTM 32N +proj=utm +zone=32 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ";
new Proj4js.Proj('EPSG:32632');
var fromProjection = map1.getProjectionObject();
var toProjection = map2.getProjectionObject();
map2.setCenter(new OpenLayers.LonLat(record.coordinate.x, record.coordinate.y).transform(fromProjection, toProjection))
}
if (!this.debug) map2.zoomToScale(map1.getScale());
},
openOrtoPhoto: function(area,map) {
this.ortoPhoto.area = area;
this.ortoPhoto.idmap = map;
this.ortoPhoto.scale = this.map.getScale();
//this.ortoPhoto.position = this.map.getCenter();
var urlOrto = this.tmsUrl + '/'+ area + '/ORTO/' + this.tilemapResource;
Ext.Ajax.request({
url: urlOrto,
success: this.fillTileMapOrto,
failure: this.fillTileMapOrtoFailure,
scope: this
});
},
/**
* Method: fillTileMap
*
* fill this object tile map with the information of the tile map
*
* @private
* @param data string of the file xml
*
*/
fillTileMapOrto: function(data) {
if (this.ortoPhoto.idmap == "map1") {
var map = this.map;
}
else {
var map = this.map2;
}
this.ortoPhoto = this.configureMap(data,this.ortoPhoto.projection,this.ortoPhoto.area);
if (this.ortoPhoto) {
this.updateOrtoPhotoLayer(map,this.ortoPhoto,'ORTO',"Ortofoto HD");
}
},
/**
* Method: fillTileMapFailure
* on failure load url
*
* @private
* @param data string of the file xml
*
*/
fillTileMapOrtoFailure: function(data) {
alert('Ortofoto associata alla foto obliqua non esistente.');
},
/**
* Method: fillTileMap
*
* fill this object tile map with the information of the tile map
*
* @private
* @param data string of the file xml
*
*/
configureMap: function(data,projection,area) {
var tilemap = {
extent: null,
tileOrigin:null,
maxResolution:null,
typeImg: null,
numLevels:0,
resolutions: null,
projection: projection,
area: area,
idmap: this.ortoPhoto.idmap
};
var doc = data.responseXML;
if (!doc || !doc.documentElement) {
doc = data.responseText;
}
var xml = new OpenLayers.Format.XML();
if (typeof doc == "string") {
doc = xml.read(doc);
}
var boundingBoxNode = doc.getElementsByTagName('BoundingBox');
if (boundingBoxNode != null && boundingBoxNode[0] != null) {
var boundingBox = boundingBoxNode[0];
var minx = boundingBox.getAttribute('miny');
var miny = boundingBox.getAttribute('minx');
var maxx = boundingBox.getAttribute('maxy');
var maxy = boundingBox.getAttribute('maxx');
if (minx != null && minx != '' && miny != null && miny != '' && maxx != null && maxx != '' && maxy != null && maxy != '') {
tilemap.extent = new OpenLayers.Bounds(minx, miny, maxx, maxy);
}
}
var tileOriginNode = doc.getElementsByTagName('Origin');
if (tileOriginNode != null && tileOriginNode[0] != null) {
var origin = tileOriginNode[0];
var x = origin.getAttribute('y');
var y = origin.getAttribute('x');
if (x != null && x != '' && y != null && y != '') {
tilemap.tileOrigin = new OpenLayers.LonLat(x, y);
}
}
var tileFormat = doc.getElementsByTagName('TileFormat');
if (tileFormat != null && tileFormat[0] != null) {
var tileType = tileFormat[0];
tilemap.typeImg = tileType.getAttribute('extension');
}
var tileSet = doc.getElementsByTagName('TileSet');
if (tileSet != null && tileSet.length > 0) {
tilemap.numLevels = tileSet.length;
tilemap.resolutions = [];
for (var i = 0; i < tileSet.length; i++) {
var firstTileSet = tileSet[i];
var order = firstTileSet.getAttribute('order');
if (order != null && order == '0') {
var unitsperpixel = firstTileSet.getAttribute('units-per-pixel');
if (unitsperpixel != null) {
tilemap.maxResolution = unitsperpixel;
}
//break;
}
tilemap.resolutions.push(parseFloat(firstTileSet.getAttribute('units-per-pixel')));
}
tilemap.resolutions = tilemap.resolutions.reverse();
}
return tilemap;
},
/**
* Method: updateFotogrammiLayer
*
* Update Fotogrammi Layer to show selected fotogramma
* @private
* @param {OpenLayers.Map} map
* @param {Object} tilemap Ortofoto corrente
* @param {String} layername
* @param {String} namePhoto
*
*/
updateOrtoPhotoLayer: function(map,tilemap,layername,namePhoto) {
var options = {
projection: tilemap.projection,
id:"mymap",
units: 'm',
resolutions: tilemap.resolutions,
maxResolution: tilemap.maxResolution,
maxExtent: tilemap.extent,
restrictedExtent: tilemap.extent,
numZoomLevels: tilemap.numLevels,
panMethod:"null",
zoom: 1
};
map.setOptions(options);
var layerTemp = new OpenLayers.Layer.TMS(
namePhoto,
this.tmsUrl + '/' + tilemap.area,
{
layername: layername,
type: tilemap.typeImg,
background: "#000000",
maxExtent: tilemap.extent,
tileOrigin: tilemap.tileOrigin,
candidateBaseLayer: true,
displayInLayerSwitcher: false,
serviceVersion: ''
});
layerTemp.setIsBaseLayer(true);
map.addLayer(layerTemp);
if (this.idDoubleMapComp) {
layerTemp.events.register('loadstart', this, this.onloadstart2);
layerTemp.events.register('loadend', this, this.onloadend2);
}
map.setBaseLayer(layerTemp);
if (!this.debug) map.zoomToScale(this.obliquePhoto.scale);
map.setCenter(this.obliquePhoto.initcoordTrap);
if (tilemap.idmap == "map1")
this.tmsOrtoLayer = layerTemp;
else
this.tmsOrtoLayer2 = layerTemp;
},
/**
* Method: onloadstart
*
* Avvio esecuzione chiamate layer TMS,
* @private
* @param {Event} evt
*
*/
onloadstart: function(evt) {
this.layerCount++;
if (!this.busyMask) {
this.busyMask = new Ext.LoadMask(
this.map.div, {
msg: this.loadingMapMessage
}
);
}
this.busyMask.show();
if (this.onlyShowOnFirstLoad === true) {
this.tmsLayer.events.unregister("loadstart", this, arguments.callee);
}
},
/**
* Method: onloadend
*
* Fine esecuzione chiamate layer TMS,
* @private
* @param {Event} evt
*
*/
onloadend: function(evt) {
this.layerCount--;
if(this.layerCount === 0) {
this.busyMask.hide();
}
if (this.onlyShowOnFirstLoad === true) {
this.tmsLayer.events.unregister("loadend", this, arguments.callee);
}
},
/**
* Method: onloadstart2
*
* Avvio esecuzione chiamate Ajax per i servizi
* @private
* @param {Event} evt
*
*/
onloadstart2: function(evt) {
if (!this.busyMask2) {
this.busyMask2 = new Ext.LoadMask(
this.map2.div, {
msg: this.loadingMapMessage
}
);
}
this.busyMask2.show();
evt.object.events.unregister("loadstart", this, arguments.callee);
},
/**
* Method: onloadend2
*
* Fine esecuzione chiamate Ajax per i servizi
* @private
* @param {Event} evt
*
*/
onloadend2: function(evt) {
this.busyMask2.hide();
evt.object.events.unregister("loadend", this, arguments.callee);
},
/**
* Opens an oblique photo but using its json representation
* @param {String} json representation of the photogram
* @param {OpenLayers.LatLon} center position
* @public
*/
openFromJSON: function(json,center) {
if (json) {
if (!this.map) {
this.map = this.target.mapPanel.map;
}
if (this.idDoubleMapComp && !this.map2) {
this.map2 = Ext.getCmp(this.idDoubleMapComp).app2.mapPanel.map;
}
var record = json;
this.obliquePhoto.area = record.area;
var position = new OpenLayers.LonLat(record.initcoordRect.lon, record.initcoordRect.lat);
this.obliquePhoto.initcoordRect = position;
var position = new OpenLayers.LonLat(record.initcoordTrap.lon, record.initcoordTrap.lat);
this.obliquePhoto.initcoordTrap = position;
this.obliquePhoto.scale = record.scale;
this.obliquePhoto.id = record.id;
this.obliquePhoto.tmsUrl = record.tmsUrl;
this.obliquePhoto.direction = record.direction;
this.obliquePhoto.initDirection = record.initDirection;
this.obliquePhoto.maxExtent = new OpenLayers.Bounds(
record.maxExtent.left,
record.maxExtent.bottom,
record.maxExtent.right,
record.maxExtent.top);
this.obliquePhoto.restrictedExtent = new OpenLayers.Bounds(
record.restrictedExtent.left,
record.restrictedExtent.bottom,
record.restrictedExtent.right,
record.restrictedExtent.top);
this.obliquePhoto.viewPort = new OpenLayers.Bounds(
record.viewPort.left,
record.viewPort.bottom,
record.viewPort.right,
record.viewPort.top);
Ext.Ajax.request({
url: record.tmsUrl + '/' + this.tilemapResource,
success: function(obj) {
if (!Ext.isEmpty(record.coordinate)) {
obj.coordinate = record.coordinate;
}
if (!Ext.isEmpty(record.zoom)) {
obj.zoom = record.zoom;
}
if (!Ext.isEmpty(record.viewPort)) {
obj.viewPort = record.viewPort;
}
this.fillTileMap(obj);
},
failure: this.fillTileMapFailure,
scope: this
});
if (this.dragcontrol)
this.dragcontrol.activate();
if (!this.compass) {
this.showCompass();
this.compass.setDirection(record.direction);
this.compass.refreshCssClass();
if (this.viewdirection) {
this.viewdirection.setDirection(record.direction);
this.viewdirection.refreshCssClass();
}
}
if (this.idDoubleMapComp) {
this.openOrtoPhoto(this.obliquePhoto.area, "map2");
}
if (this.button) {
this.enableButton();
this.button.toggle(true);
}
}
},
/**
* Method: msgAlert
*
* Messaggio di avviso
*
* @private
* @param {String} title
* @param {String} text
* @param {Boolean} toggle
*
*/
msgAlert: function (title, text, toggle) {
var mapInfo = new Ext.Panel({
title: title,
html: '
'+text+'' + '