[OpenLayers-Commits] r11258 - in trunk/openlayers: examples lib lib/OpenLayers/Control tests tests/Control

commits-20090109 at openlayers.org commits-20090109 at openlayers.org
Tue Feb 22 11:48:05 EST 2011


Author: erilem
Date: 2011-02-22 08:48:05 -0800 (Tue, 22 Feb 2011)
New Revision: 11258

Added:
   trunk/openlayers/examples/geolocation.html
   trunk/openlayers/lib/OpenLayers/Control/Geolocate.js
   trunk/openlayers/tests/Control/Geolocate.html
Modified:
   trunk/openlayers/lib/OpenLayers.js
   trunk/openlayers/tests/list-tests.html
Log:
add a Geolocate control, p=cmoullet,aabt, r=me (closes #1885)

Added: trunk/openlayers/examples/geolocation.html
===================================================================
--- trunk/openlayers/examples/geolocation.html	                        (rev 0)
+++ trunk/openlayers/examples/geolocation.html	2011-02-22 16:48:05 UTC (rev 11258)
@@ -0,0 +1,109 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+    <head>
+        <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" />
+        <meta name="apple-mobile-web-app-capable" content="yes" />
+        <title>OpenLayers Geolocation</title>
+
+        <link rel="stylesheet" href="../theme/default/style.css" type="text/css" />
+        <link rel="stylesheet" href="style.css" type="text/css" />
+        <script src="../lib/OpenLayers.js"></script>
+        <script type="text/javascript">
+            var map, layer, vector, watchId;
+            function init(){
+                var style = {
+                    fillOpacity: 0.1,
+                    fillColor: '#000',
+                    strokeColor: '#f00',
+                    strokeOpacity: 0.6
+                }
+
+                map = new OpenLayers.Map('map');
+                layer = new OpenLayers.Layer.OSM( "Simple OSM Map");
+                vector = new OpenLayers.Layer.Vector('vector');
+                map.addLayers([layer, vector]);
+
+                map.setCenter(
+                    new OpenLayers.LonLat(-71.147, 42.472).transform(
+                        new OpenLayers.Projection("EPSG:4326"),
+                        map.getProjectionObject()
+                    ), 12
+                );
+
+                var geolocate = new OpenLayers.Control.Geolocate({
+                    geolocationOptions: {
+                        enableHighAccuracy: false,
+                        maximumAge: 0,
+                        timeout: 7000
+                    }
+                });
+                map.addControl(geolocate);
+                geolocate.events.register("locationupdated",this,function(e) {
+                    vector.removeAllFeatures();
+                    vector.addFeatures([
+                        new OpenLayers.Feature.Vector(
+                            e.point,
+                            {},
+                            {
+                                graphicName: 'cross',
+                                strokeColor: '#f00',
+                                strokeWidth: 2,
+                                fillOpacity: 0,
+                                pointRadius: 10
+                            }
+                        ),
+                        new OpenLayers.Feature.Vector(
+                            OpenLayers.Geometry.Polygon.createRegularPolygon(
+                                new OpenLayers.Geometry.Point(e.point.x, e.point.y),
+                                e.position.coords.accuracy/2,
+                                50,
+                                0
+                            ),
+                            {},
+                            style
+                        )
+                    ]);
+                    map.zoomToExtent(vector.getDataExtent());
+                });
+                geolocate.events.register("locationfailed",this,function() {
+                    console.log('Location detection failed');
+                });
+                window.geolocate = geolocate;
+
+                $('locate').onclick = function() {
+                    geolocate.deactivate();
+                    $('track').checked = false;
+                    geolocate.watch = false;
+                    geolocate.activate();
+                };
+                $('track').onclick = function() {
+                    geolocate.deactivate();
+                    if (this.checked) {
+                        geolocate.watch = true;
+                        geolocate.activate();
+                    }
+                };
+            }
+        </script>
+    </head>
+    <body onload="init()">
+        <h1 id="title">Geolocation Example</h1>
+
+        <div id="tags">
+            geolocation, geolocate, mobile
+        </div>
+
+        <p id="shortdesc">
+            Track  current position and display it with its accuracy.
+        </p>
+
+        <div id="map" class="smallmap"></div>
+
+        <div id="docs">
+            <button id="locate">Locate me!</button>
+            <label>
+                <input type="checkbox" name="track" id="track" />
+                Track my position
+            </label>&nbsp;
+        </div>
+    </body>
+</html>

Added: trunk/openlayers/lib/OpenLayers/Control/Geolocate.js
===================================================================
--- trunk/openlayers/lib/OpenLayers/Control/Geolocate.js	                        (rev 0)
+++ trunk/openlayers/lib/OpenLayers/Control/Geolocate.js	2011-02-22 16:48:05 UTC (rev 11258)
@@ -0,0 +1,158 @@
+/* Copyright (c) 2006-2011 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
+
+/**
+ * @requires OpenLayers/Control.js
+ * @requires OpenLayers/Geometry/Point.js
+ * @requires OpenLayers/Projection.js
+ */
+
+/**
+ * Class: OpenLayers.Control.Geolocate
+ * The Geolocate control wraps w3c geolocation API into control that can be
+ * bound to a map, and generate events on location update
+ *
+ * To use this control requires to load the proj4js library if the projection
+ * of the map is not EPSG:4326 or EPSG:900913.
+ *
+ * Inherits from:
+ *  - <OpenLayers.Control>
+ */
+OpenLayers.Control.Geolocate = OpenLayers.Class(OpenLayers.Control, {
+
+    /**
+     * Constant: EVENT_TYPES
+     * Supported event types:
+     *  - *locationupdated* Triggered when browser return a new position
+     *  - *locationfailed* Triggered when geolocation has failed
+     *  - *locationuncapable* Triggered when control is activated on a browser
+     *  which doesn't support geolocation
+     */
+    EVENT_TYPES: ["locationupdated", "locationfailed", "locationuncapable"],
+
+    /**
+     * Property: geolocation
+     * {Object} The geolocation engine, as a property to be possibly mocked.
+     */
+    geolocation: navigator.geolocation,
+
+    /**
+     * APIProperty: bind
+     * {Boolean} If true, map center will be set on location update.
+     */
+    bind: true,
+
+    /**
+     * APIProperty: watch
+     * {Boolean} If true, position will be update regularly.
+     */
+    watch: false,
+
+    /**
+     * APIProperty: geolocationOptions
+     * {Object} Options to pass to the navigator's geolocation API. See
+     *     <http://dev.w3.org/geo/api/spec-source.html>. No specific
+     *     option is passed to the geolocation API by default.
+     */
+    geolocationOptions: null,
+
+    /**
+     * Constructor: OpenLayers.Control.Geolocate
+     * Create a new control to deal with browser geolocation API
+     *
+     */
+    initialize: function(options) {
+        // concatenate events specific to this control with those from the base
+        this.EVENT_TYPES =
+            OpenLayers.Control.Geolocate.prototype.EVENT_TYPES.concat(
+            OpenLayers.Control.prototype.EVENT_TYPES
+        );
+        this.geolocationOptions = {};
+        OpenLayers.Control.prototype.initialize.apply(this, [options]);
+    },
+
+    /**
+     * Method: activate
+     * Activates the control.
+     *
+     * Returns:
+     * {Boolean} The control was effectively activated.
+     */
+    activate: function () {
+        if (!this.geolocation) {
+            this.events.triggerEvent("locationuncapable");
+            return false;
+        }
+        if (!this.active) {
+            if (this.watch) {
+                this.watchId = this.geolocation.watchPosition(
+                    OpenLayers.Function.bind(this.geolocate, this),
+                    OpenLayers.Function.bind(this.failure, this),
+                    this.geolocationOptions
+                );
+            } else {
+                this.geolocation.getCurrentPosition(
+                    OpenLayers.Function.bind(this.geolocate, this),
+                    OpenLayers.Function.bind(this.failure, this),
+                    this.geolocationOptions
+                );
+            }
+        }
+        return OpenLayers.Control.prototype.activate.apply(
+            this, arguments
+        );
+    },
+
+    /**
+     * Method: deactivate
+     * Deactivates the control.
+     *
+     * Returns:
+     * {Boolean} The control was effectively deactivated.
+     */
+    deactivate: function () {
+        if (this.active && this.watchId !== null) {
+            this.geolocation.clearWatch(this.watchId);
+        }
+        return OpenLayers.Control.prototype.deactivate.apply(
+            this, arguments
+        );
+    },
+
+    /**
+     * Method: geolocate
+     * Activates the control.
+     *
+     */
+    geolocate: function (position) {
+        var center = new OpenLayers.LonLat(
+            position.coords.longitude,
+            position.coords.latitude
+        ).transform(
+            new OpenLayers.Projection("EPSG:4326"),
+            this.map.getProjectionObject()
+        );
+        if (this.bind) {
+            this.map.setCenter(center);
+        }
+        this.events.triggerEvent("locationupdated", {
+            position: position,
+            point: new OpenLayers.Geometry.Point(
+                center.lon, center.lat
+            )
+        });
+    },
+
+    /**
+     * Method: failure
+     * method called on browser's geolocation failure
+     *
+     */
+    failure: function (error) {
+        this.events.triggerEvent("locationfailed", {error: error});
+    },
+
+    CLASS_NAME: "OpenLayers.Control.Geolocate"
+});

Modified: trunk/openlayers/lib/OpenLayers.js
===================================================================
--- trunk/openlayers/lib/OpenLayers.js	2011-02-22 16:42:30 UTC (rev 11257)
+++ trunk/openlayers/lib/OpenLayers.js	2011-02-22 16:48:05 UTC (rev 11258)
@@ -331,6 +331,7 @@
                 "OpenLayers/Control/ZoomOut.js",
                 "OpenLayers/Control/ZoomPanel.js",
                 "OpenLayers/Control/EditingToolbar.js",
+                "OpenLayers/Control/Geolocate.js",
                 "OpenLayers/Symbolizer.js",
                 "OpenLayers/Symbolizer/Point.js",
                 "OpenLayers/Symbolizer/Line.js",

Added: trunk/openlayers/tests/Control/Geolocate.html
===================================================================
--- trunk/openlayers/tests/Control/Geolocate.html	                        (rev 0)
+++ trunk/openlayers/tests/Control/Geolocate.html	2011-02-22 16:48:05 UTC (rev 11258)
@@ -0,0 +1,105 @@
+<html>
+<head>
+  <script src="../../lib/OpenLayers.js"></script>
+  <script type="text/javascript">
+    var map, control, centerLL
+        watch = null,
+        geolocation= {
+            getCurrentPosition: function(f) {
+                f({
+                    coords: { latitude: 10, longitude: 10 }
+                });
+            },
+            watchPosition: function(f) {
+                watch = true;
+            },
+            clearWatch: function() {
+                watch = null;
+            }
+        };
+
+    function test_initialize(t) {
+        t.plan(3);
+        control = new OpenLayers.Control.Geolocate({geolocationOptions: {foo: 'bar'}});
+        t.ok(control instanceof OpenLayers.Control.Geolocate,
+             "new OpenLayers.Control returns object" );
+        t.eq(control.displayClass, "olControlGeolocate", "displayClass is correct" );
+        t.eq(control.geolocationOptions.foo, 'bar',
+             'provided geolocation options are set in the geolocationOptions prop');
+    }
+    function test_bind(t) {
+        t.plan(3);
+        var control = new OpenLayers.Control.Geolocate({
+            geolocation: geolocation
+        });
+        control.events.register('locationupdated', null, function() {
+            t.ok(true, 'locationupdated event is fired when bound');
+        });
+        map.addControl(control);
+        control.activate();
+        var center = map.getCenter();
+        t.eq(center.lon, 10, 'bound control sets the map lon');
+        t.eq(center.lat, 10, 'bound control sets the map lat');
+        control.deactivate();
+        map.removeControl(control);
+        map.setCenter(centerLL);
+    }
+    function test_unbind(t) {
+        t.plan(3);
+        var control = new OpenLayers.Control.Geolocate({
+            geolocation: geolocation,
+            bind: false
+        });
+        control.events.register('locationupdated', null, function() {
+            t.ok(true, 'locationupdated event is fired when unbound');
+        });
+        map.addControl(control);
+        control.activate();
+        var center = map.getCenter();
+        t.eq(center.lon, 0, 'unbound control doesnt sets the map lon');
+        t.eq(center.lat, 0, 'unbound control doesnt sets the map lat');
+        control.deactivate();
+        map.removeControl(control);
+        map.setCenter(centerLL);
+    }
+    function test_watch(t) {
+        t.plan(2);
+        var control = new OpenLayers.Control.Geolocate({
+            geolocation: geolocation,
+            watch: true
+        });
+        map.addControl(control);
+        control.activate();
+        t.eq(watch, true, 'watch option makes calls to watchPosition');
+        control.deactivate();
+        t.eq(watch, null, 'deactivate control calls the clearwatch');
+        map.removeControl(control);
+        map.setCenter(centerLL);
+    }
+    function test_uncapable(t) {
+        t.plan(1);
+        var control = new OpenLayers.Control.Geolocate({
+            geolocation: null,
+            bind: false
+        });
+        control.events.register('locationuncapable', null, function() {
+            t.ok(true,'uncapable browser fired locationuncapable event');
+        });
+        map.addControl(control);
+        control.activate();
+    }
+    function loader() {
+        map = new OpenLayers.Map('map');
+        var layer = new OpenLayers.Layer.WMS("Test Layer",
+            "http://labs.metacarta.com/wms-c/Basic.py?",
+            {layers: "basic"});
+        map.addLayer(layer);
+        centerLL = new OpenLayers.LonLat(0,0);
+        map.setCenter(centerLL, 5);
+    }
+  </script>
+</head>
+<body onload="loader()">
+    <div id="map" style="width: 256px; height: 256px;"/>
+</body>
+</html>

Modified: trunk/openlayers/tests/list-tests.html
===================================================================
--- trunk/openlayers/tests/list-tests.html	2011-02-22 16:42:30 UTC (rev 11257)
+++ trunk/openlayers/tests/list-tests.html	2011-02-22 16:48:05 UTC (rev 11258)
@@ -15,6 +15,7 @@
     <li>Control/DragFeature.html</li>
     <li>Control/DragPan.html</li>
     <li>Control/DrawFeature.html</li>
+    <li>Control/Geolocate.html</li>
     <li>Control/GetFeature.html</li>
     <li>Control/Graticule.html</li>
     <li>Control/KeyboardDefaults.html</li>



More information about the Commits mailing list