Skip to content

Commit 10a0d36

Browse files
committed
Improve Geolocation package.
Add the ability to tweak the PositionOptions used for Geolocation, for instance to use low-accuracy position to save battery on mobile devices. The options parameter is reactive. Add a `pause` feature to temporarily halt position updates, again to allow better power management on mobile devices. The paused status is also reactive. Stop position watcher when there are no dependencies of the location, so that we automatically save power if (for example) a reactive map view is not visible.
1 parent 7a0f796 commit 10a0d36

File tree

6 files changed

+104
-22
lines changed

6 files changed

+104
-22
lines changed

examples/simple-map/.meteor/versions

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ [email protected]
2525
2626
2727
28-
28+
2929
3030
3131

examples/simple-map/map.html

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@ <h1>Where am I?</h1>
77

88
<img src="http://maps.googleapis.com/maps/api/staticmap?center={{loc.lat}},{{loc.lng}}&zoom=15&size=600x300&maptype=roadmap&markers=color:blue%7C{{loc.lat}},{{loc.lng}}" />
99

10+
<label class="high-accuracy">
11+
<input type="checkbox" checked="{{highAccuracy}}" />
12+
High accuracy position
13+
</label>
14+
1015
{{#if error}}
1116
<p>Error: {{error.message}}</p>
1217
{{/if}}
13-
</body>
18+
</body>

examples/simple-map/map.js

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,22 @@
11
if (Meteor.isClient) {
2+
Template.body.events({
3+
"change .high-accuracy input": function (event) {
4+
Session.set("highAccuracy", event.target.checked);
5+
}
6+
});
27
Template.body.helpers({
38
loc: function () {
9+
// options is *optional*. We're including it in this demo
10+
// to show how it is reactive.
11+
var options = {
12+
enableHighAccuracy: !!Session.get("highAccuracy")
13+
};
414
// return 0, 0 if the location isn't ready
5-
return Geolocation.latLng() || { lat: 0, lng: 0 };
15+
return Geolocation.latLng(options) || { lat: 0, lng: 0 };
616
},
7-
error: Geolocation.error
17+
error: Geolocation.error,
18+
highAccuracy: function() {
19+
return Session.get("highAccuracy");
20+
}
821
});
9-
}
22+
}

packages/mdg:geolocation/README.md

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,22 @@ There are currently no options to set. Every method is reactive using [Tracker](
1010

1111
Returns the [position error](https://developer.mozilla.org/en-US/docs/Web/API/PositionError) that is currently preventing position updates.
1212

13-
### Geolocation.currentLocation()
13+
### Geolocation.currentLocation(options)
1414

1515
Returns the [position](https://developer.mozilla.org/en-US/docs/Web/API/Position) that is reported by the device, or null if no position is available.
1616

17-
### Geolocation.latLng()
17+
The `options` parameter is optional; if provided it as if `Geolocation.setOptions` was called before returning the position.
1818

19-
A simple shorthand for currentLocation() when all you need is the latitude and longitude. Returns an object that has `lat` and `lng` keys.
19+
### Geolocation.latLng(options)
20+
21+
A simple shorthand for currentLocation() when all you need is the latitude and longitude. Returns an object that has `lat` and `lng` keys.
22+
23+
The `options` parameter is optional; if provided it as if `Geolocation.setOptions` was called before returning the position.
24+
25+
### Geolocation.setOptions(options)
26+
27+
Provide [PositionOptions](https://developer.mozilla.org/en-US/docs/Web/API/PositionOptions) to manage power consumption on mobile devices. The options can be reactive.
28+
29+
### Geolocation.setPaused(boolean)
30+
31+
If the parameter is `true`, temporarily halts reactive position updates to reduce power consumption.

packages/mdg:geolocation/geolocation.js

Lines changed: 64 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,53 @@ var location = new ReactiveVar(null);
88
var error = new ReactiveVar(null);
99

1010
// options for watchPosition
11-
var options = {
11+
var options = new ReactiveVar({
1212
enableHighAccuracy: true,
1313
maximumAge: 0
14-
};
14+
}, function(a, b) {
15+
// Reject attempts to set this to a non-object.
16+
if (a == null || b == null || typeof a !== 'object' || typeof b !=='object') {
17+
return true;
18+
}
19+
return (
20+
a.enableHighAccuracy === b.enableHighAccuracy &&
21+
a.maximumAge === b.maximumAge &&
22+
a.timeout === b.timeout
23+
);
24+
});
25+
26+
// pause geolocation updates
27+
var paused = new ReactiveVar(false);
1528

1629
var onError = function (newError) {
1730
error.set(newError);
31+
checkDependents();
1832
};
1933

2034
var onPosition = function (newLocation) {
2135
location.set(newLocation);
2236
error.set(null);
37+
checkDependents();
38+
};
39+
40+
var checkDependents = function() {
41+
if (location.dep.hasDependents() || error.dep.hasDependents()) {
42+
return;
43+
}
44+
watchingPosition.stop();
45+
watchingPosition = false;
2346
};
2447

2548
var startWatchingPosition = function () {
26-
if (! watchingPosition && navigator.geolocation) {
27-
navigator.geolocation.watchPosition(onPosition, onError, options);
28-
watchingPosition = true;
49+
if (watchingPosition === false && navigator.geolocation) {
50+
watchingPosition = Tracker.autorun(function() {
51+
if (paused.get()) { return; }
52+
var watchId =
53+
navigator.geolocation.watchPosition(onPosition, onError, options.get());
54+
Tracker.onInvalidate(function() {
55+
navigator.geolocation.clearWatch(watchId);
56+
});
57+
});
2958
}
3059
};
3160

@@ -43,29 +72,37 @@ Geolocation = {
4372
* that is currently preventing position updates.
4473
*/
4574
error: function () {
46-
startWatchingPosition();
75+
Tracker.nonreactive(startWatchingPosition);
4776
return error.get();
4877
},
4978

5079
/**
5180
* @summary Get the current location
81+
* @param {PositionOptions} options Optional geolocation options
82+
* @param {Boolean} options.enableHighAccuracy
83+
* @param {Number} options.maximumAge
84+
* @param {Number} options.timeout
5285
* @return {Position | null} The
5386
* [position](https://developer.mozilla.org/en-US/docs/Web/API/Position)
5487
* that is reported by the device, or null if no position is available.
5588
*/
56-
currentLocation: function () {
57-
startWatchingPosition();
89+
currentLocation: function (_options) {
90+
if (_options != null) {
91+
Geolocation.setOptions(_options);
92+
}
93+
Tracker.nonreactive(startWatchingPosition);
5894
return location.get();
5995
},
96+
6097
// simple version of location; just lat and lng
61-
98+
6299
/**
63100
* @summary Get the current latitude and longitude
64101
* @return {Object | null} An object with `lat` and `lng` properties,
65102
* or null if no position is available.
66103
*/
67-
latLng: function () {
68-
var loc = Geolocation.currentLocation();
104+
latLng: function (options) {
105+
var loc = Geolocation.currentLocation(options);
69106

70107
if (loc) {
71108
return {
@@ -75,5 +112,20 @@ Geolocation = {
75112
}
76113

77114
return null;
115+
},
116+
117+
/**
118+
* @summary Set the PositionOptions used for geolocation.
119+
*/
120+
setOptions: function(_options) {
121+
options.set(_options);
122+
},
123+
124+
/**
125+
* @summary Allow temporarily halting reactive updates to position.
126+
*/
127+
setPaused: function(_paused) {
128+
paused.set(_paused);
78129
}
79-
};
130+
131+
};

packages/mdg:geolocation/package.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Package.describe({
22
name: "mdg:geolocation",
33
summary: "Provides reactive geolocation on desktop and mobile.",
4-
version: "1.0.2",
4+
version: "1.0.3",
55
git: "https://github.com/meteor/mobile-packages"
66
});
77

@@ -14,4 +14,4 @@ Package.on_use(function (api) {
1414
api.versionsFrom("[email protected]");
1515
api.add_files(["geolocation.js"], "client");
1616
api.export("Geolocation", "client");
17-
});
17+
});

0 commit comments

Comments
 (0)