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("############# Mapa/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) StartMessageLoop End If Else resp.ContentType = "text/html" resp.Write("Hay un error en la solicitud, son necesarios los siguientes parametros:
* r - La ruta
* a - El almacen
* 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.
* m - La matriz a usar LOCAL u OSRM (Opcional, default local
* 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("############# Mapa/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($"Mapa"$) 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("############# Mapa/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($"Mapa"$) Return 1 End Sub 'Regresa la ruta esquina a esquina. Sub ruteoCompleto(ruta As String) As ResumableSub 'ignore Log("#################################################################") Log("############# Mapa/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("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