Przybliżanie traku gpx do najbliższej drogi

Troche mnie już to przerasta ale coś zaczełem robić:
Zainstalowałem PostreQSL i PostGis wg instrukcji http://wiki.openstreetmap.org/wiki/Mapnik/PostGIS

for Ubuntu >=12.04:

sudo apt-get install postgresql-9.1-postgis postgresql-contrib-9.1
sudo -u postgres -i -H
createuser -SdR gisuser
createdb -E UTF8 -O gisuser gis
createlang plpgsql gis
psql -d gis -f /usr/share/postgresql/9.1/contrib/postgis-1.5/postgis.sql

to populate the table spatial_ref_sys (mandatory for use with osm2pgsql):

psql -d gis -f /usr/share/postgresql/9.1/contrib/postgis-1.5/spatial_ref_sys.sql

common for all three

psql gis -c “ALTER TABLE geometry_columns OWNER TO gisuser”
psql gis -c “ALTER TABLE spatial_ref_sys OWNER TO gisuser”
exit

Po wpisaniu: psql gis gisuser i \d
wyświetla mi się:
List of relations
Schema | Name | Type | Owner
--------±------------------±------±---------
public | geography_columns | view | postgres
public | geometry_columns | table | gisuser
public | spatial_ref_sys | table | gisuser

Rozumiem że teraz muszę wysłać odpowiednie zapytanie:
coś w stylu:
psql gis “select way from planet_roads where ST_Intersects(way,ST_GeomFromText(‘POLYGON((14 49, 24 49, 24 55, 14 55, 14 49))’,4326))” ??

czy planet_roads ma być ścieżką dostępu do pliku OSMowego? Ok, sprawdziłem te punkty biorą w kwadrat całą powierzchnię Polski. A czym jest liczba 4326 na końcu zapytania?
Co właściwie zwróci mi te zapytanie?

Najpierw musisz zaimportować dane z OSM do bazy :slight_smile: np. poczytaj o osmosis lub osm2pgsql.

Ta liczba to odwzorowanie geograficzne (projekcja).

Coś takiego:

                        way                         
----------------------------------------------------
 0101000020840800000BE37D338C7B1D41603AAF3641670F41
 01010000208408000086ACE512ABB91D4160AA3493B9BF0F41
 0101000020840800002641477D08AD1D41806E2A457F011041

....

są to zakodowane geometrie dróg, które przecinają (intersects) zadany obszar. Same z siebie na wiele się nie zdadzą, ale można je wsadzić w kolejne zapytanie.

Czyli biorę pojedynczy punkt z tracka gpx, robię z niego bboxa załóżmy 50 metrów czyli około 0.004504 stopnia - bbox (lon lat, lon+0.004504 lat, lon+0.004504 lat+0.004504, lon lat+lat+0.004504 , lon lat) importuje te dane z ososis do bazy i potem dalej wybieram way z tego wyniku?

witam,
udało mi się za pomocą osmosis’a, za pomocą polecenia
osmosis --read-xml planet.osm --bounding-box top=52.4058 left=20.895 bottom=52.405 right=20.896 --write-xml plik.xml
wyodrębnić jakąś tam drogę.

czy po zaimportowaniu pliku plenet.osm do bazy postgresql
osmosis --read-xml file=“planet.osm” --write-apidb host=“x” database=“x” user=“x” password=“x”
polecenie te zrobi to samo co to:
select way from planet_roads where ST_Intersects(way,ST_GeomFromText(‘POLYGON((14 49, 24 49, 24 55, 14 55, 14 49))’,4326)) ???

jako planet.osm jest u mnie tylko polska część osm, polecenie wykonuje się bardzo długo, jedno zapytanie i musze czekać ponad minute czasu na odpowiedz.

Jaki teraz powinien być mój algorytm wykonywanych działań?

Czy każdy punkt tracku powinienem przepuszczać przez te polecenie?

Bazę PostgreSQL i Postgisa tworzyłem na podstawie tej instrukcji http://www.earthisflat.net/zdp/ ćw 1 i 2

Osmosis zassa bazę inaczej niż osm2pgsql, ale dla Twoich potrzeb nie ma to aż tak dużego znaczenia. Zassaj PL do bazy.
przykład z tabelą planet_roads był po zassaniu przez osm2pgsql - tam jest osobna tabela na ulice.

W przypadku zassania osmosis metodą --write-pgsql drogi trafią do tabeli ways - ale wszystkie drogi, będziesz musiał wyjąc te których ways.id=way_tags.way_id i way_tags.k=‘highway’ i ewentualnie jeszcze typ way_tags.v = ‘motorway’, ‘primary’ itd. jakie tam potrzebujesz (budynek w osm też może mieć way, ale będzie miał k=‘building’ v=‘yes’. Co do obszaru bbox to będziesz musiał użyć ways.bbox - najszybciej - osmosis trzyma pudełko w bazie (chociaż nie wiem po co, łatwiej trzymać chyba index na st_envelope(linesting) i tak się do tego index na bbox sprowadzi, a użyteczność pudełka poza wyszukiwaniem jest IMO niewielka), a do dokładnego porównania ways.linestring.

Osmosis bardziej uniwersalnie zasysa dane, do takich operacji wygodniej niż osm2pgsql.

No co do traku to tak, powinieneś każdy punkt spróbować przyciągnąć do jakiejś drogi, zapewne kilka punktów się do 1 też może przyciągnąć.
Co gorsza, Ciebie interesuje FRAGMENT drogi, nie cała :slight_smile: ale co i jak to już pisałem we wątku, myśl, bo nie zaliczysz praktyk :wink:

Moja baza:
List of relations
Schema | Name | Type | Owner
--------±------------------±------±---------
public | geography_columns | view | postgres
public | geometry_columns | table | postgres
public | node_tags | table | postgres
public | nodes | table | postgres
public | relation_members | table | postgres
public | relation_tags | table | postgres
public | relations | table | postgres
public | schema_info | table | postgres
public | spatial_ref_sys | table | postgres
public | users | table | postgres
public | way_nodes | table | postgres
public | way_tags | table | postgres
public | ways | table | postgres
(13 rows)

Mam problem z zaimportowaniem planet.osm do postgisa, wywołuje w terminalu komendę:

osmosis --read-xml file=/home/kamil/osmosis-0.40.1/planet.osm --write-apidb host=“localhost” database=“osm” user=“kamil” password=“haslo”;

postgres@kamil-MS-1675:/home/kamil/osmosis-0.40.1/script$ osmosis --read-xml file=/home/kamil/osmosis-0.40.1/planet.osm --write-pgsimp host=“localhost” database=“osm” user=“kamil” password=“******”
Aug 24, 2012 10:51:45 AM org.openstreetmap.osmosis.core.Osmosis run
INFO: Osmosis Version 0.40.1
Aug 24, 2012 10:51:46 AM org.openstreetmap.osmosis.core.Osmosis run
INFO: Preparing pipeline.
Aug 24, 2012 10:51:46 AM org.openstreetmap.osmosis.core.Osmosis run
INFO: Launching pipeline execution.
Aug 24, 2012 10:51:46 AM org.openstreetmap.osmosis.core.Osmosis run
INFO: Pipeline executing, waiting for completion.
Aug 24, 2012 10:51:46 AM org.openstreetmap.osmosis.core.pipeline.common.ActiveTaskManager waitForCompletion
SEVERE: Thread for task 1-read-xml failed
org.openstreetmap.osmosis.core.OsmosisRuntimeException: Unable to read the schema version from the schema info table.
at org.openstreetmap.osmosis.pgsimple.common.SchemaVersionValidator.validateDBVersion(SchemaVersionValidator.java:90)
at org.openstreetmap.osmosis.pgsimple.common.SchemaVersionValidator.validateVersion(SchemaVersionValidator.java:50)
at org.openstreetmap.osmosis.pgsimple.v0_6.PostgreSqlWriter.initialize(PostgreSqlWriter.java:185)
at org.openstreetmap.osmosis.pgsimple.v0_6.PostgreSqlWriter.process(PostgreSqlWriter.java:779)
at org.openstreetmap.osmosis.xml.v0_6.impl.NodeElementProcessor.end(NodeElementProcessor.java:118)
at org.openstreetmap.osmosis.xml.v0_6.impl.OsmHandler.endElement(OsmHandler.java:107)
at org.apache.xerces.parsers.AbstractSAXParser.endElement(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanEndElement(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
at org.apache.xerces.jaxp.SAXParserImpl.parse(Unknown Source)
at javax.xml.parsers.SAXParser.parse(SAXParser.java:195)
at org.openstreetmap.osmosis.xml.v0_6.XmlReader.run(XmlReader.java:108)
at java.lang.Thread.run(Thread.java:679)
Caused by: org.postgresql.util.PSQLException: ERROR: permission denied for relation schema_info
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2102)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1835)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:500)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:374)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:254)
at org.openstreetmap.osmosis.pgsimple.common.SchemaVersionValidator.validateDBVersion(SchemaVersionValidator.java:71)
… 18 more
Aug 24, 2012 10:51:46 AM org.openstreetmap.osmosis.core.Osmosis main
SEVERE: Execution aborted.
org.openstreetmap.osmosis.core.OsmosisRuntimeException: One or more tasks failed.
at org.openstreetmap.osmosis.core.pipeline.common.Pipeline.waitForCompletion(Pipeline.java:146)
at org.openstreetmap.osmosis.core.Osmosis.run(Osmosis.java:92)
at org.openstreetmap.osmosis.core.Osmosis.main(Osmosis.java:37)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchStandard(Launcher.java:329)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:239)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
at org.codehaus.classworlds.Launcher.main(Launcher.java:47)
postgres@kamil-MS-1675:/home/kamil/osmosis-0.40.1/script$

