/**
 * A client-side geometry engine for testing, measuring, and analyzing the spatial relationship
 * between two or more 2D geometries. If more than one geometry is required for any of the methods below,
 * all geometries must have the same spatial reference for the methods to work as expected.
 *
 * Read the following blog series to learn more about GeometryEngine:
 *
 * - [ArcGIS Blog - GeometryEngine: Testing spatial relationships and editing](https://blogs.esri.com/esri/arcgis/2015/09/09/geometryengine-part-1-testing-spatial-relationships-and-editing/)
 * - [ArcGIS Blog - GeometryEngine: Measurement](https://blogs.esri.com/esri/arcgis/2015/09/16/geometryengine-part-2-measurement/)
 * - [ArcGIS Blog - GeometryEngine: Overlay analysis](https://blogs.esri.com/esri/arcgis/2015/09/23/geometryengine-part-3-overlay-analysis/)
 *
 * @deprecated since version 4.32. Use [geometry operators](https://developers.arcgis.com/javascript/latest/spatial-analysis/intro-geometry-operators/) instead.
 * @since 4.0
 * @see [Sample - Geodesic Buffers (2D & 3D)](https://developers.arcgis.com/javascript/latest/sample-code/ge-geodesicbuffer/)
 */
import type Extent from "./Extent.js";
import type Point from "./Point.js";
import type Polygon from "./Polygon.js";
import type Polyline from "./Polyline.js";
import type SpatialReference from "./SpatialReference.js";
import type { LinearUnit, AreaUnit, ExtendedSpatialReferenceInfo, NearestPointResult } from "./geometryEngineTypes.js";
import type { GeometryUnion } from "./types.js";

/**
 * Returns an object containing additional information about the input spatial reference.
 *
 * @deprecated since version 4.32.
 * @param spatialReference - The input spatial reference.
 * @returns Resolves to a [ExtendedSpatialReferenceInfo](https://developers.arcgis.com/javascript/latest/references/core/geometry/geometryEngineTypes/#ExtendedSpatialReferenceInfo) object.
 * @see [Unit IDs](https://developers.arcgis.com/java/v200/api-reference/reference/com.esri.arcgisruntime/com/esri/arcgisruntime/geometry/LinearUnitId.html#CENTIMETERS)
 */
export function extendedSpatialReferenceInfo(spatialReference: SpatialReference): ExtendedSpatialReferenceInfo;

/**
 * Calculates the clipped geometry from a target geometry by an envelope.
 *
 * @deprecated since version 4.32. Use [clipOperator](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/clipOperator/) instead.
 * @param geometry - The geometry to be clipped.
 * @param envelope - The envelope used to clip.
 * @returns Clipped geometry.
 * @example
 * // returns a new geometry of a polygon clipped by the views extent
 * const clippedGeometry= geometryEngine.clip(boundaryPolygon, view.extent);
 */
export function clip(geometry: GeometryUnion, envelope: Extent): GeometryUnion;

/**
 * Splits the input Polyline or Polygon where it crosses a cutting Polyline. For Polylines, all left cuts are
 * grouped together in the first Geometry. Right cuts and coincident cuts are grouped in the second Geometry and
 * each undefined cut, along with any uncut parts, are output as separate Polylines. For Polygons, all left cuts
 * are grouped in the first Polygon, all right cuts are grouped in the second Polygon, and each undefined cut, along with
 * any leftover parts after cutting, are output as a separate Polygon. If no cuts are returned then the array will
 * be empty. An undefined cut will only be produced if a left cut or right cut was produced and there was a part
 * left over after cutting, or a cut is bounded to the left and right of the cutter.
 *
 * @deprecated since version 4.32. Use [cutOperator](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/cutOperator/) instead.
 * @param geometry - The geometry to be cut.
 * @param cutter - The polyline to cut the geometry.
 * @returns Returns an array of geometries created by cutting the input geometry with the cutter.
 * @example
 * // returns array of cut geometries
 * const geometries = geometryEngine.cut(boundaryPolygon, polyline);
 */
export function cut(geometry: GeometryUnion, cutter: Polyline): GeometryUnion[];

/**
 * Indicates if one geometry contains another geometry.
 *
 * @deprecated since version 4.32. Use [containsOperator](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/containsOperator/) instead.
 * @param containerGeometry - The geometry that is tested for the "contains" relationship to the other geometry.
 *   Think of this geometry as the potential "container" of the `insideGeometry`.
 * @param insideGeometry - The geometry that is tested for the "within" relationship to the `containerGeometry`.
 * @returns Returns `true` if the `containerGeometry` contains the `insideGeometry`.
 * @example
 * // returns true or false for one geometry containing another
 * const isContained = geometryEngine.contains(boundaryPolygon, point);
 * @example
 * // returns true or false for one geometry containing another
 * const isContained = geometryEngine.contains(extent, boundaryPolygon);
 */
export function contains(containerGeometry: GeometryUnion, insideGeometry: GeometryUnion): boolean;

