[Commits] r1525 - in sandbox/cmoullet/ux: . GoogleEarthPanel GoogleEarthPanel/examples GoogleEarthPanel/resources GoogleEarthPanel/ux GoogleEarthPanel/ux/widgets

commits at geoext.org commits at geoext.org
Tue Dec 1 23:03:25 CET 2009


Author: cmoullet
Date: 2009-12-01 23:03:24 +0100 (Tue, 01 Dec 2009)
New Revision: 1525

Added:
   sandbox/cmoullet/ux/GoogleEarthPanel/
   sandbox/cmoullet/ux/GoogleEarthPanel/examples/
   sandbox/cmoullet/ux/GoogleEarthPanel/examples/GoogleEarthPanelExample.html
   sandbox/cmoullet/ux/GoogleEarthPanel/examples/GoogleEarthPanelExample.js
   sandbox/cmoullet/ux/GoogleEarthPanel/resources/
   sandbox/cmoullet/ux/GoogleEarthPanel/resources/eye.png
   sandbox/cmoullet/ux/GoogleEarthPanel/ux/
   sandbox/cmoullet/ux/GoogleEarthPanel/ux/widgets/
   sandbox/cmoullet/ux/GoogleEarthPanel/ux/widgets/GoogleEarthPanel.js
Log:
Initial version of Google Earth Panel


Added: sandbox/cmoullet/ux/GoogleEarthPanel/examples/GoogleEarthPanelExample.html
===================================================================
--- sandbox/cmoullet/ux/GoogleEarthPanel/examples/GoogleEarthPanelExample.html	                        (rev 0)
+++ sandbox/cmoullet/ux/GoogleEarthPanel/examples/GoogleEarthPanelExample.html	2009-12-01 22:03:24 UTC (rev 1525)
@@ -0,0 +1,30 @@
+<html>
+<head>
+    <title>GeoExt StreetView Panel UX Example</title>
+    <script type="text/javascript" src="http://extjs.cachefly.net/builds/ext-cdn-771.js"></script>
+    <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-2.2.1/resources/css/ext-all.css" />
+    <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-2.2.1/examples/shared/examples.css" />
+    <!-- Google Maps API for "localhost" -->
+    <!--
+    <script src='http://maps.google.com/maps?file=api&amp;key=ABQIAAAAjpkAC9ePGem0lIq5XcMiuhR_wWLPFku8Ix9i2SXYRVK3e45q1BQUd_beF8dtzKET_EteAjPdGDwqpQ'></script>
+    <script type="text/javascript" src="http://www.google.com/jsapi?key=ABQIAAAAY-I0w1WyNCVHbxpuwQWMpRTv_-xvSZ6KJmWSkQfCJoxbiB7tyBQ1ey_kgwA_p7sbTQSTOBeMyXtXkA"></script>
+    -->
+    <!--
+    <script src='http://maps.google.com/maps?file=api&amp;key=ABQIAAAAY-I0w1WyNCVHbxpuwQWMpRSIMweZSjbRtcUk2F5YNqLnri0MahTrQJRaRPWFP0OUB1b6unv37Jg7vQ'></script>
+    <script type="text/javascript" src="http://www.google.com/jsapi?key=ABQIAAAAY-I0w1WyNCVHbxpuwQWMpRSIMweZSjbRtcUk2F5YNqLnri0MahTrQJRaRPWFP0OUB1b6unv37Jg7vQ"></script>
+    -->
+    <!-- Google Maps API for "dev.geoext.org" -->
+    <script src='http://maps.google.com/maps?file=api&amp;key=ABQIAAAAY-I0w1WyNCVHbxpuwQWMpRTv_-xvSZ6KJmWSkQfCJoxbiB7tyBQ1ey_kgwA_p7sbTQSTOBeMyXtXkA'></script>
+    <script type="text/javascript" src="http://www.google.com/jsapi?key=ABQIAAAAY-I0w1WyNCVHbxpuwQWMpRTv_-xvSZ6KJmWSkQfCJoxbiB7tyBQ1ey_kgwA_p7sbTQSTOBeMyXtXkA"></script>
+
+
+    <script src="http://openlayers.org/api/2.8/OpenLayers.js"></script>
+    <script type="text/javascript" src="../../../trunk/geoext/lib/GeoExt.js"></script>
+
+    <script type="text/javascript" src="../ux/widgets/GoogleEarthPanel.js"></script>
+    <script type="text/javascript" src="GoogleEarthPanelExample.js"></script>
+
+</head>
+<body>
+</body>
+</html>
\ No newline at end of file

