Source: temp/jsdocinputdirs/cercalia.control.streetview.js

/**
 * @classdesc
 * Google StreetView control.<br/>
 * <br/>
 * Add a button at the upper right map corner. When clicked adds
 * a marker on the map that can be dragged in order to show StreetView 
 * on the map.<br/>
 * <br/>
 * The StreetView is shown in a dialog, with navigation functionallity.
 * @constructor  
 * @extends {ol.control.Control}
 * @param {cercaliax.Control.StreetViewOptions} opt_options
 */
cercalia.Control.StreetView =  function(opt_options) {
 	
	var options = opt_options || {};
	
	/**
	 * @private
	 * @type {string}
	 */
	this.name_ = cercalia.MapControls.StreetView;
	
	/**
	 * Class name
	 * @private
	 * @type {string}
	 */
	this.CLASS_NAME_ = "cercalia.Control.StreetView";
	
	/**
	 * @private
	 * @type {number}
	 */
	this.width_ = options.width ? options.width : 600;

	/**
	 * @private
	 * @type {number}
	 */
	this.height_ = options.height ? options.height : 480;
	
	/**
	 * Image StreetView On
	 * @private
	 * @type {String} 
	 */
	this.imgStreetViewOn_ = cercaliaGlobals.img + '/cercalia-marker-streetview-enabled.png';
	
	/**
	 * Image StreetView Off
	 * @private
	 * @type {String} 
	 */
	this.imgStreetViewOff_ = cercaliaGlobals.img + '/cercalia-marker-streetview-disabled.png';
	
	/**
	 * @private
	 * @type {ol.Feature}
	 */
	this.streetViewFeature_ = null;
	
	/**
	 * @private
	 * @type {boolean}
	 */
	this.enabled_ = false;
	
	/**
	 * @private
	 */
	this.collection_ = new ol.Collection();
	
	/**
	 * @private
	 * @type {ol.interaction.Modify}
	 */
	this.interaction_ = new ol.interaction.Modify({
		features: this.collection_
	});
	
	/**
	 * @private
	 * @type {google.maps.StreetViewPanorama}
	 */
	this.streetViewPanorama_ = null;
	
	/**
	 * @private
	 * @type {google.maps.StreetViewService}
	 */
	this.streetviewService_ = null;
	
	/**
	 * Button
	 * @private
	 * @type {HTMLElement}
	 */
	this.element_ = null;
	
	/**
	 * @private
	 * @type {HTMLElement}
	 */
	this.dialog_ = null;
	
	this.initialize_();
	
	ol.control.Control.call(this, {
		element: this.element_
	});

};
ol.inherits(cercalia.Control.StreetView, ol.control.Control);

/**
 * GoogleMaps API load for StreetView usage. Only if this control is 
 * included in the map
 * @private
 */
cercalia.Control.StreetView.prototype.initialize_ = function() {
	
	//Creamos elemento HTML del botón flotante del StreetView
	var self = this;
	this.element_ = document.createElement('div');
	this.element_.className = 'cercalia-control-streetview';
	this.element_.setAttribute('id','idStreetView' + new Date().getTime());	//Creamos un ID único
	this.element_.style.zIndex = "0";
	
	// Creamos el boton jQuery i añadimos funcion de click
	cercalia.jQuery(this.element_).button({
	    icons: { primary: "cercalia-icon-streetView-enabled" },
	    text: false
    });
	
	this.element_.addEventListener('click',function(){
		self.enabled_ ? self.disable() : self.enable();  
	}, false);
	
	cercalia.jQuery(this.element_).attr("title", cercalia.i18n._("TOOLTIP_STREETVIEW"));
	
	if( typeof google == "undefined" ){ 
		var script = document.createElement("script");
		var idDialog = this.element_.id + "dialog";
		
		script.type = "text/javascript";
		script.src = location.protocol + "//maps.google.com/maps/api/js?region=nz&async=2&callback=cercalia.GoogleMapsLoad";
		document.body.appendChild(script);
	}
	
	//Creemos el dialog
	this.dialog_ = 
		cercalia.jQuery('<div id="'+idDialog+'"/>')
			.dialog({
				//dialogClass: 'streetViewDialogControl',
				width: this.width_,
				height: this.height_,
				resizable: true,
				resize: function(){
					google.maps.event.trigger(self.streetViewPanorama_, 'resize');
				},
				close: function(){
					self.disable();
				},
				autoOpen: false,
				position: {
					  my: "right-16 bottom-16",
					  at: "right bottom",
					  of: window
				}
			})
			.append(
				cercalia.jQuery("<div class='errorMsg' style='height:60px;display:none'><\/div><br><center><h2>No Street View data at this position<\/h2><\/center>")
			);
	
	//es posa pq sino no es veu quan es posa FullScreen
	if(this.dialog_ && this.dialog_.parent()) {
		this.dialog_.parent().zIndex(10000000000);
	}
	
};


