Geometry

Geometries represent real-world objects by defining a shape at a specific geographic location. They are used throughout the API to represent the shapes of features and graphics, layer extents, viewpoints, and GPS locations. They are also used as inputs and outputs of spatial analysis and geoprocessing operations, and to measure distances and areas, among other uses.

Geometry in ArcGIS Runtime

The Geometry class provides functionality common to all types of geometry. MapPoint, Multipoint, Polyline, Polygon, and Envelope all inherit from the Geometry base class, and represent different types of shapes.

The following are common geometry characteristics:

  • Geometries have a spatial reference indicating the coordinate system used by its coordinates.
  • Geometries can be empty, indicating that they have no specific location or shape.
  • Geometries can have z-values and/or m-values.
  • Geometries can be converted to and from JSON to be persisted or to be exchanged directly with REST services.

Geometries are immutable

Most geometries are created and not changed for their lifetime. Examples include feature geometry created for storage in a geodatabase, read from a non-editable layer, or returned from tasks such as spatial queries, geocode operations, network traces, or geoprocessing. Immutable geometries (geometries that cannot be changed) offer some significant benefits to your app. They are inherently thread-safe, help prevent accidental changes, and allow for certain performance optimizations.

While immutable geometries appear to present problems for editing existing geometries, those problems are solved by using geometry builders. Geometry builders are designed to represent the state of a geometry under construction while allowing modifications, thus enabling editing workflows.

Point

MapPoint geometries represent a single point, place, or location such as a geocoded house address along a street or the location of a water meter in a water utility network. Larger geographic entities such as cities are often represented as points on small-scale maps. Points can be used as the geometry of features and graphics and are often used to help construct other geometries.

Points store a single set of x,y coordinates that represent a discrete location within a specified coordinate system (spatial reference). Optionally, a z-value (to define elevation, for example) can also be included. Instances of MapPoint can be created using a constructor that defines the full geometry by passing an x coordinate, y coordinate, and spatial reference.

Use dark colors for code blocksCopy
                                                                                                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// create a point with x, y, and z coordinate values using the WGS 1984 coordinate system
var saltLakeCity = new MapPoint(-111.88, 40.75, 1320, SpatialReferences.Wgs84);

Envelope

Envelope geometries represent rectangular shapes with sides that are parallel with the x or y axis of the coordinate system. Most commonly, they represent the spatial extent of layers or other geometries, or define areas of interest for tasks. They can be used as the geometry of graphics and in many geometry operations. Envelopes cannot be used to store feature geometry.

New instances of Envelope are defined by specifying a minimum and maximum x-coordinate and minimum and maximum y-coordinate, and a SpatialReference. Optionally, a minimum and maximum z-value can be specified to define the depth of the envelope.

Use dark colors for code blocksCopy
                                                                                                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// Envelope with bounding coords defined in longitude and latitude
var areaOfInterest = new Envelope(-117.85, 32.20, -116.50, 33.45, SpatialReferences.Wgs84);

Another way to define an envelope is by using two points. The minimum and maximum x,y coordinates are calculated from the two points.

Use dark colors for code blocksCopy
                                                                                                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// Envelope with lower-left (southwest) and upper-right (northeast) points
var southwestPoint = new MapPoint(-117.85, 32.20, SpatialReferences.Wgs84);
var northeastPoint = new MapPoint(-116.50, 33.45, SpatialReferences.Wgs84);
var env = new Envelope(southwestPoint, northeastPoint);

Multipoint

Multipoint geometries represent an ordered collection of points. They can be used as the geometry of features and graphics, or as input or output of geometry operations. For features that consist of a very large number of points that share the same set of attribute values, multipoints may be more efficient to store and analyze in a geodatabase compared to using multiple point features.

Multipoints are composed of a single read-only collection of points. To build a multipoint, create an MultipointBuilder, add points, and the geometry will return an Multipoint. You can also use geometry builders to modify an existing geometry.

