nodes extraction via postgreSQL

2

It is possible via commands in Postgres to treat vector data. I have a table with data that represent the displacement of objects and I need to extract final and initial vertex. Is this possible via PostgreSQL?

    
asked by anonymous 25.04.2018 / 20:16

1 answer

0

Short answer: yes. If you use data types that support arrays, in Postgres you can extract any elements of them, whatever their positions. Now let's get the long answer ...

PostgreSQL without extensions

Assuming you are dealing with geographic coordinates points such as those extracted from a GPS, and representing your data as latitude / longitude pairs, in "pure" PostgreSQL you can store them in arrays or json . Both methods allow the extraction of arbitrary items.

Arrays

So, a number of geographic positions like the following, picks up a random GPX here ...

34.295944 132.319809
34.295971 132.319809
34.295998 132.320129
34.296024 132.319763

... can be represented as a array of arrays with pairs of floats:

ARRAY[
  [34.295944,  132.319809], [34.295971,  132.319809], 
  [34.295998,  132.320129], [34.296024,  132.319763]
]

To get the first and last elements of array , use functions dedicated to array of Postgres:

with paths as (
 select ARRAY[
  [34.295944,  132.319809], [34.295971,  132.319809],
  [34.295998,  132.320129], [34.296024,  132.319763]
 ] as path
)
select path[1:1] as "primeiro", path[array_length(path, 1):] as "ultimo" from paths;
         primeiro         |          ultimo          
--------------------------+--------------------------
 {{34.295944,132.319809}} | {{34.296024,132.319763}}
(1 row)

A limitation of the use of arrays is the inability to create structures of mixed data types. A table field to hold the above data should be declared as array numeric of two dimensions, the second delimited to two elements:

create table teste (path numeric(9,6)[][2]);
insert into teste values (ARRAY[
  [34.295944,  132.319809], [34.295971,  132.319809],
  [34.295998,  132.320129], [34.296024,  132.319763]
 ]);
select * from teste;
                                             path                                              
-----------------------------------------------------------------------------------------------
 {{34.295944,132.319809},{34.295971,132.319809},{34.295998,132.320129},{34.296024,132.319763}}
(1 row)

JSON

The same data can be represented in array of JSON objects as follows:

'[
  {"lat": 34.295944, "lon": 132.319809},
  {"lat": 34.295971, "lon": 132.319809},
  {"lat": 34.295998, "lon": 132.320129},
  {"lat": 34.296024, "lon": 132.319763}
]'::json

And, therefore, consulted with the JSON manipulation functions and operators :

with paths as (
 select '[
  {"lat": 34.295944, "lon": 132.319809},
  {"lat": 34.295971, "lon": 132.319809},
  {"lat": 34.295998, "lon": 132.320129},
  {"lat": 34.296024, "lon": 132.319763}
 ]'::json as path
)
select path->0 as primeiro, path->json_array_length(path)-1 as ultimo from paths;
               primeiro                |                ultimo                 
---------------------------------------+---------------------------------------
 {"lat": 34.295944, "lon": 132.319809} | {"lat": 34.296024, "lon": 132.319763}
(1 row)

The use of JSON is more flexible than array , since it supports mixed structures of data types. Both solutions support indexing, especially jsonb data fields. Just create a column with the appropriate data type and put inside it data in JSON of any type and size:

create table teste (path jsonb);
insert into teste values ('[
  {"lat": 34.295944, "lon": 132.319809},
  {"lat": 34.295971, "lon": 132.319809},
  {"lat": 34.295998, "lon": 132.320129},
  {"lat": 34.296024, "lon": 132.319763}
 ]');
select * from teste;
                                                                             path                                                                             
--------------------------------------------------------------------------------------------------------------------------------------------------------------
 [{"lat": 34.295944, "lon": 132.319809}, {"lat": 34.295971, "lon": 132.319809}, {"lat": 34.295998, "lon": 132.320129}, {"lat": 34.296024, "lon": 132.319763}]
(1 row)

PostGIS

All told, for serious geoprocessing you can also use the PostGIS extension, which provides data types, functions, indexes, and other objects specific to this type of task. An interesting feature for your case might be the ability to interpolate a dot along a line.

In PostGIS, point series can be represented as a comma-separated string of lat / lon pairs, and converted to geometry data types via a function :

select ST_GeomFromText('LINESTRING(34.295944 132.319809, 34.295971 132.319809, 34.295998 132.320129, 34.296024 132.319763)');

I do not, however, have PostGIS environment created at the moment, and I imagine that the subject already runs away from the scope of the question "Is it possible to extract initial and final vertex of a vector with PostgreSQL?". If you would like to learn more about the PostGIS extension, it has documentation as well as PostgreSQL itself.

    
27.04.2018 / 19:19