Source: widgets/SpwGoogleStreetView.js

Retour à la documentation
/**
 * @class spw.widgets.SpwGoogleStreetView
 */
define([
    "dojo/_base/declare", "spw/api/SpwBaseWidget", "dojo/_base/lang", "dojo/dom-construct", "dojo/_base/window",
    "dojo/_base/connect", "esri/symbols/PictureMarkerSymbol", "esri/SpatialReference", "spw/api/MessageManager",
    "esri/geometry/Point", "spw/api/ProjectionManager", "dijit/layout/ContentPane", "esri/graphic", "dojo/has", "dojo/on", "dojo/topic",
    "dojo/_base/array", "spw/api/ConfigLoader", "dijit/ConfirmDialog", "dijit/form/CheckBox", "dojo/cookie"
], function (declare, SpwBaseWidget, lang, domConstruct, win, connect, PictureMarkerSymbol,
             SpatialReference, MessageManager, Point, ProjectionManager, ContentPane,
             Graphic, has, on, topic, array, ConfigLoader, ConfirmDialog, CheckBox, cookie) {

    return declare("spw.widgets.SpwGoogleStreetView", [SpwBaseWidget], /** @lends spw.widgets.SpwGoogleStreetView.prototype */{

        activated: false,
        height: "420px",
        width: "450px",
        widgetTitle: null,
        resizable: false,
        iconClass: "streetviewIcon",
        position: "bottom",
        
        confirmDialogStyle: 'width: 400px;',
        confirmDialogTitle: 'Avertissement',
        confirmDialogMessage: "Conformément aux conditions d'utilisation de Google, cet outil activera le fond de plan Google. Le fond de plan actuel sera réactivé lorsque vous quitterez \"StreetView\".",
        confirmDialogConfirmLabel: 'Continuer',
        confirmDialogCancelLabel: 'Annuler',
        saveChoiceText: 'Se souvenir de mon choix',
        saveChoiceCookie: 'googlestreetviewcookie',

        apiKey: null,

        imageWidth: 32,
        imageHeight: 32,

        config: null,
        _spwGoogleStreetViewPane: null,
        _spwPanoGSV: null,
        _dragSymb: null,
        _posiSymb: null,
        _mouseDragEvent: null,
        _mouseDownHandle: null,
        _mouseUpHandle: null,
        _sv: null,

        /**
         * @constructs
         */
        constructor: function (config) {
            this.config = config;

            this._dragSymb = new PictureMarkerSymbol(this.imagesPath + 'gsv_onDrag.png', 30, 30);
            this._posiSymb = new PictureMarkerSymbol(this.imagesPath + 'gsv_graphic.png', 30, 30);
        },

        onMouseDownGraphic: function (evt) {
            if (this.objGraph == evt.graphic && this.activated) {
                this.spwViewer.get('spwMap').get('esriMap').disableMapNavigation();

                if (this._mouseDragEvent != null) {
                    this._mouseDragEvent.remove();
                }
                this._mouseDragEvent = this.spwViewer.get('spwMap').get('esriMap').on("mouse-drag", lang.hitch(this, this.onMouseDragGraphic));

                evt.graphic.setSymbol(this._dragSymb);
            }
        },

        onMouseDragGraphic: function (evt) {
            if (this.activated) {
                this.spwViewer.get('spwMap').get('esriMap').disableMapNavigation();
                var moveLoc = evt.mapPoint;
                moveLoc.setSpatialReference(this.spwViewer.get('spatialReference'));
                this.objGraph.setGeometry(moveLoc);
                if (this.objGraph.getDojoShape() && this.objGraph.getDojoShape().rawNode) {
                    this.objGraph.getDojoShape().rawNode.style.cursor = "-webkit-grabbing";
                }
            }
        },

        onOnMouseUpGraphic: function (evt) {
            if (this._mouseDragEvent != null && this.activated) {
                this._mouseDragEvent.remove();

                this.spwViewer.get('spwMap').get('esriMap').enableMapNavigation();

                var moveLoc = evt.mapPoint;
                moveLoc.setSpatialReference(this.spwViewer.get('spatialReference'));
                evt.graphic.setGeometry(moveLoc);
                evt.graphic.setSymbol(this._posiSymb);

                var x = evt.mapPoint.x;
                var y = evt.mapPoint.y;

                var pointGoogle = ProjectionManager.getInstance().projectPoint(this.spwViewer.get('spwMap').getSpatialReferenceSRID(), 4326, x, y);
                var pos = new google.maps.LatLng(pointGoogle.y, pointGoogle.x);
                this._sv.getPanoramaByLocation(pos, 50, this.processSVData(pos.lng(), pos.lat(), 50));

                if (this.objGraph.getDojoShape() && this.objGraph.getDojoShape().rawNode) {
                    this.objGraph.getDojoShape().rawNode.style.cursor = "-webkit-grab";
                }
            }
        },

        postCreate: function () {
            this.inherited(arguments);

            topic.subscribe('SPWBASEMAPCHOOSER_BASEMAP_CHANGED', lang.hitch(this, this.onBaseMapChanged));

            on(this.spwViewer.get('spwMap'), 'MapCreated', lang.hitch(this, function(map) {
                if (this._activated || this.objGraph == null) {
                    return;
                }

                if (map.loaded) {
                    map.graphics.remove(this.objGraph);
                }
                else {
                    on.once(this.spwViewer.get('spwMap'), 'MapLoaded', lang.hitch(this, function() {
                        map.graphics.remove(this.objGraph);
                    }));
                }
            }));
        },

        onBaseMapChanged: function (basemap) {
            if (this._waitingBasemap && basemap.baseMapId === this._waitingBasemap.baseMapId) {
                this.onActivate();
            }
            else {
                this._oldBasemap = null;
                this.onDeactivate();
            }
        },

        onActivate: function () {
            if (this._waitingBasemap) {
                this.inherited(arguments);

                require(["//maps.googleapis.com/maps/api/js" + (this.apiKey ? ("?key=" + this.apiKey) : "")], lang.hitch(this, function(googleApi){

	                if (this._spwPanoGSV == null) {
	                	
	                    var position = new google.maps.LatLng(50.75161, 5.544501);
	                    position = new google.maps.LatLng(50.6730883, 5.485706299999999);
	                    var panOptions = {
	                        position: position,
	                        pov: {
	                            heading: 0,
	                            pitch: 0,
	                            zoom: 0
	                        }
	                    };
	
	                    //Trick to solve webkit bug when dragging elements containg canvas.
	                    //see https://code.google.com/p/chromium/issues/detail?id=166407
	                    if (this._panel && has("webkit")) {
	                        connect.connect(this._panel.moveable, "onMove", function () {
	                            win.body().style.display = 'none';
	                            win.body().offsetHeight; // no need to store this anywhere, the reference is enough
	                            win.body().style.display = 'block';
	                        });
	                    }
	                    //end trick
	
	                    this.domNode.style.width = "100%";
	                    this.domNode.style.height = "100%";
	                    this._spwGoogleStreetViewPane = domConstruct.create("div", {
	                        style: "height:100%;width:100%;"
	                    }, this.domNode);
	
	                    var panorama = new google.maps.StreetViewPanorama(this._spwGoogleStreetViewPane, panOptions);
	                    this._spwPanoGSV = panorama;
	                    this._sv = new google.maps.StreetViewService();
	                    connect.connect(panorama, "position_changed", this, function () {
	                        var lng = this._spwPanoGSV.getPosition().lng();
	                        var lat = this._spwPanoGSV.getPosition().lat();
	                        if (!isNaN(lng) && !isNaN(lat)) {
	                            var point = new Point(lng, lat, new SpatialReference({wkid: 4326}));
	                            this.projectFromWGS(point);
	                        }
	                        else {
	                            MessageManager.getInstance().notifyError("Problème pour la position Google Street View: lng:" + lng + " - lat:" + lat);
	                        }
	                    });
	
	                    this._mouseDownHandle = this.spwViewer.get('spwMap').on("GraphicsMouseDown", lang.hitch(this, this.onMouseDownGraphic));
	                    this._mouseUpHandle = this.spwViewer.get('spwMap').on("GraphicsMouseUp", lang.hitch(this, this.onOnMouseUpGraphic));
	                }
	
	                var x = (this.spwViewer.get('spwMap').get('esriMap').extent.xmin + this.spwViewer.get('spwMap').get('esriMap').extent.xmax) / 2;
	                var y = (this.spwViewer.get('spwMap').get('esriMap').extent.ymin + this.spwViewer.get('spwMap').get('esriMap').extent.ymax) / 2;
	
	                var pointGoogle = ProjectionManager.getInstance().projectPoint(this.spwViewer.get('spwMap').getSpatialReferenceSRID(), 4326, x, y);
	                var pos = new google.maps.LatLng(pointGoogle.y, pointGoogle.x);
	                this._sv.getPanoramaByLocation(pos, 50, this.processSVData(pos.lng(), pos.lat(), 50));
                }));
            }
            else {
                var currentBaseMap = this.getCurrentBaseMap();
                var baseMapConfig = ConfigLoader.getInstance().get('baseMap');
                var googleBaseMap = null;

                if (array.some(currentBaseMap.services, lang.hitch(this, function(service) {
                    return service.type === 'GMAP_LAYER';
                    }))) {
                    this._waitingBasemap = currentBaseMap;
                    this.onActivate();
                }
                else {
                    array.some(baseMapConfig, lang.hitch(this, function (basemap) {
                        if (array.some(basemap.services, lang.hitch(this, function (service) {
                                return service.type === 'GMAP_LAYER';
                            }))) {
                            googleBaseMap = basemap;
                        }
                        return googleBaseMap != null;
                    }));

                    if (googleBaseMap) {
                        if (cookie(this.saveChoiceCookie) === 'true') {
                            cookie(this.saveChoiceCookie, 'true');
                            this._waitingBasemap = googleBaseMap;
                            this._oldBasemap = currentBaseMap;
                            topic.publish('SPWBASEMAPCHOOSER_LOCK_BASEMAP', googleBaseMap);
                        }
                        else {
                            var confirmDialog = new ConfirmDialog({
                                title: this.confirmDialogTitle,
                                content: this.confirmDialogMessage,
                                closable: false,
                                style: this.confirmDialogStyle,
                                buttonOk: this.confirmDialogConfirmLabel,
                                buttonCancel: this.confirmDialogCancelLabel
                            });

                            domConstruct.create("span", {
                                innerHTML: this.saveChoiceText,
                                style: 'margin-right: 60px;'
                            }, confirmDialog.actionBarNode, 'first');

                            var cbCookie = new CheckBox({
                                checked: cookie(this.saveChoiceCookie) != "false",
                                onClick: lang.hitch(this, this.openAtStartupClicked)
                            }, domConstruct.create("input", null, confirmDialog.actionBarNode, 'first'));

                            confirmDialog.on('execute', lang.hitch(this, function() {
                                cookie(this.saveChoiceCookie, cbCookie.get('checked').toString());
                                this._waitingBasemap = googleBaseMap;
                                this._oldBasemap = currentBaseMap;
                                topic.publish('SPWBASEMAPCHOOSER_LOCK_BASEMAP', googleBaseMap);
                            }));

                            confirmDialog.show();
                        }
                    }
                    else {
                        MessageManager.getInstance().notifyError('Le widget GoogleStreetView ne peut être lancé qu\'avec un fond de plan Google. Malheureusement, aucun fond de plan de ce type n\'existe dans cette application.');
                    }
                }
            }
        },

        getCurrentBaseMap: function() {
            var basemaps = this.spwViewer.get('spwMap').getMapServices({
                isBaseMap: true,
                visible: true
            });

            var baseMapConfig = ConfigLoader.getInstance().get('baseMap');
            var currentBaseMap = null;

            array.some(baseMapConfig, lang.hitch(this, function(baseMapConfig) {
                return array.some(baseMapConfig.services, lang.hitch(this, function(service) {
                    if (array.some(basemaps, lang.hitch(this, function(basemap) { 
                        return basemap.serviceId === service.serviceId || (basemap.serviceId === ('black-and-white-' + service.serviceId));
                    }))) {
                        currentBaseMap = baseMapConfig;
                        return true;
                    }
                    return false;
                }));
            }));

            return currentBaseMap;
        },

        processSVData: function (x, y, radius) {
            var lambertPoint = ProjectionManager.getInstance().projectPoint(4326, this.spwViewer.get('spwMap').getSpatialReferenceSRID(), x, y);
            var point = new Point(lambertPoint.x, lambertPoint.y, this.spwViewer.get('spwMap').get('esriMap').spatialReference);

            var map = this.spwViewer.get('spwMap').get('esriMap');
            if (this.objGraph) {
                map.graphics.remove(this.objGraph);
            }
            this.objGraph = new Graphic(point, this._posiSymb);
            map.graphics.add(this.objGraph);
            if (this.objGraph.getDojoShape() && this.objGraph.getDojoShape().rawNode) {
                this.objGraph.getDojoShape().rawNode.style.cursor = "-webkit-grab";
            }

            return lang.hitch(this, function (data, status) {
                if (status == google.maps.StreetViewStatus.OK) {
                    this.panGoToPos(data.location.latLng);
                } else if (status == google.maps.StreetViewStatus.ZERO_RESULTS) {
                    var pos = new google.maps.LatLng(y, x);
                    this._sv.getPanoramaByLocation(pos, radius * 2, this.processSVData(pos.lng(), pos.lat(), radius * 2));
                } else {
                    MessageManager.getInstance().notifyWarning("Aucune photo google n'existe pour cet endroit.");
                }
            });
        },

        resize: function () {
            if (this._spwPanoGSV) {
                google.maps.event.trigger(this._spwPanoGSV, 'resize');
            }
        },

        onDeactivate: function () {
            this.inherited(arguments);

            this._waitingBasemap = null;

            if (this._oldBasemap) {
                topic.publish('SPWBASEMAPCHOOSER_CHANGE_BASEMAP', this._oldBasemap);
            }

            this._oldBasemap = null;

            if (this.spwViewer.get('spwMap') && this.spwViewer.get('spwMap').get('esriMap') && this.spwViewer.get('spwMap').get('esriMap').graphics) {
                this.spwViewer.get('spwMap').get('esriMap').graphics.remove(this.objGraph);
            }
        },

        findNearestPos: function (mapX, mapY) {
            //spwGeolocalisation.getNearestPosition(mapX,mapY,function(obj){dojo.publish(_SPW_GOOGLESTREETVIEW_NEARESTPOINT_FOUND,[obj]);});
        },

        onNearestPosFound: function (obj) {
            var x = obj.x;
            var y = obj.y;
            if (!isNaN(x) && !isNaN(y)) {
                var lambPoint = Point(x, y, this.spwViewer.get('spatialReference'));
                this.objGraph.setGeometry(lambPoint);
                this.projectToWGS(lambPoint);
            }
            else {
                MessageManager.getInstance().notifyError("Problème pour la position sur la carte: x:" + pos.x + " - y:" + pos.y);
            }
        },

        projectToWGS: function (point) {
            var pt = ProjectionManager.getInstance().projectPoint(this.spwViewer.get('spwMap').getSpatialReferenceSRID(), 4326, point.x, point.y);
            this.onProjectToWGSDone(pt);
        },

        projectFromWGS: function (point) {
            var pt = ProjectionManager.getInstance().projectPoint(4326, this.spwViewer.get('spwMap').getSpatialReferenceSRID(), point.x, point.y);
            this.spwRecenterMap(pt);
        },
        onProjectFromWGSDone: function (projPts) {
            var pos = projPts;
            this.spwRecenterMap(pos);
        },
        spwRecenterMap: function (pos) {
            if (!isNaN(pos.x) && !isNaN(pos.y)) {
                this.spwViewer.centerInVisibleZone(pos.x, pos.y);

                //this.spwViewer.get('spwMap').centerAt(pos.x,pos.y);
                var point = Point(pos.x, pos.y, this.spwViewer.get('spatialReference'));
                this.objGraph.setGeometry(point);
            }
            else {
                MessageManager.getInstance().notifyError("Problème pour la position sur la carte: lng:" + pos.x + " - lat:" + pos.y);
            }
        },
        onProjectToWGSDone: function (projPts) {
            var pos = new google.maps.LatLng(projPts.y, projPts.x);
            this.panGoToPos(pos);
        },
        panGoToPos: function (pos) {
            this._spwPanoGSV.setPosition(pos);
        }
    });
});