/**
 * @param {cercalia.LonLat|undefined} position
 * @private
 */
cercalia.Control.StreetView.prototype.createStreetViewMarker_ = function(position) {
	var map = this.getMap();
	this.streetViewFeature_ = new ol.Feature();
	
	var iconStyle = new ol.style.Style({
		  image: new ol.style.Icon({
			src: this.imgStreetViewOn_
		  }),
		  zIndex: 99999
	});

	this.streetViewFeature_.setStyle(iconStyle);

	var source = map.getCercalia().getLayerByName('MarkerApiLayer').getSource();
	var center;
	if(position) {
		var lon = position.getLon();
		var lat = position.getLat();
		center = ol.proj.transform([lon, lat], 'EPSG:4326', map.getCercalia().getProjectionCode());
	} else {
		center = map.getView().getCenter();
	}
	var geometry = new ol.geom.Point(center);
	
	this.streetViewFeature_.setGeometry(geometry);
	this.collection_.push(this.streetViewFeature_);

	source.addFeature(this.streetViewFeature_);
	
	map.addInteraction(this.interaction_);
	map.on('pointerup', this.pointerupFunction_, this);
	
	this.streetViewFeature_.on('change', this.draggingFeatureFunction_, this);
};

/**
 * @private
 */
cercalia.Control.StreetView.prototype.removeStreetViewMarker_ = function(argument){
	var map = this.getMap();
	var source = map.getCercalia().getLayerByName('MarkerApiLayer').getSource();

	map.removeInteraction(this.interaction_);
	map.un('pointerup', this.pointerupFunction_, this);
	
	this.streetViewFeature_.un('change:geometry', this.draggingFeatureFunction_, this);
	this.collection_.remove(this.streetViewFeature_);
	source.removeFeature(this.streetViewFeature_);
	this.streetViewFeature_ = null;
};


/**
 * Enable StreetView control
 */
cercalia.Control.StreetView.prototype.enable = function() {
	
	var self = this;
	var map = this.getMap();
	
	cercalia.jQuery(this.element_).addClass('ui-state-active');
	
	this.dialog_.dialog('open');
	
	if(!this.streetViewFeature_) {
		this.createStreetViewMarker_();
	}
	
	//Si no estaba inicializado el StreetView
	if(!this.streetViewPanorama_){
		
		this.streetviewService_ = new google.maps.StreetViewService();
		
		this.streetViewPanorama_ = new google.maps.StreetViewPanorama(
				this.dialog_[0],
				{
					position: null,
					addressControl: true,
					addressControlOptions: {
						position: google.maps.ControlPosition.BOTTOM,
						style: {
							"fontWeight" : "bold",
							"backgroundColor" : "#191970",
							"color" :"#A9203E"
						}
					},
					linksControl: true,
					navigationControlOptions: {
						position: google.maps.ControlPosition.TOP_LEFT,
						style: google.maps.NavigationControlStyle.SMALL
					},            
					enableCloseButton: false,
					pov: {
						heading: 120,
						pitch: 0,
						zoom: 2
					}
				}
		);
		
		this.streetViewPanorama_.addListener('position_changed', function() {
			var lonLat = this.getPosition();
			var position = new cercalia.LonLat(lonLat.lng(), lonLat.lat());
			self.removeStreetViewMarker_();
			self.createStreetViewMarker_(position);
		});
		
		
		//this.setLocationAndPOV_(new google.maps.LatLng(position.getLat(), position.getLon()));
	}

	var position = map.getCercalia().getCenter();
	this.setPosition(position);
	
	this.enabled_ = true;
};