Added: sandbox/cmoullet/ux/GoogleEarthPanel/examples/GoogleEarthPanelExample.js
===================================================================
--- sandbox/cmoullet/ux/GoogleEarthPanel/examples/GoogleEarthPanelExample.js	                        (rev 0)
+++ sandbox/cmoullet/ux/GoogleEarthPanel/examples/GoogleEarthPanelExample.js	2009-12-01 22:03:24 UTC (rev 1525)
@@ -0,0 +1,130 @@
+var mapPanel;
+
+var GoogleEarthPanel;
+
+var viewport;
+
+var layer;
+
+google.load("earth", "1");
+
+Ext.onReady(function() {
+
+    var options;
+    var center = new OpenLayers.LonLat(-13625995.09, 4550849.74);
+
+    options = {
+        projection: new OpenLayers.Projection("EPSG:900913"),
+        units: "m",
+        numZoomLevels: 18,
+        maxResolution: 156543.0339,
+        maxExtent: new OpenLayers.Bounds(-20037508, -20037508,
+                20037508, 20037508.34)
+    };
+
+    layer = new OpenLayers.Layer.Google(
+            "Google Street", {sphericalMercator: true});
+
+    var map = new OpenLayers.Map(options);
+
+    var mouse = new OpenLayers.Control.MousePosition();
+
+    map.addControl(mouse);
+    mouse.activate();
+
+    var toolbar = new Ext.Toolbar({
+        items: [
+            {
+                xtype: 'tbfill'
+            },
+            {
+                text: 'Google Earth',
+                id: "googleToggle",
+                enableToggle: true,
+                pressed: true,
+                handler: function() {
+                    if (this.pressed) {
+                        GoogleEarthPanel.add(googleEarthPanelItem);
+                        GoogleEarthPanel.setSize('50%', 0);
+                        GoogleEarthPanel.setVisible(true);
+                        GoogleEarthPanel.doLayout();
+                        viewport.doLayout();
+                    } else {
+                        GoogleEarthPanel.remove('googleEarthPanelItem');
+                        GoogleEarthPanel.setWidth(0);
+                        GoogleEarthPanel.setVisible(false);
+                        GoogleEarthPanel.doLayout();
+                        viewport.doLayout();
+                    }
+                }
+            },
+            {
+                text: 'Permalink',
+                enableToggle: false,
+                handler: function() {
+                    var googleEarthPanelItem = Ext.getCmp("googleEarthPanelItem");
+                    if (googleEarthPanelItem) {
+                        alert("TODO");
+                    }
+
+                }
+            }
+        ]});
+
+    var googleEarthPanelItem = {
+        xtype: 'gxux_googleearthpanel',
+        id: 'googleEarthPanelItem',
+        map: map,
+        lonLat: center,
+        altitude: 50,
+        heading: -60,
+        tilt: 70,
+        range: 700
+    };
+
+    viewport = new Ext.Viewport({
+        layout: "border",
+        id: 'mainViewport',
+        items: [
+            {
+                region: "center",
+                id: "mappanel",
+                title: "Google Map",
+                xtype: "gx_mappanel",
+                map: map,
+                layers: [layer],
+                center: center,
+                zoom: 14,
+                split: true,
+                tbar: toolbar
+            },
+            {
+                region: "east",
+                layout: 'fit',
+                width: '50%',
+                id: "googleearthpanel",
+                title: 'Google Earth Panel',
+                closeAction: 'hide',
+                split: true
+            },
+            {
+                region: "south",
+                layout: 'fit',
+                id: "readme",
+                title: 'README',
+                margins: {left: 5,top: 5, bottom: 5, right: 5},
+                html: '<p style="font-size:12pt;color:#15428B;font-weight:bold;margin:5">Click somewehere in the map to see a panorama.<br>If you click on one arrow, the video show will start and you will move every 2 seconds to a new position. You can stop the video show by clicking on an arrow.</p>'
+            }
+        ]
+    });
+
+    mapPanel = Ext.getCmp("mappanel");
+    GoogleEarthPanel = Ext.getCmp("googleearthpanel");
+    GoogleEarthPanel.add(googleEarthPanelItem);
+    GoogleEarthPanel.doLayout();
+    viewport.doLayout();
+
+    //var parameters = OpenLayers.Util.getParameters();
+    //var streetViewPanelItemObj = Ext.getCmp("googleEarthPanelItem");
+    //streetViewPanelItemObj.setPermalink(parameters);
+});
\ No newline at end of file

