Hermes
|
In this section, the data types supported by Hermes are presented in the following table.
Category | Data types |
---|---|
Temporal | Timestamp (Datetime t) |
Temporal | Interval |
Temporal | Period (Timestamp initial, Timestamp ending) |
Temporal | RangeT (Interval radius, Timestamp center) |
Spatial | PointSP (number x, number y) |
Spatial | LineSP (double A, double B, double C) |
Spatial | BoxSP (PointSP lower-left, PointSP upper-right) |
Spatial | SegmentSP (PointSP initial, PointSP ending) |
Spatial | RangeSP (number radius, PointSP center) |
Spatial | PointLL (float8 lon, float8 lat) |
Spatial | PointXY (float8 x, float8 y) |
Spatio-temporal | PointST (Timestamp t, PointSP p) |
Spatio-temporal | BoxST (PeriodT period, BoxSP box) |
Spatio-temporal | SegmentST (PeriodT period, SegmentSP segment) |
Spatio-temporal | RangeST (RangeT t-range, RangeSP sp-range) |
Spatio-temporal | Trajectory (PointST[]) |
According to [vodas2013hermes] temporal data types are those types that model only the temporal dimension of Mobility. The main type for temporal data type is introduced by PostrgreSQL and Hermes encapsulates it in its data model. An example of a timestamp is ‘2012-09-20 08:05:46’. Another encapsulated data type is the Interval which is used to store information like ‘1 second’ or ‘05:30:5’ (which means 5 hours 30 minutes and 5 seconds) hence contains a temporal quantity. One potential limitation of interval is that on cases where it was produced from a subtraction of two timestamps it won’t keep the original timestamps from which it was computed. That limitation led to the development of some custom temporal types in Hermes [vodas2013hermes.]
The user must have in his mind for using the timestamp data type that PostgreSQL can cast a string to any datatype. For example:
postgres=# SELECT '2008-12-31 19:29:30' :: Timestamp ; timestamp --------------------- 2008-12-31 19:29:30 (1 row) postgres=# SELECT '1 month'::interval; interval ---------- 1 mon (1 row)
A timestamp is given as a string and is cast using “::” to the timestamp data type. This is also possible for the interval data type. Finally Hermes introduced the Period and RangeT temporal data type.
postgres=# SELECT Period('2008-12-31 23:00:00', '2009-01-01 01:00:00'); period --------------------------------------------- '2008-12-31 23:00:00' '2009-01-01 01:00:00' (1 row) postgres=# SELECT RangeT('1 month'::interval, '2008-12-31'::Timestamp) ; ranget ------------------------------- '1 mon' '2008-12-31 00:00:00' (1 row)
According to [vodas2013hermes] spatial data types are those types that model only the spatial dimension of Mobility. Hermes is designed to work with data in the Eyclidean space, which means that a position defined in Riemannian geometry (or any other geometry) can`t be used. Usually the Cartesian system is used and the coordinates are measured in meters. To be precise due to the fact that integers are used to represent the main spatial data type, the unit length that must be used is the same with the precision we want to achieve. So if we want to have a precision of 1 meters we should store in the coordinates in the database in meters, but if we want to achieve a centimeter accuracy, we should store the coordinates in the database as centimeters.
The main spatial data types are the PointSP and the SegmentSP
The previous data types do not have a surface. In contrast, the BoxSP data type has a surface
Some examples of using the saptial data types are shown below:
postgres=# SELECT PointSP(2247569,4792246); pointsp ----------------- 2247569 4792246 (1 row) postgres=# SELECT '2247569 4792246'::pointsp; pointsp ----------------- 2247569 4792246 (1 row) postgres=# SELECT BoxSP(2337709, 4163887,3228259, 4721671) ; boxsp --------------------------------- 2337709 4163887 3228259 4721671 (1 row) postgres=# SELECT SegmentSP(PointSP(2337709, 4163887),PointSP(3228259, 4721671)) ; segmentsp --------------------------------- 2337709 4163887 3228259 4721671 (1 row) postgres=# SELECT '2247569 4792246 2246943 4782504'::segmentsp; segmentsp --------------------------------- 2247569 4792246 2246943 4782504 (1 row) postgres=# SELECT BoxSP(PointSP(2337709, 4163887),PointSP(3228259, 4721671)) ; boxsp --------------------------------- 2337709 4163887 3228259 4721671 (1 row) postgres=# SELECT RangeSP(1,1,1); rangesp --------- 1 1 1 (1 row) postgres=# SELECT LineSP(0.1,0.1,1); linesp ---------------------------- 0.100000 0.100000 1.000000 (1 row)
According to [vodas2013hermes] spatio-temporal data types are those types that model both the temporal and spatial dimension of Mobility in a unified manner. The main spatio-temporal data types are PointST, SegmentST and BoxST
Some examples of using the spatio-temporal data types are shown below:
postgres=# SELECT PointST('2008-12-31 19:29:30' :: Timestamp, PointSP(1,1)); pointst --------------------------- '2008-12-31 19:29:30' 1 1 (1 row) postgres=# SELECT BoxST(Period('2008-12-31 23:00:00', '2009-01-01 01:00:00'), BoxSP(PointSP(2337709, 4163887),PointSP(3228259, 4721671))); boxst ----------------------------------------------------------------------------- '2008-12-31 23:00:00' '2009-01-01 01:00:00' 2337709 4163887 3228259 4721671 (1 row) postgres=# SELECT SegmentST('2008-12-31 19:29:30' :: Timestamp,1,1,'2008-12-31 19:29:31' :: Timestamp,2,2); segmentst ----------------------------------------------------- '2008-12-31 19:29:30' 1 1 '2008-12-31 19:29:31' 2 2 (1 row) postgres=# SELECT RangeST(RangeT('1 month'::interval, '2008-12-31'::Timestamp),RangeSP(1,1,1)); rangest ------------------------------------- '1 mon' '2008-12-31 00:00:00' 1 1 1 (1 row)
Trajectory data type is an object containing a sequence of spatio-temporal points ordered in time. In contrast with the previous data types, it has a variable length and is compromised of sequence of PointST objects ordered by time [vodas2013hermes.] The different approach to this data type is that we look at the movement of an object as a whole and not as segments in smaller parts.
Trajectory is a dynamic data type consisted of several PointST. For this reason constructing trajectory is not a straightforward procedure.
postgres=# SELECT TrajCache_Allocate(3); trajcache_allocate -------------------- 0 (1 row)
Initially the appropriate space in memory is allocated by using the TrajCache_Allocate() function which takes as input the number of PointSTs that the trajectory is consisted of and gives as output an integer which is an identifier of the current allocation. Then we have to reset the index of the current allocation and set it at the beginning of the TrajCache allocation by using the TrajCache_ResetIndex() funcion which takes as input the identifier of the TrajCache allocation(which is the output of the TrajCache_Allocate() function).
postgres=# SELECT TrajCache_ResetIndex(0); trajcache_resetindex ---------------------- (1 row)
Subsequently, by employing the TrajCache_Append() function we append the PointSTs to the trajectory one by one. This function takes as input the identifier of the current allocation and the PointST to be added.
postgres=# SELECT TrajCache_Append(0, PointST('2008-12-31 19:29:30' :: Timestamp, PointSP(1,1))); trajcache_append ------------------ (1 row) postgres=# SELECT TrajCache_Append(0, PointST('2008-12-31 19:29:34' :: Timestamp, PointSP(1,2))); trajcache_append ------------------ (1 row)
Finally with the trajcache2trajectory() function we materialize the trajectory. This function takes as input the identifier of the current allocation and returns the actual trajectory.
postgres=# SELECT trajcache2trajectory(0); trajcache2trajectory ------------------------------------------------------------------------------- '2008-12-31 19:29:30' 1 1,'2008-12-31 19:29:32' 1 3,'2008-12-31 19:29:34' 1 2 (1 row)
Alternatively someone can use the constructor with an array of PointST. An example is shown below:
postgres=# SELECT Trajectory(ARRAY[PointST('2008-12-31 19:29:31' :: Timestamp, PointSP(2,2)),PointST('2008-12-31 19:30:30' :: Timestamp, PointSP(3,3))]); trajectory ----------------------------------------------------- '2008-12-31 19:29:31' 2 2,'2008-12-31 19:30:30' 3 3 (1 row)
For inserting the trajectory in a database an INSERT query must be used. An example is shown below:
INSERT INTO imis_traj(obj_id, traj_id, traj) VALUES (210671000, 1000, (SELECT trajcache2trajectory(0)))
As already mentioned Hermes works on the Euclidean space, meaning it needs degrees (lon, lat) to be transformed into meters (x, y). If you have installed the PostGIS you could use the ST_Transform function to do the transformations.
postgres=# SELECT ST_AsText( ST_Transform(ST_GeomFromText('POINT(23.65298 37.94176)', 4326), 2100)); st_astext ------------------------------------------ POINT(469358.735448916 4199122.03221326) (1 row)
Alternatively the transformation of Geographic to/from Topocentric conversion (EPSG 9837) has been implemented. According to this specification, to do the transformation we only need a reference point (lon, lat) which in (x, y) will be regarded as (0, 0), i.e. the Cartesian center. So, the closer a position is to this reference point the more accurate the transformation will be. Thus, a dataset must have a reference point for transformations [vodas2013hermes.] This can be achieved by using the PointXY(point PointLL, LRP PointLL)
and PointLL(point PointXY, LRP PointLL)
which are implemented by ll2xy and xy2ll functions.
postgres=# SELECT PointLL(PointXY(-240909.991094767,-323271.482666732), PointLL(23.63994,37.9453)); pointll --------------------- 20.999999 35.000044 (1 row) postgres=# SELECT PointXY(PointLL(20.999999 , 35.000044), PointLL(23.63994,37.9453)); pointxy ------------------------------- -240909.991095 -323271.482667 (1 row)