-
Notifications
You must be signed in to change notification settings - Fork 21
/
index.bs
511 lines (400 loc) · 23.5 KB
/
index.bs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
<pre class="metadata">
Title: Geolocation Sensor
Level: none
Status: ED
ED: https://w3c.github.io/geolocation-sensor/
TR: https://www.w3.org/TR/geolocation-sensor/
Shortname: geolocation-sensor
Editor: Anssi Kostiainen 41974, Intel Corporation, https://intel.com/
Editor: Thomas Steiner 44965, Google Inc., https://google.com/
Editor: Marijn Kruisselbrink 72440, Google Inc., https://google.com/
Group: dap
Status Text:
<strong>This specification presents a [[#use-cases-categorization]] informed by feedback
and requests from the wider community, end users and web developers. These use cases
welcome further review from the wider web community to ensure the documented use case set
satisfies the needs of all stakeholders and provides appropriate abstractions for these capabilities.
Review and feedback is sought after in particular for the new [[#use-cases-background-continuous]]
and [[#use-cases-background-geofence]] use case categories. All feedback, including
contributions for new informative use cases and other considerations,
is welcome via <a href="https://github.com/w3c/geolocation-sensor/issues">GitHub issues</a>.
In line with the expectations of the Working Draft maturity stage,
the normative [[#api]] definition may change based on stakeholders' feedback,
implementation experience, security and privacy, and other considerations.</strong>
The Devices and Sensors Working Group will perform a round of self-review and
revisions on the security and privacy aspects of the API before
requesting horizontal review. Existing security and privacy issues can
be found <a
href="https://www.w3.org/PM/horizontal/review.html?shortname=geolocation-sensor">here</a>.
Abstract:
This specification defines the {{GeolocationSensor}} interface for obtaining
the [=geolocation=] of the hosting device.
Indent: 2
Markup Shorthands: markdown on
Inline Github Issues: true
Repository: w3c/geolocation-sensor
Issue Tracking: Geolocation Sensor Issues Repository https://github.com/w3c/geolocation-sensor/issues
!Tests: <a href="https://github.com/web-platform-tests/wpt/tree/master/geolocation-sensor">web-platform-tests</a>
!Polyfills: <a href="https://github.com/kenchris/sensor-polyfills/blob/master/src/geolocation-sensor.js">geolocation-sensor.js</a><br><a href="https://github.com/w3c/sensors/blob/main/polyfills/geolocation.js">geolocation.js</a>
Boilerplate: omit issues-index, omit conformance, omit feedback-header, repository-issue-tracking no
Include MDN Panels: if possible
Ignored Vars: p, geo, key
Default Biblio Status: current
Note class: note
</pre>
<pre class="anchors">
urlPrefix: https://w3c.github.io/sensors; spec: GENERIC-SENSOR
type: dfn
text: high-level
text: sensor
text: latest reading
text: default sensor
text: construct a sensor object; url: construct-sensor-object
text: initialize a sensor object; url: initialize-a-sensor-object
text: sensor type
text: security and privacy; url: security-and-privacy
text: extensible; url: extensibility
text: check sensor policy-controlled features; url: check-sensor-policy-controlled-features
urlPrefix: https://dom.spec.whatwg.org; spec: DOM
type: dfn
text: add the following abort steps; url: abortsignal-add
text: aborted flag; url: abortsignal-aborted-flag
urlPrefix: http://w3c.github.io/hr-time/; spec: HR-TIME-2
type: interface
text: DOMHighResTimeStamp; url: dom-domhighrestimestamp
</pre>
</pre>
<pre class="biblio">
{
"WGS84": {
"authors": [
"National Imagery and Mapping Agency"
],
"href": "http://earth-info.nga.mil/GandG/publications/tr8350.2/wgs84fin.pdf",
"title": "Department of Defence World Geodetic System 1984",
"status": "Technical Report, Third Edition",
"publisher": "National Imagery and Mapping Agency"
}
}
</pre>
Introduction {#intro}
============
The {{GeolocationSensor}} API extends the {{Sensor}} interface [[GENERIC-SENSOR]] to provide
information about the [=geolocation=] of the hosting device.
The feature set of the {{GeolocationSensor}} is similar to that of the Geolocation API
[[GEOLOCATION-API]], but it is surfaced through a modern API that is consistent across
<a href="https://www.w3.org/das/roadmap">contemporary sensor APIs</a>, improves
<a>security and privacy</a>, and is <a>extensible</a>. The API aims to be
<a href="https://github.com/kenchris/sensor-polyfills/blob/master/src/geolocation-sensor.js">polyfillable</a>
(<a href="https://kenchris.github.io/sensor-polyfills/run-geolocation.html">example</a>)
on top of the existing Geolocation API.
Examples {#examples}
========
<p>
Get a new geolocation reading every second:
</p>
<div class="example">
<pre highlight="js">
const geo = new GeolocationSensor({ frequency: 1 });
geo.start();
geo.onreading = () => console.log(\`lat: ${geo.latitude}, long: ${geo.longitude}\`);
geo.onerror = event => console.error(event.error.name, event.error.message);
</pre>
</div>
<p>
Get a one-shot geolocation reading:
</p>
<div class="example">
<pre highlight="js">
GeolocationSensor.read()
.then(geo => console.log(\`lat: ${geo.latitude}, long: ${geo.longitude}\`))
.catch(error => console.error(error.name));
</pre>
</div>
Security and Privacy Considerations {#security-and-privacy}
===================================
Note: Investigate any geolocation-specific security and privacy considerations that are not
mitigated by the Generic Sensor API [[!GENERIC-SENSOR]], and define geolocation-specific
mitigations.
Model {#model}
=====
The term <dfn>geolocation</dfn> refers to the real-world geographic location of the
hosting device represented in geographic coordinates [[!WGS84]].
Note: An implementation can use multiple location information sources to acquire
<a>geolocation</a> information, and this specification is agnostic with respect
to those sources.
The <dfn>Geolocation Sensor</dfn> <a>sensor type</a>'s associated {{Sensor}} subclass is the
{{GeolocationSensor}} class.
The <a>Geolocation Sensor</a> has an associated {{PermissionName}} which is
<a for="PermissionName" enum-value>"geolocation"</a>.
The <a>Geolocation Sensor</a> is a [=policy-controlled feature=] identified by the string "geolocation". Its [=default allowlist=] is `'self'`.
The <a>Geolocation Sensor</a> has an associated [=virtual sensor type=] which is
"<code><dfn data-lt="geolocation virtual sensor type">geolocation</dfn></code>".
A <dfn>latest geolocation reading</dfn> is a [=latest reading=] for a {{Sensor}} of
<a>Geolocation Sensor</a> <a>sensor type</a>. It includes [=map/entries=] whose [=map/keys=]
are "latitude", "longitude", "altitude", "accuracy", "altitudeAccuracy", "heading", "speed"
and whose [=map/values=] contain the device's [=geolocation=].
Note: Consider adding a visual of the standard coordinate system for the Earth.
API {#api}
===
Issue(62):
The GeolocationSensor Interface {#geolocationsensor-interface}
-------------------------------
<pre class="idl">
[SecureContext,
Exposed=(DedicatedWorker, Window)]
interface GeolocationSensor : Sensor {
constructor(optional GeolocationSensorOptions options = {});
static Promise<GeolocationSensorReading> read(optional ReadOptions readOptions = {});
readonly attribute unrestricted double? latitude;
readonly attribute unrestricted double? longitude;
readonly attribute unrestricted double? altitude;
readonly attribute unrestricted double? accuracy;
readonly attribute unrestricted double? altitudeAccuracy;
readonly attribute unrestricted double? heading;
readonly attribute unrestricted double? speed;
};
dictionary GeolocationSensorOptions : SensorOptions {
// placeholder for GeolocationSensor-specific options
};
dictionary ReadOptions : GeolocationSensorOptions {
AbortSignal? signal;
};
dictionary GeolocationSensorReading {
DOMHighResTimeStamp? timestamp;
double? latitude;
double? longitude;
double? altitude;
double? accuracy;
double? altitudeAccuracy;
double? heading;
double? speed;
};
</pre>
<div class="note">
Normative changes to the <code>
<a href="https://dev.w3.org/geo/api/spec-source.html#coordinates_interface">
Coordinates</a></code> interface of the Geolocation API are the following:
<ul>
<li>Use <a href="https://heycam.github.io/webidl/#idl-unrestricted-double">
unrestricted double</a> to not throw TypeError on NaN, +Infinity or −Infinity.
(Geolocation API defines NaN as a valid value for heading, yet uses double as its type.)
<li>Use <a href="https://heycam.github.io/webidl/#dfn-nullable-type">nullable</a> to allow
all attributes to default to null. (Geolocation API does not provide synchronous means to
access these attributes, thus latitude, longitude, and altitude are not nullable and "must be
supported by all implementations".)
</ul>
</div>
To construct a {{GeolocationSensor}} object the user agent must invoke the
[=construct a geolocation sensor object=] abstract operation.
### GeolocationSensor.read() ### {#geolocationsensor-read}
The {{GeolocationSensor/read()}} method, when called, must run the following algorithm:
<div algorithm="read">
<!-- https://dom.spec.whatwg.org/#abortcontroller-api-integration -->
: input
:: |options|, a {{ReadOptions}} object.
: output
:: |p|, a promise.
1. Let |p| be a new promise.
1. Let |options| be the first argument.
1. Let |signal| be the |options|' dictionary member of the same name if present, or null otherwise.
1. If |signal| is <a>aborted</a>, then reject |p| with |signal|'s <a>abort reason</a> and return |p|.
1. Let |geo| be the result of invoking <a>construct a Geolocation Sensor object</a> with |options|. If this throws a {{DOMException}}, catch it, reject |p| with that {{DOMException}}, and return |p|.
1. Invoke |geo|.{{Sensor/start()}}.
1. If |signal| is not null, then <a>add the following abort steps</a> to |signal|:
1. Invoke |geo|.{{Sensor/stop()}}.
1. Reject |p| with |signal|'s <a>abort reason</a> and abort these steps.
1. Run these steps <a>in parallel</a>:
1. If <a>notify error</a> is invoked with |geo|, invoke |geo|.{{Sensor/stop()}}, and reject |p| with the {{DOMException}} passed as input to <a>notify error</a>.
1. If <a>notify new reading</a> is invoked with |geo|, then <a>resolve a geolocation promise</a> with |geo| and |p|.
1. Return |p|.
</div>
<p class="note">
Implementations can reuse the same promise for multiple concurrent calls within the same browsing context if the arguments passed to {{read()}} are the same.
</p>
To <dfn>resolve a geolocation promise</dfn> means to run the following steps:
1. Let |reading| be a {{GeolocationSensorReading}}.
1. [=set/For each=] |key| → |value| of <a>latest geolocation reading</a>:
1. [=map/Set=] |reading|[key] to |value|.
1. Invoke |geo|.{{Sensor/stop()}}.
1. Resolve |p| with |reading|.
### GeolocationSensor.latitude ### {#geolocationsensor-latitude}
The {{GeolocationSensor/latitude!!attribute}} attribute of the {{GeolocationSensor}} interface
returns the result of invoking [=get value from latest reading=] with `this` and "latitude" as
arguments. It represents the latitude coordinate of the [=geolocation=] in decimal degrees
[[!WGS84]].
### GeolocationSensor.longitude ### {#geolocationsensor-longitude}
The {{GeolocationSensor/longitude!!attribute}} attribute of the {{GeolocationSensor}} interface
returns the result of invoking [=get value from latest reading=] with `this` and "longitude" as
arguments. It represents the longitude coordinate of the [=geolocation=] in decimal degrees
[[!WGS84]].
### GeolocationSensor.altitude ### {#geolocationsensor-altitude}
The {{GeolocationSensor/altitude!!attribute}} attribute of the {{GeolocationSensor}} interface
returns the result of invoking [=get value from latest reading=] with `this` and "altitude" as
arguments. It represents the [=geolocation=] in meters above the WGS 84 ellipsoid [[!WGS84]].
### GeolocationSensor.accuracy ### {#geolocationsensor-accuracy}
The {{GeolocationSensor/accuracy!!attribute}} attribute of the {{GeolocationSensor}} interface
returns the result of invoking [=get value from latest reading=] with `this` and "accuracy" as
arguments. It represents the accuracy of the [=latest reading=]["latitude"] value and
[=latest reading=]["longitude"] value in meters with a 95% confidence level.
If the [=latest reading=]["latitude"] value is null or [=latest reading=]["longitude"] value is
null, it must return null.
### GeolocationSensor.altitudeAccuracy ### {#geolocationsensor-altitudeaccuracy}
The {{GeolocationSensor/altitudeAccuracy!!attribute}} attribute of the {{GeolocationSensor}}
interface returns the result of invoking [=get value from latest reading=] with `this` and
"altitudeAccuracy" as arguments. It represents the accuracy of the
[=latest reading=]["altitude"] value in meters with a 95% confidence level.
If the [=latest reading=]["altitude"] value is null, it must return null.
### GeolocationSensor.heading ### {#geolocationsensor-heading}
The {{GeolocationSensor/heading!!attribute}} attribute of the {{GeolocationSensor}} interface
returns the result of invoking [=get value from latest reading=] with `this` and "heading" as
arguments. It represents the direction of travel in degrees counting clockwise relative to the
true north in the range 0 ≤ heading ≤ 360.
### GeolocationSensor.speed ### {#geolocationsensor-speed}
The {{GeolocationSensor/speed!!attribute}} attribute of the {{GeolocationSensor}} interface
returns the result of invoking [=get value from latest reading=] with `this` and "speed" as
arguments. It represents the magnitude of the horizontal component of the velocity in meters
per second.
Abstract Operations {#abstract-operations}
===================
<h3 dfn export>Construct a geolocation sensor object</h3>
<div algorithm="construct a geolocation sensor object">
: input
:: |options|, a {{GeolocationSensorOptions}} object.
: output
:: A {{GeolocationSensor}} object.
1. Let |allowed| be the result of invoking [=check sensor policy-controlled features=]
with {{GeolocationSensor}}.
1. If |allowed| is false, then:
1. [=Throw=] a {{SecurityError}} {{DOMException}}.
1. Let |geo| be the new {{GeolocationSensor}} object.
1. Invoke [=initialize a sensor object=] with |geo| and |options|.
1. Return |geo|.
</div>
Automation {#automation}
==========
This section extends [[GENERIC-SENSOR#automation]] by providing [=Geolocation Sensor=]-specific virtual sensor metadata.
The [=per-type virtual sensor metadata=] [=map=] must have the following [=map/entry=]:
: [=map/key=]
:: "<code>[=geolocation virtual sensor type|geolocation=]</code>"
: [=map/value=]
:: A [=virtual sensor metadata=] whose [=virtual sensor metadata/reading parsing algorithm=] is the [=geolocation reading parsing algorithm=].
<h3 dfn>Geolocation reading parsing algorithm</h3>
<div algorithm="geolocation reading parsing algorithm">
: input
:: |parameters|, a JSON {{Object}}
: output
:: A [=sensor reading=] or **undefined**
1. Let |reading| be a new [=sensor reading=].
1. Let |keys| be the [=/list=] « "`latitude`", "`longitude`", "`altitude`", "`accuracy`", "`altitudeAccuracy`", "`heading`", "`speed`" ».
1. [=list/For each=] |key| of |keys|
1. Let |value| be the result of invoking [=parse single-value number reading=] with |parameters| and |key|.
1. If |value| is **undefined**.
1. Return **undefined**.
1. [=map/Set=] |reading|[|key|] to |value|[|key|].
1. Return |reading|.
</div>
Use Cases {#use-cases}
=========
## Categorization of use cases ## {#use-cases-categorization}
The mentioned use cases can roughly be grouped into four categories:
* **Foreground** operations:
* Getting a **one-off geolocation update**.
* Getting **continuous geolocation updates** (*aka.* foreground geotracking).
* **Background** operations:
* Getting **continuous geolocation updates** (*aka.* background geotracking).
* Getting a **one-off geolocation fence alert** (*aka.* background geofencing).
Note: Only the **foreground operations** were possible with [[GEOLOCATION-API]],
the **background operations** are completely novel.
Core constraints when obtaining the gelocation are **accuracy** (*how close to the
actual position of the user is the determined position*) and **latency**
(*how long does the user want to wait for a result*). Both are tradeoffs:
one can trade faster results for lower accuracy and vice versa.
A common theme is to first obtain a rough estimation that then gets refined over time,
for example based initially on surrounding WiFi signals (which is fast to obtain)
and then eventually based on precise GPS data (which may take some time to find a signal).
In the following, we list use cases based on the previously defined categories.
Note: The categories are not mutually exclusive and overlaps exist.
A task might start in the foreground, then continue in the background (for example,
while the user quickly responds to an incoming email),
and then eventually terminate in the foreground when the user multitasks back.
## Foreground—One-off geolocation update ## {#use-cases-foreground-one-off}
### Locate a user on a map ### {#use-case-locate-a-user-on-a-map}
A mapping application can use the Geolocation Sensor API data of a user to locate them
on the map, essentially responding to the question "Where am I right now?"
### Find points of interest in the user's area ### {#use-case-find-points-of-interest-in-the-users-area}
Someone visiting a foreign city could access a web application that allows users
to search or browse through a database of tourist attractions. Using the Geolocation Sensor API,
the web application has access to the user's approximate current position
and is therefore able to rank the search results by proximity to the user's location.
## Foreground—Continuous geolocation updates ## {#use-cases-foreground-continuous}
### Up-to-date local information ### {#use-case-up-to-date-local-information}
A widget-like web application that shows the weather or news that are relevant
to the user's current area can use the Geolocation Sensor API to register for location updates.
If the user's position changes, the widget can adapt the content accordingly.
### Alerts when points of interest are in the user's vicinity ### {#use-case-alerts-when-points-of-interest-are-in-the-users-vicinity}
A tour guide web application can use the Geolocation Sensor API to monitor the user's position
and trigger visual or audio notifications when interesting places are in the vicinity.
An online task management system can trigger reminders when the user is in the proximity
of landmarks that are associated with certain tasks.
This use case assumes active usage of the application in the foreground.
### Show the user's position on a map ### {#use-case-show-the-users-position-on-a-map}
A user finds themselves in an unfamiliar area. They want to check their position
so they use their handheld device to navigate to a web-based mapping application
that can pinpoint their exact location on the map using the Geolocation Sensor API.
They then ask the web application to provide driving directions from their current position
to their desired destination, essentially responding to the question "Where am I going?".
## Background—Continuous geolocation updates ## {#use-cases-background-continuous}
### Location-tagged status updates in social networking applications ### {#use-case-location-tagged-status-updates-in-social-networking-applications}
A social networking application allows its users to automatically tag their status updates with
location information. It does this by monitoring the user's position with the Geolocation Sensor API.
Each user can control the granularity of the location information (e.g., city or neighborhood level)
that is shared with the other users. Any user can also see their network of friends
and get real-time updates about their current location,
granted they have opted in to their location data being shared.
This use case intentionally conflates foreground location tagging and background location sharing.
### Turn-by-turn route navigation ### {#use-case-turn-by-turn-route-navigation}
A mapping application can help the user navigate along a routeby providing detailed turn-by-turn directions.
The application does this by registering with the Geolocation Sensor API to receive
repeated location updates of the user's position. These updates are delivered as soon as the implementing
user agent determines that the position of the user has changed, which allows the application
to anticipate any changes of direction that the user might need to do.
The application can be in the foreground, but likewise can be backgrounded, for example,
when the user turns their device off to save battery on a long highway route section without side roads.
### Tracking sports activity ### {#use-case-tracking-sports-activity}
A web application can track a user's sports activity, for example, a marathon run or a bicycle race.
Therefore, the application does not need to be on the screen, but would be backgrounded
while the user performs their activity, maybe with their handheld device strapped to their arm.
### Real estate search ### {#use-case-real-estate-search}
A web application on a handheld device can notify a user of interesting available properties
in a neighborhood they are passing by where the property fits the user's previously specified search criteria,
for example, 3 bedroom apartments with balcony.
This is based on the assumption that the number of possible matches is high,
that is, impossible to realize with geofences as the amount of required geofences would be too high.
### Cultural spaces ### {#use-case-cultural-spaces}
In cultural spaces like museums, festivals, exhibitions, etc., web applications can react to where the user is
or what they are seeing to cue different experiences and content.
## Background—One-off geolocation fence alert ## {#use-cases-background-geofence}
### Reminder and to-do applications ### {#use-case-reminder-and-todo-applications}
Reminder and to-do web applications can use a geofence to remind the user to do something when they cross it,
for example, to buy milk when they are near the supermarket.
### Travel applications ### {#use-case-travel-applications}
Travel applications can show venue specific data like WiFi passwords,
the user's booking confirmation etc. only within geofence boundaries.
### Ticketing or booking confirmations ### {#use-case-ticketing-or-booking-confirmations}
Ticketing or booking applications can bring up a ticket notification with a QR or bar code
once the user is near the venue of a concert or sports event or when they reach their rental car counter or similar.
### Ride share applications ### {#use-case-ride-share-applications}
Users can be informed if their designated driver reaches a pre-defined pickup point.
### Retail special offers ### {#use-case-retail-special-offers}
Given their previous consent, a user with a retailer's web application installed on their handheld device
can be alerted about special offers or location-based coupons when they are
in vicinity of a physical presence of the retailer. Further, the in-store experience can be enriched,
for example, the retailer can let the user know something they have looked at before is actually available for pick up nearby.
Acknowledgements {#acknowledgements}
================
Thanks to Tobie Langel for the work on Generic Sensor API and the early geolocation.js polyfill.
Thanks to Kenneth Rohde Christiansen for the geolocation-sensor.js polyfill and design proposals
during the incubation phase.
Special thanks to the Geolocation Working Group participants for their work on the Geolocation API
from 2008 until 2017.