Skip to content

Commit 9533bff

Browse files
paodbjavier-godoy
authored andcommitted
feat: add possibility to track location
Close #117
1 parent 5cdb14f commit 9533bff

File tree

4 files changed

+172
-14
lines changed

4 files changed

+172
-14
lines changed

src/main/java/com/flowingcode/vaadin/addons/googlemaps/GoogleMap.java

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,61 @@ public Registration addGeolocationErrorEventListener(
609609
ComponentEventListener<GeolocationErrorEvent> listener) {
610610
return addListener(GeolocationErrorEvent.class, listener);
611611
}
612+
613+
/**
614+
* Activates tracking current location on map.
615+
*
616+
* <p>Uses <a href=
617+
* "https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/watchPosition">geolocation#watchPosition</a>
618+
* method to track current position.</p>
619+
*
620+
* <p>Geolocation requires that the user gives consent to location sharing when prompted by the
621+
* browser.</p>
622+
*/
623+
public void trackLocation() {
624+
getElement().executeJs("return geolocation.trackLocation($0)", this).then(Integer.class,
625+
trackLocationId -> {
626+
ComponentUtil.fireEvent(this,
627+
new LocationTrackingActivatedEvent(this, false, trackLocationId));
628+
});
629+
}
630+
631+
/** Event that is fired when activating location tracking. */
632+
public class LocationTrackingActivatedEvent extends ComponentEvent<GoogleMap> {
633+
634+
private Integer trackLocationId;
635+
636+
public LocationTrackingActivatedEvent(GoogleMap source, boolean fromClient,
637+
Integer trackLocationId) {
638+
super(source, fromClient);
639+
this.trackLocationId = trackLocationId;
640+
}
641+
642+
public Integer getTrackLocationId() {
643+
return trackLocationId;
644+
}
645+
}
646+
647+
/**
648+
* Adds a LocationTrackingActivatedEvent listener. The listener is called when setting activating
649+
* tracking location.
650+
*
651+
* @param listener a listener for a LocationTrackingActivatedEvent
652+
* @return a handle for the listener
653+
*/
654+
public Registration addLocationTrackingActivatedEventListener(
655+
ComponentEventListener<LocationTrackingActivatedEvent> listener) {
656+
return addListener(LocationTrackingActivatedEvent.class, listener);
657+
}
658+
659+
/**
660+
* Stops location tracking.
661+
*
662+
* @param trackLocationId the id of the current activated location tracking
663+
*/
664+
public void stopTrackLocation(Integer trackLocationId) {
665+
getElement().executeJs("geolocation.clearTracking($0)", trackLocationId);
666+
}
612667

