Source: bu-street/streetviewer.js

/**
 * @fileoverview bu.street.Viewer is an abstract class for viewers
 * that show street 360 panoramas and data.
 * Created 23/03/2017.
 * @author josea.hernandez@blom.no (Jose Antonio Hernandez)
 * @author rafael.delaviuda@blom.no (Rafael de la Viuda)
 * @author raul.sangil@blom.no (Raul Sangil)
 * @copyright Blom Data S.L. 2017
 */

goog.provide('bu.street.Viewer');

goog.require('ol');
goog.require('ol.Object');
goog.require('bu.Viewer');

/*goog.require('bu.street.Image');
goog.require('bu.street.UrbexServices');
goog.require('bu.street.Transformations');*/

 /**
 * @classdesc
 * Constructor for bu.street.Viewer class 
 * This is an abstract class for viewers that show 360ยบ panorama images.
 * It is used for creating subclasses and not instantiated in apps.
 * Note that with `bu.street.Viewer` and all its subclasses, any property set in
 * the options is set as a {@link ol.Object} property on the viewer object, so
 * is observable, and has get/set accessors.
 *
 * @constructor 
 * @extends {bu.Viewer}
 * @param {bu.street.ViewerOptions} options Viewer options.
 * @abstract
 * @api
 */
 
bu.street.Viewer = function(options) {
    bu.Viewer.call(this);
    this.viewType_ = bu.ViewType.STREET;
    this.genericAsyncRequest_ = this.jqueryAsyncRequest_;
    
    var hotspotsOptions = {viewer:this};                            
    
    //this.hotspotsManager_ = new bu.street.HotspotsManager(hotspotsOptions);
    this.imagesManager_ = new bu.street.ImagesManager({});
    this.servicesManager_ = new bu.street.Services({usertoken: options.usertoken});
    
    /**
     * @type {Object.<string, *>}
     */
    var properties = ol.obj.assign({}, options);
    
    properties[bu.street.ViewerProperty.USERTOKEN] =
        options.usertoken !== undefined ? options.usertoken : "";
    properties[bu.street.ViewerProperty.IMAGEID] =
        options.imageid !== undefined ? options.imageid : "";
    properties[bu.street.ViewerProperty.CENTER] = 
        options.center !== undefined ? options.center : [0.0,0.0];
    properties[bu.street.ViewerProperty.ROTATION] =
        options.rotation !== undefined ? options.rotation : 0.0;
    properties[bu.street.ViewerProperty.FOV] =
        options.fov !== undefined ? options.fov : 1;
    properties[bu.street.ViewerProperty.PITCH] =
        options.pitch !== undefined ? options.pitch : 1;
    properties[bu.street.ViewerProperty.YAW] =
        options.yaw !== undefined ? options.yaw : 1;
    
    this.setProperties(properties);    
};
ol.inherits(bu.street.Viewer, bu.Viewer);

/**
 * Return the usertoken to be used with BlomURBEX services.
 * @return {string} The usertoken.
 * @observable
 * @api
 */
bu.street.Viewer.prototype.getUsertoken = function(){
    return /** @type {string} */ (
        this.get(bu.street.ViewerProperty.USERTOKEN));
};

//TODO Add getImage setImage

/**
 * Return the BlomURBEX 360 image currently shown. It return null if no image
 * is currently loaded.
 * @return {bu.street.Image} The image.
 * @api
 */
bu.street.Viewer.prototype.getImage = function() {
    var imageId = this.getImageID();
    return /** @type {bu.street.Image} */ (
        this.imagesManager_.getImageById(imageId));
};


/**
 * Return the image ID of the BlomURBEX 360 image to be shown.
 * @return {string} The image ID.
 * @observable
 * @api
 */
bu.street.Viewer.prototype.getImageID = function() {
    return /** @type {string} */ (
        this.get(bu.street.ViewerProperty.IMAGEID));
};

/**
 * Return the current {@link bu.Coordinate center} of the viewer. This center
 * is the point where the 360 image is shot. Coordinates are always in WGS84
 * latlon, first value in the coordinate is longitude and second latitude.
 * @return {bu.Coordinate} The viewer center.
 * @observable
 * @api
 */
bu.street.Viewer.prototype.getCenter = function() {
    var center = this.imagesManager_.getImageCenter(this.getImageID());
    return (center ? center : undefined);
};

/**
 * Return the current rotation of the viewer in decimal degrees with north equal
 * zero and values increasing towards east. Value range is [0,360).
 * @return {bu.Coordinate} The viewer rotation.
 * @observable
 * @api
 */
