ArcGIS API for Javascript calculates length, area, distance and buffer in different coordinate systems

ArcGIS API for Javascript has a variety of methods for calculating length, area, etc., which we often get confused. Today we will briefly review the applicable scenarios of each method.

1. Calculate the length

import * as geometryEngine from '@arcgis/core/geometry/geometryEngine'
import * as geodesicUtils from '@arcgis/core/geometry/support/geodesicUtils'
/** Calculate length
 * @param {Geometry} geometry geometry
 * @param {String} unit unit
 */
export function geometryLength(geometry, unit) {
  //Coordinate system type:
  //(1: WGS84 or web Mercator, 2: Geographic coordinate system other than WGS84, 3: Projected coordinate system other than web Mercator)
  const wkidType =
    view.spatialReference.isWGS84 || view.spatialReference.isWebMercator
      ? 1
      : view.spatialReference.isGeographic
      ? 2
      : 3
  switch (wkidType) {
    case 1:
      return geometryEngine.geodesicLength(geometry, unit)
    case 2:
      return geodesicUtils.geodesicLengths([geometry], unit)[0]
    case 3:
      return geometryEngine.planarLength(geometry, unit)
    default:
      return null
  }
}
1. WGS84 or web Mercator, use geometryEngine.geodesicLength() method

geometryEngine.geodesicLength() calculates the length of the input geometry. GeodesicLength() takes the curvature of the Earth into account when performing this calculation. Therefore, when using a spatial reference as WGS84 (wkid: 4326) or Web Mercator, best practice is to use geodesicLength() to calculate the length.

2. For geographic coordinate systems other than WGS84, use the geodesicUtils.geodesicLengths() method

geodesicUtils.geodesicLengths() Calculates the polygonal perimeter or line length of one or more geometries via geodesy.

3. For projected coordinate systems other than web Mercator, use the geometryEngine.planarLength() method

geometryEngine.planarLength() calculates the length of the input geometry. Unlike geodesicLength(), planeLength() uses projected coordinates and does not consider the curvature of the Earth when performing this calculation. If the input geometry has a projected coordinate system other than Web Mercator, use planeLength() instead.

Note:

1. When measuring the length of a drawn graphic, if the coordinate system of the view is web Mercator, set the coordinate system of the input geometry to web Mercator. If the coordinate system of the view is other coordinate systems, enter The geometry does not set a coordinate system, otherwise when the unit parameter is meters (meters) for calculation, an error will be reported. The coordinate system is inconsistent

2. Calculate area

import * as geometryEngine from '@arcgis/core/geometry/geometryEngine'
import * as geodesicUtils from '@arcgis/core/geometry/support/geodesicUtils'
/** Calculate area
 * @param {Geometry} geometry geometry
 * @param {String} unit unit
 */
export function geometryArea(geometry, unit) {
  //Coordinate system type:
  //(1: WGS84 or web Mercator, 2: Geographic coordinate system other than WGS84, 3: Projected coordinate system other than web Mercator)
  const wkidType =
    view.spatialReference.isWGS84 || view.spatialReference.isWebMercator
      ? 1
      : view.spatialReference.isGeographic
      ? 2
      : 3

  switch (wkidType) {
    case 1:
      return geometryEngine.geodesicArea(geometry, unit)
    case 2:
      return geodesicUtils.geodesicAreas([geometry], unit)[0]
    case 3:
      return geometryEngine.planarArea(geometry, unit)
    default:
      return null
  }
}
1. WGS84 or web Mercator, use geometryEngine.geodesicArea() method

geometryEngine.geodesicArea() calculates the area of the input geometry. The curvature of the Earth is taken into account when performing this calculation. Therefore, when using a spatial reference as WGS84 (wkid: 4326) or Web Mercator, best practice is to use geodesicArea() to calculate the area.

2. For geographic coordinate systems other than WGS84, use the geodesicUtils.geodesicAreas() method

geodesicUtils.geodesicAreas() Calculates the area of one or more polygons geodesically.

3. For projected coordinate systems other than web Mercator, use the geometryEngine.planarArea() method

geometryEngine.planarArea() calculates the area of the input geometry. Unlike geodesicArea(), planeArea() performs this calculation using projected coordinates and does not take the curvature of the Earth into account. If the input geometry has a projected coordinate system other than Web Mercator, use planeArea() instead.

Note:

1. When measuring the area of a drawn graphic, if the coordinate system of the view is web Mercator, set the coordinate system of the input geometry to web Mercator. If the coordinate system of the view is other coordinate systems, enter The geometric figures do not set a coordinate system. Otherwise, when the unit parameter is square-meters (square meters) for calculation, an error will be reported. The coordinate system is inconsistent