613668
/**
614669
* Returns a {@link CompletableFuture} containing the map current {@link LatLonBounds bounds}.

src/main/resources/META-INF/resources/frontend/googlemaps/geolocation.js

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,46 @@
2020
window.geolocation = {
2121

2222
get: function(map) {
23-
// if browser supports geolocation, return current location
24-
if(navigator.geolocation) {
23+
// if browser supports geolocation, return current location
24+
if (navigator.geolocation) {
2525

26-
navigator.geolocation.getCurrentPosition(
27-
position => {
28-
map.$server.handleGeolocation(position.coords.latitude, position.coords.longitude);
29-
},
30-
() => {
31-
map.$server.handleGeolocationError(true);
32-
});
33-
34-
} else { // browser doesn't support geolocation
35-
map.$server.handleGeolocationError(false);
36-
}
37-
}
26+
navigator.geolocation.getCurrentPosition(
27+
position => {
28+
map.$server.handleGeolocation(position.coords.latitude, position.coords.longitude);
29+
},
30+
() => {
31+
this._handleGeolocationError(true, map);
32+
}
33+
);
3834

35+
} else { // browser doesn't support geolocation
36+
this._handleGeolocationError(false, map);
37+
}
38+
},
39+
40+
trackLocation: function(map) {
41+
let trackLocationId;
42+
if (navigator.geolocation) {
43+
44+
trackLocationId = navigator.geolocation.watchPosition(
45+
position => {
46+
map.$server.handleGeolocation(position.coords.latitude, position.coords.longitude);
47+
},
48+
() => {
49+
this._handleGeolocationError(true, map);
50+
}
51+
);
52+
} else { // browser doesn't support geolocation
53+
this._handleGeolocationError(false, map);
54+
}
55+
return trackLocationId;
56+
},
57+
58+
clearTracking: function(id) {
59+
navigator.geolocation.clearWatch(id);
60+
},
61+
62+
_handleGeolocationError(error, map){
63+
map.$server.handleGeolocationError(error);
64+
}
3965
}

src/test/java/com/flowingcode/vaadin/addons/googlemaps/GooglemapsDemoView.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public GooglemapsDemoView() {
4646
addDemo(ClusteringWithCustomRendererDemo.class);
4747
addDemo(PolylinesDemo.class);
4848
addDemo(CustomizedMarkerIconsDemo.class);
49+
addDemo(TrackLocationDemo.class);
4950
setSizeFull();
5051
}
5152
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*-
2+
* #%L
3+
* Google Maps Addon
4+
* %%
5+
* Copyright (C) 2020 - 2024 Flowing Code
6+
* %%
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
* #L%
19+
*/
20+
21+
package com.flowingcode.vaadin.addons.googlemaps;
22+
23+
import com.flowingcode.vaadin.addons.demo.DemoSource;
24+
import com.flowingcode.vaadin.addons.googlemaps.GoogleMap.MapType;
25+
import com.vaadin.flow.component.button.Button;
26+
import com.vaadin.flow.component.notification.Notification;
27+
import com.vaadin.flow.router.PageTitle;
28+
import com.vaadin.flow.router.Route;
29+
30+
@PageTitle("Track Location Demo")
31+
@DemoSource
32+
@Route(value = "googlemaps/tracklocation", layout = GooglemapsDemoView.class)
33+
@SuppressWarnings("serial")
34+
public class TrackLocationDemo extends AbstractGoogleMapsDemo {
35+
36+
private Integer trackLocationId = null;
37+
38+
@Override
39+
protected void createGoogleMapsDemo(String apiKey) {
40+
GoogleMap gmaps = new GoogleMap(apiKey, null, null);
41+
gmaps.setMapType(MapType.ROADMAP);
42+
gmaps.setSizeFull();
43+
gmaps.setZoom(15);
44+
add(gmaps);
45+
46+
// create button to activate location tracking
47+
Button startLocationTrackingButton =
48+
new Button("Start tracking my location", e -> gmaps.trackLocation());
49+
// create button to stop location tracking
50+
Button stopLocationTrackingButton =
51+
new Button("Stop tracking my location", e -> gmaps.stopTrackLocation(trackLocationId));
52+
add(startLocationTrackingButton, stopLocationTrackingButton);
53+
54+
// create marker to track location
55+
GoogleMapMarker locationMarker = new GoogleMapMarker();
56+
locationMarker.setCaption("You're here");
57+
locationMarker.setDraggable(false);
58+
gmaps.addMarker(locationMarker);
59+
60+
// add listener to obtain id when track location is activated
61+
gmaps.addLocationTrackingActivatedEventListener(ev -> {
62+
trackLocationId = ev.getTrackLocationId();
63+
});
64+
65+
// add listener to know when location was updated and update location marker position
66+
gmaps.addCurrentLocationEventListener(e -> {
67+
locationMarker.setPosition(e.getSource().getCenter());
68+
});
69+
70+
// add listener to capture geolocation error
71+
gmaps.addGeolocationErrorEventListener(e -> {
72+
if (!e.isBrowserHasGeolocationSupport())
73+
Notification.show("Your browser doesn't support geolocation.");
74+
});
75+
}
76+
}

0 commit comments

Comments
 (0)