Added: sandbox/cmoullet/ux/GoogleEarthPanel/resources/eye.png
===================================================================
(Binary files differ)


Property changes on: sandbox/cmoullet/ux/GoogleEarthPanel/resources/eye.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: sandbox/cmoullet/ux/GoogleEarthPanel/ux/widgets/GoogleEarthPanel.js
===================================================================
--- sandbox/cmoullet/ux/GoogleEarthPanel/ux/widgets/GoogleEarthPanel.js	                        (rev 0)
+++ sandbox/cmoullet/ux/GoogleEarthPanel/ux/widgets/GoogleEarthPanel.js	2009-12-01 22:03:24 UTC (rev 1525)
@@ -0,0 +1,338 @@
+/**
+ * Copyright (c) 2008-2009 The Open Source Geospatial Foundation
+ *
+ * Published under the BSD license.
+ * See http://svn.geoext.org/core/trunk/geoext/license.txt for the full text
+ * of the license.
+ */
+
+Ext.namespace('GeoExt.ux');
+
+GeoExt.ux.GoogleEarthPanel = Ext.extend(Ext.Panel, {
+
+    /** api: config[map]
+     *  ``OpenLayers.Map``  A configured map
+     */
+    /** private: property[map]
+     *  ``OpenLayers.Map``  The map object.
+     */
+    map: null,
+
+    /** private: property[ge]
+     *  Google earth instance
+     */
+    ge: null,
+
+    /** private: property[earthAvailable]
+     *  Defines if Google Earth is available
+     */
+    earthAvailable: true,
+
+    /** api: config[lonLat]
+     *  `` OpenLayers.LonLat``  Initial position (default: 0,0)
+     */
+    /** private: property[map]
+     *  ``OpenLayers.LonLat``  Initial position
+     */
+    lonLat: new OpenLayers.LonLat(0, 0),
+
+    /** api: config[altitude]
+     *  Initial altitude (default: 100)
+     */
+    /** private: property[altitude]
+     *  Initial altitude
+     */
+    altitude: 100,
+
+    /** api: config[heading]
+     *  Initial heading in degrees (default: 0)
+     */
+    /** private: property[heading]
+     *  Initial heading in degrees
+     */
+    heading: 0,
+
+    /** api: config[tilt]
+     *  Initial tilt in degrees (default: o)
+     */
+    /** private: property[tilt]
+     *  Initial tilt in degrees
+     */
+    tilt: 0,
+
+    /** api: config[range]
+     *  Initial range in meters (default: 100)
+     */
+    /** private: property[range]
+     *  Initial range in meters
+     */
+    range: 100,
+
+    /** api: config[kmlUrl]
+     *  KML Url (default: null)
+     */
+    /** private: property[range]
+     *  KML Url
+     */
+    kmlUrl: null,
+
+    initComponent: function() {
+        var defConfig = {
+            border: true
+        };
+        Ext.applyIf(this, defConfig);
+        GeoExt.ux.GoogleEarthPanel.superclass.initComponent.call(this);
+        this.addEvents('earthLoaded');
+
+        // GE is EPSG:4326
+        this.geProjection = new OpenLayers.Projection("EPSG:4326");
+
+        // Vector layer
+        this.earthLayer = new OpenLayers.Layer.Vector("earthLayer");
+        this.map.addLayer(this.earthLayer);
+
+        // Camera and lookAt points to display
+        this.features = [
+            new OpenLayers.Feature.Vector(null, {role: 'line'}, {strokeColor: '#ff0000',
+                strokeWidth: 3,
+                pointRadius: 6}),
+            new OpenLayers.Feature.Vector(null, {role: 'lookAt'}, {pointRadius: 8,
+                fillColor: '#ff0000'}),
+            new OpenLayers.Feature.Vector(null, {role: 'camera'}, {externalGraphic: '../resources/eye.png',
+                graphicHeight: 18,
+                graphicWidth: 31,
+                graphicYOffset: -3,
+                rotation: 0})];
+
+        // Drag control to move camera ans lookAt points
+        this.drag = new OpenLayers.Control.DragFeature(this.earthLayer, {
+            earth: this,
+            downFeature: function(pixel) {
+                this.lastPixel = pixel;
+                this.firstPixel = pixel;
+                this.firstGeom = this.feature.geometry;
+            },
+            moveFeature: function(pixel) {
+                if (this.feature === null) {
+                    return;
+                }
+                if (this.feature.attributes.role != 'line') {
+                    var res = this.map.getResolution();
+                    var x = res * (pixel.x - this.firstPixel.x) + this.firstGeom.x;
+                    var y = res * (this.firstPixel.y - pixel.y) + this.firstGeom.y;
+                    var lonLat = new OpenLayers.LonLat(x, y);
+
+                    if (this.feature.attributes.role == 'lookAt') {
+                        this.earth.lookTo(lonLat);
+                    } else if (this.feature.attributes.role == 'camera') {
+                        this.earth.lookFrom(lonLat);
+                    }
+                }
+                this.lastPixel = pixel;
+            }
+        });
+        this.map.addControl(this.drag);
+        this.drag.activate();
+
+        // Refreshes GE on map move
+        this.map.events.on({
+            move: this.onMove,
+            scope: this
+        });
+    },
+
+    // Create Google Earth instance when panel is rendered
+    afterRender: function() {
+        if (this.ownerCt) {
+            var wh = this.ownerCt.getSize();
+            Ext.applyIf(this, wh);
+        }
+        GeoExt.ux.GoogleEarthPanel.superclass.afterRender.call(this);
+        google.earth.createInstance(this.body.dom, this.initCallback.createDelegate(this), this.failureCallback.createDelegate(this));
+    },
+
+    // Init Google Earth
+    initCallback: function(object) {
+        this.ge = object;
+        this.ge.getWindow().setVisibility(true);
+        this.fireEvent('earthLoaded', this);
+
+        // Initializes position
+        var lookAt = this.ge.createLookAt('');
+        this.transformToGE(this.lonLat);
+        lookAt.set(this.lonLat.lat, this.lonLat.lon,
+                   this.altitude, this.ge.ALTITUDE_RELATIVE_TO_GROUND,
+                   this.heading, this.tilt, this.range);
+        this.ge.getView().setAbstractView(lookAt);
+
+        this.ge.getNavigationControl().setVisibility(this.ge.VISIBILITY_SHOW);
+        this.ge.getOptions().setFlyToSpeed(this.ge.SPEED_TELEPORT);
+        this.ge.getLayerRoot().enableLayerById(this.ge.LAYER_BUILDINGS, true);
+        
+        // Downloads KML
+        if (this.kmlUrl) {
+            google.earth.fetchKml(this.ge, this.kmlUrl, function(obj) {
+                                                            this.ge.getFeatures().appendChild(obj);
+                                                        });
+        }
+
+        // Adds listener to refresh camera and lookAt points on 2D map
+        var self = this;
+        google.earth.addEventListener(this.ge, "frameend", function() { self.onFrameEnd(); });
+    },
+
+    failureCallback: function(object) {
+        this.earthAvailable = false;
+    },
+
+    /**
+     * Function transformToGE
+     * Transforms a LonLat from map projection to GE projection
+     */
+    transformToGE: function(lonLat) {
+        lonLat.transform(this.map.getProjectionObject(),
+                         this.geProjection);
+    },
+
+    /**
+     * Function transformFromGE
+     * Transforms a LonLat from GE projection to map projection
+     */
+    transformFromGE: function(geLonLat) {
+        geLonLat.transform(this.geProjection,
+                           this.map.getProjectionObject());
+    },
+    
+    // Set the permalink
+    setPermalink: function(parameters) {
+
+    },
+
+    beforeDestroy: function() {
+        //Delete object
+        GeoExt.ux.GoogleEarthPanel.superclass.beforeDestroy.apply(this, arguments);
+    },
+        /**
+     * Function onMove
+     * Changes GE position on 2D map move
+     */
+    onMove: function() {
+        this.lookTo(this.map.getCenter());
+    },
+
+    /**
+     * Function onFrameEnd
+     * Changes camera and lookAt points on GE move
+     */
+    onFrameEnd: function() {
+        this.refresh();
+    },
+
+    /**
+     * Function lookTo
+     * Changes GE position on lookAt point move
+     */
+    lookTo: function(lonLat) {
+        if (!this.ge) {
+            return;
+        }
+
+        this.transformToGE(lonLat);
+
+        var lookAt = this.ge.getView().copyAsLookAt(this.ge.ALTITUDE_RELATIVE_TO_GROUND);
+        lookAt.setLongitude(lonLat.lon);
+        lookAt.setLatitude(lonLat.lat);
+        this.ge.getView().setAbstractView(lookAt);
+    },
+
+    /**
+     * Function lookFrom
+     * Changes GE position on camera point move (rotation around lookAt point)
+     */
+    lookFrom: function(lonLat) {
+        if (!this.ge) {
+            return;
+        }
+
+        // Gets current lookAt position
+        var lookAt = this.ge.getView().copyAsLookAt(this.ge.ALTITUDE_RELATIVE_TO_GROUND);
+        var geLonLat = new OpenLayers.LonLat(lookAt.getLongitude(),
+                                             lookAt.getLatitude());
+
+        // Computes distance between lookAt and camera for range computation
+        var lonLatTmp = lonLat.clone();
+        this.transformToGE(lonLatTmp);
+        var dist = OpenLayers.Util.distVincenty(lonLatTmp, geLonLat) * 1000;
+
+        // Computes rotation
+        this.transformFromGE(geLonLat);
+        var rot = (180/Math.PI) * Math.atan((geLonLat.lon - lonLat.lon) / (geLonLat.lat - lonLat.lat));
+        if (geLonLat.lat < lonLat.lat) {
+            rot = rot + 180;
+        }
+        lookAt.setHeading(rot);
+
+        // Computes range
+        var tilt = lookAt.getTilt();
+        var range = dist / Math.sin(tilt / (180/Math.PI));
+        lookAt.setRange(range);
+
+        this.ge.getView().setAbstractView(lookAt);
+    },
+
+    /**
+     * Function refresh
+     * Refreshes camera and lookAt drawings on 2D map
+     */
+    refresh: function() {
+        if (!this.ge) {
+            return;
+        }
+
+        // Gets current camera ans lookAt positions
+        var lookAt = this.ge.getView().copyAsLookAt(this.ge.ALTITUDE_RELATIVE_TO_GROUND);
+        var pl = new OpenLayers.LonLat(lookAt.getLongitude(), lookAt.getLatitude());
+        this.transformFromGE(pl);
+        var camera = this.ge.getView().copyAsCamera(this.ge.ALTITUDE_RELATIVE_TO_GROUND);
+        var pc = new OpenLayers.LonLat(camera.getLongitude(), camera.getLatitude());
+        this.transformFromGE(pc);
+
+        // Refresh map only if camera has moved
+        if (this.pl && this.pc) {
+            if (this.pl == pl && this.pc == pc) {
+                return;
+            } else {
+                this.pl = pl;
+                this.pc = pc;
+            }
+        } else {
+            this.pl = pl;
+            this.pc = pc;
+        }
+
+        // Computes new features positions
+        this.earthLayer.removeFeatures(this.features);
+        this.features[0].geometry =
+            new OpenLayers.Geometry.LineString([new OpenLayers.Geometry.Point(pl.lon, pl.lat),
+                                                new OpenLayers.Geometry.Point(pc.lon, pc.lat)]);
+        this.features[1].geometry = new OpenLayers.Geometry.Point(pl.lon, pl.lat);
+        this.features[2].geometry = new OpenLayers.Geometry.Point(pc.lon, pc.lat);
+
+        // Computes eye orientation
+        if (pl.lon == pc.lon) {
+            this.features[2].style.rotation = 0;
+        } else {
+            var rot = (180/Math.PI) * Math.atan((pl.lon - pc.lon) / (pl.lat - pc.lat));
+            if (pl.lat > pc.lat) {
+                this.features[2].style.rotation = rot + 180;
+            } else {
+                this.features[2].style.rotation = rot;
+            }
+        }
+
+        // Redraws
+        this.earthLayer.addFeatures(this.features);
+    }
+});
+
+Ext.reg('gxux_googleearthpanel', GeoExt.ux.GoogleEarthPanel);
\ No newline at end of file



More information about the Commits mailing list