**Table of Contents**

The temporal points that we have considered so far represent the movement of objects that can move freely on space since it is assumed that they can change their position from one location to the next one without any motion restriction. This is the case for animals and for flying objects such as planes or drones. However, in many cases, objects do not move freely in space but rather within spatially embedded networks such as routes or railways. In this case, it is necessary to take the embedded networks into account while describing the movements of these moving objects. Temporal network points account for these requirements.

Compared with the free-space temporal points, network-based points have the following advantages:

Network points provide road constraints that reflect the real movements of moving objects.

The geometric information is not stored with the moving point, but once and for all in the fixed networks. In this way, the location representations and interpolations are more precise.

Network points are more efficient in terms of data storage, location update, formulation of query, as well as indexing. These are discussed later in this document.

Temporal network points are based on pgRouting, a PostgreSQL extension for developing network routing applications and doing graph analysis. Therefore, temporal network points asume that the underlying network is defined in a table named `ways`

, which has at least three columns: `gid`

containing the unique route identifier, `length`

containing the route length, and `the_geom`

containing the route geometry.

There are two static network types, `npoint`

(short for network point) and `nsegment`

(short for network segment), which represent, respectively, a point and a segment of a route. An `npoint`

value is composed of a route identifier and a float number in the range [0,1] determining a relative position of the route, where 0 corresponds to the begining of the route and 1 to the end of the route. An `nsegment`

value is composed of a route identifier and two float numbers in the range [0,1] determining the start and end relative positions. A `nsegment`

value whose start and end positions are equal corresponds to an `npoint`

value.

The `npoint`

type serves as base type for defining the temporal network point type `tnpoint`

. The `tnpoint`

type has similar functionality as the temporal point type `tgeompoint`

with the exception that it only considers two dimensions. Thus, all functions and operators described before for the `tgeompoint`

type are also applicable for the `tnpoint`

type. In addition, there are specific functions defined for the `tnpoint`

type.

An `npoint`

value is a couple of the form `(rid,position)`

where `rid`

is a `bigint`

value representing a route identifier and `position`

is a `float`

value in the range [0,1] indicating its relative position. The values 0 and 1 of `position`

denote, respectively, the starting and the ending position of the route. The road distance between an `npoint`

value and the starting position of route with identifier `rid`

is computed by multiplying `position`

by length, where `length`

is the route length. Examples of input of network point values are as follows:

SELECT npoint 'Npoint(76, 0.3)'; SELECT npoint 'Npoint(64, 1.0)';

The constructor function for network points has one argument for the route identifier and one argument for the relative position. An example of a network point value defined with the constructor function is as follows:

SELECT npoint(76, 0.3);

An `nsegment`

value is a triple of the form `(rid,startPosition,endPosition)`

where `rid`

is a `bigint`

value representing a route identifier and `startPosition`

and `endPosition`

are `float`

values in the range [0,1] such that `startPosition ≤ endPosition`

. Semantically, a network segment represents a set of network points `(rid,position)`

with `startPosition ≤ position ≤ endPosition`

. If `startPosition=0`

and `endPosition=1`

, the network segment is equivalent to the entire route. If `startPosition=endPosition`

, the network segment represents into a single network point. Examples of input of network point values are as follows:

SELECT nsegment 'Nsegment(76, 0.3, 0.5)'; SELECT nsegment 'Nsegment(64, 0.5, 0.5)'; SELECT nsegment 'Nsegment(64, 0.0, 1.0)'; SELECT nsegment 'Nsegment(64, 1.0, 0.0)'; -- converted to nsegment 'Nsegment(64, 0.0, 1.0)';

As can be seen in the last example, the `startPosition`

and `endPosition`

values will be inverted to ensure that the condition `startPosition ≤ endPosition`

is always satisfied. The constructor function for network segments has one argument for the route identifier and two optional arguments for the start and end positions. Examples of network segment values defined with the constructor function are as follows:

SELECT nsegment(76, 0.3, 0.3); SELECT nsegment(76); -- start and end position assumed to be 0 and 1 respectively SELECT nsegment(76, 0.5); -- end position assumed to be 1

Values of the `npoint`

type can be converted to the `nsegment`

type using an explicit `CAST`

or using the `::`

notation as shown next.

SELECT npoint(76, 0.33)::nsegment;

Values of static network types must satisfy several constraints so that they are well defined. These constraints are given next.

The route identifier

`rid`

must be found in column`gid`

of table`ways`

.The

`position`

,`startPosition`

, and`endPosition`

values must be in the range [0,1]. An error is raised whenever one of these constraints are not satisfied.

Examples of incorrect static network type values are as follows.

-- incorrect rid value SELECT npoint 'Npoint(87.5, 1.0)'; -- incorrect position value SELECT npoint 'Npoint(87, 2.0)'; -- rid value not found in the ways table SELECT npoint 'Npoint(99999999, 1.0)';

We give next the functions and operators for the static network types.

Set the precision of the position(s) of the network point or the network segment to the number of decimal places

`setPrecision({npoint,nsegment},integer): {npoint,nsegment}`

SELECT setPrecision(npoint(76, 0.123456789), 6); -- NPoint(76,0.123457) SELECT setPrecision(nsegment(76, 0.123456789, 0.223456789), 6); -- NSegment(76,0.123457,0.223457)

Get the route identifier

`route({npoint,nsegment}): bigint`

SELECT route(npoint 'Npoint(63, 0.3)'); -- 63 SELECT route(nsegment 'Nsegment(76, 0.3, 0.3)'); -- 76

Get the position

`getPosition(npoint): float`

SELECT getPosition(npoint 'Npoint(63, 0.3)'); -- 0.3

Get the start position

`startPosition(npoint): float`

SELECT startPosition(nsegment 'Nsegment(76, 0.3, 0.5)'); -- 0.3

Get the end position

`endPosition(npoint): float`

SELECT endPosition(nsegment 'Nsegment(76, 0.3, 0.5)'); -- 0.5

Values of the `npoint`

and `nsegment`

types can be converted to the `geometry`

type using an explicit `CAST`

or using the `::`

notation as shown next.

Cast a network point to a geometry

`{npoint,nsegment}::geometry`

SELECT ST_AsText(npoint(76, 0.33)::geometry); -- POINT(21.6338731332283 50.0545869554067) SELECT ST_AsText(nsegment(76, 0.33, 0.66)::geometry); -- LINESTRING(21.6338731332283 50.0545869554067,30.7475989651999 53.9185062927473) SELECT ST_AsText(nsegment(76, 0.33, 0.33)::geometry); -- POINT(21.6338731332283 50.0545869554067)

Similarly, `geometry`

values of subtype `point`

or `linestring`

(restricted to two points) can be converted, respectively, to `npoint`

and `nsegment`

values using an explicit `CAST`

or using the `::`

notation. For this, the route that intersects the given points must be found, where a tolerance of 0.00001 units (depending on the coordinate system) is assumed so a point and a route that are close are considered to intersect. If no such route is found, a null value is returned.

Cast a geometry to a network point

`geometry::{npoint,nsegment}`

SELECT geometry 'Point(279.269156511873 811.497076880187)'::npoint; -- NPoint(3,0.781413) SELECT geometry 'LINESTRING(406.729536784738 702.58583437902, 383.570801314823 845.137059419277)'::nsegment; -- NSegment(3,0.6,0.9) SELECT geometry 'Point(279.3 811.5)'::npoint; -- NULL SELECT geometry 'LINESTRING(406.7 702.6,383.6 845.1)'::nsegment; -- NULL

Two `npoint`

values may be have different route identifiers but may represent the same spatial point at the intersection of the two routes. Function `equals`

is used for testing spatial equality of network points.

Spatial equality for network points

`equals(npoint, npoint)::Boolean`

WITH inter(geom) AS ( SELECT st_intersection(t1.the_geom, t2.the_geom) FROM ways t1, ways t2 WHERE t1.gid = 1 AND t2.gid = 2), fractions(f1, f2) AS ( SELECT ST_LineLocatePoint(t1.the_geom, i.geom), ST_LineLocatePoint(t2.the_geom, i.geom) FROM ways t1, ways t2, inter i WHERE t1.gid = 1 AND t2.gid = 2) SELECT equals(npoint(1, f1), npoint(2, f2)) FROM fractions; -- true

The comparison operators (=, <, and so on) for static network types require that the left and right arguments be of the same type. Excepted the equality and inequality, the other comparison operators are not useful in the real world but allow B-tree indexes to be constructed on static network types.

Are the values equal?

`{npoint,nsegment} = {npoint,nsegment}`

SELECT npoint 'Npoint(3, 0.5)' = npoint 'Npoint(3, 0.5)'; -- true SELECT nsegment 'Nsegment(3, 0.5, 0.5)' = nsegment 'Nsegment(3, 0.5, 0.6)'; -- false

Are the values different?

`{npoint,nsegment} <> {npoint,nsegment}`

SELECT npoint 'Npoint(3, 0.5)' <> npoint 'Npoint(3, 0.6); -- true SELECT nsegment 'Nsegment(3, 0.5, 0.5)' <> nsegment 'Nsegment(3, 0.5, 0.5)'; -- false

Is the first value less than the second one?

`{npoint,nsegment} < {npoint,nsegment}`

SELECT nsegment 'Nsegment(3, 0.5, 0.5)' < nsegment 'Nsegment(3, 0.5, 0.6)'; -- true

Is the first value greater than the second one?

`{npoint,nsegment} > {npoint,nsegment}`

SELECT nsegment 'Nsegment(3, 0.5, 0.5)' > nsegment 'Nsegment(2, 0.5, 0.5)'; -- true

Is the first value less than or equal to the second one?

`{npoint,nsegment} <= {npoint,nsegment}`

SELECT npoint 'Npoint(1, 0.5)' <= npoint 'Npoint(2, 0.5)'; -- true

Is the first value greater than or equal to the second one?

`{npoint,nsegment} >= {npoint,nsegment}`

SELECT npoint 'Npoint(1, 0.6)' >= npoint 'Npoint(1, 0.5)'; -- true