Merge branch 'master' into validation

This commit is contained in:
Quincy Morgan
2018-12-19 13:23:54 -05:00
5 changed files with 168 additions and 11 deletions
+137
View File
@@ -0,0 +1,137 @@
import { select as d3_select } from 'd3-selection';
import { svgPointTransform } from './helpers';
import { geoMetersToLat } from '../geo';
import _throttle from 'lodash-es/throttle';
export function svgGeolocate(projection, context, dispatch) {
var layer = d3_select(null);
var _position;
function init() {
if (svgGeolocate.initialized) return; // run once
svgGeolocate.enabled = false;
svgGeolocate.initialized = true;
}
function showLayer() {
layer.style('display', 'block');
}
function hideLayer() {
layer
.transition()
.duration(250)
.style('opacity', 0);
}
function layerOn() {
layer
.style('opacity', 0)
.transition()
.duration(250)
.style('opacity', 1);
}
function layerOff() {
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]]);
// southern most point will have higher pixel value...
return Math.round(projectedLoc[1] - projectedTangent[1]).toString();
}
function update() {
var geolocation = { loc: [_position.coords.longitude, _position.coords.latitude] };
var groups = layer.selectAll('.geolocations').selectAll('.geolocation')
.data([geolocation]);
groups.exit()
.remove();
var pointsEnter = groups.enter()
.append('g')
.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', accuracy(_position.coords.accuracy, geolocation.loc));
}
function drawLocation(selection) {
var enabled = svgGeolocate.enabled;
layer = selection.selectAll('.layer-geolocate')
.data([0]);
layer.exit()
.remove();
var layerEnter = layer.enter()
.append('g')
.attr('class', 'layer-geolocate')
.style('display', enabled ? 'block' : 'none');
layerEnter
.append('g')
.attr('class', 'geolocations');
layer = layerEnter
.merge(layer);
if (enabled) {
update();
} else {
layerOff();
}
}
drawLocation.enabled = function (position, enabled) {
if (!arguments.length) return svgGeolocate.enabled;
_position = position;
svgGeolocate.enabled = enabled;
if (svgGeolocate.enabled) {
showLayer();
layerOn();
} else {
hideLayer();
}
return this;
};
init();
return drawLocation;
}
+1
View File
@@ -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';
+2
View File
@@ -9,6 +9,7 @@ import { select as d3_select } from 'd3-selection';
import { svgData } from './data';
import { svgDebug } from './debug';
import { svgGeolocate } from './geolocate';
import { svgStreetside } from './streetside';
import { svgMapillaryImages } from './mapillary_images';
import { svgMapillarySigns } from './mapillary_signs';
@@ -32,6 +33,7 @@ export function svgLayers(projection, context) {
{ id: 'mapillary-signs', layer: svgMapillarySigns(projection, context, dispatch) },
{ id: 'openstreetcam-images', layer: svgOpenstreetcamImages(projection, context, dispatch) },
{ id: 'debug', layer: svgDebug(projection, context, dispatch) },
{ id: 'geolocate', layer: svgGeolocate(projection, context, dispatch) },
{ id: 'touch', layer: svgTouch(projection, context, dispatch) }
];
+25 -9
View File
@@ -9,27 +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 success(position) {
var map = context.map(),
extent = geoExtent([position.coords.longitude, position.coords.latitude])
.padByMeters(position.coords.accuracy);
function zoomTo() {
var map = context.map();
layer.enabled(position, true);
map.centerZoom(extent.center(), Math.min(20, map.extentZoom(extent)));
}
function success(geolocation) {
position = geolocation;
extent = geoExtent([position.coords.longitude, position.coords.latitude])
.padByMeters(position.coords.accuracy);
zoomTo();
finish();
}
+3 -2
View File
@@ -26,7 +26,7 @@ describe('iD.svgLayers', function () {
it('creates default data layers', function () {
container.call(iD.svgLayers(projection, context));
var nodes = container.selectAll('svg .data-layer').nodes();
expect(nodes.length).to.eql(9);
expect(nodes.length).to.eql(10);
expect(d3.select(nodes[0]).classed('osm')).to.be.true;
expect(d3.select(nodes[1]).classed('notes')).to.be.true;
expect(d3.select(nodes[2]).classed('data')).to.be.true;
@@ -35,7 +35,8 @@ describe('iD.svgLayers', function () {
expect(d3.select(nodes[5]).classed('mapillary-signs')).to.be.true;
expect(d3.select(nodes[6]).classed('openstreetcam-images')).to.be.true;
expect(d3.select(nodes[7]).classed('debug')).to.be.true;
expect(d3.select(nodes[8]).classed('touch')).to.be.true;
expect(d3.select(nodes[8]).classed('geolocate')).to.be.true;
expect(d3.select(nodes[9]).classed('touch')).to.be.true;
});
});