/**
 * Set position of street view panorama.
 * @param {cercalia.LonLat} position
 *
 */
cercalia.Control.StreetView.prototype.setPosition = function(position) {
	this.setLocationAndPOV_(new google.maps.LatLng(position.getLat(), position.getLon()));
};


/**
 * Disable StreetView control
 * 
 */
cercalia.Control.StreetView.prototype.disable = function() {

    cercalia.jQuery(this.element_).removeClass('ui-state-active');
	this.dialog_.dialog('close');
		
	if(this.streetViewFeature_){
		this.removeStreetViewMarker_();
	}
	this.enabled_ = false;
};

/**
 *  Dragging function. Enables dragging flag
 * @private
 */
cercalia.Control.StreetView.prototype.draggingFeatureFunction_ = function() {
	if(!this.interaction_.dragging){
		this.interaction_.dragging = true;
	}
};

/**
 * "dragEnd" function
 * @private
 */
cercalia.Control.StreetView.prototype.pointerupFunction_ = function() {
	if(this.interaction_.dragging){
		this.interaction_.dragging = false;
		var cercaliaMap = this.getMap().getCercalia();
		var coordinates = this.streetViewFeature_.getGeometry().clone().transform(cercaliaMap.getProjectionCode(),'EPSG:4326').getCoordinates();
		var latLngGoogle = new google.maps.LatLng(coordinates[1], coordinates[0]);
		
		this.setLocationAndPOV_(latLngGoogle);
	}
};

/**
 * @private
 * @param {google.maps.LatLng} latLngGoogle
 */
cercalia.Control.StreetView.prototype.setLocationAndPOV_ = function(latLngGoogle){
	var self =  this;
	this.streetviewService_.getPanoramaByLocation(latLngGoogle, 50, function(data,status){
		var icon;
		if(data){
			self.dialog_.find('.errorMsg').hide();
			self.streetViewPanorama_.setPano(data.location.pano);                                                                       
			self.streetViewPanorama_.setPov({
				heading: 270,
				pitch: 0,
				zoom: 2
			});                
			self.streetViewPanorama_.setVisible(true);
			icon = self.imgStreetViewOn_;			
		} else {
			self.dialog_.find('.errorMsg').show();
			self.streetViewPanorama_.setVisible(false);
			icon = self.imgStreetViewOff_;
		}
		
		self.streetViewFeature_.setStyle(new ol.style.Style({image: new ol.style.Icon({src: icon})}));
	});
};

/**
 * Close StreetView window
 */
cercalia.Control.StreetView.prototype.close = function() {
	this.dialog_.dialog('close');
};

/**
 * Open StreetView window
 */
cercalia.Control.StreetView.prototype.open = function() {
	this.dialog_.dialog('open');
	if(!this.streetViewPanorama_){
		this.enable();
	}
};

/**
 * Returns if StreetView window is opened
 * @return {boolean}
 */
cercalia.Control.StreetView.prototype.isOpen = function() {
	return this.dialog_.dialog('isOpen');
};

/**
 * Resize StreetView dialog
 * @param {number} width
 * @param {number} height
 */
cercalia.Control.StreetView.prototype.setSize = function(width, height){
	this.width_ = width;
	this.height_ = height;
	this.dialog_.dialog({width:this.width_, height:this.height_});
	if(this.dialog_.dialog('isOpen')) {
		google.maps.event.trigger(this.streetViewPanorama_, 'resize'); //forces a fer el resize 
	}
};


/**
 * Get Street View Div
 * @return {HTMLElement|null}
 */
cercalia.Control.StreetView.prototype.getDiv = function(){
	if(this.dialog_) {
		return this.dialog_.get(0);
	} else {
		console.warn("Dialgo not initialized");
		return null;
	}
};