/**
 * Indicates if one geometry crosses another geometry.
 *
 * @deprecated since version 4.32. Use [crossesOperator](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/crossesOperator/) instead.
 * @param geometry1 - The geometry to cross.
 * @param geometry2 - The geometry being crossed.
 * @returns Returns `true` if `geometry1` crosses `geometry2`.
 * @example
 * // returns true or false if a line crosses a polygon another
 * const isCrossed = geometryEngine.crosses(boundaryPolygon, polyline);
 */
export function crosses(geometry1: GeometryUnion, geometry2: GeometryUnion): boolean;

/**
 * Calculates the shortest planar distance between two geometries. Distance is reported in the linear units specified by
 * `distanceUnit` or, if `distanceUnit` is null, the units of the spatialReference of input geometry.
 *
 * > [!WARNING]
 * >
 * > To calculate the geodesic distance between two points, first construct a
 * > [Polyline](https://developers.arcgis.com/javascript/latest/references/core/geometry/Polyline/) using the two points of interest as the beginning
 * > and ending points of a single path. Then use the polyline as input for the
 * > [geodesicLength()](https://developers.arcgis.com/javascript/latest/references/core/geometry/geometryEngine/#geodesicLength) method.
 *
 * @deprecated since version 4.32. Use [distanceOperator](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/distanceOperator/) instead.
 * @param geometry1 - First input geometry.
 * @param geometry2 - Second input geometry.
 * @param distanceUnit - Measurement unit of the return value.
 * Defaults to the units of the input geometries.
 * @returns Distance between the two input geometries.
 * @example
 * // returns numeric distance between two points
 * const totalDistance = geometryEngine.distance(point1, point2, "feet");
 */
export function distance(geometry1: GeometryUnion, geometry2: GeometryUnion, distanceUnit?: number | LinearUnit | null | undefined): number;

/**
 * Indicates if two geometries are equal.
 *
 * @deprecated since version 4.32. Use [equalsOperator](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/equalsOperator/) instead.
 * @param geometry1 - First input geometry.
 * @param geometry2 - Second input geometry.
 * @returns Returns `true` if the two input geometries are equal.
 * @example
 * // returns true if two given geometries are equal
 * const isEqual = geometryEngine.equals(line1, line2);
 */
export function equals(geometry1: GeometryUnion, geometry2: GeometryUnion): boolean;

/**
 * Indicates if one geometry intersects another geometry.
 *
 * @deprecated since version 4.32. Use [intersectsOperator](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/intersectsOperator/) instead.
 * @param geometry1 - The geometry that is tested for the intersects relationship to the other geometry.
 * @param geometry2 - The geometry being intersected.
 * @returns Returns `true` if the input geometries intersect each other.
 * @example
 * // returns true if two given geometries intersect each other
 * const isIntersecting = geometryEngine.intersects(boundaryPolygon, cityPolygon);
 */
export function intersects(geometry1: GeometryUnion, geometry2: GeometryUnion): boolean;

/**
 * Indicates if one geometry touches another geometry.
 *
 * @deprecated since version 4.32. Use [touchesOperator](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/touchesOperator/) instead.
 * @param geometry1 - The geometry to test the "touches" relationship with the other geometry.
 * @param geometry2 - The geometry to be touched.
 * @returns When `true`, `geometry1` touches `geometry2`.
 * @example
 * // returns true if the line vertex touches the edge of the polygon
 * const isTouching = geometryEngine.touches(polygon, line);
 */
export function touches(geometry1: GeometryUnion, geometry2: GeometryUnion): boolean;

/**
 * Indicates if one geometry is within another geometry.
 *
 * @deprecated since version 4.32. Use [withinOperator](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/withinOperator/) instead.
 * @param innerGeometry - The base geometry that is tested for the "within" relationship to the other geometry.
 * @param outerGeometry - The comparison geometry that is tested for the "contains" relationship to the other geometry.
 * @returns Returns `true` if `innerGeometry` is within `outerGeometry`.
 * @example
 * // returns true if a geometry is completely within another
 * const isWithin = geometryEngine.within(polygon, boundaryPolygon);
 */
export function within(innerGeometry: GeometryUnion, outerGeometry: GeometryUnion): boolean;

/**
 * Indicates if one geometry is disjoint (doesn't intersect in any way) with another geometry.
 *
 * @deprecated since version 4.32. Use [disjointOperator](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/disjointOperator/) instead.
 * @param geometry1 - The base geometry that is tested for the "disjoint" relationship to the other geometry.
 * @param geometry2 - The comparison geometry that is tested for the "disjoint" relationship to the other geometry.
 * @returns Returns `true` if `geometry1` and `geometry2` are disjoint (don't intersect in any way).
 * @example
 * // returns true if a geometry is not contained in another.
 * // operates the opposite of contains
 * const isDisjointed = geometryEngine.disjoint(polygon, boundaryPolygon);
 */
export function disjoint(geometry1: GeometryUnion, geometry2: GeometryUnion): boolean;

