File: temporal_network_points.xml

package info (click to toggle)
mobilitydb 1.3.0~rc1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 119,380 kB
  • sloc: ansic: 175,127; sql: 100,930; xml: 23,111; yacc: 447; makefile: 200; lex: 151; sh: 142
file content (881 lines) | stat: -rw-r--r-- 52,031 bytes parent folder | download
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
<?xml version="1.0" encoding="UTF-8"?>
<!--
   ****************************************************************************
    MobilityDB Manual
    Copyright(c) MobilityDB Contributors

    This documentation is licensed under a Creative Commons Attribution-Share
    Alike 3.0 License: https://creativecommons.org/licenses/by-sa/3.0/
   ****************************************************************************
-->
<chapter xml:id="temporal_network_points">
	<title>Temporal Network Points</title>

	<para>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.</para>

	<para>Compared with the free-space temporal points, network-based points have the following advantages:</para>
	<itemizedlist>
		<listitem>
			<para>Network points provide road constraints that reflect the real movements of moving objects.</para>
		</listitem>
		<listitem>
			<para>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.</para>
		</listitem>
		<listitem>
			<para>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.</para>
		</listitem>
	</itemizedlist>

	<para>Temporal network points are based on <ulink url="https://pgrouting.org/">pgRouting</ulink>, 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 <varname>ways</varname>, which has at least three columns: <varname>gid</varname> containing the unique route identifier, <varname>length</varname> containing the route length, and <varname>the_geom</varname> containing the route geometry.</para>

	<para>There are two static network types, <varname>npoint</varname> (short for network point) and <varname>nsegment</varname> (short for network segment), which represent, respectively, a point and a segment of a route. An <varname>npoint</varname> 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 <varname>nsegment</varname> value is composed of a route identifier and two float numbers in the range [0,1] determining the start and end relative positions. A <varname>nsegment</varname> value whose start and end positions are equal corresponds to an <varname>npoint</varname> value.</para>

	<para>The <varname>npoint</varname> type serves as base type for defining the temporal network point type <varname>tnpoint</varname>. The <varname>tnpoint</varname> type has similar functionality as the temporal point type <varname>tgeompoint</varname> with the exception that it only considers two dimensions. Thus, all functions and operators described before for the <varname>tgeompoint</varname> type are also applicable for the <varname>tnpoint</varname> type. In addition, there are specific functions defined for the <varname>tnpoint</varname> type.</para>

	<sect1 xml:id="static_network_types">
		<title>Static Network Types</title>

		<para>An <varname>npoint</varname> value is a couple of the form <varname>(rid,position)</varname> where <varname>rid</varname> is a <varname>bigint</varname> value representing a route identifier and <varname>position</varname> is a <varname>float</varname> value in the range [0,1] indicating its relative position. The values 0 and 1 of <varname>position</varname> denote, respectively, the starting and the ending position of the route. The road distance between an <varname>npoint</varname> value and the starting position of route with identifier <varname>rid</varname> is computed by multiplying <varname>position</varname> by length, where <varname>length</varname> is the route length. Examples of input of network point values are as follows:</para>
		<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT npoint 'Npoint(76, 0.3)';
SELECT npoint 'Npoint(64, 1.0)';
</programlisting>

		<para>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:</para>
		<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT npoint(76, 0.3);
</programlisting>

		<para>An <varname>nsegment</varname> value is a triple of the form <varname>(rid,startPosition,endPosition)</varname> where <varname>rid</varname> is a <varname>bigint</varname> value representing a route identifier and <varname>startPosition</varname> and <varname>endPosition</varname> are <varname>float</varname> values in the range [0,1] such that <varname>startPosition ≤ endPosition</varname>. Semantically, a network segment represents a set of network points <varname>(rid,position)</varname> with <varname>startPosition ≤ position ≤ endPosition</varname>. If <varname>startPosition=0</varname> and <varname>endPosition=1</varname>, the network segment is equivalent to the entire route. If <varname>startPosition=endPosition</varname>, the network segment represents into a single network point. Examples of input of network point values are as follows:</para>
			<programlisting language="sql" xml:space="preserve" format="linespecific">
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)';
</programlisting>
		<para>As can be seen in the last example, the <varname>startPosition</varname> and <varname>endPosition</varname> values will be inverted to ensure that the condition <varname>startPosition ≤ endPosition</varname> 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:</para>
			<programlisting language="sql" xml:space="preserve" format="linespecific">
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
</programlisting>
		<para>Values of the <varname>npoint</varname> type can be converted to the <varname>nsegment</varname> type using an explicit <varname>CAST</varname> or using the <varname>::</varname> notation as shown next.</para>
			<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT npoint(76, 0.33)::nsegment;
</programlisting>

		<para>Values of static network types must satisfy several constraints so that they are well defined. These constraints are given next.</para>
		<itemizedlist>
			<listitem>
				<para>The route identifier <varname>rid</varname> must be found in column <varname>gid</varname> of table <varname>ways</varname>.</para>
			</listitem>
			<listitem>
				<para>The <varname>position</varname>, <varname>startPosition</varname>, and <varname>endPosition</varname> values must be in the range [0,1]. An error is raised whenever one of these constraints are not satisfied.</para>
			</listitem>
		</itemizedlist>
		<para>Examples of incorrect static network type values are as follows.</para>
		<programlisting language="sql" xml:space="preserve" format="linespecific">
-- 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)';
</programlisting>
		<para>We give next the functions and operators for the static network types.</para>

		<sect2 xml:id="npoint_constructor_functions">
			<title>Constructors</title>

			<itemizedlist>
				<listitem xml:id="npoint">
					<indexterm significance="normal"><primary><varname>npoint</varname></primary></indexterm>
					<indexterm significance="normal"><primary><varname>nsegment</varname></primary></indexterm>
					<para>Constructors for network points and network segments</para>
					<para><varname>npoint(bigint,float) → npoint</varname></para>
					<para><varname>nsegment(bigint,float,float) → nsegment</varname></para>
					<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT npoint(76, 0.3);
SELECT nsegment(76, 0.3, 0.5);
</programlisting>
				</listitem>
			</itemizedlist>
		</sect2>

		<sect2 xml:id="npoint_conversion_functions">
			<title>Conversions</title>
			<para>Values of the <varname>npoint</varname> and <varname>nsegment</varname> types can be converted to the <varname>geometry</varname> type using an explicit <varname>CAST</varname> or using the <varname>::</varname> notation as shown below. Similarly, <varname>geometry</varname> values of subtype <varname>point</varname> or <varname>linestring</varname> (restricted to two points) can be converted, respectively, to <varname>npoint</varname> and <varname>nsegment</varname> values. 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.</para>
			<itemizedlist>
				<listitem xml:id="npoint_geometry">
					<indexterm significance="normal"><primary><varname>::</varname></primary></indexterm>
					<para>Convert between a network point or segment and a geometry</para>
					<para><varname>{npoint,nsegment}::geometry</varname></para>
					<para><varname>geometry::{npoint,nsegment}</varname></para>
					<programlisting language="sql" xml:space="preserve" format="linespecific">
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)
</programlisting>
					<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT geometry 'SRID=5676;Point(279.269156511873 811.497076880187)'::npoint;
