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
LocationDisplayobject by callinggetLocationDisplay()on the map view. - Create a
SimulatedLocationDataSourceand call itssetLocations()method, passing the routePolylineand newSimulationParametersas 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 2022 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. */module com.esri.samples.display_device_location_with_autopan_modes { // require ArcGIS Maps SDK for Java module requires com.esri.arcgisruntime;
// handle SLF4J http://www.slf4j.org/codes.html#StaticLoggerBinder requires org.slf4j.nop;
// require JavaFX modules that the application uses requires javafx.graphics; requires javafx.controls;
// require other modules the application uses requires org.apache.commons.io;
exports com.esri.samples.display_device_location_with_autopan_modes;}/* * 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); }}