/**
 * Indicates if one geometry overlaps another geometry.
 *
 * @deprecated since version 4.32. Use [overlapsOperator](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/overlapsOperator/) instead.
 * @param geometry1 - The base geometry that is tested for the "overlaps" relationship with the other geometry.
 * @param geometry2 - The comparison geometry that is tested for the "overlaps" relationship with the other geometry.
 * @returns Returns `true` if the two geometries overlap.
 * @example
 * // returns true if one geometry overlaps another,
 * // but is not contained or disjointed
 * const isOverlapping = geometryEngine.overlaps(polygon, boundaryPolygon);
 */
export function overlaps(geometry1: GeometryUnion, geometry2: GeometryUnion): boolean;

/**
 * Indicates if the given DE-9IM relation is true for the two geometries.
 *
 * @deprecated since version 4.32. Use [relateOperator](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/relateOperator/) instead.
 * @param geometry1 - The first geometry for the relation.
 * @param geometry2 - The second geometry for the relation.
 * @param relation - The Dimensionally Extended 9 Intersection Model (DE-9IM) matrix relation
 * (encoded as a string) to test against the relationship of the two geometries. This string contains the
 * test result of each intersection represented in the DE-9IM matrix. Each result is one character of the
 * string and may be represented as either a number (maximum dimension returned: `0`,`1`,`2`), a Boolean
 * value (`T` or `F`), or a mask character (for ignoring results: '\*'). For example, each of the following
 * DE-9IM string codes are valid for testing whether a polygon geometry completely contains a line geometry:
 * `TTTFFTFFT` (Boolean), 'T*\*\*\*\*\*FF\*' (ignore irrelevant intersections), or '102FF\*FF\*' (dimension form).
 * Each returns the same result. See [this article](https://en.wikipedia.org/wiki/DE-9IM) and
 * [this ArcGIS help page](https://doc.esri.com/en/arcgis-pro/latest/help/data/databases/pdf/stgeometry_reference_pro.pdf)
 * for more information about the DE-9IM model and how string codes are constructed.
 * @returns Returns `true` if the relation of the input geometries is accurate.
 * @example
 * // returns true if the polygon geometry completely
 * // contains the polyline based on the DE-9IM string
 * const isRelated = geometryEngine.relate(polygon, polyline, "TTTFFTFFT");
 */
export function relate(geometry1: GeometryUnion, geometry2: GeometryUnion, relation: string): boolean;

/**
 * Indicates if the given geometry is non-OGC topologically simple.
 * No polygon rings self-intersect.
 * Polylines paths that self-intersect are considered simple.
 *
 * @deprecated since version 4.32. Use [simplifyOperator's isSimple()](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/simplifyOperator/#isSimple) method instead.
 * @param geometry - The input geometry.
 * @returns Returns `true` if the geometry is topologically simple.
 * @example
 * // returns true if given geometry is simple
 * const simple = geometryEngine.isSimple(polyline);
 */
export function isSimple(geometry: GeometryUnion): boolean;

/**
 * Performs the simplify operation on the geometry, which alters the given geometries to make their definitions
 * topologically legal with respect to their geometry type. At the end of a simplify operation, no polygon rings
 * or polyline paths will overlap, and no self-intersection will occur.
 *
 * @deprecated since version 4.32. Use [simplifyOperator](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/simplifyOperator/) instead.
 * @param geometry - The geometry to be simplified.
 * @returns The simplified geometry.
 * @example
 * // Topologically simplifies a geometry
 * const simplified = geometryEngine.simplify(polyline);
 * console.log(geometryEngine.isSimple(simplified)); // true
 */
export function simplify(geometry: GeometryUnion): GeometryUnion;

/**
 * Calculates the convex hull of one or more geometries. A convex hull is the smallest convex polygon that encloses a group of geometries or vertices.
 * The input can be a single geometry (such as a polyline) or an array of any geometry type. The hull is typically a polygon but can also
 * be a polyline or a point in degenerate cases.
 *
 * @deprecated since version 4.32. Use [convexHullOperator](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/convexHullOperator/) instead.
 * @param geometries - The input geometry or geometries used to calculate
 *   the convex hull. If an array is specified, the input array can include various geometry types. When an array
 *   is provided, the output will also be an array.
 * @param merge - = false - Indicates whether to merge the output into a single geometry (usually a polygon).
 * @returns Returns the convex hull of the input geometries. This is usually
 *  a polygon, but can also be a polyline (if the input is a set of points or polylines forming a straight line), or a point (in degenerate cases).
 * @example
 * // returns the convex hull of a multipoint as a single polygon
 * const hull = geometryEngine.convexHull(multipoint);
 * @example
 * // returns the convex hull of an array of points as a single polygon
 * const [ hull ] = geometryEngine.convexHull([ pointA, pointB, pointC ], true);
 * @example
 * // returns the convex hull for each input line geometry as three polygons
 * const hulls = geometryEngine.convexHull([ lineA, lineB, lineC ]);
 * @example
 * // returns the convex hull for all input line geometries as a single polygon
 * const [ hull ] = geometryEngine.convexHull([ lineA, lineB, lineC ], true);
 * @example
 * // returns the convex hull for all input geometries as a single polygon
 * const [ hull ] = geometryEngine.convexHull([ point, line, polygon ], true);
 */