2. Area may calculate negative values. In this case, use geometryEngine.simplify to first simplify the input geometry so that its definition is topologically legal relative to its geometry type. At the end of the simplification operation, the polygon Loops or polyline paths do not overlap or self-intersect before performing area calculations

let area = gisAnalysis.geometryArea(view, geo, 'square-meters')
if (area !== 0 & amp; & amp; area !== -0) {
  if (area < 0) {
     const simplifiedPolygon = geometryEngine.simplify(geo)
     if (simplifiedPolygon) area = gisAnalysis.geometryArea(view,simplifiedPolygon,'square-meters')
   }
}

3. Calculate the distance between two points

import * as geometryEngine from '@arcgis/core/geometry/geometryEngine'
import * as geodesicUtils from '@arcgis/core/geometry/support/geodesicUtils'
/** Calculate the distance between two points
 * @param {Point} point1 geometric point 1
 * @param {Point} point2 geometric point 2
 * @param {String} unit unit
 */
export function geometryDistance(point1, point2, unit) {
  //Coordinate system type (1: geographical coordinate system, 2: projected coordinate system)
  const wkidType = point1.spatialReference.isGeographic? 1 : 2

  switch (wkidType) {
    case 1:
      return geodesicUtils.geodesicDistance(point1, point2, unit).distance
    case 2:
      return geometryEngine.distance(point1, point2, unit)
    default:
      return null
  }
}
1. Geographic coordinate system, use geodesicUtils.geodesicDistance() method

geodesicUtils.geodesicDistance() Geodesic calculates the direction and distance between two known locations. Both input points must have the same geographic coordinate system.

2. Projected coordinate system, using geometryEngine.distance() method

geometryEngine.distance() calculates the shortest planar distance between two geometries. Distances are reported in the linear units specified by distanceUnit or, if distanceUnit is empty, in the spatialReference units of the input geometry.

4. Obtain the buffer

import * as geometryEngine from '@arcgis/core/geometry/geometryEngine'
import BufferParameters from '@arcgis/core/rest/support/BufferParameters'
import * as geometryService from '@arcgis/core/rest/geometryService'
import * as projection from '@arcgis/core/geometry/projection'
/** Get buffer
 * @param {Geometry} geometry geometry
 * @param {Number} distance buffer distance
 * @param {String} unit unit
 * @param {Number} projectWkid The wkid value of the projected coordinate system (used when the coordinate system of the geometry is a geographical coordinate system other than WGS84)
 */
export function geometryBuffer(geometry, distance, unit, projectWkid) {
  //Coordinate system type:
  //(1: WGS84 or web Mercator, 2: Geographic coordinate system other than WGS84, 3: Projected coordinate system other than web Mercator)
  const wkidType =
    view.spatialReference.isWGS84 || view.spatialReference.isWebMercator
      ? 1
      : view.spatialReference.isGeographic
      ? 2
      : 3
  return new Promise((resolve) => {
    switch (wkidType) {
      case 1:
        resolve(geometryEngine.geodesicBuffer(geometry, distance, unit))
        break
      case 2:
        let bufferSr = new SpatialReference({ wkid: projectWkid })
        let projectGeo = projection.project(geometry, bufferSr)
        var params = new BufferParameters({
          distances: [distance],
          unit: unit,
          bufferSpatialReference: bufferSr,
          outSpatialReference: view.spatialReference,
          geometries: [projectGeo]
        })
        geometryService
          .buffer('https://sampleserver6.arcgisonline.com/arcgis/rest/services/Utilities/Geometry/GeometryServer/buffer',
            params
          )
          .then(function (results) {
            resolve(results[0])
          })
        break
      case 3:
        resolve(geometryEngine.buffer(geometry, distance, unit))
        break
      default:
        break
    }
  })
}
1. WGS84 or web Mercator, use geometryEngine.geodesicBuffer() method

geometryEngine.geodesicBuffer() creates a flow buffer polygon at a specified distance around the input geometry. This method takes into account the curvature of the Earth when calculating distances, providing highly accurate results when dealing with very large geometries and/or geometries that vary spatially across the globe, where a projected coordinate system cannot accurately plot the coordinates and Measure distances for all geometries.

This method only works with WGS84 (wkid: 4326) and Web Mercator spatial references.

2. For geographical coordinate systems other than WGS84, use the geometryService.buffer() method

geometryService.buffer() creates a buffer polygon at a specified distance around the given geometry. Requires the Server REST service URL of serverGeometryService.

3. For projection coordinate systems other than web Mercator, use the geometryEngine.buffer() method

geometryEngine.buffer() Buffer (this method) is only used when trying to buffer geometry using a projected coordinate system other than Web Mercator.