-- NPoint(3,0.781413)
SELECT geometry 'SRID=5676;LINESTRING(406.729536784738 702.58583437902,
  383.570801314823 845.137059419277)'::nsegment;
-- NSegment(3,0.6,0.9)
SELECT geometry 'SRID=5676;Point(279.3 811.5)'::npoint;
-- NULL
SELECT geometry 'SRID=5676;LINESTRING(406.7 702.6,383.6 845.1)'::nsegment;
-- NULL
</programlisting>
				</listitem>

				<listitem xml:id="npoint_stbox">
					<indexterm significance="normal"><primary><varname>stbox</varname></primary></indexterm>
					<para>Construct a spatiotemporal box from a network point and, optionally, a timestamp or a period</para>
					<para><varname>stbox(npoint) → stbox</varname></para>
					<para><varname>stbox(npoint,{timestamptz,tstzspan}) → stbox</varname></para>
					<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT stbox(npoint 'NPoint(1,0.3)');
-- STBOX X((48.711754,20.92568),(48.711758,20.925682))
SELECT stbox(npoint 'NPoint(1,0.3)', timestamptz '2001-01-01');
-- STBOX XT(((62.786633,80.143555),(62.786636,80.143562)),[2001-01-01,2001-01-01])
SELECT stbox(npoint 'NPoint(1,0.3)', tstzspan '[2001-01-01,2001-01-02]');
-- STBOX XT(((62.786633,80.143555),(62.786636,80.143562)),[2001-01-01,2001-01-02])
</programlisting>
				</listitem>
			</itemizedlist>
		</sect2>

		<sect2 xml:id="npoint_accessor_functions">
			<title>Accessors</title>
			<itemizedlist>
				<listitem xml:id="route">
					<indexterm significance="normal"><primary><varname>route</varname></primary></indexterm>
					<para>Return the route identifier</para>
					<para><varname>route({npoint,nsegment}) → bigint</varname></para>
					<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT route(npoint 'Npoint(63, 0.3)');
-- 63
SELECT route(nsegment 'Nsegment(76, 0.3, 0.3)');
-- 76
</programlisting>
				</listitem>

				<listitem xml:id="getPosition">
					<indexterm significance="normal"><primary><varname>getPosition</varname></primary></indexterm>
					<para>Return the position</para>
					<para><varname>getPosition(npoint) → float</varname></para>
					<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT getPosition(npoint 'Npoint(63, 0.3)');
-- 0.3
</programlisting>
				</listitem>

				<listitem xml:id="startPosition">
					<indexterm significance="normal"><primary><varname>startPosition</varname></primary></indexterm>
					<indexterm significance="normal"><primary><varname>endPosition</varname></primary></indexterm>
					<para>Return the start/end position</para>
					<para><varname>startPosition(nsegment) → float</varname></para>
					<para><varname>endPosition(nsegment) → float</varname></para>
					<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT startPosition(nsegment 'Nsegment(76, 0.3, 0.5)');
-- 0.3
SELECT endPosition(nsegment 'Nsegment(76, 0.3, 0.5)');
-- 0.5
</programlisting>
				</listitem>
			</itemizedlist>
		</sect2>

		<sect2 xml:id="npoint_transformation_functions">
			<title>Transformations</title>
			<itemizedlist>
				<listitem xml:id="npoint_round">
					<indexterm significance="normal"><primary><varname>round</varname></primary></indexterm>
					<para>Round the position(s) of the network point or the network segment to the number of decimal places</para>
					<para><varname>round({npoint,nsegment},integer=0) → {npoint,nsegment}</varname></para>
					<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT round(npoint(76, 0.123456789), 6);
--  NPoint(76,0.123457)
SELECT round(nsegment(76, 0.123456789, 0.223456789), 6);
--  NSegment(76,0.123457,0.223457)
</programlisting>
				</listitem>
			</itemizedlist>
		</sect2>

		<sect2 xml:id="npoint_spatial_operations">
			<title>Spatial Operations</title>
			<itemizedlist>
				<listitem xml:id="npoint_srid">
					<indexterm significance="normal"><primary><varname>SRID</varname></primary></indexterm>
					<para>Return the spatial reference identifier</para>
					<para><varname>SRID({npoint,nsegment}) → integer</varname></para>
					<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT SRID(npoint 'Npoint(76, 0.3)');
-- 5676
SELECT SRID(nsegment 'Nsegment(76, 0.3, 0.5)');
-- 5676
</programlisting>
				</listitem>
			</itemizedlist>

			<para>Two <varname>npoint</varname> values may be have different route identifiers but may represent the same spatial point at the intersection of the two routes. Function <varname>same</varname> is used for testing spatial simalarity of network points.</para>
			<itemizedlist>
				<listitem xml:id="npoint_same">
					<indexterm significance="normal"><primary><varname>::</varname></primary></indexterm>
					<para>Spatial similarity</para>
					<para><varname>equals(npoint, npoint)::Boolean</varname></para>
					<programlisting language="sql" xml:space="preserve" format="linespecific">
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
</programlisting>
				</listitem>
			</itemizedlist>
		</sect2>

		<sect2 xml:id="npoint_comparisons">
			<title>Comparisons</title>
			<para>The comparison operators (=, &lt;, 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.</para>

			<itemizedlist>
				<listitem xml:id="npoint_eq">
					<indexterm significance="normal"><primary><varname>=</varname></primary></indexterm>
					<indexterm significance="normal"><primary><varname>&lt;&gt;</varname></primary></indexterm>
					<indexterm significance="normal"><primary><varname>&lt;</varname></primary></indexterm>
					<indexterm significance="normal"><primary><varname>&lt;=</varname></primary></indexterm>
					<indexterm significance="normal"><primary><varname>&gt;</varname></primary></indexterm>
					<indexterm significance="normal"><primary><varname>&gt;=</varname></primary></indexterm>
					<para>Traditional comparisons</para>
					<para><varname>npoint {=, &lt;&gt;, &lt;, &gt;, &lt;=, &gt;=} npoint</varname></para>
					<para><varname>nsegment {=, &lt;&gt;, &lt;, &gt;, &lt;=, &gt;=} nsegment</varname></para>
					<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT npoint 'Npoint(3, 0.5)' = npoint 'Npoint(3, 0.5)';
-- true
SELECT nsegment 'Nsegment(3, 0.5, 0.5)' &lt;&gt; nsegment 'Nsegment(3, 0.5, 0.5)';
-- false
SELECT nsegment 'Nsegment(3, 0.5, 0.5)' &lt; nsegment 'Nsegment(3, 0.5, 0.6)';
-- true
SELECT nsegment 'Nsegment(3, 0.5, 0.5)' &gt; nsegment 'Nsegment(2, 0.5, 0.5)';
-- true
SELECT npoint 'Npoint(1, 0.5)' &lt;= npoint 'Npoint(2, 0.5)';
-- true
SELECT npoint 'Npoint(1, 0.6)' &gt;= npoint 'Npoint(1, 0.5)';
-- true
</programlisting>
				</listitem>
			</itemizedlist>
		</sect2>
	</sect1>

	<sect1 xml:id="temp_network_points">
		<title>Temporal Network Points</title>
		<para>The temporal network point type <varname>tnpoint</varname> allows to represent the movement of objects over a network. It corresponds to the temporal point type <varname>tgeompoint</varname> restricted to two-dimensional coordinates. As all the other temporal types it comes in three subtypes, namely, instant, sequence, and sequence set. Examples of <varname>tnpoint</varname> values in these subtypes are given next.</para>
		<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT tnpoint 'Npoint(1, 0.5)@2001-01-01';
SELECT tnpoint '{Npoint(1, 0.3)@2001-01-01, Npoint(1, 0.5)@2001-01-02,
  Npoint(1, 0.5)@2001-01-03}';