Use dark colors for code blocksCopy
                                                                                                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
var builder = new MultipointBuilder(SpatialReferences.Wgs84);
builder.Points.Add(southwestPoint);
builder.Points.Add(northeastPoint);
builder.Points.Add(saltLakeCity);

Multipoint oneMultipoint = builder.ToGeometry();

To access each MapPoint in an existing Multipoint, iterate over the read-only point collection returned from the points property.

Use dark colors for code blocksCopy
                                                                                                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
foreach (var pt in oneMultipoint.Points)
{
    var coordValues = string.Format("x: {0} y: {1} z: {2}", pt.X, pt.Y, pt.Z);
    System.Console.WriteLine(coordValues);
}

Polyline

Polyline geometries represent the shape and location of linear features, such as a street in a road network or a pipeline in an oil refinery. They can be used as the geometry of features and graphics, or as input or output of tasks or geoprocessing operations, such as the output of a network trace.

Polylines are composed of a series of connected segments, where each segment defines a continuous line between a start and an end point. The ArcGIS Platform, including ArcGIS Runtime, supports both linear segments and curve segments. For more information, see the Segments section below.

You can create a Polyline using a PolylineBuilder. The builder creates a series of straight line segments connecting the points you specify.

Polylines can have multiple parts. Each part is a series of connected segments, but the parts can be disjoint from each other, such as a polyline representing a discontinuous highway that has an unfinished section. Parts can also intersect at one or more vertices. For example, in a polyline representing a river and its tributaries. The Polyline class inherits from Multipart, which provides members for iterating through the segments and points of each part in a polyline.

To modify an existing polyline, use PolylineBuilder.

Use dark colors for code blocksCopy
                                                                                                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// define some map points (airports: LA, Chicago, Paris)
var laxPoint = new MapPoint(-118.408, 33.943, SpatialReferences.Wgs84);
var ordPoint = new MapPoint(-87.905, 41.979, SpatialReferences.Wgs84);
var orlyPoint = new MapPoint(2.379, 48.723, SpatialReferences.Wgs84);

// add the points to a collection
var stops = new MapPoint[] { laxPoint, ordPoint, orlyPoint };

// create a new Polyline from the points
var myFlightPath = new Polyline(stops);

Polygon

Polygon geometries represent the shape and location of areas, such as a country or a lake. They can be used as the geometry of features and graphics, or as input or output of tasks or geoprocessing operations, such as the output of a drive-time analysis or a buffer operation.

Polygons are similar to polylines in that they are also composed of a series of connected segments. However, polygons define closed areas, so the end point of the last segment is always in the same location as the start point of the first segment, forming a closed boundary. As with polylines, you can work with the vertices of the segments of a polygon by using point-based helper methods. For more information on segments, see Segments on this page.

To build a Polygon, create a PolygonBuilder and add points in the correct order around the polygon's perimeter. Next, use the toGeometry() method to provide the Polygon.

Similar to polylines, polygons can have multiple parts but have different rules than those for multipart polylines. Each part of a multipart polygon is a series of connected segments forming a closed ring. Each part must not cross any other part but may lie completely inside or outside another part. For example, a polygon representing the state of Hawaii would comprise eight disjoint parts, one representing each island. A polygon representing the country of South Africa, which completely surrounds the enclave of Lesotho, would comprise two parts, one contained inside the other. The Polygon class also inherits from Multipart.

Use dark colors for code blocksCopy
                                                                                                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// create a polygon builder; add each corner of the state of Colorado
var polyBuilder = new PolygonBuilder(SpatialReferences.Wgs84);
polyBuilder.AddPoint(-109.048, 40.998);
polyBuilder.AddPoint(-102.047, 40.998);
polyBuilder.AddPoint(-102.037, 36.989);
polyBuilder.AddPoint(-109.048, 36.998);

// get the defined polygon from the polygon builder
var coloradoPoly = polyBuilder.ToGeometry();

