Learn how to calculate the length and area of geometries.
You can calculate the length of a line and determine the area of a polygon using the geometryEngine. The measurement depends on the coordinate system (or spatial reference) defined for the geometry. If the geometry's spatial reference is Web Mercator (3857) or WGS84 (4326), you would use geodesic calculations to take into account the curvature of the Earth. If the spatial reference is something different from Web Mercator (3857) or WGS84 (4326), you would use planar measurements based on Euclidean distances.
In this tutorial, you will use the Sketch widget to draw graphics on the view and the geometryEngine to calculate both geodesic and planar lengths and areas to see the difference between the two measurements.
Prerequisites
Steps
Create a new pen
- To get started, either complete the Display a map tutorial or .
Get an access token
You need an access token with the correct privileges to access the location services used in this tutorial.
- Go to the Create an API key tutorial and create an API key with the following privilege(s):
- Privileges
- Location services > Basemaps
- Privileges
- In CodePen, set
esri
to your API key..Config.api Key Use dark colors for code blocks esriConfig.apiKey = "YOUR_ACCESS_TOKEN"; const map = new Map({ basemap: "arcgis/topographic" // basemap styles service });
To learn about other ways to get an access token, go to Types of authentication.
Set HTML
- Create a
measurements
div
to display the results of a calculation and add some CSS styling to set the font size and margins.Use dark colors for code blocks #viewDiv { padding: 0; margin: 0; height: 100%; width: 100%; } #measurements { padding: 4px 8px; font-size: 16px; bottom: 15px; left: 50%; margin-right: -50%; transform: translate(-50%,-50%); } </style> <link rel="stylesheet" href="https://js.arcgis.com/4.30/esri/themes/light/main.css"> <script src="https://js.arcgis.com/4.30/"></script> <script> require([ "esri/config", "esri/Map", "esri/views/MapView", "esri/widgets/ScaleBar", "esri/widgets/Sketch", "esri/Graphic", "esri/layers/GraphicsLayer", "esri/geometry/geometryEngine", ], ( esriConfig, Map, MapView, ) => { esriConfig.apiKey = "YOUR_ACCESS_TOKEN"; const map = new Map({ basemap: "arcgis/topographic", // basemap styles service }); const view = new MapView({ container: "viewDiv", map: map, }); </script> </head> <body> <div id="viewDiv"> <div id="measurements" class="esri-widget">
Add modules
-
In the
require
statement, add the modules.The ArcGIS Maps SDK for JavaScript is available as AMD modules and ES modules, but this tutorial is based on AMD. The AMD
require
function uses references to determine which modules will be loaded – for example, you can specify"esri/
for loading the Map module. After the modules are loaded, they are passed as parameters (e.g.Map" Map
) to the callback function where they can be used in your application. It is important to keep the module references and callback parameters in the same order. To learn more about the API's different modules visit the Overview Guide page.Use dark colors for code blocks <link rel="stylesheet" href="https://js.arcgis.com/4.30/esri/themes/light/main.css"> <script src="https://js.arcgis.com/4.30/"></script> <script> require([ "esri/config", "esri/Map", "esri/views/MapView", "esri/widgets/ScaleBar", "esri/widgets/Sketch", "esri/Graphic", "esri/layers/GraphicsLayer", "esri/geometry/geometryEngine", ], ( esriConfig, Map, MapView, ScaleBar, Sketch, Graphic, GraphicsLayer, geometryEngine, ) => { esriConfig.apiKey = "YOUR_ACCESS_TOKEN"; const map = new Map({ basemap: "arcgis/topographic", // basemap styles service }); const view = new MapView({ container: "viewDiv", map: map,
Recenter and add a scalebar
The ScaleBar widget will display a scale bar on the map. You can choose either metric or imperial values. For example, if you specify metric
, it will show either kilometers or meters depending on the scale.
-
Change the
center
to andzoom
levels for theview
.Use dark colors for code blocks const view = new MapView({ container: "viewDiv", map: map, center: [-10, 30], zoom: 3, });
-
Create a
scalebar
and set theview
parameter to theview
. Specify theunit
asmetric
.Use dark colors for code blocks center: [-10, 30], zoom: 3, }); const scalebar = new ScaleBar({ view: view, unit: "metric" });
-
Add the
scalebar
to thebottom-right
of theview
.Use dark colors for code blocks center: [-10, 30], zoom: 3, }); const scalebar = new ScaleBar({ view: view, unit: "metric" }); view.ui.add(scalebar, "bottom-right");
-
Run the app to verify the change in the
center
andzoom
level. Thescalebar
should appear at the bottom of the view.
Add the Sketch widget
The Sketch widget provides UI that allows you to create and update graphics in the MapView.
-
Create a
graphics
to add aLayer Graphics
to theLayer map
.Use dark colors for code blocks const scalebar = new ScaleBar({ view: view, unit: "metric" }); view.ui.add(scalebar, "bottom-right"); const graphicsLayer = new GraphicsLayer(); map.add(graphicsLayer);
-
Create a
sketch
widget. Set thelayer
parameter to thegraphics
. Any geometry drawn using the widget will be added to theLayer graphics
. Limit the features on the widget by setting theLayer available
to only showCreate Tools polyline
,polygon
, andrectangle
options and disabling other default settings found in thevisible
andElements selection
properties.Tools Use dark colors for code blocks const scalebar = new ScaleBar({ view: view, unit: "metric" }); view.ui.add(scalebar, "bottom-right"); const graphicsLayer = new GraphicsLayer(); map.add(graphicsLayer); const sketch = new Sketch({ layer: graphicsLayer, view: view, availableCreateTools: ["polyline", "polygon", "rectangle"], creationMode: "update", updateOnGraphicClick: true, visibleElements: { createTools: { point: false, circle: false }, selectionTools:{ "lasso-selection": false, "rectangle-selection":false, }, settingsMenu: false, undoRedoMenu: false } });
-
Add the
sketch
widget to thetop-right
of theview
.Use dark colors for code blocks const sketch = new Sketch({ layer: graphicsLayer, view: view, availableCreateTools: ["polyline", "polygon", "rectangle"], creationMode: "update", updateOnGraphicClick: true, visibleElements: { createTools: { point: false, circle: false }, selectionTools:{ "lasso-selection": false, "rectangle-selection":false, }, settingsMenu: false, undoRedoMenu: false } }); view.ui.add(sketch, "top-right");
-
Add the
measurements
element to theview
to display the measurements when you draw a geometry.Use dark colors for code blocks view.ui.add(sketch, "top-right"); const measurements = document.getElementById("measurements"); view.ui.add(measurements, "manual");
-
Run the app to verify that the widget appears in the view and that you are able to draw geometries.
Calculate length and area
The geometry
allows you to calculate either the planar length/area or geodesic length/area of a geometry. Because the geometries in this application are projected in Web Mercator, it is best practice to use geodesic measurements. However, to visualize the difference between geodesic and planar calculations, measure both when a geometry is drawn.
-
Create a
get
function that takes aArea polygon
as its parameter. Call thegeodesic
method and theArea() planar
methods to calculate the area of the polygon inArea() square-kilometers
.Use dark colors for code blocks const measurements = document.getElementById("measurements"); view.ui.add(measurements, "manual"); function getArea(polygon) { const geodesicArea = geometryEngine.geodesicArea(polygon, "square-kilometers"); const planarArea = geometryEngine.planarArea(polygon, "square-kilometers"); }
-
Append the results of the calculation to the
inner
ofHTML measurements
.Use dark colors for code blocks function getArea(polygon) { const geodesicArea = geometryEngine.geodesicArea(polygon, "square-kilometers"); const planarArea = geometryEngine.planarArea(polygon, "square-kilometers"); measurements.innerHTML = "<b>Geodesic area</b>: " + geodesicArea.toFixed(2) + " km\xB2" + " | <b>Planar area</b>: " + planarArea.toFixed(2) + " km\xB2"; }
-
Create a
get
function that takes aLength line
parameter. Call thegeodesic
andLength planar
methods to calculate the length of theLength line
in kilometers.Use dark colors for code blocks measurements.innerHTML = "<b>Geodesic area</b>: " + geodesicArea.toFixed(2) + " km\xB2" + " | <b>Planar area</b>: " + planarArea.toFixed(2) + " km\xB2"; } function getLength(line) { const geodesicLength = geometryEngine.geodesicLength(line, "kilometers"); const planarLength = geometryEngine.planarLength(line, "kilometers"); }
-
Append the results of the geodesic length calculation to the
inner
ofHTML measurements
.Use dark colors for code blocks function getLength(line) { const geodesicLength = geometryEngine.geodesicLength(line, "kilometers"); const planarLength = geometryEngine.planarLength(line, "kilometers"); measurements.innerHTML = "<b>Geodesic length</b>: " + geodesicLength.toFixed(2) + " km" + " | <b>Planar length</b>: " + planarLength.toFixed(2) + " km"; }
-
Create a
switch
statement that will either call theget
function or theArea get
function depending on whether the geometry is aLength polygon
or apolyline
.Use dark colors for code blocks function getLength(line) { const geodesicLength = geometryEngine.geodesicLength(line, "kilometers"); const planarLength = geometryEngine.planarLength(line, "kilometers"); measurements.innerHTML = "<b>Geodesic length</b>: " + geodesicLength.toFixed(2) + " km" + " | <b>Planar length</b>: " + planarLength.toFixed(2) + " km"; } function switchType(geom) { switch (geom.type) { case "polygon": getArea(geom); break; case "polyline": getLength(geom); break; default: console.log("No value found"); } }
Create a default graphic to measure
To show the user the way in which to interact with the application, create a default polygon and display its area when the app starts.
-
Create a
polygon
. Set thetype
topolygon
and thewkid
in thespatial
property toReference 3857
(Web Mercator). Create asimple
to style the graphic.Polygon Symbol Use dark colors for code blocks const measurements = document.getElementById("measurements"); view.ui.add(measurements, "manual"); const polygon = { type: "polygon", spatialReference: { wkid: 3857, }, rings: [ [ [-4508069.082189632, 3599936.936171892], [-4508069.082189632, 5478453.343307884], [-2629552.6750536393, 5478453.343307884], [-2629552.6750536393, 3599936.936171892], [-4508069.082189632, 3599936.936171892], ], ], }; const simplePolygonSymbol = { type: "simple-fill", outline: { color: [200, 0, 0], width: 2, }, };
-
Create an instance of the Graphic class. Set the
geometry
andsymbol
properties to thepolygon
andsimple
. Add the graphic to thePolygon Symbol graphics
.Layer Use dark colors for code blocks const measurements = document.getElementById("measurements"); view.ui.add(measurements, "manual"); const polygon = { type: "polygon", spatialReference: { wkid: 3857, }, rings: [ [ [-4508069.082189632, 3599936.936171892], [-4508069.082189632, 5478453.343307884], [-2629552.6750536393, 5478453.343307884], [-2629552.6750536393, 3599936.936171892], [-4508069.082189632, 3599936.936171892], ], ], }; const simplePolygonSymbol = { type: "simple-fill", outline: { color: [200, 0, 0], width: 2, }, }; const polygonGraphic = new Graphic({ geometry: polygon, symbol: simplePolygonSymbol }); graphicsLayer.add(polygonGraphic);
-
when
theview
loads, call theupdate
method on thepolygon
and call theGraphic get
function based on theArea geometry
of thepolygon
.Graphic Use dark colors for code blocks graphicsLayer.add(polygonGraphic); view.when(() => { sketch.update(polygonGraphic); getArea(polygonGraphic.geometry); });
Add an event listener
The settings of the Sketch widget allow you to edit the geometry drawn on the view. Create an event listener to register the different states of the geometry on the update and dynamically measure its area or length.
-
Create an event listener that listens for changes
on
theupdate
when you create, resize, or move a graphic. Set thegeometry
element with thegeometry
of the first graphic from the event.Use dark colors for code blocks view.when(() => { sketch.update(polygonGraphic); getArea(polygonGraphic.geometry); }); sketch.on("update", (e) => { const geometry = e.graphics[0].geometry; });
-
Create conditional statements based on whether the
sketch
event'sstate
is:start
,complete
, or in a state of change. For each state, except forcomplete
, call theswitch
statement withType geometry
as its parameter. When the event iscomplete
, remove the graphic from thegraphics
and clear theLayer inner
.HTML Use dark colors for code blocks sketch.on("update", (e) => { const geometry = e.graphics[0].geometry; if (e.state === "start") { switchType(geometry); } if (e.state === "complete") { graphicsLayer.remove(graphicsLayer.graphics.getItemAt(0)); measurements.innerHTML = null; } if ( e.toolEventInfo && (e.toolEventInfo.type === "scale-stop" || e.toolEventInfo.type === "reshape-stop" || e.toolEventInfo.type === "move-stop") ) { switchType(geometry); } });
Run the app
In CodePen, run your code to display the map.
When you run the app, you will see a polygon with its calculated geodesic and planar area. You can use the sketch widget to draw other geometries and display their measurements. If you move the geometry, the geodesic measurements will change but the planar measurements will not.
What's next?
Learn how to use additional API features and ArcGIS services in these tutorials: