GeoGeometry Class
A geometry, as defined by GeoJSON and the Simple Features of the OGC: a GeoPoint, a GeoMultiPoint, a GeoLineString, a GeoMultiLineString, a GeoPolygon, a GeoMultiPolygon or a GeoGeometryCollection.
public abstract class GeoGeometryRemarks
The geometries are immutable.
Properties
| Name | Description |
|---|---|
| CrossesAntimeridian | Gets a value that indicates whether a line or a ring of the geometry has an edge that is meant to cross the 180th meridian: an edge whose ends are more than 180° of longitude apart, such as an edge from the longitude 179 to the longitude -179. The edges whose ends are both on the 180th meridian, such as the edges of a box around the whole world from -180 to 180, do not count. |
| IsEmpty | Gets a value that indicates whether the geometry has no position. |
| LabelPosition | Gets a position to label the geometry: the centroid of the exterior ring of its largest polygon (so the islands of a country do not pull it away), else the mean of the positions of its lines, else the mean of its points. The centroid is computed on the longitudes and latitudes, as on an equirectangular map. A ring with an edge that crosses the 180th meridian (see GeoGeometry.CrossesAntimeridian) and the positions on both sides of it are taken as they are on the globe, so the label does not move to the other side of the world. It is null for an empty geometry. |
| Type | Gets the type of the geometry. |
CrossesAntimeridian
GeoGeometry.csGets a value that indicates whether a line or a ring of the geometry has an edge that is meant to cross the 180th meridian: an edge whose ends are more than 180° of longitude apart, such as an edge from the longitude 179 to the longitude -179. The edges whose ends are both on the 180th meridian, such as the edges of a box around the whole world from -180 to 180, do not count.
public bool CrossesAntimeridian { get; }Property value
Remarks
RFC 7946 wants such geometries split along the 180th meridian: the operations of this class draw the edge from 179 to -179 the long way, through the Greenwich meridian. Split them with GeoGeometry.SplitAtAntimeridian, or use GeoEdgeType.Geodesic edges.
IsEmpty
GeoGeometry.csLabelPosition
GeoGeometry.csGets a position to label the geometry: the centroid of the exterior ring of its largest polygon (so the islands of a country do not pull it away), else the mean of the positions of its lines, else the mean of its points. The centroid is computed on the longitudes and latitudes, as on an equirectangular map. A ring with an edge that crosses the 180th meridian (see GeoGeometry.CrossesAntimeridian) and the positions on both sides of it are taken as they are on the globe, so the label does not move to the other side of the world. It is null for an empty geometry.
public GeoPosition? LabelPosition { get; }Property value
Type
Methods
| Name | Description |
|---|---|
| Buffer(double, GeoBufferOptions?) | Gets the area within a distance of the geometry, such as a zone around a position for a geofence or a corridor along a route. |
| Clip(GeoBounds) | Cuts the geometry to a box: the parts of the points, lines and polygons that are inside it. |
| ConvexHull() | Gets the smallest convex polygon that contains every position of the geometry. |
| Difference(GeoGeometry) | Gets the area of this geometry that is outside another one. |
| Distance(GeoGeometry) | Gets the shortest distance between this geometry and another one, on the WGS 84 ellipsoid. |
| GetBoundaryLines() | Gets the rings of the polygons of the geometry as closed lines, such as the coastlines of land polygons. |
| GetBounds() | Gets the smallest box that contains the geometry. |
| GetBounds(GeoEdgeType) | Gets the smallest box that contains the geometry, whose edges are drawn as an edge type says. |
| GetPositions() | Gets the positions of the geometry: every position of every point, line and ring, in order. |
| GetSimpleGeometries() | Gets the simple geometries of the geometry: itself for a simple geometry, its parts for a multi-geometry or a collection, recursively. |
| Intersection(GeoGeometry) | Gets the area that this geometry and another one have in common. |
| MakeValid() | Repairs the polygons of the geometry: a ring that crosses itself or another ring of its polygon, a hole outside its exterior ring, rings in the wrong direction or repeated positions. Each polygon becomes the area its rings enclose an odd number of times (a bow-tie becomes two triangles), and a multi-polygon the union of the areas of its polygons. The exterior rings of the result turn counter-clockwise and its holes clockwise, as RFC 7946 wants them. |
| Simplify(double) | Simplifies the lines and the rings of the geometry with the Douglas–Peucker algorithm: the positions that are closer than the tolerance to the line between the positions kept around them are removed. The simplified polygons are repaired with GeoGeometry.MakeValid, since removing positions can make a ring cross itself or another one. |
| SplitAtAntimeridian() | Splits the lines and the polygons of the geometry along the 180th meridian, as RFC 7946 wants it, and moves every longitude to [-180, 180]. The edges that cross the 180th meridian (see GeoGeometry.CrossesAntimeridian) take the shortest way, and the longitudes greater than 180 or smaller than -180 go around the world. |
| Transform(CoordinateReferenceSystem, CoordinateReferenceSystem) | Gets a geometry of the same type whose positions are converted from a coordinate reference system to another one, such as from Lambert 93 to the longitudes and latitudes of WGS 84. |
| Transform(Func<GeoPosition, GeoPosition>) | Gets a geometry of the same type whose positions are transformed, such as positions in another coordinate system converted to longitudes and latitudes. |
| Union(GeoGeometry) | Gets the union of the area of this geometry and of the area of another one. |
Buffer(double, GeoBufferOptions?)
GeoGeometry.csGets the area within a distance of the geometry, such as a zone around a position for a geofence or a corridor along a route.
public GeoGeometry? Buffer(double distance, GeoBufferOptions? options = null)Parameters
distancedouble- The distance, in meters. A negative distance shrinks the polygons; the points and lines then have no buffer.
optionsGeoBufferOptions?- The shape of the joins and of the ends of the lines, or
nullfor round ones.
Returns
GeoGeometry? The buffer, a GeoPolygon or a GeoMultiPolygon, or null when it is empty: a point or a line with a distance of 0 or less, or a polygon that shrinks to nothing.
Exceptions
ArgumentOutOfRangeExceptiondistanceis infinite or not a number.InvalidOperationException- A coordinate of a polygon is not a number between -100,000 and 100,000.
Remarks
The positions at the distance are computed on the WGS 84 ellipsoid, and joined by edges straight in degrees: the circles are polygons of 4 × GeoBufferOptions.SegmentsPerQuarterCircle sides. The edges of the geometry are cut in pieces that span less than half a degree of latitude. The result is combined as by GeoGeometry.Union: its positions are on the grid of ten-millionths of a degree. A buffer that contains a pole is not handled, and one that crosses the 180th meridian has longitudes beyond 180 or -180.
Clip(GeoBounds)
GeoGeometry.csCuts the geometry to a box: the parts of the points, lines and polygons that are inside it.
public GeoGeometry? Clip(GeoBounds bounds)Parameters
boundsGeoBounds- The box.
Returns
GeoGeometry? The part of the geometry that is inside the box, or null when nothing is. The geometry itself when it is entirely inside. A line that leaves the box and comes back becomes a GeoMultiLineString. The polygons are cut as by GeoGeometry.Intersection. Where a line crosses the side of the box, the new position gets the altitude, the measure and the time interpolated between the positions around it, when both have one.
Exceptions
ArgumentException- The box is empty: its south side is north of its north side.
Remarks
A box whose west side is east of its east side crosses the 180th meridian (see GeoBounds.CrossesAntimeridian): the result is the part of the geometry east of its west side and the part west of its east side, as a multi-geometry. Split the geometries that cross the 180th meridian with GeoGeometry.SplitAtAntimeridian first.
ConvexHull()
GeoGeometry.csGets the smallest convex polygon that contains every position of the geometry.
public GeoGeometry? ConvexHull()Returns
GeoGeometry? The convex hull: a GeoPolygon whose exterior ring turns counter-clockwise, a GeoLineString between the two ends when the positions are on a line, a GeoPoint when they are all the same, or null for an empty geometry. The positions of the result are positions of the geometry.
Remarks
The hull is computed on the longitudes and latitudes, as on an equirectangular map: its edges are straight in degrees.
Difference(GeoGeometry)
GeoGeometry.csGets the area of this geometry that is outside another one.
public GeoGeometry? Difference(GeoGeometry other)Parameters
otherGeoGeometry- The other geometry: a polygon, a multi-polygon or a collection of polygons.
Returns
GeoGeometry? The difference, or null when it is empty.
Exceptions
InvalidOperationException- This geometry is not a polygon, a multi-polygon or a collection of polygons.
ArgumentExceptionotheris not a polygon, a multi-polygon or a collection of polygons.
Remarks
See GeoGeometry.Union for how the rings are read and what the result is made of.
Distance(GeoGeometry)
GeoGeometry.csGets the shortest distance between this geometry and another one, on the WGS 84 ellipsoid.
public double? Distance(GeoGeometry other)Parameters
otherGeoGeometry- The other geometry.
Returns
double? The distance, in meters: 0 when the geometries meet, such as a point inside a polygon or two lines that cross. null when one of the geometries is empty. The altitudes are ignored.
Remarks
The edges are straight in degrees, as for the other operations, and the inside of the polygons is the inside as tested by GeoPolygon.Contains. The distance between the nearest positions is computed with the formulas of Vincenty, accurate to a millimeter, except for nearly antipodal positions, where it is the great-circle distance (within 0.5%). The nearest position of an edge is found to a fraction of a millimeter on edges of a few kilometers.
GetBoundaryLines()
GeoGeometry.csGets the rings of the polygons of the geometry as closed lines, such as the coastlines of land polygons.
public IEnumerable<GeoLineString> GetBoundaryLines()Returns
IEnumerable<GeoLineString> A line for each ring of each polygon, exterior rings and holes, in order. Nothing for points and lines.
GetBounds overloads
GetBounds()
GeoGeometry.csGets the smallest box that contains the geometry.
public GeoBounds? GetBounds()Returns
GeoBounds? The box, or null for an empty geometry.
Remarks
The box contains the positions, as the edges are straight in degrees (GeoEdgeType.Planar): it does not cross the 180th meridian.
GetBounds(GeoEdgeType)
GeoGeometry.csGets the smallest box that contains the geometry, whose edges are drawn as an edge type says.
public GeoBounds? GetBounds(GeoEdgeType edgeType)Parameters
edgeTypeGeoEdgeType- How the edges are drawn.
Returns
GeoBounds? The box, or null for an empty geometry. With GeoEdgeType.Planar, the box of GeoGeometry.GetBounds. With GeoEdgeType.Geodesic, the smallest box that contains the shortest great-circle arcs between the consecutive positions: it can cross the 180th meridian (its west side is east of its east side, as RFC 7946 allows), such as the box of a flight from Tokyo to San Francisco or of the parts of Fiji on both sides of the 180th meridian, and it goes past the latitudes of the positions where the arcs bend toward a pole. A ring that goes around a pole, such as the coast of Antarctica, gives a box that contains the pole and every longitude.
Exceptions
ArgumentOutOfRangeExceptionedgeTypeis not a value ofGeoEdgeType.
GetPositions()
Gets the positions of the geometry: every position of every point, line and ring, in order.
public abstract IEnumerable<GeoPosition> GetPositions()Returns
IEnumerable<GeoPosition> The positions.
GetSimpleGeometries()
GeoGeometry.csGets the simple geometries of the geometry: itself for a simple geometry, its parts for a multi-geometry or a collection, recursively.
public IEnumerable<GeoGeometry> GetSimpleGeometries()Returns
IEnumerable<GeoGeometry> The points, line strings and polygons of the geometry.
Intersection(GeoGeometry)
GeoGeometry.csGets the area that this geometry and another one have in common.
public GeoGeometry? Intersection(GeoGeometry other)Parameters
otherGeoGeometry- The other geometry: a polygon, a multi-polygon or a collection of polygons.
Returns
GeoGeometry? The intersection, or null when it is empty.
Exceptions
InvalidOperationException- This geometry is not a polygon, a multi-polygon or a collection of polygons.
ArgumentExceptionotheris not a polygon, a multi-polygon or a collection of polygons.
Remarks
See GeoGeometry.Union for how the rings are read and what the result is made of.
MakeValid()
GeoGeometry.csRepairs the polygons of the geometry: a ring that crosses itself or another ring of its polygon, a hole outside its exterior ring, rings in the wrong direction or repeated positions. Each polygon becomes the area its rings enclose an odd number of times (a bow-tie becomes two triangles), and a multi-polygon the union of the areas of its polygons. The exterior rings of the result turn counter-clockwise and its holes clockwise, as RFC 7946 wants them.
public GeoGeometry MakeValid()Returns
GeoGeometry The repaired geometry: a polygon becomes a GeoPolygon, or a GeoMultiPolygon when it is cut in several parts. The positions of the polygons move to the nearest ten-millionth of a degree (about a centimeter), and lose their altitude, measure and time. The consecutive repeated positions of the lines (same coordinates and altitude) are removed, the first one being kept; the points are unchanged.
Exceptions
InvalidOperationException- A coordinate of a polygon is not a number between -100,000 and 100,000.
Remarks
The computation is exact on the grid of ten-millionths of a degree, as on an equirectangular map: the edges are straight in degrees.
Simplify(double)
GeoGeometry.csSimplifies the lines and the rings of the geometry with the Douglas–Peucker algorithm: the positions that are closer than the tolerance to the line between the positions kept around them are removed. The simplified polygons are repaired with GeoGeometry.MakeValid, since removing positions can make a ring cross itself or another one.
public GeoGeometry? Simplify(double tolerance)Parameters
tolerancedouble- The largest distance between the geometry and its simplification, in degrees: 0.001° is about 100 meters.
Returns
GeoGeometry? The simplified geometry, or null when every line and ring collapses. The points are unchanged.
Exceptions
ArgumentOutOfRangeExceptiontoleranceis negative, infinite or not a number.
SplitAtAntimeridian()
GeoGeometry.csSplits the lines and the polygons of the geometry along the 180th meridian, as RFC 7946 wants it, and moves every longitude to [-180, 180]. The edges that cross the 180th meridian (see GeoGeometry.CrossesAntimeridian) take the shortest way, and the longitudes greater than 180 or smaller than -180 go around the world.
public GeoGeometry SplitAtAntimeridian()Returns
GeoGeometry The geometry itself when no edge crosses the 180th meridian and every longitude is in [-180, 180]. Otherwise, a line that crosses it becomes a GeoMultiLineString whose parts end and start on it, at the longitudes 180 and -180, and a polygon a GeoMultiPolygon with a polygon on each side. The points are moved, not split. The positions where a line crosses the meridian are interpolated as on an equirectangular map. A polygon is cut with GeoGeometry.Clip: the positions of a polygon that is cut move to the nearest ten-millionth of a degree and lose their altitude. A ring that goes around a pole, such as the coast of Antarctica, is closed through the pole it is nearest to.
Exceptions
InvalidOperationException- A coordinate of a polygon to split is not a number between -100,000 and 100,000.
Transform overloads
Transform(CoordinateReferenceSystem, CoordinateReferenceSystem)
GeoGeometry.csGets a geometry of the same type whose positions are converted from a coordinate reference system to another one, such as from Lambert 93 to the longitudes and latitudes of WGS 84.
public GeoGeometry Transform(CoordinateReferenceSystem source, CoordinateReferenceSystem target)Parameters
sourceCoordinateReferenceSystem- The coordinate reference system of the positions of this geometry.
targetCoordinateReferenceSystem- The coordinate reference system to convert the positions to, such as
CoordinateReferenceSystem.Wgs84.
Returns
GeoGeometry The converted geometry.
Remarks
The positions are converted one by one: the edges between them are not curved to follow the projection.
Transform(Func<GeoPosition, GeoPosition>)
GeoGeometry.csGets a geometry of the same type whose positions are transformed, such as positions in another coordinate system converted to longitudes and latitudes.
public GeoGeometry Transform(Func<GeoPosition, GeoPosition> transform)Parameters
transformFunc<GeoPosition, GeoPosition>- The function that transforms each position. Return
position with { Longitude = ..., Latitude = ... }to keep its altitude, measure and time.
Returns
GeoGeometry The transformed geometry.
Union(GeoGeometry)
GeoGeometry.csGets the union of the area of this geometry and of the area of another one.
public GeoGeometry? Union(GeoGeometry other)Parameters
otherGeoGeometry- The other geometry: a polygon, a multi-polygon or a collection of polygons.
Returns
GeoGeometry? The union, or null when it is empty.
Exceptions
InvalidOperationException- This geometry is not a polygon, a multi-polygon or a collection of polygons.
ArgumentExceptionotheris not a polygon, a multi-polygon or a collection of polygons.
Remarks
The exterior ring of each polygon adds its area, and its holes remove theirs, whatever their direction: call GeoGeometry.MakeValid first on polygons whose rings cross. The result is a GeoPolygon or a GeoMultiPolygon whose positions are on the grid of ten-millionths of a degree.