export function convexHull(geometries: GeometryUnion | GeometryUnion[], merge: boolean): GeometryUnion | GeometryUnion[];

/**
 * Creates the difference of two geometries. The resultant geometry is the portion of `inputGeometry` not in the `subtractor`.
 * The dimension of the `subtractor` has to be equal to or greater than that of the `inputGeometry`.
 *
 * @deprecated since version 4.32. Use [differenceOperator](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/differenceOperator/) instead.
 * @param inputGeometry - The input geometry to subtract from.
 * @param subtractor - The geometry being subtracted from inputGeometry.
 * @returns Returns the geometry of inputGeometry minus the subtractor geometry.
 * @example
 * // Creates a new geometry based on the
 * // difference of the two
 * const geometry = geometryEngine.difference(boundaryPolygon, buffers);
 */
export function difference(inputGeometry: GeometryUnion | GeometryUnion[], subtractor: GeometryUnion): GeometryUnion | GeometryUnion[];

/**
 * Creates the symmetric difference of two geometries. The symmetric difference includes the parts
 * that are in either of the sets, but not in both.
 *
 * @deprecated since version 4.32. Use [symmetricDifferenceOperator](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/symmetricDifferenceOperator/) instead.
 * @param leftGeometry - One of the Geometry instances in the XOR operation.
 * @param rightGeometry - One of the Geometry instances in the XOR operation.
 * @returns The symmetric differences of the two geometries.
 * @example
 * // Creates a new geometry based on the
 * // symmetric difference of the two
 * const geometry = geometryEngine.symmetricDifference(boundaryPolygon, buffers);
 */
export function symmetricDifference(leftGeometry: GeometryUnion | GeometryUnion[], rightGeometry: GeometryUnion): GeometryUnion | GeometryUnion[];

/**
 * Creates new geometries from the intersections between two geometries. If the input geometries
 * have different dimensions (i.e. point = 0; polyline = 1; polygon = 2), then the result's
 * dimension will be equal to the lowest dimension of the
 * inputs. The table below describes the expected output for various combinations of geometry
 * types. Note that `geometry1` and `geometry2` are interchangeable in this operation
 * and will return the same result if flipped.
 *
 * Geometry1 type | Geometry2 type | Result geometry type
 * --------------|---------------------------|---------------------
 * Polygon | Polygon | Polygon
 * Polygon | Polyline | Polyline
 * Polygon | Point | Point
 * Polyline | Polyline | Polyline
 * Polyline | Point | Point
 * Point | Point | Point
 *
 * Note that two intersecting polylines will not return Point geometries.
 * Rather, this function will return Polyline paths that are equal between the two geometries.
 * See [intersectLinesToPoints()](https://developers.arcgis.com/javascript/latest/references/core/geometry/geometryEngine/#intersectLinesToPoints) to find the point intersections
 * of two polylines.
 *
 * @deprecated since version 4.32. Use [intersectionOperator](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/intersectionOperator/) instead.
 * @param geometry1 - The input geometry or array of geometries.
 * @param geometry2 - The geometry to intersect with geometry1.
 * @returns The intersections of the geometries.
 * @see [intersectLinesToPoints()](https://developers.arcgis.com/javascript/latest/references/core/geometry/geometryEngine/#intersectLinesToPoints)
 * @example
 * // Creates a new geometry from the intersection
 * // of the two geometries
 * const intersecting = geometryEngine.intersect(boundaryPolygon, buffers);
 */
export function intersect(geometry1: GeometryUnion | GeometryUnion[], geometry2: GeometryUnion): GeometryUnion | GeometryUnion[];

/**
 * All inputs must be of the same type of geometries and share one spatial reference.
 *
 * @deprecated since version 4.32. Use [unionOperator](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/unionOperator/) instead.
 * @param geometries - An array of Geometries to union.
 * @returns The union of the geometries.
 * @example
 * // pt1 and pt2 are Point geometries to union together
 * const union = geometryEngine.union([pt1, pt2]);
 */
export function union(geometries: GeometryUnion[]): GeometryUnion;

/**
 * The offset operation creates a geometry that is a constant planar distance from an input
 * polyline or polygon. It is similar to buffering, but produces a one-sided result.
 *
 * @deprecated since version 4.32. Use [offsetOperator](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/offsetOperator/) instead.
 * @param geometry - The geometries to offset.
 * @param offsetDistance - The planar distance to offset from the input geometry. If offsetDistance > 0, then the offset
 * geometry is constructed to the right of the oriented input geometry, if offsetDistance = 0, then there is no
 * change in the geometries, otherwise it is constructed to the left. For a simple polygon, the orientation of outer
 * rings is clockwise and for inner rings it is counter clockwise. So the "right side" of a simple polygon is always its inside.
 * @param offsetUnit - Measurement unit of the offset distance.
 * Defaults to the units of the input geometries.
 * @param joinType - The join type.
 * @param bevelRatio - Applicable when `joinType = 'miter'`; bevelRatio is multiplied by the offset distance and
 * the result determines how far a mitered offset intersection can be located before it is beveled.
 * @param flattenError - Applicable when `joinType = 'round'`; flattenError determines the maximum distance of the resulting
 * segments compared to the true circular arc. The algorithm never produces more than around 180 vertices for each round join.
 * @returns The offset geometries.
 * @example
 * // Creates a new geometry offset from the provided geometry
 * const offset = geometryEngine.offset(boundaryPolygon, 500, "meters", "round");
 */
