diff --git a/src/main/java/com/flowingcode/vaadin/addons/googlemaps/GeolocationOptions.java b/src/main/java/com/flowingcode/vaadin/addons/googlemaps/GeolocationOptions.java new file mode 100644 index 0000000..184bf2e --- /dev/null +++ b/src/main/java/com/flowingcode/vaadin/addons/googlemaps/GeolocationOptions.java @@ -0,0 +1,73 @@ +/*- + * #%L + * Google Maps Addon + * %% + * Copyright (C) 2020 - 2025 Flowing Code + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ +package com.flowingcode.vaadin.addons.googlemaps; + +import elemental.json.Json; +import elemental.json.JsonObject; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +/** + * Representation of optional parameters for a geolocation request. + * + * @see Options + * documentation + */ +@Getter +@Setter +@AllArgsConstructor +public class GeolocationOptions { + /** + * A boolean value that indicates the application would like to receive the best possible results. + * If true and if the device is able to provide a more accurate position, it will do so. This may + * result in slower response times or increased power consumption. + */ + private boolean enableHighAccuracy; + + /** + * A positive long value representing the maximum length of time (in milliseconds) the device is + * allowed to take in order to return a position. + * If null, the device won't timeout until the position is available. + */ + private Long timeout; + + /** + * A positive long value representing the maximum age (in milliseconds) of a possible cached + * position that is acceptable to return. + */ + private long maximumAge; + + /** + * Converts the options to a JsonObject to be sent to the client-side. + * + * @return a JsonObject representing the configured options + */ + public JsonObject toJson() { + JsonObject json = Json.createObject(); + json.put("enableHighAccuracy", enableHighAccuracy); + json.put("maximumAge", maximumAge); + if (timeout != null) { + json.put("timeout", timeout); + } + return json; + } +} diff --git a/src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMap.java b/src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMap.java index db602c7..512c65f 100644 --- a/src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMap.java +++ b/src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMap.java @@ -2,7 +2,7 @@ * #%L * Google Maps Addon * %% - * Copyright (C) 2020 - 2024 Flowing Code + * Copyright (C) 2020 - 2025 Flowing Code * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -535,15 +535,28 @@ public Registration addRightClickListener(ComponentEventListenerSetting geolocation requires that the user gives consent to location sharing when prompted * by the browser. */ public void goToCurrentLocation() { - getElement().executeJs("geolocation.get($0)", this); + goToCurrentLocation(null); + } + + /** + * Sets current location on map using specific geolocation options. + * + *

Setting geolocation requires that the user gives consent to location sharing when prompted + * by the browser. + * + * @param options the geolocation options (enableHighAccuracy, timeout, maximumAge) + */ + public void goToCurrentLocation(GeolocationOptions options) { + JsonObject optionsJson = options == null ? Json.createObject() : options.toJson(); + getElement().executeJs("geolocation.get($0, $1)", this, optionsJson); } @ClientCallable @@ -610,6 +623,24 @@ public Registration addGeolocationErrorEventListener( ComponentEventListener listener) { return addListener(GeolocationErrorEvent.class, listener); } + + /** + * Activates tracking current location on map using default geolocation options. + * + *

Uses geolocation#watchPosition + * method to track current position.

+ * + *

Geolocation requires that the user gives consent to location sharing when prompted by the + * browser.

+ * + * @throws IllegalStateException if a tracking location session is already active. + * The current session must be stopped before starting a new one. + */ + public void trackLocation() { + trackLocation(null); + } + /** * Activates tracking current location on map. @@ -621,13 +652,15 @@ public Registration addGeolocationErrorEventListener( *

Geolocation requires that the user gives consent to location sharing when prompted by the * browser.

* + * @param options the geolocation options (enableHighAccuracy, timeout, maximumAge) * @throws IllegalStateException if a tracking location session is already active. * The current session must be stopped before starting a new one. */ - public void trackLocation() { + public void trackLocation(GeolocationOptions options) { if (getTrackLocationId() == null) { - getElement().executeJs("return geolocation.trackLocation($0)", this).then(Integer.class, - trackLocationId -> { + JsonObject optionsJson = options == null ? Json.createObject() : options.toJson(); + getElement().executeJs("return geolocation.trackLocation($0, $1)", this, optionsJson) + .then(Integer.class, trackLocationId -> { this.trackLocationId = trackLocationId; ComponentUtil.fireEvent(this, new LocationTrackingActivatedEvent(this, false)); }); diff --git a/src/main/resources/META-INF/resources/frontend/googlemaps/geolocation.js b/src/main/resources/META-INF/resources/frontend/googlemaps/geolocation.js index e8441ac..b49313f 100644 --- a/src/main/resources/META-INF/resources/frontend/googlemaps/geolocation.js +++ b/src/main/resources/META-INF/resources/frontend/googlemaps/geolocation.js @@ -2,7 +2,7 @@ * #%L * Google Maps Addon * %% - * Copyright (C) 2020 - 2024 Flowing Code + * Copyright (C) 2020 - 2025 Flowing Code * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,7 @@ */ window.geolocation = { - get: function(map) { + get: function(map, options) { // if browser supports geolocation, return current location if (navigator.geolocation) { @@ -29,7 +29,8 @@ window.geolocation = { }, () => { this._handleGeolocationError(true, map); - } + }, + options ); } else { // browser doesn't support geolocation @@ -37,7 +38,7 @@ window.geolocation = { } }, - trackLocation: function(map) { + trackLocation: function(map, options) { let trackLocationId; if (navigator.geolocation) { @@ -47,7 +48,8 @@ window.geolocation = { }, () => { this._handleGeolocationError(true, map); - } + }, + options ); } else { // browser doesn't support geolocation this._handleGeolocationError(false, map); diff --git a/src/test/java/com/flowingcode/vaadin/addons/googlemaps/TrackLocationDemo.java b/src/test/java/com/flowingcode/vaadin/addons/googlemaps/TrackLocationDemo.java index b42e3d1..aeed72f 100644 --- a/src/test/java/com/flowingcode/vaadin/addons/googlemaps/TrackLocationDemo.java +++ b/src/test/java/com/flowingcode/vaadin/addons/googlemaps/TrackLocationDemo.java @@ -2,7 +2,7 @@ * #%L * Google Maps Addon * %% - * Copyright (C) 2020 - 2024 Flowing Code + * Copyright (C) 2020 - 2025 Flowing Code * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,12 +41,15 @@ protected void createGoogleMapsDemo(String apiKey) { gmaps.setSizeFull(); gmaps.setZoom(15); add(gmaps); + + // define geolocation options for more accurate tracking + GeolocationOptions options = new GeolocationOptions(true, 5000L, 0L); // create buttons to activate/stop location tracking Button startLocationTrackingButton = new Button("Start tracking my location"); Button stopLocationTrackingButton = new Button("Stop tracking my location"); startLocationTrackingButton.addClickListener(e -> { - gmaps.trackLocation(); + gmaps.trackLocation(options); stopLocationTrackingButton.setEnabled(true); }); startLocationTrackingButton.setDisableOnClick(true);