SELECT tnpoint '[Npoint(1, 0.2)@2001-01-01, Npoint(1, 0.4)@2001-01-02,
  Npoint(1, 0.5)@2001-01-03]';
SELECT tnpoint '{[Npoint(1, 0.2)@2001-01-01, Npoint(1, 0.4)@2001-01-02,
  Npoint(1, 0.5)@2001-01-03], [Npoint(2, 0.6)@2001-01-04, Npoint(2, 0.6)@2001-01-05]}';
</programlisting>
		<para>The temporal network point type accepts type modifiers (or <varname>typmod</varname> in PostgreSQL terminology). The possible values for the type modifier are <varname>Instant</varname>, <varname>Sequence</varname>, and <varname>SequenceSet</varname>. If no type modifier is specified for a column, values of any subtype are allowed.</para>
		<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT tnpoint(Sequence) '[Npoint(1, 0.2)@2001-01-01, Npoint(1, 0.4)@2001-01-02,
  Npoint(1, 0.5)@2001-01-03]';
SELECT tnpoint(Sequence) 'Npoint(1, 0.2)@2001-01-01';
-- ERROR: Temporal type (Instant) does not match column type (Sequence)
</programlisting>

		<para>Temporal network point values of sequence subtype and linear or step interpolation must be defined on a single route. Therefore, a value of sequence set subtype is needed for representing the movement of an object that traverses several routes, even if there is no temporal gap. For example, in the following value</para>
		<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT tnpoint '{[NPoint(1, 0.2)@2001-01-01, NPoint(1, 0.5)@2001-01-03),
  [NPoint(2, 0.4)@2001-01-03, NPoint(2, 0.6)@2001-01-04)}';
</programlisting>
		<para>the network point changes its route at 2001-01-03.</para>

		<para>Temporal network point values of sequence or sequence set subtype are converted into a normal form so that equivalent values have identical representations. For this, consecutive instant values are merged when possible. Three consecutive instant values can be merged into two if the linear functions defining the evolution of values are the same. Examples of transformation into a normal form are as follows.</para>
		<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT tnpoint '[NPoint(1, 0.2)@2001-01-01, NPoint(1, 0.4)@2001-01-02,
  NPoint(1, 0.6)@2001-01-03)';
-- [NPoint(1,0.2)@2001-01-01, NPoint(1,0.6)@2001-01-03)
SELECT tnpoint '{[NPoint(1, 0.2)@2001-01-01, NPoint(1, 0.3)@2001-01-02,
  NPoint(1, 0.5)@2001-01-03), [NPoint(1, 0.5)@2001-01-03, NPoint(1, 0.7)@2001-01-04)}';
-- {[NPoint(1,0.2)@2001-01-01, NPoint(1,0.3)@2001-01-02, NPoint(1,0.7)@2001-01-04)}
</programlisting>
	</sect1>

	<sect1 xml:id="tnpoint_validity">
		<title>Validity of Temporal Network Points</title>

		<para>Temporal network point values must satisfy the constraints specified in <xref linkend="ttype_validity"/> so that they are well defined. An error is raised whenever one of these constraints are not satisfied. Examples of incorrect values are as follows.</para>
		<programlisting language="sql" xml:space="preserve" format="linespecific">
-- Null values are not allowed
SELECT tnpoint 'NULL@2001-01-01 08:05:00';
SELECT tnpoint 'Point(0 0)@NULL';
-- Base type is not a network point
SELECT tnpoint 'Point(0 0)@2001-01-01 08:05:00';
-- Multiple routes in a continuous sequence
SELECT tnpoint '[Npoint(1, 0.2)@2001-01-01 09:00:00, Npoint(2, 0.2)@2001-01-01 09:05:00)';
</programlisting>

		<para>We present next the operation for temporal network point types. Most functions for temporal types described in the previous chapters can be applied for temporal network point types. Therefore, in the signatures of the functions, the notation <varname>base</varname> also represents an <varname>npoint</varname> and the notations <varname>ttype</varname>, <varname>tpoint</varname>, and <varname>tgeompoint</varname> also represent a <varname>tnpoint</varname>. Furthermore, the functions that have an argument of type <varname>geometry</varname> accept in addition an argument of type <varname>npoint</varname>. To avoid redundancy, we only present next some examples of these functions and operators for temporal network points.</para>
	</sect1>

	<sect1 xml:id="tnpoint_constructors">
		<title>Constructors</title>
			<itemizedlist>
				<listitem xml:id="tnpoint_const">
					<indexterm significance="normal"><primary><varname>tnpoint</varname></primary></indexterm>
					<indexterm significance="normal"><primary><varname>tnpointSeq</varname></primary></indexterm>
					<indexterm significance="normal"><primary><varname>tnpointSeqSet</varname></primary></indexterm>
					<para>Constructor for temporal network points having a constant value</para>
					<para><varname>tnpoint(npoint,timestamptz) → tnpointInst</varname></para>
					<para><varname>tnpoint(npoint,tstzset) → tnpointDiscSeq</varname></para>
					<para><varname>tnpoint(npoint,tstzspan,interp='linear') → tnpointContSeq</varname></para>
					<para><varname>tnpoint(npoint,tstzspanset,interp='linear') → tnpointSeqSet</varname></para>
					<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT tnpoint('Npoint(1, 0.5)', timestamptz '2001-01-01');
