[Gfoss] POSTGIS e i dislivelli

Ciao (scusate il cross-post errato in lista soci),

devo calcolare i dislivelli in discesa e in salita di una polilinea 3D, sapete
se (e come) si può fare con postgis?

--
Alessandro Pasotti
itOpen - "Open Solutions for the Net Age"
w3: www.itopen.it
Linux User# 167502

Alessandro Pasotti ha scritto:

Ciao (scusate il cross-post errato in lista soci),

devo calcolare i dislivelli in discesa e in salita di una polilinea 3D, sapete
se (e come) si può fare con postgis?

SELECT ST_ZMAX(the_geom) as z_max, ST_ZMIN(the_geom) as z_min,
(ST_ZMAX(the_geom) - ST_ZMIN(the_geom)) as delta_z FROM streets;

se ti interessa il dislivello esistente in assoluto, mentre per quello
relativo occorre usare anche ST_PointN.

ciao
Antonio

--
Antonio Falciano
http://www.linkedin.com/in/antoniofalciano

Il venerdì 02 ottobre 2009, Antonio Falciano ha scritto:

Alessandro Pasotti ha scritto:
> Ciao (scusate il cross-post errato in lista soci),
>
> devo calcolare i dislivelli in discesa e in salita di una polilinea 3D,
> sapete se (e come) si può fare con postgis?

SELECT ST_ZMAX(the_geom) as z_max, ST_ZMIN(the_geom) as z_min,
(ST_ZMAX(the_geom) - ST_ZMIN(the_geom)) as delta_z FROM streets;

se ti interessa il dislivello esistente in assoluto, mentre per quello
relativo occorre usare anche ST_PointN.

ciao
Antonio

Grazie!

se ho capito bene le prime due funzioni restituiscono quote minime e massime,
se voglio sapere i dislivelli relativi devo quindi scrivere una funzione che
iterando su tutti i punti della polilinea, sommi tutti i dislivelli in un
verso (convenzionalmente salita) e in quello opposto (discesa) ?

L'idea è generare i valori per il costo e usarli per il routing
escursionistico, dove oltre alla distanza contano i dislivelli.

Ciao

--
Alessandro Pasotti
itOpen - "Open Solutions for the Net Age"
w3: www.itopen.it
Linux User# 167502

Alessandro Pasotti ha scritto:

Il venerdì 02 ottobre 2009, Antonio Falciano ha scritto:

Alessandro Pasotti ha scritto:

Ciao (scusate il cross-post errato in lista soci),

devo calcolare i dislivelli in discesa e in salita di una polilinea 3D,
sapete se (e come) si può fare con postgis?

SELECT ST_ZMAX(the_geom) as z_max, ST_ZMIN(the_geom) as z_min,
(ST_ZMAX(the_geom) - ST_ZMIN(the_geom)) as delta_z FROM streets;

se ti interessa il dislivello esistente in assoluto, mentre per quello
relativo occorre usare anche ST_PointN.

ciao
Antonio

Grazie!

se ho capito bene le prime due funzioni restituiscono quote minime e massime,

ok

se voglio sapere i dislivelli relativi devo quindi scrivere una funzione che
iterando su tutti i punti della polilinea, sommi tutti i dislivelli in un
verso (convenzionalmente salita) e in quello opposto (discesa) ?

