
net.java.html.geo.Position Maven / Gradle / Ivy
/**
* HTML via Java(tm) Language Bindings
* Copyright (C) 2013 Jaroslav Tulach
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. apidesign.org
* designates this particular file as subject to the
* "Classpath" exception as provided by apidesign.org
* in the License file that accompanied this code.
*
* You should have received a copy of the GNU General Public License
* along with this program. Look for COPYING file in the top folder.
* If not, see http://wiki.apidesign.org/wiki/GPLwithClassPathException
*/
package net.java.html.geo;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apidesign.html.geo.impl.JsG;
/** Class that represents a geolocation position provided as a callback
* to {@link Handle#onLocation(net.java.html.geo.Position)} method. The
* class getters mimic closely the structure of the position object as
* specified by
* W3C's Geolocation API.
*
* @author Jaroslav Tulach
*/
public final class Position {
static final Logger LOG = Logger.getLogger(Position.class.getName());
private final long timestamp;
private final Coordinates coords;
Position(Object position) {
Object obj = JsG.get(position, "timestamp");
timestamp = obj instanceof Number ? ((Number)obj).longValue() : 0L;
coords = new Coordinates(JsG.get(position, "coords"));
}
/** The actual location of the position.
* @return non-null coordinates
*/
public Coordinates getCoords() {
return coords;
}
/** The time when the position has been recorded.
* @return time in milliseconds since era (e.g. Jan 1, 1970).
*/
public long getTimestamp() {
return timestamp;
}
/** Actual location of a {@link Position}.
* Mimics closely
* W3C's Geolocation API.
*/
public static final class Coordinates {
private final Object data;
Coordinates(Object data) {
this.data = data;
}
public double getLatitude() {
return ((Number)JsG.get(data, "latitude")).doubleValue(); // NOI18N
}
public double getLongitude() {
return ((Number)JsG.get(data, "longitude")).doubleValue(); // NOI18N
}
public double getAccuracy() {
return ((Number)JsG.get(data, "accuracy")).doubleValue(); // NOI18N
}
public Double getAltitude() {
return (Double)JsG.get(data, "altitude"); // NOI18N
}
public Double getAltitudeAccuracy() {
return (Double)JsG.get(data, "altitudeAccuracy"); // NOI18N
}
public Double getHeading() {
return (Double)JsG.get(data, "heading"); // NOI18N
}
public Double getSpeed() {
return (Double)JsG.get(data, "speed"); // NOI18N
}
} // end of Coordinates
/** Rather than subclassing this class directly consider using {@link OnLocation}
* annotation. Such annotation will generate a subclass for you automatically
* with two static methods createQuery
and createWatch
* which can be used to obtain instance of this class.
*/
public static abstract class Handle {
private final boolean oneTime;
private boolean enableHighAccuracy;
private long timeout;
private long maximumAge;
volatile JsH handle;
/** Creates new instance of this handle.
*
* @param oneTime true
if the handle represents one time
* query. false
if it represents a watch
*/
protected Handle(boolean oneTime) {
super();
this.oneTime = oneTime;
}
/** Callback from the implementation when a (new) position has been
* received and identified
* @param p the position
* @throws Throwable if an exception is thrown, it will be logged by the system
*/
protected abstract void onLocation(Position p) throws Throwable;
/** Callback when an error occurs.
* @param ex the exception describing what went wrong
* @throws Throwable if an exception is thrown, it will be logged by the system
*/
protected abstract void onError(Exception ex) throws Throwable;
/** Check whether the location API is supported.
* @return true, if one can call {@link #start}.
*/
public final boolean isSupported() {
return JsG.hasGeolocation();
}
/** Turns on high accuracy mode as specified by the
*
* W3C's Geolocation API. By default the mode is disabled.
* @param enable true
or false
*/
public final void setHighAccuracy(boolean enable) {
this.enableHighAccuracy = enable;
}
/** The amount of milliseconds to wait for a result.
* By default infinity.
* @param timeout time in milliseconds to wait for a result.
*/
public final void setTimeout(long timeout) {
this.timeout = timeout;
}
/** Sets maximum age of cached results which are acceptable to be
* returned. By default maximum age is set to zero.
* @param age time in milliseconds of acceptable cached results
*/
public final void setMaximumAge(long age) {
this.maximumAge = age;
}
/** Initializes the query or watch request(s) and
* returns immediately. Has no effect if the query has already been
* started. If a problem appears while starting the system,
* it is immediately reported via the {@link #onError(java.lang.Exception)}
* callback. For example, if the {@link #isSupported()} method
* returns false
an IllegalStateException is created
* and sent to the {@link #onError(java.lang.Exception) callback} method.
*/
public final void start() {
if (handle != null) {
return;
}
handle = new JsH();
try {
if (!isSupported()) {
throw new IllegalStateException("geolocation API not supported");
}
handle.start();
} catch (Exception ex) {
try {
onError(ex);
} catch (Throwable thr) {
LOG.log(Level.INFO, "Problems delivering onError report", thr);
}
}
}
/** Stops all pending requests. After this call no further callbacks
* can be obtained. Does nothing if no query or watch was in progress.
*/
public final void stop() {
JsH h = handle;
if (h == null) {
return;
}
handle = null;
h.stop();
}
private final class JsH extends JsG {
long watch;
@Override
public void onLocation(Object position) {
if (handle != this) {
return;
}
if (oneTime) {
stop();
}
try {
Handle.this.onLocation(new Position(position));
} catch (Throwable ex) {
LOG.log(Level.SEVERE, null, ex);
}
}
@Override
public void onError(Object error) {
if (handle != this) {
return;
}
if (oneTime) {
stop();
}
try {
Handle.this.onError(new Exception());
} catch (Throwable ex) {
LOG.log(Level.SEVERE, null, ex);
}
}
final void start() {
watch = start(oneTime, enableHighAccuracy, timeout, maximumAge);
}
protected final void stop() {
super.stop(watch);
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy