kolesar-andras / turistautak-osm-api

turistautak.hu osm api
GNU General Public License v2.0
8 stars 5 forks source link

utak automatikus összefűzése #4

Open BathoryPeter opened 9 years ago

BathoryPeter commented 9 years ago

Az utak szakaszolásának különbségeiről volt már szó (http://turistautak.hu/forum.php?action=thread&id=osm&message_id=449639)

Meggyorsítaná a munkát, ha az utak eleve OSM-es gyakorlat szerint összefűzve jönnének le. Tehát azok az egymást követő vonalak, amiknek az OSM formátumba konvertált címkéi azonosak, kerüljenek összefűzésre. Mivel a tuhuból jövő paraméterek közül garantáltan lesznek nem egyezők (id, létrehozva, módosítva, stb.) ezekkel valamit kezdeni kell. Eldobni, vagy összefűzni.

kolesar-andras commented 9 years ago

Egyetértek, támogatom.

Fontos elvi kérdés, hogy elég-e, ha csak az OSM címkék egyezését vizsgáljuk, nem lehet-e olyan fontos tulajdonsága a vonalnak, ami nem kerül OSM címkébe. Egyet biztosan tudok: turistajelzés. Persze ez megjelenik kapcsolatként, de címkeként nem, tehát kivételként mindenképpen be kell építeni az ellenőrzésbe.

Az egymástól gyakran különböző turistautak.hu tulajdonságok kezelésének módszerét kiegészíteném, kezdem az általad említettekkel:

Az egyediek összefűzésénél feltüntethetjük a vonalak darabszámát vagy a vonal hosszára mért arányát százalékban, például:

JarhatosagBabakocsival=B (60%), C (40%)
vagy másképpen:
JarhatosagBabakocsival=60%: B, 40%: D

Az összefűzéshez felhasználható a turistajelzések összekapcsolásához használt logika, két különbséggel:

  1. Turistajelzés-kapcsolat fűzésekor a tagokat kell összefűzni, illetve sorrendjüket megfordítani. Utak fűzésekor majdnem ugyanez történik töréspontokkal, csak annyi a különbség, hogy a fűzés pontja a végeredményben csak egyszer szerepel.
  2. Turistajelzéseket csak olyan helyeket köt össze, ahol egy adott jelzés pontosan két irányba indul. (Egyébként ennek végiggondolása is megérne egy kört, de egyelőre így van.) Azonos típusú vonalakból viszont lehet Y, X vagy még több ágú kereszteződés is, ahol indokolt az összekötés.

Ha kettőnél több fűzhető össze, akkor készíthetünk algoritmust arra, hogy mely vonalak legyenek párban. X kereszteződésnél szemre eléggé egyértelmű, de több vonalnál már általánosabb algoritmus szükséges: amelyek leginkább szemben vannak a másikkal. Fogjuk a vonalak első szakaszának irányszögét, meghatározzuk a lehetséges folytatásokhoz tartozó irányszögeket és úgy választunk párokat, hogy a legkisebb legyen a törésszögek összege. Erre most nincs jobb ötletem, mint az összes lehetőség végignyálazása, szóljatok ha tudtok jobbat.

Az biztosan nem jó megközelítés, ha az első kezünkbe kerülő vonalhoz máris párosítjuk a vele leginkább szemköztit, mert így földutak T elágazásánál alulról jövet két 90 közeli törés közül bután választunk egyet, az egyenes folytatás meg árván marad.

Ha a T ágai alulról kezdve órairányban ABC, akkor felírhatunk egy ilyen táblázatot:

B--+--C
   |
   A

AB -90
AC 90
BC 0

Ha a táblázatot szögek abszolút értéke szerint sorba rendezzük és vesszük az elsőt, megkapjuk a BC kapcsolatot. Ugyanez négyre:

   C
   |
B--+--D
   |
   A

AB -90
AC 0
AD 90
BA 90
BC -90
BD 0

Ami már volt szemből, azt nem érdemes kiszámolni újra, már a BA-t is átugorhattam volna. Így a két egymásba ágyazott ciklusból a belső indulhat a külsőben használt indextől, megfelezve a számításokat:

for ($honnan='A'; $honnan<='D'; $honnan++)
    for ($hová=$honnan+1; $hová<='D'; $hová++)

A számokból szépen kijön, hogy az AC és BD irányok lesznek a jók. Eléggé valószínű, hogy az algoritmus négynél több vonalra is működik. A biztonság kedvéért leírom:

   C D
   |/
B--+--E
   |
   A

AB -90
AC 0
AD 45
AE 90
BC -90
BD -45
BE 0
CD -135
CE -90
DE -135

Jó lesz ez így. Általánosítva tehát mindig az első n/2 darab legkisebb törésszögű vonalpárt kötjük össze, páratlan szám esetén lefelé kerekítve.

A fűzésnél figyelemmel kell lennünk a vonalak kapcsolati tagságára is, ami a jelenlegi feldolgozásba nehezen illeszthető. A vonalak értelmezésekor ugyanis elkészül az út és a turistajelzés-kapcsolat is, így ha ezután kezdünk fűzni, akkor mindkettőt frissítenünk kell.

Az első gondolatom az volt, hogy tegyük a turistaút-kapcsolatok képzését a fűzés utánra. Ebből jöhet viszont egy komoly hiányosság: ha a Label (=turistajelzés ASCII átirata) mező különbsége esetén nem fűzünk, viszont csak sorrendben különböznek, például "S+ S3" és "S3 S+", akkor indokolatlanul hagyjuk ki a fűzést. Ehhez tehát okos összehasonlítás szükséges, ami szóközök mentén felszabdalja, sorba rendezi és újra összefűzi. Kisbetűsíteni is érdemes, mert lehet egymás mellett KL és Kl is.

Úgy is megoldható, hogy ha a turistajelzéseket elkészítjük minden vonalra, majd a fűzéskor a kapcsolatokkal is bíbelődünk. Ez eléggé erőforrás-igényesnek tűnik, ráadásul ugyanúgy nem ússzuk meg a jelzések (=turistaút-kapcsolat-tagságok) összehasonlítását.

kolesar-andras commented 9 years ago

Elkészültem az összefűzés első változatával. Ami megvan:

Ami még hátravan:

Fontos, hogy ha átfedő területeket töltünk le, akkor meg tud duplázódni vonal egy szakasza, mivel újabb vonalak belefűzésével valószínűleg más azonosítót kap. A funkció kikapcsolható a noconcat paraméterrel, ennek elhagyása esetén fűz, vagyis alaphelyzetben is.

http://turistautak.hu/api

Összefűzés nélkül:

http://turistautak.hu/api-noconcat
kolesar-andras commented 9 years ago

Kiegészítettem a letöltést, hogy a vonalak összefűzésekor kezelje azokat a csomópontokat is, ahol kettőnél több azonos tulajdonságú, vagyis összefűzhető vonal találkozik. Ilyenkor megkeresi a legkisebb törésszögeket és eszerint fűzi össze őket.

Az előzőleg vázolt algoritmus nem volt teljesen jó, mert a törésszögek listájából nem mindig jó a legfelső kettő. Előfordulhat, hogy az első kettőben ugyanaz a vonal érintett, ilyenkor a második összefűzés nem sikerül, mivel már felhasználtuk az előbb.

Megoldásképpen addig lépkedek végig a sorbarendezett tömbön, és ha olyan párosokat találok, amelyek egyik taga sem volt még, akkor azokat fűzöm össze. Így ki sem kell számolni a párok számát, adódik magától.

nemethtamas commented 9 years ago

A Turamozgalom paramétert tartalmazó utak kezelve vannak valamilyen módon? Lehetséges lenne az API-val erre szűrni, még ha csak egy lat/lon párokat tartalmazó szövegfájlt adna vissza, hiszen úgy már könnyen létre lehetne hozni egy kapcsolatot hozzá, ha betölti az ember egy rétegre, ha látom, melyik utak futnak alatta

kolesar-andras commented 9 years ago

Nagyon jó ötlet, készítettem neki egy külön témát.

kolesar-andras commented 9 years ago

Hiba: rosszul fűzi az üres paramétereket:

ID=123033, 123032
Zsakutca=, 2
kolesar-andras commented 9 years ago

Javítottam az összefűzést. Egyúttal okosítottam is, hogy a min ... max értékeket ne írja intervallumként, ha a két vége azonos.

nemethtamas commented 9 years ago

Most akartam írni, hogy találtam egy hibát, ahol az SL helyett s"négyzet" került az összefűzött name címkébe, holott a jel címkében helyesen szerepel, de ahogy kimásoltam, és ide beillesztettem, kiderült, csak a JOSM nem ismeri a ▙ -t.