Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add circle to GeolocateControl showing accuracy of position #9181

Closed
wants to merge 46 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
8d05a1d
add circle to GeolocateControl showing accuracy of position
Meekohi Jan 14, 2020
d93e091
number not Number for typechecks
Meekohi Jan 14, 2020
d694f36
looks slightly better with the circle underneath
Meekohi Jan 14, 2020
b290bce
clarify div id
Meekohi Jan 15, 2020
d13e371
clarify div id
Meekohi Jan 15, 2020
036c2e0
onZoom not onMove
Meekohi Jan 15, 2020
f77d16d
docs
Meekohi Jan 15, 2020
e1980e3
Update package version to 1.8.0-dev (#9190)
ahk Jan 15, 2020
b2c4b04
Prefer line-pattern over line-dasharray in accordance with documentat…
kkaefer Jan 15, 2020
a5ab875
rename, extra safety checks
Meekohi Jan 15, 2020
85a11c8
a test
Meekohi Jan 15, 2020
d915500
test for showAccuracy toggle
Meekohi Jan 15, 2020
bbcfbe5
typo
Meekohi Jan 15, 2020
954bb99
pitch with map
Meekohi Jan 15, 2020
ff03457
Remove Object.values usage that was causing IE11 to fail (#9193)
Jan 16, 2020
51d75fc
LOD support for tile coverage (#8975)
mpulkki-mapbox Jan 17, 2020
2af4c8b
pull updateCircle back into GeolocateControl
Meekohi Jan 17, 2020
87f3393
fix promoteId spec definitions (#9212)
mourner Jan 21, 2020
a13efc0
upgrade earcut to v2.2.2 (#9214)
mourner Jan 21, 2020
28603d1
Fix promoteId for line layers (#9210)
mourner Jan 22, 2020
980d1fb
Fix line distances breaking gradient across tile boundaries (#9220)
karimnaaji Jan 23, 2020
b7e8fb3
Update image expression SDK support table (#9228)
Jan 24, 2020
8cd474e
Refactor style._load function, move sprite loading to a private metho…
webdeb Jan 24, 2020
8c9ace1
[tests][tile mode] Add left-top-right-buttom-offset-tile-map-mode test
pozdnyakov Jan 27, 2020
be4f189
Reduce size of line atlas by removing unused channels (#9232)
karimnaaji Jan 27, 2020
99bfc7f
Fix a bug where lines with duplicate endpoint disappear on z18+ (#9218)
mourner Jan 27, 2020
77cfc5c
Canonicalize Mapbox tile URLs from inline TileJSON as well (#9217)
kkaefer Jan 28, 2020
1eed2ae
Hide glyphs behind the camera (#9229)
mpulkki-mapbox Jan 29, 2020
fa59cf3
Prevent empty buffers from being created for debug data (#9237)
karimnaaji Jan 30, 2020
5d8ef1a
refactor LngLat distance calculations (#9202)
Meekohi Jan 31, 2020
03c4339
add circle to GeolocateControl showing accuracy of position
Meekohi Jan 14, 2020
3574318
number not Number for typechecks
Meekohi Jan 14, 2020
1f76684
looks slightly better with the circle underneath
Meekohi Jan 14, 2020
b3ed503
clarify div id
Meekohi Jan 15, 2020
ae8bd00
clarify div id
Meekohi Jan 15, 2020
d8a5e0d
onZoom not onMove
Meekohi Jan 15, 2020
e2da6ab
docs
Meekohi Jan 15, 2020
0c45a27
rename, extra safety checks
Meekohi Jan 15, 2020
5fd231f
a test
Meekohi Jan 15, 2020
412d257
test for showAccuracy toggle
Meekohi Jan 15, 2020
790732a
typo
Meekohi Jan 15, 2020
64e8312
pitch with map
Meekohi Jan 15, 2020
125c623
pull updateCircle back into GeolocateControl
Meekohi Jan 17, 2020
b1a67c6
Merge branch 'master' of github.com:Meekohi/mapbox-gl-js
Meekohi Jan 31, 2020
6f7f2ef
refactor distance calculations
Meekohi Jan 31, 2020
136a291
rename param and better docs
Meekohi Jan 31, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "mapbox-gl",
"description": "A WebGL interactive maps library",
"version": "1.7.0-dev",
"version": "1.8.0-dev",
"main": "dist/mapbox-gl.js",
"style": "dist/mapbox-gl.css",
"license": "SEE LICENSE IN LICENSE.txt",
Expand All @@ -23,7 +23,7 @@
"@mapbox/vector-tile": "^1.3.1",
"@mapbox/whoots-js": "^3.1.0",
"csscolorparser": "~1.0.2",
"earcut": "^2.2.0",
"earcut": "^2.2.2",
"geojson-vt": "^3.2.1",
"gl-matrix": "^3.0.0",
"grid-index": "^1.1.0",
Expand Down
7 changes: 7 additions & 0 deletions src/css/mapbox-gl.css
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,13 @@ a.mapboxgl-ctrl-logo.mapboxgl-compact {
display: none;
}

.mapboxgl-user-location-accuracy-circle {
background-color: #1da1f233;
width: 1px;
height: 1px;
border-radius: 100%;
}

.mapboxgl-crosshair,
.mapboxgl-crosshair .mapboxgl-interactive,
.mapboxgl-crosshair .mapboxgl-interactive:active {
Expand Down
18 changes: 11 additions & 7 deletions src/data/bucket/line_bucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ class LineBucket implements Bucket {
const lineSortKey = this.layers[0].layout.get('line-sort-key');
const bucketFeatures = [];

for (const {feature, index, sourceLayerIndex} of features) {
for (const {feature, id, index, sourceLayerIndex} of features) {
if (!this.layers[0]._featureFilter(new EvaluationParameters(this.zoom), feature)) continue;

const geometry = loadGeometry(feature);
Expand All @@ -130,7 +130,7 @@ class LineBucket implements Bucket {
undefined;

const bucketFeature: BucketFeature = {
id: feature.id,
id,
properties: feature.properties,
type: feature.type,
sourceLayerIndex,
Expand Down Expand Up @@ -231,6 +231,7 @@ class LineBucket implements Bucket {
for (let i = 0; i < vertices.length - 1; i++) {
this.totalDistance += vertices[i].dist(vertices[i + 1]);
}
this.updateScaledDistance();
}

const isPolygon = vectorTileFeatureTypes[feature.type] === 'Polygon';
Expand Down Expand Up @@ -273,8 +274,8 @@ class LineBucket implements Bucket {

for (let i = first; i < len; i++) {

nextVertex = isPolygon && i === len - 1 ?
vertices[first + 1] : // if the line is closed, we treat the last vertex like the first
nextVertex = i === len - 1 ?
(isPolygon ? vertices[first + 1] : (undefined: any)) : // if it's a polygon, treat the last vertex like the first
vertices[i + 1]; // just the next vertex

// if two consecutive vertices exist, skip the current one
Expand Down Expand Up @@ -526,9 +527,7 @@ class LineBucket implements Bucket {
}
}

updateDistance(prev: Point, next: Point) {
this.distance += prev.dist(next);

updateScaledDistance() {
// Knowing the ratio of the full linestring covered by this tiled feature, as well
// as the total distance (in tile units) of this tiled feature, and the distance
// (in tile units) of the current vertex, we can determine the relative distance
Expand All @@ -537,6 +536,11 @@ class LineBucket implements Bucket {
(this.clipStart + (this.clipEnd - this.clipStart) * this.distance / this.totalDistance) * (MAX_LINE_DISTANCE - 1) :
this.distance;
}

updateDistance(prev: Point, next: Point) {
this.distance += prev.dist(next);
this.updateScaledDistance();
}
}

register('LineBucket', LineBucket, {omit: ['layers', 'patternFeatures']});
Expand Down
52 changes: 39 additions & 13 deletions src/data/bucket/symbol_bucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,18 @@ export class SymbolBuffers {
this.placedSymbolArray = new PlacedSymbolArray();
}

isEmpty() {
return this.layoutVertexArray.length === 0 &&
this.indexArray.length === 0 &&
this.dynamicLayoutVertexArray.length === 0 &&
this.opacityVertexArray.length === 0;
}

upload(context: Context, dynamicIndexBuffer: boolean, upload?: boolean, update?: boolean) {
if (this.isEmpty()) {
return;
}

if (upload) {
this.layoutVertexBuffer = context.createVertexBuffer(this.layoutVertexArray, symbolLayoutAttributes.members);
this.indexBuffer = context.createIndexBuffer(this.indexArray, dynamicIndexBuffer);
Expand Down Expand Up @@ -376,11 +387,6 @@ class SymbolBucket implements Bucket {
this.text = new SymbolBuffers(new ProgramConfigurationSet(symbolLayoutAttributes.members, this.layers, this.zoom, property => /^text/.test(property)));
this.icon = new SymbolBuffers(new ProgramConfigurationSet(symbolLayoutAttributes.members, this.layers, this.zoom, property => /^icon/.test(property)));

this.textCollisionBox = new CollisionBuffers(CollisionBoxLayoutArray, collisionBoxLayout.members, LineIndexArray);
this.iconCollisionBox = new CollisionBuffers(CollisionBoxLayoutArray, collisionBoxLayout.members, LineIndexArray);
this.textCollisionCircle = new CollisionBuffers(CollisionCircleLayoutArray, collisionCircleLayout.members, TriangleIndexArray);
this.iconCollisionCircle = new CollisionBuffers(CollisionCircleLayoutArray, collisionCircleLayout.members, TriangleIndexArray);

this.glyphOffsetArray = new GlyphOffsetArray();
this.lineVertexArray = new SymbolLineVertexArray();
this.symbolInstances = new SymbolInstanceArray();
Expand Down Expand Up @@ -539,7 +545,7 @@ class SymbolBucket implements Bucket {
}

upload(context: Context) {
if (!this.uploaded) {
if (!this.uploaded && this.hasDebugData()) {
this.textCollisionBox.upload(context);
this.iconCollisionBox.upload(context);
this.textCollisionCircle.upload(context);
Expand All @@ -550,15 +556,22 @@ class SymbolBucket implements Bucket {
this.uploaded = true;
}

destroy() {
this.text.destroy();
this.icon.destroy();
destroyDebugData() {
this.textCollisionBox.destroy();
this.iconCollisionBox.destroy();
this.textCollisionCircle.destroy();
this.iconCollisionCircle.destroy();
}

destroy() {
this.text.destroy();
this.icon.destroy();

if (this.hasDebugData()) {
this.destroyDebugData();
}
}

addToLineVertexArray(anchor: Anchor, line: any) {
const lineStartIndex = this.lineVertexArray.length;
if (anchor.segment !== undefined) {
Expand Down Expand Up @@ -752,6 +765,15 @@ class SymbolBucket implements Bucket {
}

generateCollisionDebugBuffers() {
if (this.hasDebugData()) {
this.destroyDebugData();
}

this.textCollisionBox = new CollisionBuffers(CollisionBoxLayoutArray, collisionBoxLayout.members, LineIndexArray);
this.iconCollisionBox = new CollisionBuffers(CollisionBoxLayoutArray, collisionBoxLayout.members, LineIndexArray);
this.textCollisionCircle = new CollisionBuffers(CollisionCircleLayoutArray, collisionCircleLayout.members, TriangleIndexArray);
this.iconCollisionCircle = new CollisionBuffers(CollisionCircleLayoutArray, collisionCircleLayout.members, TriangleIndexArray);

for (let i = 0; i < this.symbolInstances.length; i++) {
const symbolInstance = this.symbolInstances.get(i);
this.addDebugCollisionBoxes(symbolInstance.textBoxStartIndex, symbolInstance.textBoxEndIndex, symbolInstance, true);
Expand Down Expand Up @@ -840,20 +862,24 @@ class SymbolBucket implements Bucket {
return this.icon.segments.get().length > 0;
}

hasDebugData() {
return this.textCollisionBox && this.iconCollisionBox && this.textCollisionCircle && this.iconCollisionCircle;
}

hasTextCollisionBoxData() {
return this.textCollisionBox.segments.get().length > 0;
return this.hasDebugData() && this.textCollisionBox.segments.get().length > 0;
}

hasIconCollisionBoxData() {
return this.iconCollisionBox.segments.get().length > 0;
return this.hasDebugData() && this.iconCollisionBox.segments.get().length > 0;
}

hasTextCollisionCircleData() {
return this.textCollisionCircle.segments.get().length > 0;
return this.hasDebugData() && this.textCollisionCircle.segments.get().length > 0;
}

hasIconCollisionCircleData() {
return this.iconCollisionCircle.segments.get().length > 0;
return this.hasDebugData() && this.iconCollisionCircle.segments.get().length > 0;
}

addIndicesForPlacedSymbol(iconOrText: SymbolBuffers, placedSymbolIndex: number) {
Expand Down
28 changes: 28 additions & 0 deletions src/geo/lng_lat.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
import {wrap} from '../util/util';
import LngLatBounds from './lng_lat_bounds';

/*
* Approximate radius of the earth in meters.
* Uses the WGS-84 approximation. The radius at the equator is ~6378137 and at the poles is ~6356752. https://en.wikipedia.org/wiki/World_Geodetic_System#WGS84
* 6371008.8 is one published "average radius" see https://en.wikipedia.org/wiki/Earth_radius#Mean_radius, or ftp://athena.fsv.cvut.cz/ZFG/grs80-Moritz.pdf p.4
*/
export const earthRadius = 6371008.8;

/**
* A `LngLat` object represents a given longitude and latitude coordinate, measured in degrees.
*
Expand Down Expand Up @@ -73,6 +80,27 @@ class LngLat {
return `LngLat(${this.lng}, ${this.lat})`;
}

/**
* Returns the approximate distance between a pair of coordinates in meters
* Uses the Haversine Formula (from R.W. Sinnott, "Virtues of the Haversine", Sky and Telescope, vol. 68, no. 2, 1984, p. 159)
*
* @param {LngLat} lngLat coordinates to compute the distance to
* @returns {number} Distance in meters between the two coordinates.
* @example
* var new_york = new mapboxgl.LngLat(-74.0060, 40.7128);
* var los_angeles = new mapboxgl.LngLat(-118.2437, 34.0522);
* new_york.distanceTo(los_angeles); // = 3935751.690893987, "true distance" using a non-spherical approximation is ~3966km
*/
distanceTo(lngLat: LngLat) {
const rad = Math.PI / 180;
const lat1 = this.lat * rad;
const lat2 = lngLat.lat * rad;
const a = Math.sin(lat1) * Math.sin(lat2) + Math.cos(lat1) * Math.cos(lat2) * Math.cos((lngLat.lng - this.lng) * rad);

const maxMeters = earthRadius * Math.acos(Math.min(a, 1));
return maxMeters;
}

/**
* Returns a `LngLatBounds` from the coordinates extended by a given `radius`. The returned `LngLatBounds` completely contains the `radius`.
*
Expand Down
12 changes: 6 additions & 6 deletions src/geo/mercator_coordinate.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
// @flow

import LngLat from '../geo/lng_lat';
import LngLat, {earthRadius} from '../geo/lng_lat';
import type {LngLatLike} from '../geo/lng_lat';

/*
* The circumference of the world in meters at the equator.
* The average circumference of the world in meters.
*/
const circumferenceAtEquator = 2 * Math.PI * 6378137;
const earthCircumfrence = 2 * Math.PI * earthRadius; // meters

/*
* The circumference of the world in meters at the given latitude.
* The circumference at a line of latitude in meters.
*/
function circumferenceAtLatitude(latitude: number) {
return circumferenceAtEquator * Math.cos(latitude * Math.PI / 180);
return earthCircumfrence * Math.cos(latitude * Math.PI / 180);
}

export function mercatorXfromLng(lng: number) {
Expand Down Expand Up @@ -142,7 +142,7 @@ class MercatorCoordinate {
*/
meterInMercatorCoordinateUnits() {
// 1 meter / circumference at equator in meters * Mercator projection scale factor at this latitude
return 1 / circumferenceAtEquator * mercatorScale(latFromMercatorY(this.y));
return 1 / earthCircumfrence * mercatorScale(latFromMercatorY(this.y));
}

}
Expand Down
Loading