export function offset(geometry: GeometryUnion | GeometryUnion[], offsetDistance: number, offsetUnit?: number | LinearUnit, joinType?: any, bevelRatio?: number, flattenError?: number): GeometryUnion | GeometryUnion[];

/**
 * Creates planar (or Euclidean) buffer polygons at a specified distance around the input geometries.
 *
 * The GeometryEngine has two methods for buffering geometries client-side: buffer and [geodesicBuffer()](https://developers.arcgis.com/javascript/latest/references/core/geometry/geometryEngine/#geodesicBuffer).
 * Use caution when
 * deciding which method to use. As a general rule, use [geodesicBuffer()](https://developers.arcgis.com/javascript/latest/references/core/geometry/geometryEngine/#geodesicBuffer) if the input geometries
 * have a spatial reference of either WGS84 (wkid: 4326) or [Web Mercator](https://developers.arcgis.com/javascript/latest/references/core/geometry/SpatialReference/#isWebMercator). Only use buffer (this method)
 * when attempting to buffer geometries with a [projected coordinate system](https://developers.arcgis.com/rest/services-reference/enterprise/using-spatial-references.htm) other than Web Mercator. If you need to buffer geometries
 * with a geographic coordinate system other than WGS84 (wkid: 4326), use
 * [buffer()](https://developers.arcgis.com/javascript/latest/references/core/rest/geometryService/#buffer).
 *
 * @deprecated since version 4.32. Use [bufferOperator](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/bufferOperator/) instead.
 * @param geometry - The buffer input geometry.
 *        The `geometry` and `distance` parameters must be specified as either both arrays or
 *        both non-arrays. Never specify one as an array and the other a non-array.
 * @param distance - The specified distance(s) for buffering. The `geometry` and `distance` parameters must be specified as either both arrays or
 *        both non-arrays. Never specify one as an array and the other a non-array.
 *        When using an array of geometries as input, the length of the geometry array does not have to
 *        equal the length of the `distance` array. For example, if you pass an array of four geometries:
 *        `[g1, g2, g3, g4]` and an array with one distance: `[d1]`, all four geometries will be buffered by the
 *        single distance value. If instead you use an array of three distances: `[d1, d2, d3]`, `g1` will be buffered by
 *        `d1`, `g2` by `d2`, and `g3` and `g4` will both be buffered by `d3`. The value of the geometry array will
 *        be matched one to one with those in the distance array until the final value of the distance array is reached,
 *        in which case that value will be applied to the remaining geometries.
 * @param unit - Measurement unit of the distance(s).
 *        Defaults to the units of the input geometries.
 * @param toUnionResults - = false - Determines whether the output geometries should be unioned into a single
 *        polygon.
 * @returns The resulting buffer(s).
 * The result will be an array if an array of geometries is used as input. It will be a single polygon if
 * a single geometry is input into the function.
 * @see [geodesicBuffer()](https://developers.arcgis.com/javascript/latest/references/core/geometry/geometryEngine/#geodesicBuffer)
 * @example
 * // Buffer point by 1000 feet
 * const ptBuff = geometryEngine.buffer(point, 1000, "feet");
 */
export function buffer(geometry: GeometryUnion | GeometryUnion[], distance: number, unit?: number | LinearUnit, toUnionResults?: boolean): Polygon | Polygon[];