-- NPoint(1,0.5)@2001-01-01
SELECT tnpointSeq('Npoint(1, 0.3)', tstzset '{2001-01-01, 2001-01-03, 2001-01-05}');
-- {NPoint(1,0.3)@2001-01-01, NPoint(1,0.3)@2001-01-03, NPoint(1,0.3)@2001-01-05}
SELECT tnpointSeq('Npoint(1, 0.5)', tstzspan '[2001-01-01, 2001-01-02]');
-- [NPoint(1,0.5)@2001-01-01, NPoint(1,0.5)@2001-01-02]
SELECT tnpointSeqSet('Npoint(1, 0.2)', tstzspanset '{[2001-01-01, 2001-01-03]}', 'step');
-- Interp=Step;{[NPoint(1,0.2)@2001-01-01, NPoint(1,0.2)@2001-01-03]}
</programlisting>
				</listitem>

				<listitem xml:id="tnpointSeq">
					<indexterm significance="normal"><primary><varname>=</varname></primary></indexterm>
					<para>Constructor for temporal network points of sequence subtype</para>
					<para><varname>tnpointSeq(tnpointInst[],interp={'step','linear'},leftInc bool=true,</varname></para>
					<para><varname>  rightInc bool=true) →tnpointSeq</varname></para>
					<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT tnpointSeq(ARRAY[tnpoint 'Npoint(1, 0.3)@2001-01-01',
  'Npoint(1, 0.5)@2001-01-02', 'Npoint(1, 0.5)@2001-01-03']);
-- {NPoint(1,0.3)@2001-01-01, NPoint(1,0.5)@2001-01-02, NPoint(1,0.5)@2001-01-03}
SELECT tnpointSeq(ARRAY[tnpoint 'Npoint(1, 0.2)@2001-01-01',
  'Npoint(1, 0.4)@2001-01-02', 'Npoint(1, 0.5)@2001-01-03']);
-- [NPoint(1,0.2)@2001-01-01, NPoint(1,0.4)@2001-01-02, NPoint(1,0.5)@2001-01-03]
</programlisting>
				</listitem>

				<listitem xml:id="tnpointSeqSet">
					<indexterm significance="normal"><primary><varname>tnpointSeqSet</varname></primary></indexterm>
					<para>Constructor for temporal network points of sequence set subtype</para>
					<para><varname>tnpointSeqset(tnpoint[]) → tnpointSeqSet</varname></para>
					<para><varname>tnpointSeqSetGaps(tnpointInst[],maxt=NULL,maxdist=NULL,interp='linear') →</varname></para>
					<para><varname>  tnpointSeqSet</varname></para>
					<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT tnpointSeqSet(ARRAY[tnpoint '[Npoint(1,0.2)@2001-01-01, Npoint(1,0.4)@2001-01-02,
  Npoint(1,0.5)@2001-01-03]', '[Npoint(2,0.6)@2001-01-04, Npoint(2,0.6)@2001-01-05]']);
/* {[NPoint(1,0.2)@2001-01-01, NPoint(1,0.4)@2001-01-02, NPoint(1,0.5)@2001-01-03],
   [NPoint(2,0.6)@2001-01-04, NPoint(2,0.6)@2001-01-05]} */
SELECT tnpointSeqSetGaps(ARRAY[tnpoint 'NPoint(1,0.1)@2001-01-01',
  'NPoint(1,0.3)@2001-01-03', 'NPoint(1,0.5)@2001-01-05'], '1 day');
-- {[NPoint(1,0.1)@2001-01-01], [NPoint(1,0.3)@2001-01-03], [NPoint(1,0.5)@2001-01-05]}
</programlisting>
				</listitem>
			</itemizedlist>
	</sect1>

	<sect1 xml:id="tnpoint_conversions">
		<title>Conversions</title>

		<para>A temporal network point value can be converted to and from a temporal geometry point. This can be done using an explicit <varname>CAST</varname> or using the <varname>::</varname> notation. A null value is returned if any of the composing geometry point values cannot be converted into a <varname>npoint</varname> value.</para>
		<itemizedlist>
			<listitem xml:id="tnpoint_tgeompoint">
				<indexterm significance="normal"><primary><varname>::</varname></primary></indexterm>
				<para>Convert between a temporal network point and a temporal geometry point</para>
				<para><varname>tnpoint::tgeompoint</varname></para>
				<para><varname>tgeompoint::tnpoint</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT asText((tnpoint '[NPoint(1, 0.2)@2001-01-01,
  NPoint(1, 0.3)@2001-01-02)')::tgeompoint);
/* [POINT(23.057077727326 28.7666335767956)@2001-01-01,
   POINT(48.7117553116406 20.9256801894708)@2001-01-02) */
SELECT tgeompoint '[POINT(23.057077727326 28.7666335767956)@2001-01-01,
  POINT(48.7117553116406 20.9256801894708)@2001-01-02)'::tnpoint
-- [NPoint(1,0.2)@2001-01-01, NPoint(1,0.3)@2001-01-02)
SELECT tgeompoint '[POINT(23.057077727326 28.7666335767956)@2001-01-01,
  POINT(48.7117553116406 20.9)@2001-01-02)'::tnpoint
-- NULL
</programlisting>
			</listitem>
		</itemizedlist>
	</sect1>

	<sect1 xml:id="tnpoint_accessors">
		<title>Accessors</title>
		<itemizedlist>
			<listitem xml:id="tnpoint_getValues">
				<indexterm significance="normal"><primary><varname>getValues</varname></primary></indexterm>
				<para>Return the values</para>
				<para><varname>getValues(tnpoint) → npointset</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT getValues(tnpoint '{[NPoint(1, 0.3)@2001-01-01, NPoint(1, 0.5)@2001-01-02)}');
-- {"NPoint(1,0.3)","NPoint(1,0.5)"}
SELECT getValues(tnpoint '{[NPoint(1, 0.3)@2001-01-01, NPoint(1, 0.3)@2001-01-02)}');
-- {"NPoint(1,0.3)"}
</programlisting>
			</listitem>

			<listitem xml:id="tnpoint_routes">
				<indexterm significance="normal"><primary><varname>routes</varname></primary></indexterm>
				<para>Return the road identifiers</para>
				<para><varname>routes(tnpoint) → bigintset</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT routes(tnpoint '{NPoint(3, 0.3)@2001-01-01, NPoint(1, 0.5)@2001-01-02}');
-- {1, 3}
</programlisting>
			</listitem>

			<listitem xml:id="tnpoint_valueAtTimestamp">
				<indexterm significance="normal"><primary><varname>valueAtTimestamp</varname></primary></indexterm>
				<para>Return the value at a timestamp</para>
				<para><varname>valueAtTimestamp(tnpoint,timestamptz) → npoint</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT valueAtTimestamp(tnpoint '[NPoint(1, 0.3)@2001-01-01, NPoint(1, 0.5)@2001-01-03)',
  '2001-01-02');
