A polyline is an ordered collection of paths. Each path is a collection of contiguous line segments. A line segment is defined by a pair of consecutive points.

Polyline with 3 paths

Boundary, Interior & Exterior

The boundary of a polyline is the set of start and end points of each path. The interior of a polyline is the set of points in the polyline that are not in the boundary. The exterior of a polyline is the set of points that are not in the boundary or the interior. It is important to understand the boundary, interior and exterior of a geometry when using the various operators. The relational operators, for example, rely heavily on these concepts.

For the polyline shown below, the set of points comprising the boundary is shown in red. The interior of the polyline is shown in black.

Red is boundary, black is interior

If a vertex is contained in several paths, how do we determine if it is in the boundary of the polyline? To determine if a vertex is in the boundary of a polyline count the number of segments in which it is it is contained. If that number is even, then the vertex is not in the boundary. If that number is odd, then the vertex is in the boundary.

For example, consider the polyline shown below.

Red is boundary, green is ?

Clearly, the red vertices are in the boundary of the polyline. But what about the green one? The answer is that the green vertex is not in the boundary since it is contained in four segments.

Here is another example.

Red is boundary, green is ?

In this case, since the green vertex is contained in five segments, it is in the boundary of the polyline.

One way to remember this rule is to think of a single path with three vertices.

Red is boundary

It is easy to see that the red vertices are in the boundary and the black vertex is not. Notice that the number of segments containing each of the red vertices is one, an odd number. Now count the number of segments containing the black vertex. Two, an even number.

Valid polylines

A valid polyline is such that every path has at least two distinct points. Tolerance is used to determine if two points are distinct. In other words, if the distance between two points is less than the tolerance specified by the spatial reference, then the points are considered equal.

A closed path is a path with more than two distinct points and the start point equals the end point. A closed path is a valid polyline.

Closed path is valid

A valid polyline is said to be simple. See the Simplify operator for a more detailed specification of simple polylines. Note that a simple polyline may not be OGC compliant. See the Simplify operator with OGC restrictions.

Examples

Let's look at some examples of polylines.
In the first group of examples, the green circles are the vertices of the polyline.

Polylines

This example shows polylines which represent some of the major highways in the United States.

U.S. Highways

JSON format

A polyline can be represented as a JSON string. A polyline in JSON format contains an array of paths and an optional spatialReference. A polyline can also have boolean-valued hasM and hasZ fields. The default value is false for both the hasM and hasZ fields.

Each path is represented by an array of points. Each point in a path is represented as an array of numbers. See the description of JSON multipoints for details on the interpretation of the point arrays.

An empty polyline is represented with an empty array for the paths field.

Syntax

{
  "hasZ" : true | false,
  "hasM" : true | false,
  "paths": [
             [[<x11>,<y11>,<z11>,<m11>],[<x12>,<y12>,<z12>,<m12>], ... ,[<x1j>,<y1j>,<z1j>,<m1j>]],
             ... ,
             [[<xn1>,<yn1>,<zn1>,<mn1>],[<xn2>,<yn2>,<zn2>,<mn2>], ... ,[<xnk>,<ynk>,<znk>,<mnk>]]
           ],
  "spatialReference" : {"wkid" : <wkid>}
}

2D polyline

{
  "paths": [
             [[32462,-57839],[43892,-49160],[35637,-65035],[46009,-60379]],
             [[52570,-77736],[39870,-83027],[46644,-99114]]
           ],
  "spatialReference" : {"wkid" : 54004}
}

3D polyline with Ms

Note that the third point does not have a z-value, and the second ring does not have any m-values.

{
  "hasZ" : true,
  "hasM" : true,
  "paths": [
             [[32462,-57839,20,1],[43892,-49160,25,2],[35637,-65035,null,3],[46009,-60379,22,4]],
             [[52570,-77736,30],[39870,-83027,32],[46644,-99114,35]]
           ],
  "spatialReference" : {"wkid" : 54004}
}

Empty polyline

{"paths": []}

Creating a polyline

To create a polyline, we can use the Polyline class methods or one of the import operators.

Each of the code samples below creates a polyline with three paths.
The polyline looks like this:

Create this polyline

Polyline class methods

To begin each path, we call the startPath method and then successsive calls to the lineTo method.

static Polyline createPolyline1() {

    Polyline line = new Polyline();

    // Path 1
    line.startPath(6.9, 9.1);
    line.lineTo(7, 8.8);

    // Path 2
    line.startPath(6.8, 8.8);
    line.lineTo(7, 9);
    line.lineTo(7.2, 8.9);
    line.lineTo(7.4, 9);

    // Path 3
    line.startPath(7.4, 8.9);
    line.lineTo(7.25, 8.6);
    line.lineTo(7.15, 8.8);

    return poly;
}

Import from JSON

We first create the JSON string which represents the polyline. Note that the order of the paths doesn't matter. Only the order of the points within each path is important. We then call the execute method of OperatorImportFromJson.

static Polyline createPolygonFromJson() throws JsonParseException, IOException {

    String jsonString = "{\"paths\":[[[6.8,8.8],[7,9],[7.2,8.9],[7.4,9]],"
                      + "[[7.4,8.9],[7.25,8.6],[7.15,8.8]],[[6.9, 9.1],[7, 8.8]]],"
                      + "\"spatialReference\":{\"wkid\":4326}}";

    MapGeometry mapGeom = OperatorImportFromJson.local().execute(Geometry.Type.Polyline, jsonString);

    return (Polyline)mapGeom.getGeometry();
}

Import from GeoJSON

We first create the GeoJSON string which represents the polyline. We then call the execute method of OperatorImportFromGeoJson.

The code shown below creates the same polygon as in the previous examples.

static Polyline createPolylineFromGeoJson() throws JsonParseException, IOException {

    String geoJsonString = "{\"type\":\"MultiLineString\","
                         + "\"coordinates\":[[[6.8,8.8],[7,9],[7.2,8.9],[7.4,9]],"
                         + "[[7.4,8.9],[7.25,8.6],[7.15,8.8]],[[6.9, 9.1],[7, 8.8]]],"
                         + "\"crs\":\"EPSG:4326\"}";

    MapGeometry mapGeom = OperatorImportFromGeoJson.local().execute(GeoJsonImportFlags.geoJsonImportDefaults, Geometry.Type.Polyline, geoJsonString, null);

    return (Polyline)mapGeom.getGeometry();
}

Import from WKT

We first create the WKT string which represents the polyline. We then call the execute method of OperatorImportFromWkt.

The code shown below creates the same polygon as in the previous examples.

static Polyline createPolylineFromWKT() throws JsonParseException, IOException {

    String wktString = "MULTILINESTRING ((6.9 9.1,7 8.8),(6.8 8.8,7 9,7.2 8.9,7.4 9),(7.4 8.9,7.25 8.6,7.15 8.8))";
    Geometry geom = OperatorImportFromWkt.local().execute(WktImportFlags.wktImportDefaults, Geometry.Type.Polyline, wktString, null);

    return (Polyline)geom;
}