Display your position on the map and switch between different types of autopan modes.
Use case
When using a map within a GIS, it may be helpful for a user to know their own location within a map, whether that's to aid the user's navigation or to provide an easy means of identifying/collecting geospatial information at their location.
How to use the sample
The sample loads with a symbol marking a simulated location on the map. Explore the available autopan modes by selecting an option from the drop down box:
- Off - Shows the location with no autopan mode set.
- Re-Center - In this mode, the map re-centers on the location symbol when the symbol moves outside a "wander extent".
- Navigation - This mode is best suited for in-vehicle navigation.
- Compass - This mode is better suited for waypoint navigation when the user is walking.
Uncheck the box to stop the location display.
How it works
- Create a
MapView
. - Get the
LocationDisplay
object by callinggetLocationDisplay()
on the map view. - Create a
SimulatedLocationDataSource
and call itssetLocations()
method, passing the routePolyline
and newSimulationParameters
as parameters. - Start the location display with
startAsync()
to begin receiving location updates. - Use
locationDisplay.setAutoPanMode()
to change how the map view behaves when location updates are received.
Relevant API
- LocationDisplay
- LocationDisplay.AutoPanMode
- MapView
- SimulatedLocationDataSource
- SimulationParameters
Additional information
A custom set of points (provided in JSON format) is used to create a Polyline
and configure a SimulatedLocationDataSource
. The simulated location data source enables easier testing and allows the sample to be used on devices without an actively updating GPS signal. To display a user's real position, use NMEALocationDataSource
instead.
Tags
compass, GPS, location, map view, mobile, navigation
Sample Code
/*
* Copyright 2020 Esri.
*
* 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.
*/
package com.esri.samples.display_device_location_with_autopan_modes;
import java.nio.charset.StandardCharsets;
import java.util.Calendar;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Paint;
import javafx.stage.Stage;
import com.esri.arcgisruntime.ArcGISRuntimeEnvironment;
import com.esri.arcgisruntime.geometry.Geometry;
import com.esri.arcgisruntime.geometry.Polyline;
import com.esri.arcgisruntime.geometry.SpatialReferences;
import com.esri.arcgisruntime.loadable.LoadStatus;
import com.esri.arcgisruntime.location.SimulatedLocationDataSource;
import com.esri.arcgisruntime.location.SimulationParameters;
import com.esri.arcgisruntime.mapping.ArcGISMap;
import com.esri.arcgisruntime.mapping.BasemapStyle;
import com.esri.arcgisruntime.mapping.view.LocationDisplay;
import com.esri.arcgisruntime.mapping.view.MapView;
import org.apache.commons.io.IOUtils;
public class DisplayDeviceLocationWithAutopanModesSample extends Application {
private MapView mapView;
@Override
public void start(Stage stage) {
try {
// create the stack pane and the application scene
StackPane stackPane = new StackPane();
Scene scene = new Scene(stackPane);
// set a title, size, and add the scene to stage
stage.setTitle("Display Device Location With Autopan Modes Sample");
stage.setWidth(800);
stage.setHeight(700);
stage.setScene(scene);
stage.show();
scene.getStylesheets().add(getClass().getResource("/display_device_location_with_autopan_modes/style.css").toExternalForm());
// authentication with an API key or named user is required to access basemaps and other location services
String yourAPIKey = System.getProperty("apiKey");
ArcGISRuntimeEnvironment.setApiKey(yourAPIKey);
// create a map with the standard imagery basemap style
ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_IMAGERY_STANDARD);
// create a map view and set the map to it
mapView = new MapView();
mapView.setMap(map);
// create a combo box
ComboBox<String> comboBox = new ComboBox<>();
comboBox.setMaxWidth(Double.MAX_VALUE);
comboBox.setDisable(true);
// add the autopan modes to the combo box
comboBox.getItems().addAll("Re-Center", "Navigation", "Compass", "Off");
comboBox.setValue("Re-Center");
// add a label
Label autopanModeLabel = new Label("Choose an autopan mode:");
// add a checkbox that toggles the visibility of the location display
CheckBox checkBox = new CheckBox("Show device location");
checkBox.setDisable(true);
// access the json of the location points
String polylineData = IOUtils.toString(getClass().getResourceAsStream(
"/display_device_location_with_autopan_modes/polyline_data.json"), StandardCharsets.UTF_8);
// create a polyline from the location points
Polyline locations = (Polyline) Geometry.fromJson(polylineData, SpatialReferences.getWgs84());
// create a simulated location data source
SimulatedLocationDataSource simulatedLocationDataSource = new SimulatedLocationDataSource();
// set the location of the simulated location data source with simulation parameters to set a consistent velocity
simulatedLocationDataSource.setLocations(
locations, new SimulationParameters(Calendar.getInstance(), 5.0, 0.0, 0.0));
// configure the map view's location display to follow the simulated location data source
LocationDisplay locationDisplay = mapView.getLocationDisplay();
locationDisplay.setLocationDataSource(simulatedLocationDataSource);
locationDisplay.setAutoPanMode(LocationDisplay.AutoPanMode.RECENTER);
locationDisplay.setInitialZoomScale(1000);
// enable the checkbox and combo box interactions when the map is loaded
map.addDoneLoadingListener(() -> {
if (map.getLoadStatus() == LoadStatus.LOADED) {
checkBox.setDisable(false);
checkBox.setSelected(true);
comboBox.setDisable(false);
// start the location display
locationDisplay.startAsync();
} else {
new Alert(Alert.AlertType.ERROR, "Map failed to load: " + map.getLoadError().getCause().getMessage()).show();
}
});
// control location display updates and visibility
checkBox.setOnAction(event -> {
if (checkBox.isSelected()) {
// start receiving location updates and display the current location with a default round blue symbol
locationDisplay.startAsync();
} else {
// stop receiving location updates and displaying location symbol
locationDisplay.stop();
}
// toggle the combo box interactions
comboBox.setDisable(!checkBox.isSelected());
});
// set the autopan mode of the location display based on the mode chosen from the combo box
comboBox.getSelectionModel().selectedItemProperty().addListener(e -> {
// set the scale that the map view will zoom to when the autopan mode is changed
locationDisplay.setInitialZoomScale(1000);
switch (comboBox.getSelectionModel().getSelectedItem()) {
case "Off":
locationDisplay.setAutoPanMode(LocationDisplay.AutoPanMode.OFF);
break;
case "Re-Center":
locationDisplay.setAutoPanMode(LocationDisplay.AutoPanMode.RECENTER);
break;
case "Navigation":
locationDisplay.setAutoPanMode(LocationDisplay.AutoPanMode.NAVIGATION);
break;
case "Compass":
locationDisplay.setAutoPanMode(LocationDisplay.AutoPanMode.COMPASS_NAVIGATION);
break;
}
});
mapView.setOnMouseClicked(event -> {
if (event.getButton() == MouseButton.PRIMARY) {
// if the user has panned away from the location display
if (locationDisplay.getAutoPanMode() == LocationDisplay.AutoPanMode.OFF) {
// set the combo box
comboBox.setValue("Off");
}
}
});
// create a control panel
VBox controlsVBox = new VBox(6);
controlsVBox.setBackground(new Background(new BackgroundFill(Paint.valueOf("rgba(0,0,0,0.3)"), CornerRadii.EMPTY,
Insets.EMPTY)));
controlsVBox.setPadding(new Insets(10.0));
controlsVBox.setMaxSize(230, 50);
controlsVBox.getStyleClass().add("panel-region");
// add the checkbox, label and combo box to the control panel
controlsVBox.getChildren().addAll(checkBox, autopanModeLabel, comboBox);
// add the map view and control panel to the stack pane
stackPane.getChildren().addAll(mapView, controlsVBox);
StackPane.setAlignment(controlsVBox, Pos.TOP_RIGHT);
StackPane.setMargin(controlsVBox, new Insets(10, 10, 0, 0));
} catch (Exception e) {
// on any error, display the stack trace.
e.printStackTrace();
}
}
/**
* Stops and releases all resources used in application.
*/
@Override
public void stop() {
if (mapView != null) {
mapView.dispose();
}
}
/**
* Opens and runs application.
*
* @param args arguments passed to this application
*/
public static void main(String[] args) {
Application.launch(args);
}
}