Intersect

Download Sample Viewer

Description

This application shows how to compute the intersection of two polygons. The first polygon is drawn on the map programmatically, and the second polygon is drawn by the user which is implemented using a Map Overlay to handle mouse events. The 'intersect' operation is then performed between the two polygons and the resulting graphic is shown on the map. This application uses the static method GeometryEngine.intersect which returns the Geometry object resulting from the intersection between two Geometry objects.

Code snippet


    // get the intersection
    Geometry intersection = GeometryEngine.intersect(
        polygon1, polygon2, jMap.getSpatialReference());
 
    // show the resulting geometry on the map
    Graphic graphic = new Graphic(intersection, SYM_FILL_INTER); 
    graphicsLayer.addGraphic(graphic);
  

Sample Code

/* Copyright 2014 Esri

All rights reserved under the copyright laws of the United States
and applicable international laws, treaties, and conventions.

You may freely redistribute and use this sample code, with or
without modification, provided you include the original copyright
notice and use restrictions.

See the use restrictions.*/
package com.esri.client.samples.geometry;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;

import com.esri.client.local.ArcGISLocalTiledLayer;
import com.esri.toolkit.overlays.DrawingCompleteEvent;
import com.esri.toolkit.overlays.DrawingCompleteListener;
import com.esri.toolkit.overlays.DrawingOverlay;
import com.esri.toolkit.overlays.DrawingOverlay.DrawingMode;
import com.esri.core.geometry.Envelope;
import com.esri.core.geometry.Geometry;
import com.esri.core.geometry.GeometryEngine;
import com.esri.core.geometry.Polygon;
import com.esri.core.geometry.SpatialReference;
import com.esri.core.map.Graphic;
import com.esri.core.symbol.SimpleFillSymbol;
import com.esri.core.symbol.SimpleLineSymbol;
import com.esri.map.GraphicsLayer;
import com.esri.map.JMap;
import com.esri.map.LayerList;
import com.esri.map.MapEvent;
import com.esri.map.MapEventListenerAdapter;
import com.esri.runtime.ArcGISRuntime;

/**
 * This application shows how to compute the intersection of two geometries,
 * in this case polygons. The first polygon is drawn on the map
 * programmatically while the second polygon is drawn by the user, using
 * a {@link DrawingOverlay} set up in polygon drawing mode.
 * <p>
 * The 'intersect' operation is then performed between the two polygons
 * and the resulting graphic is shown on the map.  This application uses
 * the static method <code>GeometryEngine.intersect</code> which returns
 * the <code>Geometry</code> object resulting from the intersection between
 * two <code>Geometry</code> objects.
 */
public class IntersectApp {

  // symbology
  final static SimpleLineSymbol SYM_LINE =
      new SimpleLineSymbol(new Color(200, 0, 0), 2);
  final static SimpleFillSymbol SYM_FILL =
      new SimpleFillSymbol(new Color(200, 0, 0, 120), SYM_LINE);
  final static SimpleFillSymbol SYM_FILL_INTER =
      new SimpleFillSymbol(new Color(0, 0, 200, 120), new SimpleLineSymbol(new Color(0, 0, 200), 2));

  private JMap map;
  private DrawingOverlay polygonOverlay;
  private GraphicsLayer graphicsLayer;
  private Polygon shape1; // drawn by default at start
  private Polygon shape2; // drawn by user

  // the spatial reference of the map, defined by the base layer used
  private SpatialReference srMap;
  // define the spatial reference of our points, WGS84
  private static SpatialReference wgs84 = SpatialReference.create(4326);
  private static final int PANEL_WIDTH = 275;
  private static final Color BG_COLOR = new Color(0, 0, 0, 60);
  private static final String FSP = System.getProperty("file.separator");

  // ------------------------------------------------------------------------
  // Constructor
  // ------------------------------------------------------------------------
  public IntersectApp() {
  }

  // ------------------------------------------------------------------------
  // Core functionality
  // ------------------------------------------------------------------------
  private void computeIntersection(Polygon polygon1, Polygon polygon2) {
    // compute the intersection
    Geometry intersection = GeometryEngine.intersect(polygon1, polygon2, srMap);
    // add the result as a graphic to the map
    Graphic graphic = new Graphic(intersection, SYM_FILL_INTER);
    graphicsLayer.addGraphic(graphic);
  }