-- NPoint(1,0.4)
</programlisting>
			</listitem>

			<listitem xml:id="tnpoint_length">
				<indexterm significance="normal"><primary><varname>length</varname></primary></indexterm>
				<para>Return the length traversed by the temporal network point</para>
				<para><varname>length(tnpoint) → float</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT length(tnpoint '[NPoint(1, 0.3)@2001-01-01, NPoint(1, 0.5)@2001-01-02]');
-- 54.3757408468784
</programlisting>
			</listitem>

			<listitem xml:id="tnpoint_cumulativeLength">
				<indexterm significance="normal"><primary><varname>cumulativeLength</varname></primary></indexterm>
				<para>Return the cumulative length traversed by the temporal network point</para>
				<para><varname>cumulativeLength(tnpoint) → tfloat</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT cumulativeLength(tnpoint '{[NPoint(1, 0.3)@2001-01-01, NPoint(1, 0.5)@2001-01-02,
  NPoint(1, 0.5)@2001-01-03], [NPoint(1, 0.6)@2001-01-04, NPoint(1, 0.7)@2001-01-05]}');
/* {[0@2001-01-01, 54.3757408468784@2001-01-02, 54.3757408468784@2001-01-03],
   [54.3757408468784@2001-01-04, 81.5636112703177@2001-01-05]} */
</programlisting>
			</listitem>

			<listitem xml:id="tnpoint_speed">
				<indexterm significance="normal"><primary><varname>speed</varname></primary></indexterm>
				<para>Return the speed of the temporal network point in units per second</para>
				<para><varname>speed({tnpointSeq, tnpointSeqSet}) → tfloatSeqSet</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT speed(tnpoint '[NPoint(1, 0.1)@2001-01-01, NPoint(1, 0.4)@2001-01-02,
  NPoint(1, 0.6)@2001-01-03]') * 3600 * 24;
/* Interp=Step;[21.4016800272077@2001-01-01, 14.2677866848051@2001-01-02,
   14.2677866848051@2001-01-03] */
</programlisting>
			</listitem>
		</itemizedlist>
	</sect1>

	<sect1 xml:id="tnpoint_transformations">
		<title>Transformations</title>
		<itemizedlist>
			<listitem xml:id="tnpoint_subtype">
				<indexterm significance="normal"><primary><varname>tnpointInst</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>tnpointSeq</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>tnpointSeqSet</varname></primary></indexterm>
				<para>Transform a temporal network point to another subtype</para>
				<para><varname>tnpointInst(tnpoint) → tnpointInst</varname></para>
				<para><varname>tnpointSeq(tnpoint) → tnpointSeq</varname></para>
				<para><varname>tnpointSeqSet(tnpoint) → tnpointSeqSet</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT tnpointSeq(tnpoint 'NPoint(1, 0.5)@2001-01-01', 'discrete');
-- {NPoint(1,0.5)@2001-01-01}
SELECT tnpointSeq(tnpoint 'NPoint(1, 0.5)@2001-01-01');
-- [NPoint(1,0.5)@2001-01-01]
SELECT tnpointSeqSet(tnpoint 'NPoint(1, 0.5)@2001-01-01');
-- {[NPoint(1,0.5)@2001-01-01]}
</programlisting>
			</listitem>

			<listitem xml:id="tnpoint_setInterp">
				<indexterm significance="normal"><primary><varname>setInterp</varname></primary></indexterm>
				<para>Transform a temporal network point to another interpolation</para>
				<para><varname>setInterp(tnpoint, interp) → tnpoint</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT setInterp(tnpoint 'NPoint(1,0.2)@2001-01-01','linear');
-- [NPoint(1,0.2)@2001-01-01]
SELECT setInterp(tnpoint '{[NPoint(1,0.1)@2001-01-01], [NPoint(1,0.2)@2001-01-02]}',
  'discrete');
-- {NPoint(1,0.1)@2001-01-01, NPoint(1,0.2)@2001-01-02}
</programlisting>
			</listitem>

			<listitem xml:id="tnpoint_round">
				<indexterm significance="normal"><primary><varname>round</varname></primary></indexterm>
				<para>Round the fraction of the temporal network point to the number of decimal places</para>
				<para><varname>round(tnpoint,integer) → tnpoint</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT round(tnpoint '{[NPoint(1,0.123456789)@2001-01-01, NPoint(1,0.5)@2001-01-02)}', 6);
-- {[NPoint(1,0.123457)@2001-01-01 00:00:00+01, NPoint(1,0.5)@2001-01-02 00:00:00+01)}
</programlisting>
			</listitem>
		</itemizedlist>
	</sect1>

	<sect1 xml:id="tnpoint_restrictions">
		<title>Restrictions</title>
		<itemizedlist>
			<listitem xml:id="tnpoint_atValues">
				<indexterm significance="normal"><primary><varname>atValues</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>minusValues</varname></primary></indexterm>
				<para>Restrict to (the complement of) a set of values</para>
				<para><varname>atValues(tnpoint,values) → tnpoint</varname></para>
				<para><varname>minusValues(tnpoint,values) → tnpoint</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT atValues(tnpoint '[NPoint(2, 0.3)@2001-01-01, NPoint(2, 0.7)@2001-01-03]',
  'NPoint(2, 0.5)');
-- {[NPoint(2,0.5)@2001-01-02]}
SELECT minusValues(tnpoint '[NPoint(2, 0.3)@2001-01-01, NPoint(2, 0.7)@2001-01-03]',
  'NPoint(2, 0.5)');
/* {[NPoint(2,0.3)@2001-01-01, NPoint(2,0.5)@2001-01-02),
   (NPoint(2,0.5)@2001-01-02, NPoint(2,0.7)@2001-01-03]} */
</programlisting>
			</listitem>

			<listitem xml:id="tnpoint_atGeometry">
				<indexterm significance="normal"><primary><varname>atGeometry</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>minusGeometry</varname></primary></indexterm>
				<para>Restrict to (the complement of) a geometry</para>
				<para><varname>atGeometry(tnpoint,geometry) → tnpoint</varname></para>
				<para><varname>minusGeometry(tnpoint,geometry) → tnpoint</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT atGeometry(tnpoint '[NPoint(2, 0.3)@2001-01-01, NPoint(2, 0.7)@2001-01-03]',
  'Polygon((40 40,40 50,50 50,50 40,40 40))');
SELECT minusGeometry(tnpoint '[NPoint(2, 0.3)@2001-01-01, NPoint(2, 0.7)@2001-01-03]',
  'Polygon((40 40,40 50,50 50,50 40,40 40))');