Multipart (Polygon and Polyline)

Polygon and Polyline inherit from Multipart. Multipart provides access to a collection of the geometry's parts. Each part in the collection is a collection of segment objects (see Segments below). You can iterate through the segments or points in each part.

Use dark colors for code blocksCopy
                                                                                                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// loop through all parts in a Polygon
foreach (var island in hawaiiPoly.Parts)
{
    // loop through the points of each part
    var points = island.Points;
    foreach (var pt in points)
    {
        // read the point coordinates
        var coordValues = string.Format("x: {0} y: {1} z: {2}", pt.X, pt.Y, pt.Z);
        System.Console.WriteLine(coordValues);
    }
}

You can iterate through the points that represent the vertices in all the parts.

Use dark colors for code blocksCopy
                                                                                                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// loop through all points (vertices) in all parts of a Polygon
foreach (var part in hawaiiPoly.Parts)
{
    foreach (var pt in part.Points)
    {
        // read the point coordinates
        var coordValues = string.Format("x: {0} y: {1} z: {2}", pt.X, pt.Y, pt.Z);
        System.Console.WriteLine(coordValues);
    }
}

In the same way as Polygon and Polyline are immutable, the collections returned from Multipart are also immutable.

Segments

A segment describes a continuous line between a start location and an end location. Every part in a multipart geometry is a collection of Segments where the end of one segment is at exactly the same location as the start of the following segment. The ArcGIS system, including ArcGIS Runtime, supports both straight and curved segments, with a few exceptions noted in the Perform edits section of the Edit topic in this guide. Multipart geometries can be composed from and decomposed into segments if required.

Linear segments are represented with instances of the LineSegment class. Curve segments can be represented with an EllipticArcSegment or CubicBezierSegment. See the True curves section of this topic for more information about working with curve geometries.

Because a single location is shared by adjacent segments, a single MapPoint object is used to represent the shared location when you iterate through the points in a part. As a result, when iterating through the points in a part of a polyline, there will be one more MapPoint than the number of Segments in that same part.

Similar to the geometries they comprise, Segments are immutable.

Work with geometry

Spatial references

The meaning of the coordinates in a geometry is determined by the geometry's spatial reference. The vertices and spatial reference together allow your app to translate a real-world object from its location on the Earth to its location on your map or scene.

In some cases, a geometry's spatial reference may not be set. Graphics that do not have a spatial reference are drawn using the same spatial reference as the map view in which they are drawn. When using a geometry builder to create a polyline or polygon geometry from point geometries, you don't need to set the spatial reference of every point before you add it to the builder, as it will be assigned the spatial reference of the builder it's added to. In most other cases, such as when using a geometry in geometry operations or when editing a feature table, the geometry's spatial reference must be set.

Learn more about spatial references

Linear, angular, and area units

Different types of unit of measurement can be used throughout ArcGIS Runtime API. Projected coordinate systems define coordinates using linear measurements, for example using meters or miles, which are represented by LinearUnit. Linear units are also used to return distance measurements, for example by some members of GeometryEngine. Geographic coordinate systems define coordinates using angular measurements, for example using degrees or radians, which are represented by AngularUnit. Methods that calculate the size of areas, for example in acres or square kilometers, use area units. These are represented by AreaUnit. Linear, angular, and area units can be defined by using enumerations of the most common units of measurement. They can also be defined by Well-Known ID (WKID) or Well-Known Text (WKT).

Projection, topological, and other operations

Changing the coordinates of a geometry to have the same shape and location represented using a different spatial reference is known as "projection" or sometimes as "reprojection". Because geometries are immutable, they do not have any member methods that project, transform, or otherwise modify their content.

The GeometryEngine class provides a wide range of methods that read the content of geometries and modify that content to create new geometries. There are methods to project, buffer, union, and so on. Note that not all methods support true curves. When creating geometries using locations from the screen, and the map is a wraparound map, you may also need to consider normalizing a geometry before you save it to a geodatabase or use it in tasks or other operations.