Proszę o pomoc

Użyj --write-psql bo taki masz załadowany schemat bazy.

Dalej jest coś nie tak. Wszystkie czynności które wykonuje:

createuser db_user
postgres=# ALTER USER db_user WITH ENCRYPTED PASSWORD ‘password’;
createdb db_osm
createlang plpgsql db_osm
psql -d db_osm -f postgis.sql
psql -d db_osm -f spatial_ref_sys.sql
psql db_osm -f pgsimple_schema_0.6.sql

postgres@kamil-MS-1675:/home/kamil/osmosis-0.40.1$ osmosis --read-xml file=/home/kamil/osmosis-0.40.1/planet.osm --write-psql host=“localhost” database=“db_osm” user=“db_user” password=“haslo”;
Aug 27, 2012 11:18:51 AM org.openstreetmap.osmosis.core.Osmosis run
INFO: Osmosis Version 0.40.1
Aug 27, 2012 11:18:51 AM org.openstreetmap.osmosis.core.Osmosis run
INFO: Preparing pipeline.
Aug 27, 2012 11:18:51 AM org.openstreetmap.osmosis.core.Osmosis main
SEVERE: Execution aborted.
org.openstreetmap.osmosis.core.OsmosisRuntimeException: Task type write-psql doesn’t exist.
at org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactoryRegister.getInstance(TaskManagerFactoryRegister.java:60)
at org.openstreetmap.osmosis.core.pipeline.common.Pipeline.buildTasks(Pipeline.java:50)
at org.openstreetmap.osmosis.core.pipeline.common.Pipeline.prepare(Pipeline.java:112)
at org.openstreetmap.osmosis.core.Osmosis.run(Osmosis.java:86)
at org.openstreetmap.osmosis.core.Osmosis.main(Osmosis.java:37)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchStandard(Launcher.java:329)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:239)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
at org.codehaus.classworlds.Launcher.main(Launcher.java:47)

