Skip to content

Commit

Permalink
implement point/puck geolocation
Browse files Browse the repository at this point in the history
ref #5587
  • Loading branch information
maxgrossman committed Dec 19, 2018
1 parent b7f0d86 commit b9ddfca
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 39 deletions.
88 changes: 61 additions & 27 deletions modules/svg/geolocate.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
import { svgPointTransform } from "./helpers";
import { select as d3_select } from 'd3-selection';

import { svgPointTransform } from './helpers';
import { geoMetersToLat } from '../geo';
import {
geoIdentity as d3_geoIdentity,
geoPath as d3_geoPath,
geoStream as d3_geoStream
} from 'd3-geo';
import _throttle from 'lodash-es/throttle';

export function svgGeolocate(projection, context, dispatch) {
var throttledRedraw = _throttle(function () { dispatch.call('change'); }, 1000);
Expand All @@ -14,8 +23,7 @@ export function svgGeolocate(projection, context, dispatch) {
}

function showLayer() {
layer.attr('display', 'block');
layerOn();
layer.style('display', 'block');
}


Expand All @@ -25,89 +33,115 @@ export function svgGeolocate(projection, context, dispatch) {
.transition()
.duration(250)
.style('opacity', 0)
.on('end', function() {});
.on('end', function () { });
}

function layerOn() {
layer
.style('opacity', 0)
.transition()
.duration(250)
.style('opacity', 1)
.on('end', function () { dispatch.call('change'); });
.style('opacity', 1);

}

function layerOff() {
// layer.selectAll('.viewfield-group').remove();
layer.style('display', 'none');
}

function transform(d) {
return svgPointTransform(projection)(d);
}


function accuracy(accuracy, loc) { // converts accuracy to pixels...
var degreesRadius = geoMetersToLat(accuracy),
tangentLoc = [loc[0], loc[1] + degreesRadius],
projectedTangent = projection(tangentLoc),
projectedLoc = projection([loc[0], loc[1]]);

return Math.round(projectedLoc[1] - projectedTangent[1]).toString(); // more south point will have higher pixel value...
}

function update() {
var points = layer.selectAll('.geolocations').selectAll('.geolocation')
.data([_position]);

var geolocation = { loc: [_position.coords.longitude, _position.coords.latitude] },
pixelAccuracy = accuracy(_position.coords.accuracy, geolocation.loc);

var groups = layer.selectAll('.geolocations').selectAll('.geolocation')
.data([geolocation]);

groups.exit()
.remove();

points.enter()
var pointsEnter = groups.enter()
.append('g')
.attr('class', 'point')
.attr('class', 'geolocation');

pointsEnter
.append('circle')
.attr('id', 'geolocate-radius')
.attr('dx', '0')
.attr('dy', '0')
.attr('fill', 'rgb(15,128,225)')
.attr('fill-opacity', '0.3')
.attr('r', '0');

pointsEnter
.append('circle')
.attr('dx', '0')
.attr('dy', '0')
.attr('fill', 'rgb(15,128,225)')
.attr('stroke', 'white')
.attr('stroke-width', '1.5')
.attr('r', '6');

groups.merge(pointsEnter)
.attr('transform', transform);

d3_select('#geolocate-radius').attr('r', pixelAccuracy)
}

function drawLocation(selection) {
var enabled = svgGeolocate.enabled;

layer = selection.selectAll('.layer-geolocate')
.data([]);
.data([0]);

layer.exit()
.remove();

var layerEnter = layer.enter()
.append('g')
.attr('class', 'layer-geolocation')
.attr('class', 'layer-geolocate')
.style('display', enabled ? 'block' : 'none');

layerEnter
.append('g')
.attr('class', 'geolocations');

layerEnter
.append('g')
.attr('class', 'radius');

layer = layerEnter
.merge(layer);

if (enabled) {
layerOn();
update();
} else {
layerOff();
}
}

drawLocation.enabled = function(_) {
drawLocation.enabled = function (position, enabled) {
if (!arguments.length) return svgGeolocate.enabled;
_position = _;
svgGeolocate.enabled = true;
_position = position;
svgGeolocate.enabled = enabled;
if (svgGeolocate.enabled) {
showLayer();
update();
layerOn();
} else {
hideLayer();
}
dispatch.call('change');
// dispatch.call('change');
return this;
};



init();
return drawLocation;
}
1 change: 1 addition & 0 deletions modules/svg/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export { svgData } from './data.js';
export { svgDebug } from './debug.js';
export { svgDefs } from './defs.js';
export { svgIcon } from './icon.js';
export { svgGeolocate } from './geolocate';
export { svgLabels } from './labels.js';
export { svgLayers } from './layers.js';
export { svgLines } from './lines.js';
Expand Down
35 changes: 23 additions & 12 deletions modules/ui/geolocate.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,43 @@ import { uiLoading } from './loading';
export function uiGeolocate(context) {
var geoOptions = { enableHighAccuracy: false, timeout: 6000 /* 6sec */ },
locating = uiLoading(context).message(t('geolocate.locating')).blocking(true),
layer = context.layers().layer('geolocate'),
position,
extent,
timeoutId;


function click() {
if (context.inIntro()) return;
context.enter(modeBrowse(context));
context.container().call(locating);
navigator.geolocation.getCurrentPosition(success, error, geoOptions);

if (!layer.enabled()) {
if (!position) {
context.container().call(locating);
navigator.geolocation.getCurrentPosition(success, error, geoOptions);
} else {
zoomTo();
}
} else {
layer.enabled(null, false);
}
// This timeout ensures that we still call finish() even if
// the user declines to share their location in Firefox
timeoutId = setTimeout(finish, 10000 /* 10sec */ );
}

function zoomTo() {
var map = context.map();
layer.enabled(position, true);
map.centerZoom(extent.center(), Math.min(20, map.extentZoom(extent)));
}

function success(position) {
var location = { loc: [position.coords.longitude, position.coords.latitude] },
layer = context.layers().layer('geolocate');

layer.enabled(location);

var map = context.map(),
extent = geoExtent([position.coords.longitude, position.coords.latitude])
.padByMeters(position.coords.accuracy);
function success(geolocation) {
position = geolocation;
extent = geoExtent([position.coords.longitude, position.coords.latitude])
.padByMeters(position.coords.accuracy);

map.centerZoom(extent.center(), Math.min(20, map.extentZoom(extent)));
zoomTo();
finish();
}

Expand Down

0 comments on commit b9ddfca

Please sign in to comment.