Use the GeometryEngine class to project geometries to a different spatial reference.

Use dark colors for code blocksCopy
                                                                                                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
var wgsPoint = new MapPoint(-121, 38, SpatialReferences.Wgs84);
var projectedPoint = GeometryEngine.Project(wgsPoint, SpatialReferences.WebMercator);

True curves

Sometimes, shapes that appear as curves on a map are really a series of connected linear segments that approximate a curve. For many use cases (and depending on the accuracy you require for the data), this is an acceptable way to represent curved features. ArcGIS can also store and display geometry using segments that accurately represent curvilinear geometry. In ArcGIS Runtime, curved segments are represented with instances of the EllipticArcSegment or CubicBezierSegment classes. These segments are referred to as true curves.

You can add curve segments to a MultipartBuilder, and if a geometry has curves then curve segments are returned where applicable from the collections that comprise the multipart geometry. Curve and linear segments can be mixed together in the same multipart geometry.

You can use GeometryEngine.Densify() to create an approximated curve from a true curve based on several linear segments. Such a curve is often referred to as a densified curve. By default, curve geometries are not fetched from services that support curves, meaning that densified versions of true curve geometries are returned instead. Use ServiceCurveGeometryMode to change this default behavior.

Curve geometries stored in services where OnlyAllowTrueCurveUpdatesByTrueCurveClients is true cannot be updated by default. To update such geometries, ensure your app correctly handles curve segments in geometries throughout the workflow and set ServiceCurveGeometryMode to TrueCurveClient. You must do this before any calls to services are made as it cannot be changed after making the first request.

Convert to and from JSON

Geometries can be serialized and de-serialized to and from JSON. The ArcGIS REST API documentation describes the JSON representation of geometry objects. You can use this encoding and decoding mechanism to exchange geometries with REST Web services or to store them in text files.

Converting to or from JSON can add points to multipart geometries if the geometry has insufficient points to construct a segment.

Use dark colors for code blocksCopy
                                                                                                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// return a polygon as json-formatted text
var jsonString = coloradoPoly.ToJson();

// re-create the polygon from json using the static FromJson method on Geometry
var newPoly = Geometry.FromJson(jsonString);

Z-values and 3D

Geometries can have z-values, indicating values along the z-axis, which is orthogonal to both the x-axis and y-axis. Z-values can indicate height above or depth below a surface, or an absolute elevation. For example, z-values are used to draw the locations of geometries in scene views. Note that geometries are not considered true 3D shapes and are draped onto surfaces in the view, or in some cases, drawn in a single plane by using z-values. Z-values are stored on MapPoint and Envelope. Therefore, because all other geometries are created from MapPoint, all types of geometry can have z-values.

Whether or not a geometry has z-values is determined when the geometry is created; if you use a method that has a z-value parameter, the new geometry will have z-values (the geometry's hasZ will be true). If you create geometries using constructors that take z-value parameters, or if you pass into the constructor points or segments that have z-values, the new geometry will have z-values. A geometry with z-values is sometimes known as a z-aware geometry.

It may be that not all vertices in your geometry have a z-value defined. NaN is a valid z-value used to indicate an unknown z-value. However, the default z-value is zero. It is important to note that when you get z-values from a geometry that does not have z-values, the default value of zero is returned. Check the hasZ property to determine whether a z-value of zero means that there are no z-values in the geometry or that the z-value in the geometry's coordinates really is zero.

M-values

M-values are used in linear referencing scenarios, and like z-values, every geometry can optionally store m-values. The default m-value is NaN. If an m-value is specified as a parameter when a geometry is created, the new geometry will have m-values (the geometry's hasM will be true). Note that when you get m-values back from a geometry, the default value of NaN (different than the default for z-values) is returned for vertices that do not have m-values. A geometry with m-values is sometimes known as an m-aware geometry.

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.