Show device location (GPS)

There are two ways to display GPS locations on a map using the API:

  1. Use a GPS layer
  2. Use a graphics layer and a custom GPS event listener

The first option is best for the simple display of GPS location data, including the current location, previous track points, and a trail connecting the track points. This option includes the ability to set a GPS mode on the layer, such as automatically panning the map to keep the latest GPS point visible. The second option is best if you want to further customize the display of GPS information, for example, to display satellite information on screen or change the GPS symbol based on the status of the GPS device. With either option, you can display the location data either from a connected device or from a text file containing raw NMEA sentences.

Use a GPS layer

If you have not already done so, create a Java application with a map as described in the topic Create a simple map application.

In the Java map application, create a GPSLayer instance and add it to the map, placing the code after the tiled layer code, which will serve as a basemap:

// create the tiled layer and add to map (could also be an ArcGISLocalTiledLayer)
ArcGISTiledMapServiceLayer tiledLayer = new ArcGISTiledMapServiceLayer(
    "http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer");
map.getLayers().add(tiledLayer);

// create a GPS layer and add to map
GPSLayer gpsLayer = new GPSLayer();
map.getLayers().add(gpsLayer);

You can create a GPSLayer with no parameters, as in the previous code example, which results in a default serial port GPS watcher (SerialPortGPSWatcher) being used internally to obtain data for the layer. This is the option to use if you want to display data from a connected GPS device via a serial port (it could be a virtual serial port for testing purposes).

You can also create a GPSLayer using a custom IGPSWatcher as a parameter. For example, to display data from a file containing raw NMEA data, you can create a FileGPSWatcher and pass it as a parameter to the layer:

IGPSWatcher watcher = new FileGPSWatcher("path of NMEA text file", 500, true);
GPSLayer gpsLayer = new GPSLayer(watcher);

To display data from a GPS device connected to a specific serial port, create a SerialPortGPSWatcher with the desired serial port information (SerialPortInfo), and pass the watcher as a parameter when you create the GPSLayer:

// create SerialPortInfo for a port named "COM2"
SerialPortInfo myPortInfo = new SerialPortInfo(
    "COM2", BaudRate.BAUD_4800, Parity.NONE, StopBits.ONE, 7);
SerialPortGPSWatcher myWatcher = new SerialPortGPSWatcher(myPortInfo);
GPSLayer gpsLayer = new GPSLayer(myWatcher);

Note:

Creating a SerialPortInfo object with the parameters matching your serial port's settings is necessary if your serial port or virtual serial port is named something other than COM* on Windows, or /dev/ttyS* on Linux.

Now that your GPSLayer has been created and added to the map, you can run the application, and it will display your location if you have a GPS receiver connected to your machine. If you're using a FileGPSWatcher, the application will display the location of the object tracked in the file containing the raw NMEA sentences.

The GPS layer can be set to different modes, depending on how you want the map to pan and the GPS symbol aligned. See the GPS layer modes section for more information. You can also customize the GPS layer, for example, by setting your own location symbol or choosing not to display a trail or track points, using the following methods on the GPS layer:

  • setLocationSymbol(MarkerSymbol)
  • setShowStatus(boolean), setStatusSymbol(TextSymbol)
  • setShowTrackPoints(boolean), setTrackPointSymbol(MarkerSymbol)
  • setShowTrail(boolean), setTrailSymbol(LineSymbol)

Use a custom GPS event listener

To further customize the display of GPS information—for example, to display satellite information on screen or change the GPS symbol based on the status of the GPS device—use a graphics layer in conjunction with a GPSWatcher and a custom GPSEventListener. First, create a GraphicsLayer instance, which will display the GPS data, and add it to the map:

GraphicsLayer myGpsLayer = new GraphicsLayer();
map.getLayers().add(myGpsLayer);

Secondly, create a custom GPSEventListener. This is a listener that implements the interface GPSEventListener. You can implement four methods from this interface:

  • onNMEASentenceReceived(String newSentence)
  • onPositionChanged(GeoPosition newPosition)
  • onSatellitesInViewChanged(Map<Integer,Satellite> satellitesInView)
  • onStatusChanged(GPSStatus newStatus)

These methods will contain the logic behind displaying GPS information or reacting to a change in the status of the GPS device, as the next step is to pass this custom GPS event listener to a GPS Watcher. If displaying GPS data from a connected GPS device, create a SerialPortGPSWatcher with the custom listener as a parameter in the constructor. If displaying GPS data saved to a text file (containing the raw NMEA sentences), create a FileGPSWatcher with the custom listener as one of the parameters in the constructor. The listener receives events from the GPS watcher when an NMEA sentence is received, when the position of the tracked object has changed, when the satellites in view have changed, and when the status of the GPS watcher has changed (representing the status of the underlying GPS device).

As an example, you can display satellite information on screen using a custom GPS event listener by implementing the onSatellitesInViewChanged method of the listener to take the data passed in as a parameter and display it in a UI element of your choice. To display the current location of the tracked object (a user's computer if a GPS device is connected and receiving data), implement the onPositionChanged method to take the position received, and display it as a graphic in the graphics layer of the map. Take care to reproject the point from the spatial reference of the GPS data points (WGS84) to the spatial reference of the map if they differ.

GPS layer modes

If you decide to use a GPSLayer, three modes can be set on the layer, which define how the map will behave when location updates are received: OFF, AUTOPAN, and NAVIGATION.

OFF

In this mode, the GPS layer does not pan or zoom automatically. GPS points can be plotted off-screen and, in this case, the user must pan the map with the mouse to see them. The map has North at the top of the screen, but the mode does not enforce this; the user can rotate the map as desired using a rotation control.

AUTOPAN

This is the default mode for the GPS layer. In this mode, the GPS layer always keeps the latest point on screen. The map will pan automatically if the latest GPS point is outside of an envelope taking up a certain percentage of the dimensions of the map. In this case, the new extent will be centered at this latest GPS point. Set the boundary of this envelope using setAutoFocusBoundary(int i), where i is between 0 and 100. For example, setting the auto-focus boundary to 0 means the map pans only when the latest point is outside the visible map; setting the boundary to 99 means the map will recenter on every location update. The default auto-focus boundary is 20.

gpsLayer.setMode(Mode.AUTOPAN);
gpsLayer.setAutoFocusBoundary(40);

NAVIGATION

This mode is most useful for in-vehicle navigation. In this mode, the GPS symbol for the current location is fixed at a certain position on the map and appears stationary while the map pans and rotates around it. The rotation angle of the map will be equal to the current course of the tracked device, such that the symbol will always be pointing to the top of the map. The location on the map of the GPS symbol will always be somewhere along an invisible vertical line dividing the map into equals halves, and the location of the point along this line can be controlled using the setPointHeightFactor(float factor) method. For example, setting this factor to 0.0 will show the GPS symbol centered along the bottom edge of the map; setting this to 1.0 will show the symbol centered along the top edge of the map. The default value is 0.5, showing the symbol at the center of the map.

gpsLayer.setMode(Mode.NAVIGATION);
gpsLayer.setNavigationPointHeightFactor(0.3);

Sample code

Several interactive sample applications that use the methods discussed here are available in the ArcGIS Runtime for Java sample viewer, installed with the SDK, under the table of content heading Routing and navigation.