  /**
   * Creates the map, adding to it a base layer, a graphics layer, and a
   * map overlay enabling the user to draw polygons.
   * @return a map.
   */
  private JMap createMap() throws Exception {
    final JMap jMap = new JMap();
    // -----------------------------------------------------------------------------------------
    // Base Layer: local tile package
    // -----------------------------------------------------------------------------------------
    final ArcGISLocalTiledLayer tiledLayer = new ArcGISLocalTiledLayer(
        getPathSampleData() + "tpks" + FSP + "Topographic.tpk");
    LayerList layers = jMap.getLayers();
    layers.add(tiledLayer);

    // -----------------------------------------------------------------------------------------
    // Graphics Layer - to add polygon graphics to
    // -----------------------------------------------------------------------------------------
    graphicsLayer = new GraphicsLayer();
    layers.add(graphicsLayer);

    // -----------------------------------------------------------------------------------------
    // Drawing Overlay - set up in polygon drawing mode
    // -----------------------------------------------------------------------------------------
    polygonOverlay = new DrawingOverlay();
    polygonOverlay.setUp(DrawingMode.POLYGON, SYM_FILL, null);
    polygonOverlay.addDrawingCompleteListener(new DrawingCompleteListener() {

      @Override
      public void drawingCompleted(DrawingCompleteEvent arg0) {
        // get the graphic
        Graphic graphic = (Graphic) polygonOverlay.getAndClearFeature();
        // add graphic to our map's graphics layer
        graphicsLayer.addGraphic(graphic);
        // store the geometry for the computation
        shape2 = (Polygon) graphic.getGeometry();
        // deactivate overlay so user can only draw one polygon at a time
        polygonOverlay.setActive(false);
      }
    });
    jMap.addMapOverlay(polygonOverlay);
    // activate the overlay to enable the default 'pan tolerance'
    polygonOverlay.setActive(true);

    // set extent to Europe and get spatial reference
    jMap.setExtent(new Envelope(-3054370, 2633000, 6553460, 9041460));

    // store the map's spatial reference once the map is ready, then add the first polygon
    jMap.addMapEventListener(new MapEventListenerAdapter() {
      @Override
      public void mapReady(final MapEvent mapEvent) {
        SwingUtilities.invokeLater(new Runnable() {
          @Override
          public void run() {
            srMap = mapEvent.getMap().getSpatialReference();
            addFirstPolygon();
          }
        });
      }
    });

    return jMap;
  }

