Multiple maps

An app can contain more than one map. Most often, an additional map is used to display an overview of the area of interest that is being studied on the main map. You can also use multiple maps to show the following:

  • Different layers of information about a specific area side by side
  • The detail of an area of the main map, such as its center or the area around the mouse

The number of maps that can be shown is limited by your hardware. Screen size and graphics processing will dictate how many maps can be practically used in your app. There is no hard limit imposed by ArcGIS Runtime.

Add an overview map

An overview map shows the extent of the main map at a smaller scale and provides spatial context for the area of interest. When you pan a map looking at detail, it is easy to lose where you started or to be unable to estimate how far away you are from features that are no longer in view.

The ArcGIS Runtime SDK for Java toolkit has an OverviewMap component that you can use to display a smaller map showing the current extent of a larger map that you navigate. The full source code of this component is available, so you can either use it as is or modify it to suit your purposes. Find this OverviewMap component in the com.esri.toolkit package of the toolkit jar.

By using the toolkit's OverviewMap component, adding an overview map to your app takes just a few lines of code. Ensure that your app is referencing the toolkit jar, then create and add an instance of OverviewMap using your main map component and the layer to display in the overview map, as shown in the following code snippet:

// create the main map component
JMap map = new JMap();
// ... add layers

// create a layer to display in the overview map
ArcGISTiledMapServiceLayer overviewLayer = new ArcGISTiledMapServiceLayer(BASEMAP_URL);

// create the overview map
overviewMap = new OverviewMap(map, overviewLayer);
overviewMap.setSize(250, 200);
// optional customization of the overview map
overviewMap.setMinimumFocusSize(8);
overviewMap.setFocusPointSize(12);

The following screen capture shows an overview map component displaying over the main map component from which it was created:

The Java toolkit Overview Map component screen capture

You can also build your own overview map component rather than using the toolkit component. The main steps to create an overview map of your own are as follows:

  • Ensure you have a main map component.
  • Define a second map component as your overview map.
  • Handle the extent-changed event of the main map and update the overview map extent appropriately.
  • Optionally display a graphic on the overview map that represents the current extent of the main map.

To display an outline representing the current extent of the main map in the overview map, you must include a graphics layer in your overview map and maintain a graphic representing the extent. Add a MapEventListener to your main map in order to update your overview map whenever the main map's extent changes. In the extent-changed event, after optionally updating the extent of the overview map, update the geometry of the extent graphic to show the current extent of the main map.

Side-by-side maps

Side-by-side maps are a great way to show different layers of information at the same time. For example, you can compare imagery with topographic information, display before and after images, or show different levels of detail side by side.

In one approach, you can create two map instances, set their initial extents to match, display them side by side in the layout of your choice, and let the user interact with both map components. In a second approach, you can let the first map control the extent of the second map. The following code snippet updates the extent of the secondary map whenever the main map's extent has changed:

mainMap = new JMap();
ArcGISTiledMapServiceLayer topoBasemap = new ArcGISTiledMapServiceLayer(BASEMAP_URL1);
mainMap.getLayers().add(topoBasemap);

secondaryMap = new JMap();
ArcGISTiledMapServiceLayer imageryBasemap = new ArcGISTiledMapServiceLayer(BASEMAP_URL2);
secondaryMap.getLayers().add(imageryBasemap);

// when mainMap's extent changes, update secondaryMap's extent
mainMap.addMapEventListener(new MapEventListenerAdapter() {

  @Override
  public void mapExtentChanged(MapEvent event) {
    // set secondary map's extent to the main map's extent
    secondaryMap.setExtent(event.getExtent());
  }
});

The recommended approach when sharing extents between multiple maps is to disable interaction for all but one map and allow that interaction to control updates to all other (dependent) maps. Mouse and keyboard interaction is enabled by default on map components, but it can be disabled. The following code snippet shows how you can disable interaction on a JMap instance:

secondaryMap = new JMap();
  ...

  // disable keyboard interaction
  secondaryMap.setKeyboardEnabled(false);
  // disable mouse interaction
  removeMouseListeners(secondaryMap);
}

private void removeMouseListeners(JComponent component) {
  MouseMotionListener[] mouseMotionListeners = component.getMouseMotionListeners();
  for (MouseMotionListener mouseMotionListener : mouseMotionListeners) {
    component.removeMouseMotionListener(mouseMotionListener);
  }
  MouseListener[] mouseListeners = component.getMouseListeners();
  for (MouseListener mouseListener : mouseListeners) {
    component.removeMouseListener(mouseListener);
  }
  MouseWheelListener[] mouseWheelListeners = component.getMouseWheelListeners();
  for (MouseWheelListener mouseWheelListener : mouseWheelListeners) {
    component.removeMouseWheelListener(mouseWheelListener);
  }
}

Detail map

Using an overview as your main map and showing detail in a separate window might be useful when you have multiple project sites spread apart geographically. You can define each map to have different layers of information, or they can have the same map layers but shown at a different scale.

To define a detail map that is related to a main map, a similar approach to the one described for an overview map can be used. The extent of the detail map can be updated when the main map's extent changes and adjusted to be a fraction of the scale of the main map. In the following example, the detail map uses a scale of 1/5 of the main map:

// when mainMap's extent changes, update detailMap's extent
mainMap.addMapEventListener(new MapEventListenerAdapter() {

  @Override
  public void mapExtentChanged(MapEvent event) {
    detailMap.setExtent(event.getExtent());
    double mainMapScale = event.getMap().getScale();
    detailMap.setScale(mainMapScale/5);
  }
});

A graphic of the area shown in the detail map could be displayed in the main map by adding a graphics layer to it and updating the graphic's geometry in the extent-changed event. You may also want to disable mouse and keyboard interaction in the detail map, which can be done in the same way as shown for side-by-side maps.