### ArcGIS DevLabsJavaScriptSpatial Analysis

View it live

###### Feedback

Get in touch with us.

## Overview

You will learn: how to perform buffer, intersect and distance calculations using the geometry engine.

The geometry engine and the ArcGIS Geometry Service can be used to perform sophisticated spatial operations with geometry such as buffering, projecting, simplification, calculating distance and area, and determining spatial relationships. The geometry engine performs all of its operations client-side and can be used to build high performance and highly interactive applications. The ArcGIS Geometry Service performs all of the same operations as the geometry engine, with the addition of being able to project geometries and perform geometric operations in different spatial references. You can use the geometryEngine class for synchronous operations and the GeometryEngineAsync class for asynchronous operations, while the ArcGIS Geometry Service only works asynchronously. To learn more about all of the possible geometric operations, please visit the documentation.

In this lab you will use the geometry engine to buffer, intersect and calculate distances between points.

## Steps

#### Create a starter app

1. Go to the JavaScript Starter App.

2. In CodePen, click Fork and save the pen as `ArcGIS DevLabs: Buffer and intersect geometry`.

#### Create a point

In this step you will load the required modules for the application and create a point that represents the location for Malibu, California. This point will be used to for the geometric calculations in later steps.

1. In the `require` statement, add the Point, Graphic and geometryEngine module. The Graphic and geometryEngine module will be used later.

``````require([
"esri/Map",
"esri/views/MapView",
"esri/geometry/Point",
"esri/Graphic",
"esri/geometry/geometryEngine",
], function(Map, MapView, Point, Graphic, geometryEngine
) {
``````
2. In the main `function`, declare a `malibuPoint` variable and create it when the View is ready.

``````  //*** ADD ***//
var malibuPoint;

view.when(function(){
malibuPoint = new Point({
latitude: 34.03539,
longitude: -118.68634,
spatialReference: view.spatialReference
});
});
``````
3. Run the app to ensure there are no errors.

#### Create a buffer

In this step you will create and display a ten mile buffer graphic every time the cursor moves.

1. In the main `function`, create a `bufferGraphic` variable and add code to listen to when the pointer moves over the View. Create a point and use the geometryEngine `buffer` function to create a ten mile buffer and then add it to the map as a graphic.

``````  //*** ADD ***//
var bufferGraphic;

view.on("pointer-move", function(event){
// Buffer the point
var point = view.toMap(event);
var buffer = geometryEngine.buffer(point, 10, "miles");
// Draw the buffer
view.graphics.remove(bufferGraphic);  // Remove graphic
bufferGraphic = new Graphic({
geometry: buffer,
symbol: {
type: "simple-fill",
color: "rgba(0,0,0,.15)",
outline: {
color: "green",
width: 2
}
}
});
});
``````
2. Add code to listen for the `drag` event and use `StopPropagation` to prevent the map from panning as you move the mouse or your finger on the map. Clear all graphics when the pointer leaves the map.

``````  //*** ADD ***//
view.on("drag", function(){
// Prevent panning
event.stopPropagation();
});

view.on("pointer-leave", function(){
view.graphics.removeAll();
});
``````
3. Run the app and move your mouse on the map. You should see a buffer appear as you move.

#### Intersect a point with a polygon

In this step you will determine if the `malibuPoint` intersects with the buffer (polygon), and if it does, you will change the border color accordingly.

1. In the same function, add code to use the geometryEngine `intersects` function to determine if the `malibuPoint` and buffer intersect. If they do, change the symbol color of the buffer to red.

``````  view.on("pointer-move", function(event){
// Buffer the point
var point = view.toMap(event);
var buffer = geometryEngine.buffer(point, 10, "miles");

var intersects = geometryEngine.intersects(malibuPoint, buffer);

// Draw the buffer green or red (if it intersects)
bufferGraphic = new Graphic({
geometry: buffer,
symbol: {
type: "simple-fill",
color: "rgba(0,0,0,.15)",
outline: {

color: intersects ? "red" : "green",

width: 2
}
}
});
});
``````
2. Run the app and move your cursor over Malibu. You should see the buffer outline turn red when they intersect.

#### Calculate distance

In this step you will create a line to show the "line of sight" distance between the cursor and Malibu.

1. In the `pointer-move` function, add code to create a line graphic and draw a line from the cursor to the `malibuPoint`.

``````  //*** ADD ***//
var lineGraphic;

view.on("pointer-move", function(event){

...

// Draw line between points
view.graphics.remove(lineGraphic);
lineGraphic = new Graphic({
geometry: {
type: "polyline",
paths: [
[point.longitude, point.latitude],
[malibuPoint.longitude, malibuPoint.latitude]
]
},
symbol: {
type: "simple-line",
color: "#333",
width: 1
}
});
});
``````
2. In the `pointer-move` function, add code to create text graphic and use the geometryEngine `distance` function to calculate how far the cursor is from the `malibuPoint` and add the distance to the map.

``````  //*** ADD ***//
var textGraphic;

view.on("pointer-move", function(event){

...

// Draw a text label to show distance
var distance = geometryEngine.distance(point, malibuPoint,"miles");

view.graphics.remove(textGraphic);
textGraphic = new Graphic({
geometry: point,
symbol: {
type: "text",
text: distance.toFixed(2) + " miles",
color: "black",
font: {
size: 12
}
}
});
});
``````
3. Run the app and move your cursor around the map. You should see a line and the distance draw on the map.

#### Congratulations, you're done!

Your app should look something like this.

## Challenge

#### Densify the buffer and find the nearest point

You can add or remove points to any geometry by using the `densify` function. Use this function to add points every 250 meters around the buffer. Next, use the `nearestVertex` function to find the closest vertex in the buffer to the `malibuPoint`. Add the nearest vertex (point) as a graphic to the map after the buffer draws.

``````    //*** ADD ***//
var nearestPointGraphic;

view.on("pointer-move", function(event){
event.stopPropagation();
// Buffer the point
var point = view.toMap(event);
var buffer = geometryEngine.buffer(point, 10, "miles");
buffer = geometryEngine.densify(buffer, 250, "meters");

...

var nearestPoint = geometryEngine.nearestVertex(buffer, malibuPoint);

view.graphics.remove(nearestPointGraphic);
nearestPointGraphic = new Graphic({
geometry: nearestPoint.coordinate,
symbol: {
type: "simple-marker",
color: "black",
size: 6,
outline: {
color: "white",
width: 1
}
}
});
});
``````

#### Perform geodesic calculations

Geodesic calculations take into consideration the curvature of the earth and provide highly accurate results. Try replacing the `buffer` and `distance` functions with the `geodesicBuffer` and `geodesicLength` functions and compare the results. Visit the documentation to see what other geodesic functions are available.

NOTE: Geodesic functions only work with WGS84 and Web Mercator spatial references. Use the ArcGIS Geometry Service if you need to work in a different spatial reference.

``````  //*** Add ***//
var buffer = geometryEngine.geodesicBuffer(point, 500, "meters");

...