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

Improve Geolocation package. #36

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion examples/simple-map/.meteor/versions
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jquery@1.0.1
json@1.0.1
livedata@1.0.11
logging@1.0.4
mdg:geolocation@1.0.2
mdg:geolocation@1.0.3
meteor-platform@1.1.2
meteor@1.1.2
minifiers@1.1.1
Expand Down
7 changes: 6 additions & 1 deletion examples/simple-map/map.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ <h1>Where am I?</h1>

<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}}" />

<label class="high-accuracy">
<input type="checkbox" checked="{{highAccuracy}}" />
High accuracy position
</label>

{{#if error}}
<p>Error: {{error.message}}</p>
{{/if}}
</body>
</body>
19 changes: 16 additions & 3 deletions examples/simple-map/map.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
if (Meteor.isClient) {
Template.body.events({
"change .high-accuracy input": function (event) {
Session.set("highAccuracy", event.target.checked);
}
});
Template.body.helpers({
loc: function () {
// options is *optional*. We're including it in this demo
// to show how it is reactive.
var options = {
enableHighAccuracy: !!Session.get("highAccuracy")
};
// return 0, 0 if the location isn't ready
return Geolocation.latLng() || { lat: 0, lng: 0 };
return Geolocation.latLng(options) || { lat: 0, lng: 0 };
},
error: Geolocation.error
error: Geolocation.error,
highAccuracy: function() {
return Session.get("highAccuracy");
}
});
}
}
18 changes: 15 additions & 3 deletions packages/mdg:geolocation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,22 @@ There are currently no options to set. Every method is reactive using [Tracker](

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

### Geolocation.currentLocation()
### Geolocation.currentLocation(options)

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.

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

A simple shorthand for currentLocation() when all you need is the latitude and longitude. Returns an object that has `lat` and `lng` keys.
### Geolocation.latLng(options)

A simple shorthand for currentLocation() when all you need is the latitude and longitude. Returns an object that has `lat` and `lng` keys.

The `options` parameter is optional; if provided it as if `Geolocation.setOptions` was called before returning the position.

### Geolocation.setOptions(options)

Provide [PositionOptions](https://developer.mozilla.org/en-US/docs/Web/API/PositionOptions) to manage power consumption on mobile devices. The options can be reactive.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does "The options can be reactive." mean in this context?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the simple-map example above. You can call:

var loc = Geolocation.latLng({ enableHighAccuracy: !!Session.get("highAccuracy") });

and the reactive-dependency magic will work to ensure that loc is properly updated if the Session variable changes (or if the location changes, naturally). The watcher that is created behind the scenes will be properly torn down/rebuilt iff it is necessary when this statement is recomputed.


### Geolocation.setPaused(boolean)

If the parameter is `true`, temporarily halts reactive position updates to reduce power consumption.
76 changes: 64 additions & 12 deletions packages/mdg:geolocation/geolocation.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,53 @@ var location = new ReactiveVar(null);
var error = new ReactiveVar(null);

// options for watchPosition
var options = {
var options = new ReactiveVar({
enableHighAccuracy: true,
maximumAge: 0
};
}, function(a, b) {
// Reject attempts to set this to a non-object.
if (a == null || b == null || typeof a !== 'object' || typeof b !=='object') {
return true;
}
return (
a.enableHighAccuracy === b.enableHighAccuracy &&
a.maximumAge === b.maximumAge &&
a.timeout === b.timeout
);
});

// pause geolocation updates
var paused = new ReactiveVar(false);

var onError = function (newError) {
error.set(newError);
Tracker.afterFlush(checkDependents);
};

var onPosition = function (newLocation) {
location.set(newLocation);
error.set(null);
Tracker.afterFlush(checkDependents);
};

var checkDependents = function() {
if (location.dep.hasDependents() || error.dep.hasDependents()) {
return;
}
watchingPosition.stop();
watchingPosition = false;
};

var startWatchingPosition = function () {
if (! watchingPosition && navigator.geolocation) {
navigator.geolocation.watchPosition(onPosition, onError, options);
watchingPosition = true;
if (watchingPosition === false && navigator.geolocation) {
watchingPosition = Tracker.autorun(function() {
if (paused.get()) { return; }
var watchId =
navigator.geolocation.watchPosition(onPosition, onError, options.get());
Tracker.onInvalidate(function() {
navigator.geolocation.clearWatch(watchId);
});
});
}
};

Expand All @@ -43,29 +72,37 @@ Geolocation = {
* that is currently preventing position updates.
*/
error: function () {
startWatchingPosition();
Tracker.nonreactive(startWatchingPosition);
return error.get();
},

/**
* @summary Get the current location
* @param {PositionOptions} options Optional geolocation options
* @param {Boolean} options.enableHighAccuracy
* @param {Number} options.maximumAge
* @param {Number} options.timeout
* @return {Position | null} 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.
*/
currentLocation: function () {
startWatchingPosition();
currentLocation: function (_options) {
if (_options != null) {
Geolocation.setOptions(_options);
}
Tracker.nonreactive(startWatchingPosition);
return location.get();
},

// simple version of location; just lat and lng

/**
* @summary Get the current latitude and longitude
* @return {Object | null} An object with `lat` and `lng` properties,
* or null if no position is available.
*/
latLng: function () {
var loc = Geolocation.currentLocation();
latLng: function (options) {
var loc = Geolocation.currentLocation(options);

if (loc) {
return {
Expand All @@ -75,5 +112,20 @@ Geolocation = {
}

return null;
},

/**
* @summary Set the PositionOptions used for geolocation.
*/
setOptions: function(_options) {
options.set(_options);
},

/**
* @summary Allow temporarily halting reactive updates to position.
*/
setPaused: function(_paused) {
paused.set(_paused);
}
};

};
4 changes: 2 additions & 2 deletions packages/mdg:geolocation/package.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package.describe({
name: "mdg:geolocation",
summary: "Provides reactive geolocation on desktop and mobile.",
version: "1.0.2",
version: "1.0.3",
git: "https://github.com/meteor/mobile-packages"
});

Expand All @@ -14,4 +14,4 @@ Package.on_use(function (api) {
api.versionsFrom("METEOR@0.9.2");
api.add_files(["geolocation.js"], "client");
api.export("Geolocation", "client");
});
});