Files
Ruteador-NonUI/rutaCompleta.bas

201 lines
7.6 KiB
QBasic

B4J=true
Group=Default Group
ModulesStructureVersion=1
Type=Class
Version=10
@EndOfDesignText@
'Class module
Sub Class_Globals
Private mreq As ServletRequest 'ignore
Private mresp As ServletResponse 'ignore
' Dim cmd As DBCommand
Dim getHash As CalculateHash
Dim js As JSONGenerator
End Sub
Public Sub Initialize
End Sub
'Resumable Subs (wait for / sleep) in server handlers
'Resumable subs can only work when there is a message queue.
'By default, server handlers end when the Handle sub is completed. They do not create a message loop.
'If you want to wait for an event then you need to call StartMessageLoop and later StopMessageLoop.
'https://www.b4x.com/android/forum/threads/resumable-subs-wait-for-sleep-in-server-handlers.81833/
Sub Handle(req As ServletRequest, resp As ServletResponse)
Log("##########################################################")
Log("############# rutaCompleta/Handle ################")
Log("##########################################################")
' Log("q='"&req.GetParameter("q")&"'")
' Log($"REQ: ${req.FullRequestURI}"$)
Private elHash As String = getHash.CalculateTheHash(req.FullRequestURI)
' Log(elHash)
Private ruta As String = req.GetParameter("r")
Private almacen As String = req.GetParameter("a")
Private coords As String = req.GetParameter("c")
Private matriz As String = req.GetParameter("m")
If matriz <> "" And matriz <> "OSRM" Then matriz = ""
' Log($"r: ${ruta}, a: ${almacen}, Coords: ${coords}"$)
Private urlParams As Map
If ruta <> "" And almacen <> "" And coords <> "" Then
ruta = "R" & ruta
urlParams.Initialize
urlParams.Put("almacen", almacen)
urlParams.Put("coords", coords)
urlParams.Put("hash", elHash)
urlParams.Put("ruta", ruta)
Main.db.InitializeSQLite(File.DirApp, "kmt.db", True)
' Si no existe la tabla del ruteo, la creamos.
If Not(checkIfTableExists($"${ruta}A${almacen}_${elHash}_punteo"$)) Then
Log($"Creamos tablas ruta ${ruta}, almacen ${almacen}"$)
Main.creaTablas(urlParams)
generaMatrizRuteoTiempos($"${ruta}A${almacen}_${elHash}"$, resp, ruta, almacen, matriz)
StartMessageLoop
Else 'Si ya existe, solo calculamos los tiempos y distancias.
' tiempos($"${ruta}A${almacen}_${elHash}"$, resp, ruta, almacen, matriz)
ruteoCompleto($"${ruta}A${almacen}_${elHash}"$)
StartMessageLoop
End If
Else
resp.ContentType = "text/html"
resp.Write("Hay un error en la solicitud, son necesarios los siguientes parametros:<br>* r - La ruta<br>* a - El almacen<br>* c - Lista de puntos (id_cliente,lon,lat) separadas por punto y coma, el primer punto de la lista, se considera el punto de INICIO de la ruta.<br>* m - La matriz a usar LOCAL u OSRM (Opcional, default local<br>* f - El destino final (id_cliente,lon,lat) de donde termina la ruta (Opcional)") 'this file will be loaded from the www folder
End If
End Sub
Sub generaMatrizRuteoTiempos(r As String, resp As ServletResponse, ruta As String, almacen As String, matriz As String) As ResumableSub
Log("############################################################################")
Log("############# rutaCompleta/generaMatrizRuteoTiempos ################")
Log("############################################################################")
'Generamos la matriz
If matriz = "OSRM" Then
Wait for(Main.generaMatrizOSRM(r)) Complete (Result As Int)
Else
Main.generaMatrizLocal(r)
End If
'Generamos el ruteo
Main.ruteo($"${r}"$, matriz)
' Wait for(Main.tiempos($"${r}"$)) Complete (Result As Int)
' Private ts As Map = Main.ts.Get($"${r}"$)
' Log(ts)
Private p As ResultSet = Main.db.ExecQuery($"select * from ${r}_punteo"$)
Private listCoords As String = ""
'Ponemos el id de la tienda y las coordenadas en una lista para regresarla en un JSON.
Do While p.NextRow
If listCoords = "" Then
listCoords = $"${p.GetString("lon")},${p.GetString("lat")}"$
Else
listCoords = $"${listCoords}:${p.GetString("lon")},${p.GetString("lat")}"$
End If
Loop
Main.db.Close
StopMessageLoop
Main.error = ""
resp.ContentType = "text/html"
resp.Write($"<a href="https://osm.quelltextlich.at/viewer-js.html?kml_url=https://pi.famguerra.com/kmz.php?c=${listCoords}">Mapa</a>"$)
Return 1
End Sub
Sub tiempos(r As String, resp As ServletResponse, ruta As String, almacen As String, matriz As String) As ResumableSub
Log("###########################################################")
Log("############# rutaCompleta/tiempos ################")
Log("###########################################################")
Private p As ResultSet = Main.db.ExecQuery($"select * from ${r}_punteo"$)
Private listCoords As String = ""
Do While p.NextRow
If listCoords = "" Then
listCoords = $"${p.GetString("lon")},${p.GetString("lat")}"$
Else
listCoords = $"${listCoords}:${p.GetString("lon")},${p.GetString("lat")}"$
End If
Loop
Main.db.Close
' Log("Iniciamos ruteoCompleto")
' ruteoCompleto(r)
StopMessageLoop
Main.error = ""
resp.ContentType = "text/html"
resp.Write($"<a href="https://osm.quelltextlich.at/viewer-js.html?kml_url=https://pi.famguerra.com/kmz.php?c=${listCoords}">Mapa</a>"$)
Return 1
End Sub
'Regresa la ruta esquina a esquina.
Sub ruteoCompleto(ruta As String) As ResumableSub 'ignore
Log("#################################################################")
Log("############# rutaCompleta/ruteoCompleto ################")
Log("#################################################################")
' Log("Tiempos: " & ruta)
Private c As ResultSet = Main.db.ExecQuery($"select * from ${ruta}_punteo"$)
Private estasCoords As String = ""
Private ts As Map
ts.Initialize
Do While c.NextRow
If estasCoords = "" Then
estasCoords = $"${c.GetString("lon")},${c.GetString("lat")}"$
Else
estasCoords = $"${estasCoords};${c.GetString("lon")},${c.GetString("lat")}"$
End If
Loop
Dim j As HttpJob
j.Initialize("", Me)
j.Download($"http://router.project-osrm.org/route/v1/driving/${estasCoords}?steps=true"$)
Wait For (j) JobDone(j As HttpJob)
If j.Success Then
' Log(j.GetString)
Private j0 As String = j.GetString
End If
j.Release
' StopMessageLoop
Private js1 As JSONParser
js1.Initialize(j0)
' Log(js1)
' For Each colroot As Map In js
' Log(colroot)
' Next
' Log("*****************************************")
' Log(js.NextObject)
ts.Put(ruta, CreateMap("code":"KO", "duration":0, "distance":0, "puntos":0))
Try
Private m As Map = js1.NextObject
' Private estatus As String = m.Get("code")
Private rutas As Map = m.Get("routes").as(List).Get(0)
' Private waypoints As List = m.Get("waypoints")
' Log("Response: " & estatus)
' Log("Duration: " & rutas.Get("duration"))
' Log("Distance: " & rutas.Get("distance"))
' Log("Legs: " & rutas.Get("legs").As(List).Size)
' Log("Waypoints: " & waypoints.Size)
Private steps As List
steps.Initialize
steps = rutas.Get("legs").as(List).get(0).As(Map).Get("steps")
Log("STEPS SIZE: " & steps.Size)
ts.Put(ruta, CreateMap("code":"OK", "duration":rutas.Get("duration"), "distance":rutas.Get("distance"), "puntos":rutas.Get("legs").As(List).Size))
' Log(">>>>>>>>>>>>>>>>>>>>>>>>>>>" & ts)
Catch
Log(LastException)
End Try
Return 1
End Sub
'Convierte una lista en un arreglo (array as object).
Public Sub ListToArray(inList As List) As Object()
Dim OutArray(inList.Size) As Object
For i = 0 To inList.Size - 1
OutArray(i) = inList.Get(i)
Next
Return OutArray
End Sub
Sub checkIfTableExists(table As String) As Boolean
' B4XPages.MainPage.db.InitializeSQLite(File.DirApp, "kmt.db", True)
Private r As ResultSet = Main.db.ExecQuery($"Select name FROM sqlite_master WHERE Type='table' AND name='${table}'"$)
If r.NextRow Then
' B4XPages.MainPage.db.close
' Log($"NAME: ${r.GetString("name")}"$)
Return True
Else
' B4XPages.MainPage.db.close
Return False
End If
End Sub