Skip To Content ArcGIS for Developers Sign In Dashboard

Closest Facility


 * Copyright 2017 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
 * 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.


import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutionException;

import javafx.application.Application;
import javafx.geometry.Point2D;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

import com.esri.arcgisruntime.concurrent.ListenableFuture;
import com.esri.arcgisruntime.geometry.Point;
import com.esri.arcgisruntime.geometry.SpatialReference;
import com.esri.arcgisruntime.geometry.SpatialReferences;
import com.esri.arcgisruntime.loadable.LoadStatus;
import com.esri.arcgisruntime.mapping.ArcGISMap;
import com.esri.arcgisruntime.mapping.Basemap;
import com.esri.arcgisruntime.mapping.Viewpoint;
import com.esri.arcgisruntime.mapping.view.Graphic;
import com.esri.arcgisruntime.mapping.view.GraphicsOverlay;
import com.esri.arcgisruntime.mapping.view.MapView;
import com.esri.arcgisruntime.symbology.PictureMarkerSymbol;
import com.esri.arcgisruntime.symbology.SimpleLineSymbol;
import com.esri.arcgisruntime.symbology.SimpleMarkerSymbol;
import com.esri.arcgisruntime.tasks.networkanalysis.ClosestFacilityParameters;
import com.esri.arcgisruntime.tasks.networkanalysis.ClosestFacilityResult;
import com.esri.arcgisruntime.tasks.networkanalysis.ClosestFacilityRoute;
import com.esri.arcgisruntime.tasks.networkanalysis.ClosestFacilityTask;
import com.esri.arcgisruntime.tasks.networkanalysis.Facility;
import com.esri.arcgisruntime.tasks.networkanalysis.Incident;

public class ClosestFacilitySample extends Application {

  // black cross were user clicked
  private Point incidentPoint;
  private GraphicsOverlay facilityGraphicsOverlay;
  private GraphicsOverlay incidentGraphicsOverlay;
  // holds locations of hospitals around San Diego
  private List<Facility> facilities;
  private MapView mapView;
  // solves task to find closest route between an incident and a facility
  private ClosestFacilityTask task;
  // parameters needed to solve for route
  private ClosestFacilityParameters closestFacilityParameters;
  // used to display route between incident and facility to mapview
  private SimpleLineSymbol routeSymbol;
  // same spatial reference of the map
  private final SpatialReference spatialReference = SpatialReferences.getWebMercator();

  public void start(Stage stage) {

    // pane will hold mapview to be displayed on application 
    StackPane stackPane = new StackPane();
    Scene scene = new Scene(stackPane);

    // set title, size, and add scene to stage
    stage.setTitle("Closest Facility Sample");

    try {

      // create a map with streets basemap and add to view
      ArcGISMap map = new ArcGISMap(Basemap.createStreets());
      mapView = new MapView();
      // add the mapview to stack pane

      // set view to be over San Diego
      mapView.setViewpoint(new Viewpoint(32.727, -117.1750, 40000));

      facilityGraphicsOverlay = new GraphicsOverlay();
      incidentGraphicsOverlay = new GraphicsOverlay();
      // to load graphics faster, add graphics overlay to view once all graphics are in graphics overlay

      // task to find the closest route between an incident and a facility 
      final String sanDiegoRegion =
      task = new ClosestFacilityTask(sanDiegoRegion);
      task.addDoneLoadingListener(() -> {
        if (task.getLoadStatus() == LoadStatus.LOADED) {
          try {
            closestFacilityParameters = task.createDefaultParametersAsync().get();
            // set new parameters to find route
          } catch (ExecutionException | InterruptedException e) {
        } else {
          Alert alert = new Alert(Alert.AlertType.ERROR, "Closest Facility Task Failed to Load!");

      // symbols that display incident(black cross) and route(blue line) to view
      SimpleMarkerSymbol incidentSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CROSS, 0xFF000000, 20);
      routeSymbol = new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, 0xFF0000FF, 2.0f);

      // place incident were user clicks and display route to closest facility
      mapView.setOnMouseClicked(e -> {
        // check that the primary mouse button was clicked
        if (e.getButton() == MouseButton.PRIMARY && e.isStillSincePress()) {
          // remove last incident from view
          // show incident to the mapview
          Point mapPoint = mapView.screenToLocation(new Point2D(e.getX(), e.getY()));
          incidentPoint = new Point(mapPoint.getX(), mapPoint.getY(), spatialReference);
          Graphic graphic = new Graphic(incidentPoint, incidentSymbol);

    } catch (Exception e) {
      // on any error, display the stack trace.

   * Creates facilities around the San Diego region.
   * <p>
   * Facilities are created using point geometry which is then used to make graphics for the graphics overlay.
  private void createFacilitiesAndGraphics() {
    // List of facilities to be placed around San Diego area
    facilities = Arrays.asList(
        new Facility(new Point(-1.3042129900625112E7, 3860127.9479775648, spatialReference)),
        new Facility(new Point(-1.3042193400557665E7, 3862448.873041752, spatialReference)),
        new Facility(new Point(-1.3046882875518233E7, 3862704.9896770366, spatialReference)),
        new Facility(new Point(-1.3040539754780494E7, 3862924.5938606677, spatialReference)),
        new Facility(new Point(-1.3042571225655518E7, 3858981.773018156, spatialReference)),
        new Facility(new Point(-1.3039784633928463E7, 3856692.5980474586, spatialReference)),
        new Facility(new Point(-1.3049023883956768E7, 3861993.789732541, spatialReference)));

    // image for displaying facility
    String facilityUrl = "";
    PictureMarkerSymbol facilitySymbol = new PictureMarkerSymbol(facilityUrl);

    // for each facility, create a graphic and add to graphics overlay -> new Graphic(f.getGeometry(), facilitySymbol))
        .collect(Collectors.toCollection(() -> facilityGraphicsOverlay.getGraphics()));

   * Adds facilities(hospitals) and user's incident(black cross) to closest facility parameters which will be used to 
   * display the closest route from the user's incident to its' nearest facility.
  private void populateParametersAndSolveRoute() {
    closestFacilityParameters.setIncidents(Collections.singletonList(new Incident(incidentPoint)));

    // find closest route using parameters from above
    ListenableFuture<ClosestFacilityResult> result = task.solveClosestFacilityAsync(closestFacilityParameters);
    result.addDoneListener(() -> {
      try {
        ClosestFacilityResult facilityResult = result.get();
        // a list of closest facilities based on users incident
        List<Integer> rankedList = facilityResult.getRankedFacilityIndexes(0);
        // get the index of the closest facility to incident
        int closestFacility = rankedList.get(0);
        // get route from incident to closest facility and display to mapview
        ClosestFacilityRoute route = facilityResult.getRoute(closestFacility, 0);
        incidentGraphicsOverlay.getGraphics().add(new Graphic(route.getRouteGeometry(), routeSymbol));
      } catch (ExecutionException e) {
        if (e.getMessage().contains("Unable to complete operation")) {
          Alert dialog = new Alert(AlertType.WARNING);
          dialog.setTitle("Route Error");
          dialog.setContentText("Incident not within San Diego area!");
        } else {
      } catch (InterruptedException e) {

   * Stops and releases all resources used in application.
  public void stop() {

    if (mapView != null) {

   * Opens and runs application.
   * @param args arguments passed to this application
  public static void main(String[] args) {



In this topic
  1. Code