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 (=, <, 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><></varname></primary></indexterm>
<indexterm significance="normal"><primary><varname><</varname></primary></indexterm>
<indexterm significance="normal"><primary><varname><=</varname></primary></indexterm>
<indexterm significance="normal"><primary><varname>></varname></primary></indexterm>
<indexterm significance="normal"><primary><varname>>=</varname></primary></indexterm>
<para>Traditional comparisons</para>
<para><varname>npoint {=, <>, <, >, <=, >=} npoint</varname></para>
<para><varname>nsegment {=, <>, <, >, <=, >=} 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)' <> nsegment 'Nsegment(3, 0.5, 0.5)';
-- false
SELECT nsegment 'Nsegment(3, 0.5, 0.5)' < nsegment 'Nsegment(3, 0.5, 0.6)';
-- true
SELECT nsegment 'Nsegment(3, 0.5, 0.5)' > nsegment 'Nsegment(2, 0.5, 0.5)';
-- true
SELECT npoint 'Npoint(1, 0.5)' <= npoint 'Npoint(2, 0.5)';
-- true
SELECT npoint 'Npoint(1, 0.6)' >= 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><-></varname></primary></indexterm>
<para>Return the temporal distance</para>
<para><varname>tnpoint <-> 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]' <->
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]' <->
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]' <->
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>&&</varname></primary></indexterm>
<indexterm significance="normal"><primary><varname><@</varname></primary></indexterm>
<indexterm significance="normal"><primary><varname>@></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} {&&, <@, @>, ~=, -|-} {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]' &&
tstzspan '[2001-01-02,2001-01-03]';
-- true
SELECT tnpoint '[NPoint(1, 0.3)@2001-01-01, NPoint(1, 0.5)@2001-01-02]' @>
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} {<<, &<, >>, &>} {stbox,tnpoint} → boolean</varname></para>
<para><varname>{stbox,tnpoint} {<<|, &<|, |>>, |&>} {stbox,tnpoint} → boolean</varname></para>
<para><varname>{tstzspan,stbox,tnpoint} {<<#, &<#, #>>, #&>} {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]' <<
stbox(npoint 'NPoint(1, 0.2)');
-- true
SELECT tnpoint '[NPoint(1, 0.3)@2001-01-01, NPoint(1, 0.5)@2001-01-02]' <<|
stbox(npoint 'NPoint(1, 0.5)');
-- false
SELECT tnpoint '[NPoint(1, 0.3)@2001-01-03, NPoint(1, 0.5)@2001-01-05]' #&>
tstzspan '[2001-01-01,2001-01-03]';
-- true
SELECT tnpoint '[NPoint(1, 0.3)@2001-01-03, NPoint(1, 0.3)@2001-01-05]' #>>
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 {=, <>, <, >, <=, >=} 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]}' <>
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]' <
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)' &= 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} {#=, #<>} {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)' #<>
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><<</varname>, <varname>&<</varname>, <varname>&></varname>, <varname>>></varname>, <varname><<|</varname>, <varname>&<|</varname>, <varname>|&></varname>, <varname>|>></varname>, which only consider the spatial dimension in temporal network points,</para>
</listitem>
<listitem>
<para><varname><<#</varname>, <varname>&<#</varname>, <varname>#&></varname>, <varname>#>></varname>, which only consider the time dimension in temporal network points,</para>
</listitem>
<listitem>
<para><varname>&&</varname>, <varname>@></varname>, <varname><@</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>
|