/**
 * Creates geodesic buffer polygons at a specified distance around the input geometries. When calculating distances,
 * this method takes the curvature of the earth into account, which provides highly accurate results when dealing with
 * very large geometries and/or geometries that spatially vary on a global scale where one projected coordinate
 * system could not accurately plot coordinates and measure distances for all the geometries.
 *
 * This method only works with WGS84 (wkid: 4326) and [Web Mercator](https://developers.arcgis.com/javascript/latest/references/core/geometry/SpatialReference/#isWebMercator) spatial references. In general,
 * if your input geometries are assigned one of those two spatial references, you should always use geodesicBuffer() to
 * obtain the most accurate results for those geometries. If needing to buffer points assigned a
 * [projected coordinate system other than Web Mercator](https://developers.arcgis.com/rest/services-reference/enterprise/using-spatial-references.htm), use [buffer()](https://developers.arcgis.com/javascript/latest/references/core/geometry/geometryEngine/#buffer) instead. If the input geometries
 * have a geographic coordinate system other than WGS84 (wkid: 4326), use
 * [buffer()](https://developers.arcgis.com/javascript/latest/references/core/rest/geometryService/#buffer).
 *
 * @deprecated since version 4.32. Use [geodesicBufferOperator](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/geodesicBufferOperator/) instead.
 * @param geometry - The buffer input geometry.
 *        The `geometry` and `distance` parameters must be specified as either both arrays or
 *        both non-arrays. Never specify one as an array and the other a non-array.
 * @param distance - The specified distance(s) for buffering. The `geometry` and
 * `distance` parameters must be specified as either both arrays or both non-arrays. Never specify one
 * as an array and the other a non-array. When using an array of geometries as input, the length of the
 * geometry array does not have to equal the length of the `distance` array. For example, if you pass an array of four geometries:
 * `[g1, g2, g3, g4]` and an array with one distance: `[d1]`, all four geometries will be buffered by the
 * single distance value. If instead you use an array of three distances: `[d1, d2, d3]`, `g1` will be buffered by
 * `d1`, `g2` by `d2`, and `g3` and `g4` will both be buffered by `d3`. The value of the geometry array will
 * be matched one to one with those in the distance array until the final value of the distance array is reached,
 * in which case that value will be applied to the remaining geometries.
 * @param unit - Measurement unit of the distance(s).
 *        Defaults to the units of the input geometries.
 * @param toUnionResults - = false - Determines whether the output geometries should be unioned into a single
 *        polygon.
 * @returns The resulting buffer(s).
 * The result will be an array if an array of geometries is used as input. It will be a single polygon if
 * a single geometry is input into the function.
 * @example
 * // point is a Point geometry
 * const ptBuff = geometryEngine.geodesicBuffer(point, 1000, "kilometers");  // Buffer point by 1000km
 */
export function geodesicBuffer(geometry: GeometryUnion | GeometryUnion[], distance: number | number[], unit?: number | LinearUnit, toUnionResults?: boolean): Polygon | Polygon[];

/**
 * Finds the coordinate of the geometry that is closest to the specified point.
 *
 * @deprecated since version 4.32. Use [proximityOperator's getNearestCoordinate()](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/proximityOperator/#getNearestCoordinate) method instead.
 * @param geometry - The geometry to consider.
 * @param inputPoint - The point used to search the nearest coordinate in the geometry.
 * @returns Returns an object containing the nearest coordinate.
 */
export function nearestCoordinate(geometry: GeometryUnion, inputPoint: Point): NearestPointResult<Point>;

/**
 * Finds the vertex on the geometry nearest to the specified point.
 *
 * @deprecated since version 4.32. Use [proximityOperator's getNearestVertex()](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/proximityOperator/#getNearestVertex) method instead.
 * @param geometry - The geometry to consider.
 * @param inputPoint - The point used to search the nearest vertex in the geometry.
 * @returns Returns an object containing the nearest vertex.
 * @example
 * // Finds the nearest vertex of the polygon to the input point
 * const {
 *  coordinate,
 *  distance
 * } = geometryEngine.nearestVertex(boundaryPolygon, point);
 */
export function nearestVertex(geometry: GeometryUnion, inputPoint: Point): NearestPointResult<Point>;

/**
 * Finds all vertices in the given distance from the specified point, sorted from the closest to the furthest and
 * returns them as an array of Objects.
 *
 * @deprecated since version 4.32. Use [proximityOperator's getNearestVertices()](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/proximityOperator/#getNearestVertices) method instead.
 * @param geometry - The geometry to consider.
 * @param inputPoint - The point from which to measure.
 * @param searchRadius - The distance to search from the inputPoint in the units of the view's spatial reference.
 * @param maxVertexCountToReturn - The maximum number of vertices to return.
 * @returns An array of objects containing the nearest
 *  vertices within the given `searchRadius`.
 * @example
 * // Returns an array of the nearest vertices
 * const nearest = geometryEngine.nearestVertices(boundaryPolygon, point, 500, 2);
 */
export function nearestVertices(geometry: GeometryUnion, inputPoint: Point, searchRadius: number, maxVertexCountToReturn: number): NearestPointResult<Point>[];

/**
 * Rotates a geometry counterclockwise by the specified number of degrees.
 * Rotation is around the centroid, or a given rotation point.
 *
 * @deprecated since version 4.32. Use [Transformation's rotate()](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/support/Transformation/#rotate) method and the [affineTransformOperator](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/affineTransformOperator/) instead.
 * @param geometry - The geometry to rotate.
 * @param angle - The rotation angle in degrees.
 * @param rotationOrigin - Point to rotate the geometry around. Defaults to the centroid of the geometry.
 * @returns The rotated geometry.
 * @example
 * // Returns a geometry rotated by 45 degrees
 * const geometry = geometryEngine.rotate(boundaryPolygon, 45);
 */
export function rotate(geometry: GeometryUnion, angle: number, rotationOrigin?: Point | null): GeometryUnion;

/**
 * Flips a geometry on the horizontal axis. Can optionally be flipped around a point.
 *
 * @deprecated since version 4.32. Use [Transformation's flipY()](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/support/Transformation/#flipY) method and the [affineTransformOperator](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/affineTransformOperator/) instead.
 * @param geometry - The input geometry to be flipped.
 * @param flipOrigin - Point to flip the geometry around. Defaults to the centroid of the geometry.
 * @returns The flipped geometry.
 * @example
 * // Returns a geometry flipped horizontally
 * const geometry = geometryEngine.flipHorizontal(boundaryPolygon);
 */