  // ------------------------------------------------------------------------
  // Static methods
  // ------------------------------------------------------------------------
  /**
   * Starting point of this application.
   * @param args arguments to this application.
   */
  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
      @Override
      public void run() {
        try {
          // instance of this application
          IntersectApp intersectApp = new IntersectApp();

          // create the UI, including the map, for the application.
          JFrame appWindow = intersectApp.createWindow();
          appWindow.add(intersectApp.createUI());
          appWindow.setVisible(true);
        } catch (Exception e) {
          // on any error, display the stack trace.
          e.printStackTrace();
        }
      }
    });
  }

  // ------------------------------------------------------------------------
  // Public methods
  // ------------------------------------------------------------------------
  /**
   * Creates and displays the UI, including the map, for this application.
   */
  public JComponent createUI() throws Exception {

    // application content
    JLayeredPane contentPane = createContentPane();

    // map
    map = createMap();

    // user panel
    JPanel panel = createUserPanel();

    contentPane.add(panel);
    contentPane.add(map);

    return contentPane;
  }

  // ------------------------------------------------------------------------
  // Private methods
  // ------------------------------------------------------------------------
  private void addFirstPolygon() {
    Polygon polygon1 = new Polygon();
    polygon1.startPath(23, 52);
    polygon1.lineTo(28, 59);
    polygon1.lineTo(45, 59);
    polygon1.lineTo(47, 55);
    polygon1.lineTo(45, 48);
    polygon1.closePathWithLine();

    // project polygon to our map's spatial reference
    shape1 = (Polygon) GeometryEngine.project(polygon1, wgs84, srMap);
    Graphic graphic = new Graphic(shape1, SYM_FILL);
    graphicsLayer.addGraphic(graphic);
  }

  /**
   * Creates a window.
   * @return a window.
   */
  private JFrame createWindow() {
    JFrame window = new JFrame("Intersect Application");
    window.setBounds(100, 100, 1000, 700);
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.getContentPane().setLayout(new BorderLayout(0, 0));
    window.addWindowListener(new WindowAdapter() {
      @Override
      public void windowClosing(WindowEvent windowEvent) {
        super.windowClosing(windowEvent);
        map.dispose();
      }
    });
    return window;
  }

  /**
   * Creates a content pane.
   * @return a content pane.
   */
  private static JLayeredPane createContentPane() {
    JLayeredPane contentPane = new JLayeredPane();
    contentPane.setBounds(100, 100, 1000, 700);
    contentPane.setLayout(new BorderLayout(0, 0));
    contentPane.setVisible(true);
    return contentPane;
  }

  /**
   * Creates a description for this application.
   * @return description
   */
  private JTextArea createDescription() {
    JTextArea description = new JTextArea(
        "Draw a second polygon on the map via left clicks of the mouse; " +
            "double-click to complete the polygon. Click the button below to " +
            "compute the 'intersect' operation between the two polygons and " +
            "show the resulting geometry on the map. Click the 'reset' button " +
        "to clear the drawn polygon and start over.");
    description.setFont(new Font("Verdana", Font.PLAIN, 11));
    description.setForeground(Color.WHITE);
    description.setEditable(false);
    description.setLineWrap(true);
    description.setWrapStyleWord(true);
    description.setBackground(new Color(0, 0, 0, 180));
    description.setBorder(BorderFactory.createEmptyBorder(5,10,5,5));
    return description;
  }

  /**
   * Creates the panel to display description and capture user input
   */
  private JPanel createUserPanel() {

    // description
    JTextArea description = createDescription();

    // buttons
    Dimension buttonDim = new Dimension(PANEL_WIDTH, 30);

    // button panel
    final JButton btnIntersect = new JButton("Compute and show intersection");
    btnIntersect.setMinimumSize(buttonDim);
    btnIntersect.setMaximumSize(buttonDim);
    btnIntersect.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        if (shape2 != null) {
          computeIntersection(shape1, shape2);
          shape2 = null;
        }
      }
    });

    final JButton btnReset = new JButton("Reset");
    btnReset.setMinimumSize(buttonDim);
    btnReset.setMaximumSize(buttonDim);
    btnReset.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        graphicsLayer.removeAll();
        addFirstPolygon();
        shape2 = null;
        polygonOverlay.setActive(true); // reactivate the overlay
      }
    });

    // button panel
    JPanel buttonPanel = new JPanel();
    buttonPanel.setBackground(BG_COLOR);
    buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.Y_AXIS));
    buttonPanel.add(Box.createRigidArea(new Dimension(0, 5)));
    buttonPanel.add(btnIntersect);
    buttonPanel.add(Box.createRigidArea(new Dimension(0, 5)));
    buttonPanel.add(btnReset);

    JPanel panel = new JPanel();
    panel.setLayout(new BorderLayout(0, 0));
    panel.setLocation(10, 10);
    panel.setSize(PANEL_WIDTH, 210);
    panel.setBackground(new Color(0, 0, 0, 0));
    panel.setBorder(new LineBorder(BG_COLOR, 5, false));

    // group description and buttons in a panel
    panel.add(description, BorderLayout.CENTER);
    panel.add(buttonPanel, BorderLayout.SOUTH);

    return panel;
  }

  private String getPathSampleData() {
    String dataPath = null;
    String javaPath = ArcGISRuntime.getInstallDirectory();
    if (javaPath != null) {
      if (!(javaPath.endsWith("/") || javaPath.endsWith("\\"))){
        javaPath += FSP;
      }
      dataPath = javaPath + "sdk" + FSP + "samples" + FSP + "data" + FSP;
    }
    File dataFile = new File(dataPath);
    if (!dataFile.exists()) { 
      dataPath = ".." + FSP + "data" + FSP;
    }
    return dataPath;
  }
}
Feedback on this topic?