No, perche' per via dei segni perderesti per strada buona parte
dell'informazione. Cosi' facendo calcolaresti il dislivello tra il punto
iniziale e finale e, a tal fine, basterebbe semplicemente recuperare la
z di questi due agendo con ST_PointN (v. 2° es. in
http://postgis.refractions.net/docs/ST_PointN.html
Purtroppo cosi' si perdono tutti i dislivelli intermedi.

L'idea è generare i valori per il costo e usarli per il routing
escursionistico, dove oltre alla distanza contano i dislivelli.

Se ti interessa calcolare una funzione di costo a partire dalle
geometrie, la pendenza media e' sicuramente il parametro piu'
rappresentativo del "lavoro" necessario a percorre l'intero itinerario.
Inoltre, potresti considerare anche la tipologia di tracciato (sterrato,
pavimentato, ecc.) in modo considerare il grado di difficolta' nella sua
percorrenza. Davvero interessante la tua applicazione, buon lavoro!

Ciao
Antonio

--
Antonio Falciano
http://www.linkedin.com/in/antoniofalciano

Il venerdì 02 ottobre 2009, Antonio Falciano ha scritto:

Alessandro Pasotti ha scritto:
> Il venerdì 02 ottobre 2009, Antonio Falciano ha scritto:
>> Alessandro Pasotti ha scritto:
>>> Ciao (scusate il cross-post errato in lista soci),
>>>
>>> devo calcolare i dislivelli in discesa e in salita di una polilinea 3D,
>>> sapete se (e come) si può fare con postgis?
>>
>> SELECT ST_ZMAX(the_geom) as z_max, ST_ZMIN(the_geom) as z_min,
>> (ST_ZMAX(the_geom) - ST_ZMIN(the_geom)) as delta_z FROM streets;
>>
>> se ti interessa il dislivello esistente in assoluto, mentre per quello
>> relativo occorre usare anche ST_PointN.
>>
>> ciao
>> Antonio
>
> Grazie!
>
> se ho capito bene le prime due funzioni restituiscono quote minime e
> massime,

ok

> se voglio sapere i dislivelli relativi devo quindi scrivere una funzione
> che iterando su tutti i punti della polilinea, sommi tutti i dislivelli
> in un verso (convenzionalmente salita) e in quello opposto (discesa) ?

No, perche' per via dei segni perderesti per strada buona parte
dell'informazione. Cosi' facendo calcolaresti il dislivello tra il punto
iniziale e finale e, a tal fine, basterebbe semplicemente recuperare la
z di questi due agendo con ST_PointN (v. 2° es. in
http://postgis.refractions.net/docs/ST_PointN.html
Purtroppo cosi' si perdono tutti i dislivelli intermedi.

Ho dato per scontato che userei due variabili, una per accumulare i dislivelli
in discesa e l'altra per quelli in salita (pseudo codice):

for punto in linea
  if punto_tmp
    if punto.z > punto_tmp.z
      salita += punto.z - punto_tmp.z
    else
      discesa += punto_tmp.z - punto.z
  punto_tmp = punto

sbaglio qualcosa?

Inoltre, potresti considerare anche la tipologia di tracciato (sterrato,
pavimentato, ecc.) in modo considerare il grado di difficolta' nella sua
percorrenza.

Ho anche le variabili del mezzo: a piedi, in bici ecc. ma non so se mi
spingerò così avanti.

Ciao

--
Alessandro Pasotti
itOpen - "Open Solutions for the Net Age"
w3: www.itopen.it
Linux User# 167502

Alessandro Pasotti ha scritto:

Il venerdì 02 ottobre 2009, Antonio Falciano ha scritto:

Alessandro Pasotti ha scritto:

Il venerdì 02 ottobre 2009, Antonio Falciano ha scritto:

Alessandro Pasotti ha scritto:

Ciao (scusate il cross-post errato in lista soci),

devo calcolare i dislivelli in discesa e in salita di una polilinea 3D,
sapete se (e come) si può fare con postgis?

SELECT ST_ZMAX(the_geom) as z_max, ST_ZMIN(the_geom) as z_min,
(ST_ZMAX(the_geom) - ST_ZMIN(the_geom)) as delta_z FROM streets;

se ti interessa il dislivello esistente in assoluto, mentre per quello
relativo occorre usare anche ST_PointN.

ciao
Antonio

Grazie!

se ho capito bene le prime due funzioni restituiscono quote minime e
massime,

ok

se voglio sapere i dislivelli relativi devo quindi scrivere una funzione
che iterando su tutti i punti della polilinea, sommi tutti i dislivelli
in un verso (convenzionalmente salita) e in quello opposto (discesa) ?

No, perche' per via dei segni perderesti per strada buona parte
dell'informazione. Cosi' facendo calcolaresti il dislivello tra il punto
iniziale e finale e, a tal fine, basterebbe semplicemente recuperare la
z di questi due agendo con ST_PointN (v. 2° es. in
http://postgis.refractions.net/docs/ST_PointN.html
Purtroppo cosi' si perdono tutti i dislivelli intermedi.

Ho dato per scontato che userei due variabili, una per accumulare i dislivelli
in discesa e l'altra per quelli in salita (pseudo codice):

for punto in linea
  if punto_tmp
    if punto.z > punto_tmp.z
      salita += punto.z - punto_tmp.z
    else
      discesa += punto_tmp.z - punto.z
  punto_tmp = punto

sbaglio qualcosa?

ok, cosi' va meglio... ma, in ogni caso, mi calcolerei la pendenza,
poiche' uno stesso dislivello lo puoi avere lungo 1 km opp. dopo soli 5
m di tracciato, ti pare?
Un'altra strategia potrebbe essere quella di "esplodere" le polilinee in
linee, calcolare agevolmente il dislivello e quindi la pendenza di ogni
singola linea ed, infine, riaggregare il tutto mediando le pendenze.

Inoltre, potresti considerare anche la tipologia di tracciato (sterrato,
pavimentato, ecc.) in modo considerare il grado di difficolta' nella sua
percorrenza.

Ho anche le variabili del mezzo: a piedi, in bici ecc. ma non so se mi
spingerò così avanti.

Altre variabili da tenere conto nella funzione di costo potrebbero
essere la tortuosita' del tracciato e le condizioni psico-fisiche del
soggetto che lo percorre, ad es. con o senza grappino! :slight_smile:

ciao

--
Antonio Falciano
http://www.linkedin.com/in/antoniofalciano

Il venerdì 02 ottobre 2009, Antonio Falciano ha scritto:

Alessandro Pasotti ha scritto:
> Il venerdì 02 ottobre 2009, Antonio Falciano ha scritto:
>> Alessandro Pasotti ha scritto:
>>> Il venerdì 02 ottobre 2009, Antonio Falciano ha scritto:
>>>> Alessandro Pasotti ha scritto:
>>>>> Ciao (scusate il cross-post errato in lista soci),
>>>>>
>>>>> devo calcolare i dislivelli in discesa e in salita di una polilinea
>>>>> 3D, sapete se (e come) si può fare con postgis?
>>>>
>>>> SELECT ST_ZMAX(the_geom) as z_max, ST_ZMIN(the_geom) as z_min,
>>>> (ST_ZMAX(the_geom) - ST_ZMIN(the_geom)) as delta_z FROM streets;
>>>>
>>>> se ti interessa il dislivello esistente in assoluto, mentre per quello
>>>> relativo occorre usare anche ST_PointN.
>>>>
>>>> ciao
>>>> Antonio
>>>
>>> Grazie!
>>>
>>> se ho capito bene le prime due funzioni restituiscono quote minime e
>>> massime,
>>
>> ok
>>
>>> se voglio sapere i dislivelli relativi devo quindi scrivere una
>>> funzione che iterando su tutti i punti della polilinea, sommi tutti i
>>> dislivelli in un verso (convenzionalmente salita) e in quello opposto
>>> (discesa) ?
>>
>> No, perche' per via dei segni perderesti per strada buona parte
>> dell'informazione. Cosi' facendo calcolaresti il dislivello tra il punto
>> iniziale e finale e, a tal fine, basterebbe semplicemente recuperare la
>> z di questi due agendo con ST_PointN (v. 2° es. in
>> http://postgis.refractions.net/docs/ST_PointN.html
>> Purtroppo cosi' si perdono tutti i dislivelli intermedi.
>
> Ho dato per scontato che userei due variabili, una per accumulare i
> dislivelli in discesa e l'altra per quelli in salita (pseudo codice):
>
> for punto in linea
> if punto_tmp
> if punto.z > punto_tmp.z
> salita += punto.z - punto_tmp.z
> else
> discesa += punto_tmp.z - punto.z
> punto_tmp = punto
>
>
> sbaglio qualcosa?

ok, cosi' va meglio... ma, in ogni caso, mi calcolerei la pendenza,
poiche' uno stesso dislivello lo puoi avere lungo 1 km opp. dopo soli 5
m di tracciato, ti pare?
Un'altra strategia potrebbe essere quella di "esplodere" le polilinee in
linee, calcolare agevolmente il dislivello e quindi la pendenza di ogni
singola linea ed, infine, riaggregare il tutto mediando le pendenze.

>> Inoltre, potresti considerare anche la tipologia di tracciato (sterrato,
>> pavimentato, ecc.) in modo considerare il grado di difficolta' nella sua
>> percorrenza.
>
> Ho anche le variabili del mezzo: a piedi, in bici ecc. ma non so se mi
> spingerò così avanti.

Altre variabili da tenere conto nella funzione di costo potrebbero
essere la tortuosita' del tracciato e le condizioni psico-fisiche del
soggetto che lo percorre, ad es. con o senza grappino! :slight_smile:

ciao

Grappino a parte, ecco la funzione, in caso serva a qualcuno.

CREATE OR REPLACE FUNCTION dislivelli(line geometry)
  RETURNS real AS
$BODY$
DECLARE
  discesa real;
  salita real;
  point_iter geometry;
  point_tmp geometry;
  line_tmp geometry;
  num_points integer;
  i integer;
BEGIN
  discesa := 0.0;
  salita := 0.0;
  IF (GEOMETRYTYPE(line) = 'MULTILINESTRING') THEN
    line_tmp := ST_Force_3D(linemerge(line));
  ELSIF (GEOMETRYTYPE(line) = 'LINESTRING') THEN
    line_tmp := ST_Force_3D(line);
  ELSE
    Raise Exception 'Not a linestring or multilenstring!';
  END IF;
  num_points := ST_NPoints(line_tmp);
  --Raise Notice 'Points: %', i;
  point_tmp := NULL;
  FOR i IN 1..num_points LOOP
    point_iter := ST_PointN(line_tmp, i);
    --Raise Notice 'Point Iter % : %', i, ST_asEWKT(point_iter);
    --Raise Notice 'Point Tmp % : %', i, ST_asEWKT(point_tmp);
    IF (NOT point_tmp IS NULL) THEN
      IF ST_Z(point_tmp) > ST_Z(point_iter) THEN
        discesa := discesa + ST_Z(point_tmp) - ST_Z(point_iter);
        --Raise Notice 'Discesa : %' , discesa;
      ELSE
        salita := salita + ST_Z(point_iter) - ST_Z(point_tmp);
        --Raise Notice 'Salita : %' , salita;
      END IF;
    END IF;
    point_tmp := point_iter;
  END LOOP;
  
  RETURN ARRAY[salita,discesa];
END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE STRICT
  COST 100;
COMMENT ON FUNCTION dislivelli(geometry) IS 'Calcola i dislivelli in salita e
in discesa di una polilinea

Test: select dislivelli(st_geomfromewkt(''LINESTRING(1 2 4.0, 2 3 5.8, 3 6
8.09, 2 4 1.0008)''));';

Ciao

--
Alessandro Pasotti
itOpen - "Open Solutions for the Net Age"
w3: www.itopen.it
Linux User# 167502