moze być schemat --write-pgsimp chociaż łatwiej byłoby gdybyś napisał jakiego schematu użyłeś.

To ten? http://wiki.openstreetmap.org/wiki/Osmosis/Detailed_Usage_0.40#PostGIS_Tasks_.28Simple_Schema.29

tego użyłem psql db_osm -f pgsimple_schema_0.6.sql

ok, zmieniłem na pgsimp i ruszyło

osmosis --read-xml file=/home/kamil/osmosis-0.40.1/planet.osm --write-pgsimp host=“localhost” database=“db_osm” user=“db_user” password=“haslo”;
Aug 27, 2012 11:37:27 AM org.openstreetmap.osmosis.core.Osmosis run
INFO: Osmosis Version 0.40.1
Aug 27, 2012 11:37:27 AM org.openstreetmap.osmosis.core.Osmosis run
INFO: Preparing pipeline.
Aug 27, 2012 11:37:28 AM org.openstreetmap.osmosis.core.Osmosis run
INFO: Launching pipeline execution.
Aug 27, 2012 11:37:28 AM org.openstreetmap.osmosis.core.Osmosis run
INFO: Pipeline executing, waiting for completion.

Ok tak wygląda moja baza.

           List of relations

Schema | Name | Type | Owner
--------±------------------±------±---------
public | geography_columns | view | postgres
public | geometry_columns | table | db_user
public | node_tags | table | postgres
public | nodes | table | postgres
public | relation_members | table | postgres
public | relation_tags | table | postgres
public | relations | table | postgres
public | schema_info | table | postgres
public | spatial_ref_sys | table | db_user
public | users | table | postgres
public | way_nodes | table | postgres
public | way_tags | table | postgres
public | ways | table | postgres
(13 rows)

Ok, rzeczą którą teraz chce zrobić to wyjąć jakąś tam drogę z bazy. Załóżmy że to będzie bbox ograniczony współrzędnymi: 52.679504,22.824512 52.67581,22.848458 52.668003,22.841249 52.669304,22.825713

Rozumiem, że zapytanie powinno wyglądać mniejwięcej tak, ale mam wątpliwości bo w mojej bazie nie ma takiej tabeli jak planet_roads
select way from planet_roads where ST_Intersects(way,ST_GeomFromText(‘POLYGON((22.824512 52.679504, 22.848458 52.67581, 22.841249 52.668003, 22.825713 52.669304, 22.824512 52.679504))’,4326))
Proszę o jakąś podpowiedz

Masz nieco inny schemat. Proponuję abyś sobie dodatkowo wrzucił:


    pgsimple_schema_0.6_bbox.sql - Adds the optional bbox column to the way table.
    pgsimple_schema_0.6_linestring.sql - Adds the optional linestring column to the way table.

Najważniejszy dla Ciebie w tym przypadku to linestring, abyś miał odpowiednią kolumnę w tabeli ways.

CZyli muszę jeszcze raz stworzyć tą bazę, załadować te wszystkie skrypty a potem zaimportować mapę?

Myślę, że możesz jakoś zmodyfikować te skrypty i wygenerować sobie linestringi z obecnych danych. Ale jeśli chcesz możesz załadować na nowo, będzie pewnie szybciej jeśli pracujesz na jakimś wycinku mapy.

w takim razie jak to zrobię to jak powinna wyglądać ta komenda poprawiona?

select way from planet_roads where ST_Intersects(way,ST_GeomFromText(‘POLYGON((22.824512 52.679504, 22.848458 52.67581, 22.841249 52.668003, 22.825713 52.669304, 22.824512 52.679504))’,4326))

raczej “from ways”. A kolumny nie pamiętam, pewnie geom albo linestring.