/* {(NPoint(2,0.342593)@2001-01-01 05:06:40.364673+01,
   NPoint(2,0.7)@2001-01-03 00:00:00+01]} */
</programlisting>
			</listitem>
		</itemizedlist>
	</sect1>

	<sect1 xml:id="tnpoint_distance_ops">
		<title>Distance Operations</title>
		<itemizedlist>
			<listitem xml:id="tnpoint_nearestApproachDistance">
				<indexterm significance="normal"><primary><varname>|=|</varname></primary></indexterm>
				<para>Return the smallest distance ever</para>
				<para><varname>{geo,npoint,tnpoint} |=| {geo,npoint,tnpoint} → float</varname></para>
				<para>The operator <varname>|=|</varname> can be used for doing nearest neightbor searches using a GiST or an SP-GiST index (see <xref linkend="ttype_indexing"/>).</para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT tnpoint '[NPoint(2, 0.3)@2001-01-01, NPoint(2, 0.7)@2001-01-02]' |=|
   geometry 'SRID=5676;Linestring(50 50,55 55)';
-- 31.69220882252415
SELECT tnpoint '[NPoint(2, 0.3)@2001-01-01, NPoint(2, 0.7)@2001-01-02]' |=|
  npoint 'NPoint(1, 0.5)';
-- 19.49691305292373
SELECT tnpoint '[NPoint(2, 0.3)@2001-01-01, NPoint(2, 0.7)@2001-01-02]' |=|
  tnpoint '[NPoint(1, 0.3)@2001-01-01, NPoint(1, 0.7)@2001-01-02]';
-- 5.231180723735304
</programlisting>
			</listitem>

			<listitem xml:id="tnpoint_nearestApproachInstant">
				<indexterm significance="normal"><primary><varname>nearestApproachInstant</varname></primary></indexterm>
				<para>Return the instant of the first temporal network point at which the two arguments are at the nearest distance</para>
				<para><varname>nearestApproachInstant({geo,npoint,tnpoint},{geo,npoint,tnpoint}) → tnpoint</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT nearestApproachInstant(tnpoint '[NPoint(2, 0.3)@2001-01-01,
  NPoint(2, 0.7)@2001-01-02]', geometry 'Linestring(50 50,55 55)');
-- NPoint(2,0.349928)@2001-01-01 02:59:44.402905+01
SELECT nearestApproachInstant(tnpoint '[NPoint(2, 0.3)@2001-01-01,
  NPoint(2, 0.7)@2001-01-02]', npoint 'NPoint(1, 0.5)');
