From 69e3e4f2357b207f8453aeb1b9022b1b84d31511 Mon Sep 17 00:00:00 2001 From: Paola De Bartolo Date: Thu, 21 Aug 2025 15:59:31 -0300 Subject: [PATCH 1/2] feat: add API to define geolocation options if needed Those options can help to get more accurate results on trackLocation and goToCurrentLocation features. Close #151 --- .../addons/googlemaps/GeolocationOptions.java | 76 +++++++++++++++++++ .../vaadin/addons/googlemaps/GoogleMap.java | 47 ++++++++++-- .../frontend/googlemaps/geolocation.js | 12 +-- .../addons/googlemaps/TrackLocationDemo.java | 7 +- 4 files changed, 128 insertions(+), 14 deletions(-) create mode 100644 src/main/java/com/flowingcode/vaadin/addons/googlemaps/GeolocationOptions.java 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..59d14aa --- /dev/null +++ b/src/main/java/com/flowingcode/vaadin/addons/googlemaps/GeolocationOptions.java @@ -0,0 +1,76 @@ +/*- + * #%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. + */ + 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(); + if (enableHighAccuracy != null) { + json.put("enableHighAccuracy", enableHighAccuracy); + } + if (timeout != null) { + json.put("timeout", timeout); + } + if (maximumAge != null) { + json.put("maximumAge", maximumAge); + } + 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); From 53b4a869a8eb8fbec0360fdd33c563840c8978c8 Mon Sep 17 00:00:00 2001 From: Paola De Bartolo Date: Thu, 21 Aug 2025 17:47:24 -0300 Subject: [PATCH 2/2] WIP: use primitives and improve documentation --- .../addons/googlemaps/GeolocationOptions.java | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/flowingcode/vaadin/addons/googlemaps/GeolocationOptions.java b/src/main/java/com/flowingcode/vaadin/addons/googlemaps/GeolocationOptions.java index 59d14aa..184bf2e 100644 --- a/src/main/java/com/flowingcode/vaadin/addons/googlemaps/GeolocationOptions.java +++ b/src/main/java/com/flowingcode/vaadin/addons/googlemaps/GeolocationOptions.java @@ -41,11 +41,12 @@ public class GeolocationOptions { * 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; + 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. + * allowed to take in order to return a position. + * If null, the device won't timeout until the position is available. */ private Long timeout; @@ -53,7 +54,7 @@ public class GeolocationOptions { * A positive long value representing the maximum age (in milliseconds) of a possible cached * position that is acceptable to return. */ - private Long maximumAge; + private long maximumAge; /** * Converts the options to a JsonObject to be sent to the client-side. @@ -62,15 +63,11 @@ public class GeolocationOptions { */ public JsonObject toJson() { JsonObject json = Json.createObject(); - if (enableHighAccuracy != null) { - json.put("enableHighAccuracy", enableHighAccuracy); - } + json.put("enableHighAccuracy", enableHighAccuracy); + json.put("maximumAge", maximumAge); if (timeout != null) { json.put("timeout", timeout); } - if (maximumAge != null) { - json.put("maximumAge", maximumAge); - } return json; } }