export function flipHorizontal(geometry: GeometryUnion, flipOrigin?: Point | null | undefined): GeometryUnion;

/**
 * Flips a geometry on the vertical axis. Can optionally be flipped around a point.
 *
 * @deprecated since version 4.32. Use [Transformation's flipX()](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/support/Transformation/#flipX) method and the [affineTransformOperator](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/affineTransformOperator/) instead.
 * @param geometry - The input geometry to be flipped.
 * @param flipOrigin - Point to flip the geometry around. Defaults to the centroid of the geometry.
 * @returns The flipped geometry.
 * @example
 * // Returns a geometry flipped vertically
 * const geometry = geometryEngine.flipVertical(boundaryPolygon);
 */
export function flipVertical(geometry: GeometryUnion, flipOrigin?: Point | null | undefined): GeometryUnion;

/**
 * Performs the generalize operation on the geometries in the cursor. Point and Multipoint geometries are left unchanged.
 * Envelope is converted to a Polygon and then generalized.
 *
 * @deprecated since version 4.32. Use [generalizeOperator](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/generalizeOperator/) instead.
 * @param geometry - The input geometry to be generalized.
 * @param maxDeviation - The maximum allowed deviation from the generalized geometry to the original geometry.
 * @param removeDegenerateParts - When `true` the degenerate parts of the geometry will
 * be removed from the output (may be undesired for drawing).
 * @param maxDeviationUnit - Measurement unit for maxDeviation.
 * Defaults to the units of the input geometry.
 * @returns The generalized geometry.
 * @example
 * // Returns a generalized geometry
 * const geometry = geometryEngine.generalize(boundaryPolygon, 2.5, true, "miles");
 */
export function generalize(geometry: GeometryUnion, maxDeviation: number, removeDegenerateParts?: boolean, maxDeviationUnit?: number | LinearUnit): GeometryUnion;

/**
 * Densify geometries by plotting points between existing vertices.
 *
 * @deprecated since version 4.32. Use [densifyOperator](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/densifyOperator/) instead.
 * @param geometry - The geometry to be densified.
 * @param maxSegmentLength - The maximum segment length allowed. Must be a positive value.
 * @param maxSegmentLengthUnit - Measurement unit for maxSegmentLength.
 * Defaults to the units of the input geometry.
 * @returns The densified geometry.
 * @see [geodesicDensify()](https://developers.arcgis.com/javascript/latest/references/core/geometry/geometryEngine/#geodesicDensify)
 * @example
 * // Returns a densified geometry
 * const geometry = geometryEngine.densify(boundaryPolygon, 25);
 */
export function densify(geometry: GeometryUnion, maxSegmentLength: number, maxSegmentLengthUnit?: number | LinearUnit): GeometryUnion;

/**
 * Returns a geodetically densified version of the input geometry. Use this function to draw the line(s) of the geometry along great circles.
 *
 * @deprecated since version 4.32. Use [geodeticDensifyOperator](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/geodeticDensifyOperator/) instead.
 * @param geometry - A polyline or polygon to densify.
 * @param maxSegmentLength - The maximum segment length allowed (in meters if a `maxSegmentLengthUnit` is not provided). This must be a positive value.
 * @param maxSegmentLengthUnit - Measurement unit for `maxSegmentLength`. If not provided, the unit will default to `meters`.
 * @returns Returns the densified geometry.
 * @example
 * // lineGeom is a line geometry
 * const densifiedGeom = geometryEngine.geodesicDensify(lineGeom, 10000);
 */
export function geodesicDensify(geometry: Polyline | Polygon, maxSegmentLength: number, maxSegmentLengthUnit?: LinearUnit): GeometryUnion;

/**
 * Calculates the area of the input geometry. As opposed to [geodesicArea()](https://developers.arcgis.com/javascript/latest/references/core/geometry/geometryEngine/#geodesicArea), planarArea() performs
 * this calculation using projected coordinates and does not take into account the earth's curvature. When using input geometries with a
 * spatial reference of either WGS84 (wkid: 4326) or [Web Mercator](https://developers.arcgis.com/javascript/latest/references/core/geometry/SpatialReference/#isWebMercator), it is best practice to
 * calculate areas using [geodesicArea()](https://developers.arcgis.com/javascript/latest/references/core/geometry/geometryEngine/#geodesicArea). If the input geometries have a projected coordinate system other than
 * Web Mercator, use planarArea() instead.
 *
 * @deprecated since version 4.32. Use [areaOperator](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/areaOperator/) instead.
 * @param geometry - The input polygon.
 * @param unit - Measurement unit of the return value.
 * Defaults to the units of the input geometries.
 * @returns The area of the input geometry.
 * @example
 * // Returns the numeric area of the given polygon
 * const area = geometryEngine.planarArea(boundaryPolygon, "square-miles");
 */
export function planarArea(geometry: Polygon, unit?: number | AreaUnit): number;

