aboutsummaryrefslogtreecommitdiffstats
path: root/web/js/map-OpenLayers.js
diff options
context:
space:
mode:
authorDave Arter <davea@mysociety.org>2019-12-16 17:31:41 +0000
committerDave Arter <davea@mysociety.org>2020-01-08 13:58:13 +0000
commit88ad6b00dfc050db1ba5ae9bf14b900382cd24a7 (patch)
treee6c30019af765b4492b796887a1c4c5dd76760dd /web/js/map-OpenLayers.js
parente04a1f81b0e532e227aa0237a1d7c629f13e6897 (diff)
Display GPS marker on /around & /report/new if geolocate link used
Attempts to allow for CSS animations by not destroying the marker's DOM element each time a location update is received - with limited success.
Diffstat (limited to 'web/js/map-OpenLayers.js')
-rw-r--r--web/js/map-OpenLayers.js94
1 files changed, 94 insertions, 0 deletions
diff --git a/web/js/map-OpenLayers.js b/web/js/map-OpenLayers.js
index eb62904b0..7781d845b 100644
--- a/web/js/map-OpenLayers.js
+++ b/web/js/map-OpenLayers.js
@@ -375,6 +375,96 @@ $.extend(fixmystreet.utils, {
new OpenLayers.LonLat( state.lon, state.lat ),
state.zoom
);
+ },
+
+ setup_geolocation: function() {
+ if (!OpenLayers.Control.Geolocate || !fixmystreet.map ||
+ !fixmystreet.utils || !fixmystreet.utils.parse_query_string ||
+ fixmystreet.utils.parse_query_string().geolocate !== '1'
+ ) {
+ return;
+ }
+
+ var layer;
+
+ function createCircleOfUncertainty(e) {
+ var loc = new OpenLayers.Geometry.Point(e.point.x, e.point.y);
+ return new OpenLayers.Feature.Vector(
+ OpenLayers.Geometry.Polygon.createRegularPolygon(
+ loc,
+ e.position.coords.accuracy,
+ 40,
+ 0
+ ),
+ {},
+ {
+ fillColor: '#0074FF',
+ fillOpacity: 0.3,
+ strokeWidth: 0
+ }
+ );
+ }
+ function addGeolocationLayer(e) {
+ layer = new OpenLayers.Layer.Vector('Geolocation');
+ fixmystreet.map.addLayer(layer);
+ layer.setZIndex(fixmystreet.map.getLayersByName("Pins")[0].getZIndex() - 1);
+ var marker = new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Point(e.point.x, e.point.y),
+ {
+ marker: true
+ },
+ {
+ graphicName: 'circle',
+ strokeColor: '#fff',
+ strokeWidth: 4,
+ fillColor: '#0074FF',
+ fillOpacity: 1,
+ pointRadius: 10
+ }
+ );
+ layer.addFeatures([ createCircleOfUncertainty(e), marker ]);
+ }
+
+ function updateGeolocationMarker(e) {
+ if (!layer) {
+ addGeolocationLayer(e);
+ } else {
+ // Reuse the existing circle marker so its DOM element (and
+ // hopefully CSS animation) is preserved.
+ var marker = layer.getFeaturesByAttribute('marker', true)[0];
+ // Can't reuse the background circle feature as there seems to
+ // be no easy way to replace its geometry with a new
+ // circle sized according to this location update's accuracy.
+ // Instead recreate the feature from scratch.
+ var uncertainty = createCircleOfUncertainty(e);
+ // Because we're replacing the accuracy circle, it needs to be
+ // rendered underneath the location marker. In order to do this
+ // we have to remove all features and re-add, as simply removing
+ // and re-adding one feature will always render it on top of others.
+ layer.removeAllFeatures();
+ layer.addFeatures([ uncertainty, marker ]);
+
+ // NB The above still breaks CSS animation because the marker
+ // was removed from the DOM and re-added. We could leave the
+ // marker alone and just remove the uncertainty circle
+ // feature, re-add it as a new feature and then manually shift
+ // its position in the DOM by getting its element's ID from
+ // uncertainty.geometry.id and moving it before the <circle>
+ // element.
+
+ // Don't forget to update the position of the GPS marker.
+ marker.move(new OpenLayers.LonLat(e.point.x, e.point.y));
+ }
+ }
+
+ var control = new OpenLayers.Control.Geolocate({
+ bind: false, // Don't want the map to pan to each location
+ watch: true,
+ enableHighAccuracy: true
+ });
+ control.events.register("locationupdated", null, updateGeolocationMarker);
+ fixmystreet.map.addControl(control);
+ control.activate();
}
});
@@ -787,6 +877,10 @@ $.extend(fixmystreet.utils, {
setup_inspector_marker_drag();
}
+ if (fixmystreet.page == "around" || fixmystreet.page == "new") {
+ fixmystreet.maps.setup_geolocation();
+ }
+
if ( fixmystreet.zoomToBounds ) {
zoomToBounds( fixmystreet.markers.getDataExtent() );
}