bu.street.Viewer.prototype.getRotation = function() {
    return /** @type {number} */ (
        this.get(bu.street.ViewerProperty.ROTATION));
};

/**
 * Return the current FOV of the viewer in decimal degrees. FOV or Field of View
 * is the angle of the 360 image that is currently visible in the viewer. It depends
 * on the size of the viewer and the angular resolution of the current zoom level.
 * Changing this value causes the same effect of changing zoom level but this value
 * gives more grain control. Value range is [0,360) though values up 180 aren't
 * logical ones in a 2D screen. The projection in a 2D screen is limited to values
 * far under 180. Values above 180 have sense, on the contrary, for VR screens.
 * @return {number} The viewer FOV.
 * @observable
 * @api
 */
bu.street.Viewer.prototype.getFOV = function() {
    return /** @type {number} */ (
        this.get(bu.street.ViewerProperty.FOV));
};

/**
 * Set the usertoken to be used with BlomURBEX services.
 * @param {string} usertoken The usertoken.
 * @observable
 * @api
 */
bu.street.Viewer.prototype.setUsertoken = function(usertoken){
    this.set(bu.street.ViewerProperty.USERTOKEN, usertoken);
};

/**
 * Set the BlomSTREET 360? panorama image to be shown.
 * @param {bu.street.Image} image The image.
 * @api
 */
bu.street.Viewer.prototype.setImage = function(image) {
    if (image.zcp) {
        this.imagesManager_.addImage(image);
        this.setImageID(image.id);
    } else {
        this.setImageID(image.id);
    }
};

/**
 * Set the image ID of the BlomURBEX 360 image to be shown.
 * @param {string} imageid The image ID.
 * @observable
 * @api
 */
bu.street.Viewer.prototype.setImageID = function(imageid) {
    this.set(bu.street.ViewerProperty.IMAGEID, imageid);
};


/**
 * SZet the current rotation of the viewer in decimal degrees with north equal
 * zero and values increasing towards east. Value range is [0,360).
 * @param {bu.Coordinate} rotation The viewer rotation.
 * @observable
 * @api
 */
bu.street.Viewer.prototype.setRotation = function(rotation) {
    this.set(bu.street.ViewerProperty.ROTATION, rotation);
};

/**
 * Set the current FOV of the viewer in decimal degrees. FOV or Field of View
 * is the angle of the 360 image that is currently visible in the viewer. It depends
 * on the size of the viewer and the angular resolution of the current zoom level.
 * Changing this value causes the same effect of changing zoom level but this value
 * gives more grain control. Value range is [0,360) though values up 180 aren't
 * logical ones in a 2D screen. The projection in a 2D screen is limited to values
 * far under 180. Values above 180 have sense, on the contrary, for VR screens.
 * @param {number} fov The viewer FOV.
 * @observable
 * @api
 */
bu.street.Viewer.prototype.setFOV = function(fov) {
    this.set(bu.street.ViewerProperty.FOV, fov);
};

/**
 * Set the current YAW value of the viewer in radians. Valid range is [-Pi, Pi]
 * When yaw value is 0 the viewer is aligned with the yaw of the shots taking 
 * vehicle. 
 * @param {number} yaw The viewer YAW.
 * @observable
 * @api
 */
bu.street.Viewer.prototype.setYaw = function(yaw) {
    this.set(bu.street.ViewerProperty.YAW, yaw);
};

/**
 * Valid range is (-Pi/2, Pi/2).
 * Set the current PITCH value of the viewer in radians. Valid range is [-Pi, Pi].
 * When yaw value is 0 the viewer is aligned with horizont, -Pi value is the 
 * highest angle we can focus of the image and Pi is the lower. 
 * @param {number} pitch The PITCH value
 * @observable
 * @api
 */
bu.street.Viewer.prototype.setPitch = function(pitch) {
    this.set(bu.street.ViewerProperty.PITCH, pitch);
};

/**
 * Returns current pitch value of the viewer and [-Pi/2, Pi/2] is the expected 
 * values range.
 * @return {number} 
 * @observable
 * @api
 */
bu.street.Viewer.prototype.getPitch = function() {
    return this.get(bu.street.ViewerProperty.PITCH);
};

/**
 * Returns current yaw value of the viewer and [-Pi, Pi] is the expected values
 * range.
 * @return {number} Yaw - The yaw value of the viewer. Range is [-Pi, Pi].
 * @observable
 * @api
 */
bu.street.Viewer.prototype.getYaw = function() {
    return this.get(bu.street.ViewerProperty.YAW);
};