Intersect
Download Sample ViewerDescription
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;
}
}