-- NPoint(2,0.592181)@2001-01-01 17:31:51.080405+01
</programlisting>
			</listitem>

			<listitem xml:id="tnpoint_shortestLine">
				<indexterm significance="normal"><primary><varname>shortestLine</varname></primary></indexterm>
				<para>Return the line connecting the nearest approach point between the two arguments</para>
				<para><varname>shortestLine({geo,npoint,tpoint},{geo,npoint,tpoint}) → geometry</varname></para>
				<para>The function will only return the first line that it finds if there are more than one</para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT ST_AsText(shortestLine(tnpoint '[NPoint(2, 0.3)@2001-01-01,
  NPoint(2, 0.7)@2001-01-02]', geometry 'Linestring(50 50,55 55)'));
-- LINESTRING(50.7960725266492 48.8266286733015,50 50)
SELECT ST_AsText(shortestLine(tnpoint '[NPoint(2, 0.3)@2001-01-01,
  NPoint(2, 0.7)@2001-01-02]', npoint 'NPoint(1, 0.5)'));
-- LINESTRING(77.0902838115125 66.6659083092593,90.8134936900394 46.4385792121146)
</programlisting>
			</listitem>

			<listitem xml:id="tnpoint_tdistance">
				<indexterm significance="normal"><primary><varname>&lt;-&gt;</varname></primary></indexterm>
				<para>Return the temporal distance</para>
				<para><varname>tnpoint &lt;-&gt; tnpoint → tfloat</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT tnpoint '[NPoint(1, 0.3)@2001-01-01, NPoint(1, 0.5)@2001-01-03]' &lt;-&gt;
  npoint 'NPoint(1, 0.2)';
-- [2.34988300875063@2001-01-02 00:00:00+01, 2.34988300875063@2001-01-03 00:00:00+01]
SELECT tnpoint '[NPoint(1, 0.3)@2001-01-01, NPoint(1, 0.5)@2001-01-03]' &lt;-&gt;
  geometry 'Point(50 50)';
-- [25.0496666945044@2001-01-01 00:00:00+01, 26.4085688426232@2001-01-03 00:00:00+01]
SELECT tnpoint '[NPoint(1, 0.3)@2001-01-01, NPoint(1, 0.5)@2001-01-03]' &lt;-&gt;
  tnpoint '[NPoint(1, 0.3)@2001-01-02, NPoint(1, 0.5)@2001-01-04]'
-- [2.34988300875063@2001-01-02 00:00:00+01, 2.34988300875063@2001-01-03 00:00:00+01]
</programlisting>
			</listitem>
		</itemizedlist>
	</sect1>

	<sect1 xml:id="tnpoint_spatial_ops">
		<title>Spatial Operations</title>
		<itemizedlist>
			<listitem xml:id="tnpoint_twCentroid">
				<indexterm significance="normal"><primary><varname>twCentroid</varname></primary></indexterm>
				<para>Return the time-weighted centroid</para>
				<para><varname>twCentroid(tnpoint) → geometry(Point)</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT ST_AsText(twCentroid(tnpoint '{[NPoint(1, 0.3)@2001-01-01,
  NPoint(1, 0.5)@2001-01-02, NPoint(1, 0.5)@2001-01-03, NPoint(1, 0.7)@2001-01-04)}'));
-- POINT(79.9787466444847 46.2385558051041)
</programlisting>
			</listitem>
		</itemizedlist>
	</sect1>

	<sect1 xml:id="tnpoint_bbox_ops">
		<title>Bounding Box Operations</title>
		<itemizedlist>
			<listitem xml:id="tnpoint_topo">
				<indexterm significance="normal"><primary><varname>&amp;&amp;</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>&lt;@</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>@&gt;</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>~=</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>-|-</varname></primary></indexterm>
				<para>Topological operators</para>
				<para><varname>{tstzspan,stbox,tnpoint} {&amp;&amp;, &lt;@, @&gt;, ~=, -|-} {tstzspan,stbox,tnpoint} → boolean</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT tnpoint '[NPoint(1, 0.3)@2001-01-01, NPoint(1, 0.5)@2001-01-02]' &amp;&amp;
  tstzspan '[2001-01-02,2001-01-03]';
-- true
SELECT tnpoint '[NPoint(1, 0.3)@2001-01-01, NPoint(1, 0.5)@2001-01-02]' @&gt;
  stbox(npoint 'NPoint(1, 0.5)');
-- true
SELECT tnpoint '[NPoint(1, 0.3)@2001-01-01, NPoint(1, 0.5)@2001-01-03]' ~=
  tnpoint '[NPoint(1, 0.3)@2001-01-01, NPoint(1, 0.35)@2001-01-02,
  NPoint(1, 0.5)@2001-01-03]';
-- true
</programlisting>
			</listitem>

			<listitem xml:id="tnpoint_pos">
				<indexterm significance="normal"><primary><varname>::</varname></primary></indexterm>
				<para>Position operators</para>
				<para><varname>{stbox,tnpoint} {&lt;&lt;, &amp;&lt;, &gt;&gt;, &amp;&gt;} {stbox,tnpoint} → boolean</varname></para>
				<para><varname>{stbox,tnpoint} {&lt;&lt;|, &amp;&lt;|, |&gt;&gt;, |&amp;&gt;} {stbox,tnpoint} → boolean</varname></para>
				<para><varname>{tstzspan,stbox,tnpoint} {&lt;&lt;#, &amp;&lt;#, #&gt;&gt;, #&amp;&gt;} {tstzspan,stbox,tnpoint} → boolean</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT tnpoint '[NPoint(1, 0.3)@2001-01-01, NPoint(1, 0.5)@2001-01-02]' &lt;&lt;
  stbox(npoint 'NPoint(1, 0.2)');
-- true
SELECT tnpoint '[NPoint(1, 0.3)@2001-01-01, NPoint(1, 0.5)@2001-01-02]' &lt;&lt;|
  stbox(npoint 'NPoint(1, 0.5)');
-- false
SELECT tnpoint '[NPoint(1, 0.3)@2001-01-03, NPoint(1, 0.5)@2001-01-05]' #&amp;&gt;
  tstzspan '[2001-01-01,2001-01-03]';
-- true
SELECT tnpoint '[NPoint(1, 0.3)@2001-01-03, NPoint(1, 0.3)@2001-01-05]' #&gt;&gt;
  tnpoint '[NPoint(1, 0.3)@2001-01-01, NPoint(1, 0.3)@2001-01-02]';
-- true
</programlisting>
			</listitem>
		</itemizedlist>
	</sect1>

	<sect1 xml:id="tnpoint_spatial_rels">
		<title>Spatial Relationships</title>
		<para>
			The topological and distance relationships described in <xref linkend="tgeo_spatial_rel"/> such as <varname>eIntersects</varname>, <varname>aDwithin</varname>, or <varname>tContains</varname> are defined over the geographical space while the temporal network points are defined over the network space. To be able to apply these relationships to the temporal network points, they must be transformed to temporal geometry points. This can be easily performed using the functions <varname>geometry</varname> and <varname>tgeompoint</varname> or using an explicit casting <varname>::</varname> as shown in the examples below.
		</para>

		<itemizedlist>
			<listitem xml:id="tnpoint_espatialrels">
				<para>Ever and always spatial relationships</para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT eContains(geometry 'SRID=5676;Polygon((0 0,0 50,50 50,50 0,0 0))',
  tgeompoint(tnpoint '[NPoint(1, 0.1)@2001-01-01, NPoint(1, 0.3)@2001-01-03)'));
-- false
SELECT eDisjoint(geometry(npoint 'NPoint(2, 0.0)'),
  tgeompoint(tnpoint '[NPoint(1, 0.1)@2001-01-01, NPoint(1, 0.3)@2001-01-03)'));
-- true
SELECT eIntersects(
  tnpoint '[NPoint(1, 0.1)@2001-01-01, NPoint(1, 0.3)@2001-01-03)'::tgeompoint,
  tnpoint '[NPoint(2, 0.0)@2001-01-01, NPoint(2, 1)@2001-01-03)'::tgeompoint);
-- false
</programlisting>
			</listitem>

			<listitem xml:id="tnpoint_tspatialrels">
				<para>Spatiotemporal relationships</para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT tContains(geometry 'SRID=5676;Polygon((0 0,0 50,50 50,50 0,0 0))',
  tgeompoint(tnpoint '[NPoint(1, 0.1)@2001-01-01, NPoint(1, 0.3)@2001-01-03)'));
-- [f@2001-01-01 00:00:00+01, f@2001-01-03 00:00:00+01)
SELECT tDisjoint(geometry(npoint 'NPoint(2, 0.0)'),
  tgeompoint(tnpoint '[NPoint(1, 0.1)@2001-01-01, NPoint(1, 0.3)@2001-01-03)'));
-- [t@2001-01-01 00:00:00+01, t@2001-01-03 00:00:00+01)
SELECT tDwithin(
  tnpoint '[NPoint(1, 0.3)@2001-01-01, NPoint(1, 0.5)@2001-01-03)'::tgeompoint,
  tnpoint '[NPoint(1, 0.5)@2001-01-01, NPoint(1, 0.3)@2001-01-03)'::tgeompoint, 1);
/* {[t@2001-01-01 00:00:00+01, t@2001-01-01 22:35:55.379053+01],
   (f@2001-01-01 22:35:55.379053+01, t@2001-01-02 01:24:04.620946+01,
   t@2001-01-03 00:00:00+01)} */
</programlisting>
			</listitem>
		</itemizedlist>
	</sect1>

	<sect1 xml:id="tnpoint_comparisons">
		<title>Comparisons</title>
		<itemizedlist>
			<listitem xml:id="tnpoint_comp">
				<indexterm significance="normal"><primary><varname>::</varname></primary></indexterm>
				<para>Traditional comparisons</para>
				<para><varname>tnpoint {=, &lt;&gt;, &lt;, &gt;, &lt;=, &gt;=} tnpoint → boolean</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT tnpoint '{[NPoint(1, 0.1)@2001-01-01, NPoint(1, 0.3)@2001-01-02),
  [NPoint(1, 0.3)@2001-01-02, NPoint(1, 0.5)@2001-01-03]}' =
  tnpoint '[NPoint(1, 0.1)@2001-01-01, NPoint(1, 0.5)@2001-01-03]';
-- true
SELECT tnpoint '{[NPoint(1, 0.1)@2001-01-01, NPoint(1, 0.5)@2001-01-03]}' &lt;&gt;
  tnpoint '[NPoint(1, 0.1)@2001-01-01, NPoint(1, 0.5)@2001-01-03]';
-- false
SELECT tnpoint '[NPoint(1, 0.1)@2001-01-01, NPoint(1, 0.5)@2001-01-03]' &lt;
  tnpoint '[NPoint(1, 0.1)@2001-01-01, NPoint(1, 0.6)@2001-01-03]';
-- true
</programlisting>
			</listitem>

			<listitem xml:id="tnpoint_ever_always">
				<indexterm significance="normal"><primary><varname>?=</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>%=</varname></primary></indexterm>
				<para>Ever and always comparisons</para>
				<para><varname>{npoint,tnpoint} {?=, %=} {npoint,tnpoint} → boolean</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT tnpoint '[Npoint(1, 0.2)@2001-01-01, Npoint(1, 0.4)@2001-01-04)' ?= Npoint(1, 0.3);
-- true
SELECT tnpoint '[Npoint(1, 0.2)@2001-01-01, Npoint(1, 0.2)@2001-01-04)' &amp;= Npoint(1, 0.2);
-- true
</programlisting>
			</listitem>

			<listitem xml:id="tnpoint_tcomp">
				<indexterm significance="normal"><primary><varname>::</varname></primary></indexterm>
				<para>Temporal comparisons</para>
				<para><varname>{npoint,tnpoint} {#=, #&lt;&gt;} {npoint,tnpoint} → tbool</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT tnpoint '[NPoint(1, 0.2)@2001-01-01, NPoint(1, 0.4)@2001-01-03)' #=
  npoint 'NPoint(1, 0.3)';
-- {[f@2001-01-01, t@2001-01-02], (f@2001-01-02, f@2001-01-03)}
SELECT tnpoint '[NPoint(1, 0.2)@2001-01-01, NPoint(1, 0.8)@2001-01-03)' #&lt;&gt;
  tnpoint '[NPoint(1, 0.3)@2001-01-01, NPoint(1, 0.7)@2001-01-03)';
-- {[t@2001-01-01, f@2001-01-02], (t@2001-01-02, t@2001-01-03)}
</programlisting>
			</listitem>
		</itemizedlist>
	</sect1>

	<sect1 xml:id="tnpoint_aggregations">
		<title>Aggregations</title>

		<para>The three aggregate functions for temporal network points are illustrated next.</para>

		<itemizedlist>
			<listitem xml:id="tnpoint_tCount">
				<indexterm significance="normal"><primary><varname>tCount</varname></primary></indexterm>
				<para>Temporal count</para>
				<para><varname>tCount(tnpoint) → {tintSeq,tintSeqSet}</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
WITH Temp(temp) AS (
  SELECT tnpoint '[NPoint(1, 0.1)@2001-01-01, NPoint(1, 0.3)@2001-01-03)' UNION
  SELECT tnpoint '[NPoint(1, 0.2)@2001-01-02, NPoint(1, 0.4)@2001-01-04)' UNION
  SELECT tnpoint '[NPoint(1, 0.3)@2001-01-03, NPoint(1, 0.5)@2001-01-05)' )
SELECT tCount(Temp)
FROM Temp;
-- {[1@2001-01-01, 2@2001-01-02, 1@2001-01-04, 1@2001-01-05)}
</programlisting>
			</listitem>

			<listitem xml:id="tnpoint_wCount">
				<indexterm significance="normal"><primary><varname>wCount</varname></primary></indexterm>
				<para>Window count</para>
				<para><varname>wCount(tnpoint) → {tintSeq,tintSeqSet}</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
WITH Temp(temp) AS (
  SELECT tnpoint '[NPoint(1, 0.1)@2001-01-01, NPoint(1, 0.3)@2001-01-03)' UNION
  SELECT tnpoint '[NPoint(1, 0.2)@2001-01-02, NPoint(1, 0.4)@2001-01-04)' UNION
  SELECT tnpoint '[NPoint(1, 0.3)@2001-01-03, NPoint(1, 0.5)@2001-01-05)' )
SELECT wCount(Temp, '1 day')
FROM Temp;
/* {[1@2001-01-01, 2@2001-01-02, 3@2001-01-03, 2@2001-01-04, 1@2001-01-05,
   1@2001-01-06)} */
</programlisting>
			</listitem>

			<listitem xml:id="tnpoint_tCentroid">
				<indexterm significance="normal"><primary><varname>tCentroid</varname></primary></indexterm>
				<para>Temporal centroid</para>
				<para><varname>tCentroid(tnpoint) → tgeompoint</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
WITH Temp(temp) AS (
SELECT tnpoint '[NPoint(1, 0.1)@2001-01-01, NPoint(1, 0.3)@2001-01-03)' UNION
SELECT tnpoint '[NPoint(1, 0.2)@2001-01-01, NPoint(1, 0.4)@2001-01-03)' UNION
SELECT tnpoint '[NPoint(1, 0.3)@2001-01-01, NPoint(1, 0.5)@2001-01-03)' )
SELECT astext(tCentroid(Temp))
FROM Temp;
/* {[POINT(72.451531682218 76.5231414472853)@2001-01-01,
   POINT(55.7001249027598 72.9552602410653)@2001-01-03)} */
</programlisting>
			</listitem>
		</itemizedlist>
	</sect1>

	<sect1 xml:id="tnpoint_indexing">
		<title>Indexing</title>

		<para>GiST and SP-GiST indexes can be created for table columns of temporal networks points. An example of index creation is follows:</para>
		<programlisting language="sql" xml:space="preserve" format="linespecific">
CREATE INDEX Trips_Trip_SPGist_Idx ON Trips USING SPGist(Trip);
</programlisting>
		<para>The GiST and SP-GiST indexes store the bounding box for the temporal network points, which is an <varname>stbox</varname> and thus stores the absolute coordinates of the underlying space.</para>

		<para>A GiST or SP-GiST index can accelerate queries involving the following operators:</para>
		<itemizedlist>
			<listitem>
				<para><varname>&lt;&lt;</varname>, <varname>&amp;&lt;</varname>, <varname>&amp;&gt;</varname>, <varname>&gt;&gt;</varname>, <varname>&lt;&lt;|</varname>, <varname>&amp;&lt;|</varname>, <varname>|&amp;&gt;</varname>, <varname>|&gt;&gt;</varname>, which only consider the spatial dimension in temporal network points,</para>
			</listitem>
			<listitem>
				<para><varname>&lt;&lt;#</varname>, <varname>&amp;&lt;#</varname>, <varname>#&amp;&gt;</varname>, <varname>#&gt;&gt;</varname>, which only consider the time dimension in temporal network points,</para>
			</listitem>
			<listitem>
				<para><varname>&amp;&amp;</varname>, <varname>@&gt;</varname>, <varname>&lt;@</varname>, <varname>~=</varname>, <varname>-|-</varname>, and <varname>|=|</varname> , which consider as many dimensions as they are shared by the indexed column and the query argument.</para>
			</listitem>
		</itemizedlist>
		<para>These operators work on bounding boxes, not the entire values.</para>
	</sect1>
</chapter>