/**
 * Calculates the length of the input geometry. As opposed to [geodesicLength()](https://developers.arcgis.com/javascript/latest/references/core/geometry/geometryEngine/#geodesicLength), planarLength() uses
 * projected coordinates and does not take into account
 * the curvature of the earth when performing this calculation. When using input geometries with a
 * spatial reference of either WGS84 (wkid: 4326) or [Web Mercator](https://developers.arcgis.com/javascript/latest/references/core/geometry/SpatialReference/#isWebMercator), it is best practice to
 * calculate lengths using [geodesicLength()](https://developers.arcgis.com/javascript/latest/references/core/geometry/geometryEngine/#geodesicLength). If the input geometries have a projected coordinate system other than
 * Web Mercator, use planarLength() instead.
 *
 * @deprecated since version 4.32. Use [lengthOperator](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/lengthOperator/) instead.
 * @param geometry - The input geometry.
 * @param unit - Measurement unit of the return value.
 * Defaults to the units of the input geometries.
 * @returns The length of the input geometry.
 * @example
 * // Returns the numeric length of the given line
 * const length = geometryEngine.planarLength(riverGeometry, "miles");
 */
export function planarLength(geometry: GeometryUnion, unit?: number | LinearUnit): number;

/**
 * Calculates the area of the input geometry. As opposed to [planarArea()](https://developers.arcgis.com/javascript/latest/references/core/geometry/geometryEngine/#planarArea), geodesicArea takes into account
 * the curvature of the earth when performing this calculation. Therefore, when using input geometries with a
 * spatial reference of either WGS84 (wkid: 4326) or [Web Mercator](https://developers.arcgis.com/javascript/latest/references/core/geometry/SpatialReference/#isWebMercator), it is best practice to
 * calculate areas using geodesicArea(). If the input geometries have a projected coordinate system other than
 * Web Mercator, use [planarArea()](https://developers.arcgis.com/javascript/latest/references/core/geometry/geometryEngine/#planarArea) instead.
 *
 * This method only works with WGS84 (wkid: 4326) and [Web Mercator](https://developers.arcgis.com/javascript/latest/references/core/geometry/SpatialReference/#isWebMercator) spatial references.
 *
 * @deprecated since version 4.32. Use [geodeticAreaOperator](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/geodeticAreaOperator/) instead.
 * @param geometry - The input polygon.
 * @param unit - Measurement unit of the return value.
 * Defaults to the units of the input geometries.
 * @returns Area of the input geometry.
 * @example
 * // Returns the numeric geodesic area of the given polygon
 * const area = geometryEngine.geodesicArea(boundaryPolygon, "square-miles");
 */
export function geodesicArea(geometry: Polygon, unit?: number | AreaUnit): number;

/**
 * Calculates the length of the input geometry. As opposed to [planarLength()](https://developers.arcgis.com/javascript/latest/references/core/geometry/geometryEngine/#planarLength), geodesicLength() takes into account
 * the curvature of the earth when performing this calculation. Therefore, when using input geometries with a
 * spatial reference of either WGS84 (wkid: 4326) or [Web Mercator](https://developers.arcgis.com/javascript/latest/references/core/geometry/SpatialReference/#isWebMercator), it is best practice to
 * calculate lengths using geodesicLength(). If the input geometries have a projected coordinate system other than
 * Web Mercator, use [planarLength()](https://developers.arcgis.com/javascript/latest/references/core/geometry/geometryEngine/#planarLength) instead.
 *
 * This method only works with WGS84 (wkid: 4326) and [Web Mercator](https://developers.arcgis.com/javascript/latest/references/core/geometry/SpatialReference/#isWebMercator) spatial references.
 *
 * @deprecated since version 4.32. Use [geodeticLengthOperator](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/geodeticLengthOperator/) instead.
 * @param geometry - The input geometry.
 * @param unit - Measurement unit of the return value.
 * Defaults to the units of the input geometry.
 * @returns Length of the input geometry.
 * @example
 * // Returns the numeric geodesic length of the given line
 * const length = geometryEngine.geodesicLength(riverGeometry, "miles");
 */
export function geodesicLength(geometry: GeometryUnion, unit?: number | LinearUnit): number;

/**
 * Returns an array of points at the intersecting locations of two input polylines. Use
 * [intersect()](https://developers.arcgis.com/javascript/latest/references/core/geometry/geometryEngine/#intersect) for all other geometry intersect operations.
 *
 * @deprecated since version 4.32. Use [intersectionOperator's executeMany()](https://developers.arcgis.com/javascript/latest/references/core/geometry/operators/intersectionOperator/#executeMany) method instead.
 * @param line1 - The first polyline to use in the intersect operation.
 * @param line2 - The second polyline to use in the intersect operation.
 * @returns The point intersections of the input polylines.
 * @since 4.25
 * @see [intersect()](https://developers.arcgis.com/javascript/latest/references/core/geometry/geometryEngine/#intersect)
 * @example
 * // Creates an array of points for the intersections of the input lines
 * const intersections = geometryEngine.intersectLinesToPoints(line1, line2);
 */
export function intersectLinesToPoints(line1: Polyline, line2: Polyline): Point[];