AppType=StandardJava Build1=Default,b4j.example Group=Default Group Library1=compressstrings Library10=byteconverter Library2=jcore Library3=jfx Library4=jokhttputils2 Library5=jrandomaccessfile Library6=jserver Library7=json Library8=jsql Library9=nhcalculatehash Module1=DBRequestManager Module2=delDB Module3=Mapa Module4=rutaCompleta Module5=Ruteador NumberOfFiles=0 NumberOfLibraries=10 NumberOfModules=5 Version=10 @EndOfDesignText@ #Region Project Attributes #CommandLineArgs: #MergeLibraries: True #AdditionalJar: sqlite-jdbc-3.7.2.jar '########################################################################################################### '###################### PULL ############################################################# 'Ctrl + click ide://run?file=%WINDIR%\System32\cmd.exe&Args=/c&Args=git&Args=pull '########################################################################################################### '###################### PUSH ############################################################# 'Ctrl + click ide://run?file=%WINDIR%\System32\WindowsPowerShell\v1.0\powershell.exe&Args=github&Args=..\..\ '########################################################################################################### '###################### PUSH TORTOISE GIT ######################################################### 'Ctrl + click ide://run?file=%WINDIR%\System32\WindowsPowerShell\v1.0\powershell.exe&Args=TortoiseGitProc&Args=/command:commit&Args=/path:"./../"&Args=/closeonend:2 '########################################################################################################### #End Region Sub Process_Globals Private srvr As Server Dim db As SQL ' Dim fx As JFX Dim punteoLista As List Dim algoritmo As Int = 1 ' Dim api As Int = 0 ' Dim matriz As String = "" ' Dim urlParams As Map Dim ts As Map Dim inicio As String = "", final As String = "" ' Dim coords As List ' Dim estePunto() As String Dim error As String = "" Dim msg As String = "" End Sub Sub AppStart (Args() As String) srvr.Initialize("srvr") srvr.Port = 9002 If(Args.Length > 0) Then Log($"Args=${Args(0)}"$) For i=0 To Args.Length -1 If(Args(i).StartsWith("portX=") Or Args(i).StartsWith("PortX=")) Then ' DBRPort = Args(i).SubString(5) ' Log($"Puerto de DBRequest = ${Args(i).SubString(5)}"$) Else if (Args(i).StartsWith("ip=") Or Args(i).StartsWith("IP=")) Then ' DBRIp = Args(i).SubString(3) ' Log($"IP de DBRequest = ${Args(i).SubString(3)}"$) Else if (Args(i).ToUpperCase.StartsWith("PORT=") Or Args(i).ToUpperCase.StartsWith("P=")) Then srvr.Port = Args(i).SubString(Args(i).IndexOf("=")+1) Log($"Puerto del servidor = ${Args(i).SubString(Args(i).IndexOf("="))}"$) End If Next End If ' Log($"ARGS=${DBRIp}:${DBRPort}"$) Log("Server Port=" & srvr.Port) ts.Initialize srvr.StaticFilesFolder = File.Combine(File.DirApp, "www") srvr.LogsFileFolder = File.Combine(File.DirApp, "logs") srvr.LogsRetainDays = 15 srvr.AddHandler("/ruteador", "Ruteador", False) srvr.AddHandler("/mapa", "Mapa", False) srvr.AddHandler("/rutacompleta", "rutaCompleta", False) srvr.AddHandler("/borrar", "delDB", False) srvr.Start StartMessageLoop 'open browser and navigate to: http://127.0.0.1:51042/ End Sub #Region Shared Files '#CustomBuildAction: folders ready, %WINDIR%\System32\Robocopy.exe,"..\..\Shared Files" "..\Files" 'Ctrl + click to sync files: ide://run?file=%WINDIR%\System32\Robocopy.exe&args=..\..\Shared+Files&args=..\Files&FilesSync=True #End Region 'Ctrl + click to export as zip: ide://run?File=%B4X%\Zipper.jar&Args=Project.zip Public Sub Initialize ' B4XPages.GetManager.LogEvents = True End Sub 'This event will be called once, before the page becomes visible. Private Sub B4XPage_CreatedX ' urlParams.Initialize ' ts.Initialize ' Log(File.DirApp) ' db.InitializeSQLite(File.DirApp, "kmt.db", True) ' '' almacen.Initialize2("19.44598465518769", "-99.1818326916271") 'Mexico-España - Lago Iseo 128 ' db.ExecNonQuery("CREATE TABLE IF NOT EXISTS R1_puntos (id TEXT, nombre TEXT, lat TEXT, lon TEXT)") ' db.ExecNonQuery("CREATE TABLE IF NOT EXISTS R1_punteo (pos TEXT, id TEXT, nombre TEXT, lat TEXT, lon TEXT)") ' db.ExecNonQuery("CREATE TABLE IF NOT EXISTS R1_matriz (idT TEXT, t1 TEXT, t2 TEXT, t3 TEXT, t4 TEXT, t5 TEXT, t6 TEXT, t7 TEXT, t8 TEXT, t9 TEXT, t10 TEXT)") ' db.ExecNonQuery("CREATE TABLE IF NOT EXISTS R1_matrizOSRM (idT TEXT, t1 TEXT, t2 TEXT, t3 TEXT, t4 TEXT, t5 TEXT, t6 TEXT, t7 TEXT, t8 TEXT, t9 TEXT, t10 TEXT)") ' ' 'Generamos la lista de puntos y la guardamos en la tabla "R1_puntos" ' coords.Initialize ' coords.AddAll(Array As String ("Mexico-España,19.44598465518769,-99.1818326916271", "Xochimilco 47,19.448171727202524,-99.1779942882756", "Little Caesars,19.449867997938245,-99.1833874413472", "El Globo,19.451633331080625,-99.18485729424397", "Bodega Aurrera,19.445747004224824,-99.18301691592744", "Wetter 76,19.446150110778017,-99.1936412539473", "Papeleria Progreso,19.443934235653053,-99.18575629823629", "La Esperanza,19.442779235275808,-99.19255124428338", "Modelo,19.440456467281724,-99.18896176081896", "Gringo,19.441000733767016,-99.1817225994711", "Pemex,19.439420250127483,-99.17486856671235")) '' db.ExecNonQuery("delete from R1_puntos") '' For a = 0 To coords.Size - 1 '' estePunto = Regex.Split(",", coords.Get(a)) '' db.ExecNonQuery($"insert into R1_puntos (id, nombre, lat, lon) values ('A${a}', '${estePunto(0)}', '${estePunto(1)}', '${estePunto(2)}')"$) '' Next ' 'Creamos la tabla de la matriz con las columnas necesarias. ' Try ' db.ExecNonQuery($"drop table R1_matriz"$) ' db.ExecNonQuery($"drop table R1_matrizOSRM"$) ' db.ExecNonQuery("vacuum") ' Catch ' Log(LastException) ' End Try ' Private colsMatriz As String = "idT TEXT" ' Private pp As ResultSet = db.ExecQuery("select * from R1_puntos") ' Do While pp.NextRow ' colsMatriz = $"${colsMatriz},'${pp.GetString("id")}' REAL"$ ' Loop ' Log(colsMatriz) ' db.ExecNonQuery($"create table if not exists R1_matriz (${colsMatriz})"$) ' db.ExecNonQuery($"create table if not exists R1_matrizOSRM (${colsMatriz})"$) ' 'Generamos la matriz ' b_generaMatriz_Click End Sub Sub creaTablas(params As Map) 'Creamos las tablas de la ruta con las columnas necesarias. Log("##########################################################") Log("############# Main/creaTablas ####################") Log("##########################################################") Log(params) Private almacen As String = params.Get("almacen") Private estasCoords As String = params.Get("coords") Private hash As String = params.Get("hash") Private ruta As String = $"${params.Get("ruta")}A${almacen}_${hash}"$ db.BeginTransaction Try ' Log($"drop table if exists ${ruta}_matriz"$ db.ExecNonQuery($"drop table if exists ${ruta}_matriz"$) ' Log($"drop table if exists ${ruta}_matrizOSRM"$) db.ExecNonQuery($"drop table if exists ${ruta}_matrizOSRM"$) ' Log($"drop table if exists ${ruta}_puntos"$) db.ExecNonQuery($"drop table if exists ${ruta}_puntos"$) db.ExecNonQuery($"create table if not exists ${ruta}_puntos (id TEXT, nombre TEXT, lat TEXT, lon TEXT)"$) ' Log($"create table if not exists ${ruta}_puntos (id TEXT, nombre TEXT, lat TEXT, lon TEXT)"$) db.ExecNonQuery($"create table if not exists ${ruta}_punteo (pos TEXT, id TEXT, nombre TEXT, lat TEXT, lon TEXT)"$) ' Log($"create table if not exists ${ruta}_punteo (pos TEXT, id TEXT, nombre TEXT, lat TEXT, lon TEXT)"$) Private f() As String = Regex.Split(";", estasCoords) For i = 0 To f.Length - 1 ' Log(f(i)) Private pars() As String = Regex.Split(",", f(i)) If pars(2) > 0 Or pars(2) > 0 Then If pars.Length < 3 Then Log("####################" & CRLF & "Se necesita el id del cliente, la longitud y la latitud" & CRLF & "##############################") ' Log($"(${i}, ${pars(0)}, 'a', ${pars(2)}, ${pars(1)})"$) db.ExecNonQuery($"insert into ${ruta}_puntos (id, nombre, lat, lon) values ('_${pars(0)}','a', ${pars(2)}, ${pars(1)})"$) Else msg = "Hay puntos con coordenadas en CERO, se eliminaron." End If Next Private colsMatriz As String = "idT TEXT" Private pp As ResultSet = db.ExecQuery($"select * from ${ruta}_puntos"$) Do While pp.NextRow colsMatriz = $"${colsMatriz},'${pp.GetString("id")}' REAL"$ Loop ' Log(colsMatriz) db.ExecNonQuery($"create table if not exists ${ruta}_matriz (${colsMatriz})"$) db.ExecNonQuery($"create table if not exists ${ruta}_matrizOSRM (${colsMatriz})"$) db.TransactionSuccessful Catch Log(LastException) If error = "" Then error = LastException db.Rollback End Try End Sub Private Sub b_generaMatriz_Click ' If api = 0 Then ' generaMatrizLocal("R1") ' Else ' generaMatrizOSRM("R1") ' End If End Sub Sub generaMatrizLocal(ruta As String) 'ignore Log("#################################################################") Log("############# Main/generaMatrizLocal ####################") Log("#################################################################") ' Log($"delete from ${ruta}_punteo"$) Log("Generamos matriz LOCAL") Try db.ExecNonQuery($"delete from ${ruta}_punteo"$) ' Log($"delete from ${ruta}_matriz"$) db.ExecNonQuery($"delete from ${ruta}_matriz"$) ' matriz = "" punteoLista.Initialize ' Private otroPunto() As String Private lasCols, losVals As String Private c As ResultSet = db.ExecQuery($"select * from ${ruta}_puntos"$) ' Dim h As String = c.GetString("id") db.ExecNonQuery($"insert into ${ruta}_punteo (pos, id, nombre, lat, lon) values ('0', '${c.GetString("id")}', 'Almacen', ${c.Getdouble("lat")}, ${c.Getdouble("lon")})"$) ' Log($"insert into ${ruta}_punteo (pos, id, nombre, lat, lon) values ('0', '${c.GetString("id")}', 'Almacen', ${c.Getdouble("lat")}, ${c.Getdouble("lon")})"$) punteoLista.Add(c.GetString("id")) 'Lista para ruteoNearestInsertion, ponemos el primer punto (almacen). Do While c.NextRow lasCols = "idT" ' Log($"${c.GetString("id")}, ${c.GetString("nombre")}, ${c.GetString("lat")}, ${c.GetString("lon")}"$) Private d As ResultSet = db.ExecQuery($"select * from ${ruta}_puntos"$) losVals = $"'${c.GetString("id")}'"$ Do While d.NextRow Private laDist As Double = calculateDistance1(c.GetDouble("lat"), c.GetDouble("lon"), d.GetDouble("lat"), d.GetDouble("lon")) lasCols = $"${lasCols}, '${d.GetString("id")}'"$ losVals = $"${losVals}, '${laDist}'"$ ' Log($"(${c.GetString("id")},${d.GetString("id")}) - Dist entre ${c.GetString("nombre")} y ${d.GetString("nombre")} = ${laDist}"$) Loop ' Log($"${lasCols}${CRLF}${losVals}"$) db.ExecNonQuery($"insert into ${ruta}_matriz (${lasCols}) values (${losVals})"$) Loop Log("Matriz LOCAL generada") Catch Log(LastException) If error = "" Then error = LastException End Try ' generaMatrizOSRM End Sub Sub generaMatrizOSRM(ruta As String) As ResumableSub 'ignore Log("Generamos matriz OSRM") Log("################################################################") Log("############# Main/generaMatrizOSRM ####################") Log("################################################################") Try db.ExecNonQuery($"delete from ${ruta}_punteo"$) db.ExecNonQuery($"delete from ${ruta}_matrizOSRM"$) ' matriz = "OSRM" punteoLista.Initialize Private c As ResultSet = db.ExecQuery($"select * from ${ruta}_puntos"$) db.ExecNonQuery($"insert into ${ruta}_punteo (pos, id, nombre, lat, lon) values ('0', '${c.GetString("id")}', 'Almacen', ${c.Getdouble("lat")}, ${c.Getdouble("lon")})"$) punteoLista.Add(c.GetString("id")) 'Lista para ruteoNearestInsertion, ponemos el primer punto (almacen). Private lasCoords = "", lasCols = "idT", losIds = c.GetString("id") As String 'ignore Private listLasCols As List listLasCols.Initialize Do While c.NextRow listLasCols.Add(c.GetString("Id")) If lasCoords = "" Then lasCoords = $"${c.GetString("lon")},${c.GetString("lat")}"$ lasCols = $"${lasCols},'${c.GetString("Id")}'"$ Else lasCoords = $"${lasCoords};${c.GetString("lon")},${c.GetString("lat")}"$ lasCols = $"${lasCols},'${c.GetString("Id")}'"$ End If Loop Log(">>>>>>>>>>>> " & lasCols & CRLF & lasCoords) Dim j As HttpJob j.Initialize("", Me) j.Download($"http://router.project-osrm.org/table/v1/driving/${lasCoords}"$) 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 durs As String = j0.SubString2(j0.IndexOf($""durations""$)+12, j0.IndexOf($""sources""$)).Replace("[","") Private dur1() As String = Regex.Split("]", durs) Log(durs) For i = 0 To dur1.Length - 1 Private estosVals As String = dur1(i) If estosVals.StartsWith(",") Then estosVals = $"${estosVals.SubString(1)}"$ If estosVals.Length > 0 Then estosVals = $"'${listLasCols.get(i)}',${estosVals}"$ Log(estosVals) ' Log($"insert into ${ruta}_matrizOSRM (${lasCols}) values (${estosVals})"$) db.ExecNonQuery($"insert into ${ruta}_matrizOSRM (${lasCols}) values (${estosVals})"$) End If Next ' fx.ShowExternalDocument($"http://router.project-osrm.org/table/v1/driving/${lasCoords}"$) Log("Matriz OSRM generada") Catch Log(LastException) If error = "" Then error = LastException End Try End Sub Sub b_ruteo_Click ' ruteo("R1") End Sub 'Genera el ruteo de la ruta especificada. Sub ruteo(ruta As String, matriz As String) 'ignore Log("#####################################################") Log("############# Main/ruteo ####################") Log("#####################################################") If checkIfTableExists(ruta&"_puntos") Then db.ExecNonQuery($"delete from ${ruta}_punteo"$) punteoLista.Initialize Private c As ResultSet = db.ExecQuery($"select * from ${ruta}_puntos limit 1"$) Do While c.NextRow db.ExecNonQuery($"insert into ${ruta}_punteo (pos, id, nombre, lat, lon) values ('0', '${c.GetString("id")}', 'Almacen', ${c.Getdouble("lat")}, ${c.Getdouble("lon")})"$) punteoLista.Add(c.GetString("id")) 'Lista para ruteoNearestInsertion, ponemos el primer punto de la lista de coordenadas. Loop ' Private c As ResultSet = db.ExecQuery($"select * from ${ruta}_puntos where id = 'CCINCIO' limit 1"$) ' Do While c.NextRow ' db.ExecNonQuery($"insert into ${ruta}_punteo (pos, id, nombre, lat, lon) values ('0', '${c.GetString("id")}', 'Almacen', ${c.Getdouble("lat")}, ${c.Getdouble("lon")})"$) ' Loop ' c.Close ' punteoLista.Add("CCINICIO") If final <> "" Then ' Si en los parametros se especifica un punto de destino (punto final), se agrega aqui a la lista, se agrega como segundo punto, porque todos los demas puntos de la lista se van a agregar ENTRE estos dos puntos iniciales. Log("Agregamos punto final.") Private pf() As String = Regex.Split(",", final) ' Obtenemos id, lon y lat. Private c As ResultSet = db.ExecQuery($"select * from ${ruta}_puntos where id = '_${pf(0)}' limit 1"$) Do While c.NextRow db.ExecNonQuery($"insert into ${ruta}_punteo (pos, id, nombre, lat, lon) values ('0', '${c.GetString("id")}', 'Almacen', ${c.Getdouble("lat")}, ${c.Getdouble("lon")})"$) Loop punteoLista.Add("_" & pf(0)) c.Close End If Private cualAlgoritmo As String = "" 'ignore Log($"Usamos matriz |${matriz}|"$) If algoritmo = 1 Then ruteoNearestInsertion(ruta, matriz) cualAlgoritmo = " (NI)" Else If algoritmo = 0 Then Log(3) ruteoNearestNeighbor(ruta, matriz) cualAlgoritmo = " (NN)" Else ruteoNearestInsertion2 cualAlgoritmo = " (NI2)" End If End If End Sub Private Sub b_verRuta_Click ' verRuta("R1") End Sub Sub verRuta(ruta As String) 'ignore Log("#######################################################") Log("############# Main/verRuta ####################") Log("#######################################################") Private r As ResultSet = db.ExecQuery($"select * from ${ruta}_punteo"$) Private coords2 As String = "" Do While r.NextRow If coords2 = "" Then coords2 = $"${r.GetString("lon")},${r.GetString("lat")}"$ Else coords2 = $"${coords2}:${r.GetString("lon")},${r.GetString("lat")}"$ End If Loop Log($"http://keymon.lat:9001/kmz.php?a=1&c=${coords2}"$) ' fx.ShowExternalDocument($"https://osm.quelltextlich.at/viewer-js.html?kml_url=https://pi.famguerra.com/kmz.php?c=${coords2}"$) ' r = db.ExecQuery("select * from ${ruta}_punteo") ' Private coords2 As String = "" ' Do While r.NextRow ' If coords2 = "" Then ' coords2 = $"${r.GetString("lon")},${r.GetString("lat")}"$ ' Else ' coords2 = $"${coords2};${r.GetString("lon")},${r.GetString("lat")}"$ ' End If ' Loop ' fx.ShowExternalDocument($"http://router.project-osrm.org/route/v1/driving/${coords2}?overview=false"$) End Sub Private Sub b_tiempos_Click ' tiempos("R1") End Sub 'Regresa El tiempo y distancia de la ruta especificada. Sub tiempos(ruta As String) As ResumableSub 'ignore Log("#######################################################") Log("############# Main/tiempos ####################") Log("#######################################################") ' Log("Tiempos: " & ruta) If checkIfTableExists(ruta&"_punteo") Then Private c As ResultSet = db.ExecQuery($"select * from ${ruta}_punteo"$) Private estasCoords As String = "" 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 Private d() As String d = Regex.Split(";", estasCoords) ' Log("$$$$$$ " & d.Length) Log($"http://router.project-osrm.org/route/v1/driving/${estasCoords}"$) Dim j As HttpJob j.Initialize("", Me) j.Download($"http://router.project-osrm.org/route/v1/driving/${estasCoords}"$) Wait For (j) JobDone(j As HttpJob) If j.Success Then Log("RESPONSE:") Log(j.GetString) Private j0 As String = j.GetString End If j.Release ' StopMessageLoop Private js As JSONParser js.Initialize(j0) Log(j0) ' Log("*****************************************") ' Log(js) '' For Each colroot As Map In js '' Log(colroot) '' Next ' Log("*****************************************") ts.Put(ruta, CreateMap("code":"KO", "duration":0, "distance":0, "puntos":0)) Try Private m As Map = js.NextObject Log(m) 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) 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) If error = "" Then error = LastException End Try End If Return 1 End Sub 'Nearest Neighbor 'The nearest neighbor heuristic Is another greedy algorithm, Or what some may call naive. 'It starts at one city And connects with the closest unvisited city. It repeats until every city has been visited. 'It Then returns To the starting city. Sub ruteoNearestNeighbor(ruta As String, matriz As String) 'ignore Log("Usamos Nearest Neighbor") Log("####################################################################") Log("############# Main/ruteoNearestNeighbor ####################") Log("####################################################################") Dim g As ResultSet Private x As ResultSet = db.ExecQuery($"select id from ${ruta}_puntos"$) Do While x.NextRow 'Ejecutamos el siguiente codigo la cantidad de veces que hay puntos. Private punto As ResultSet = db.ExecQuery($"select id, count(id) as regs from ${ruta}_punteo order by pos DESC limit 1"$) Do While punto.NextRow ' Log($"Select idt, '${punto.GetString("id")}', nombre, lat, lon from R1_matriz join R1_puntos on idT = id where idT Not in (Select id from r1_punteo) order by '${punto.GetString("id")}' Asc limit 1"$) g = db.ExecQuery($"Select idt, '${punto.GetString("id")}', nombre, lat, lon from ${ruta}_matriz${matriz} join ${ruta}_puntos on idT = id where idT Not in (Select id from ${ruta}_punteo) order by '${punto.GetString("id")}' Asc limit 1"$) Do While g.NextRow db.ExecNonQuery($"insert into ${ruta}_punteo (pos, id, nombre, lat, lon) values (${punto.GetString("regs")}, '${g.GetString("idT")}', '${g.GetString("nombre")}', '${g.GetString("lat")}', '${g.GetString("lon")}')"$) Loop Loop Loop End Sub 'Nearest Insertion 'The insertion algorithms add new points between existing points on a tour As it grows. 'One implementation of Nearest Insertion begins with two cities. 'It then repeatedly finds the city not already in the tour that Is closest to any city in the tour, 'and places it between whichever two cities would cause the resulting tour to be the shortest possible. 'It stops when no more insertions remain. Sub ruteoNearestInsertion(ruta As String, matriz As String) 'ignore Log($"Usamos Nearest Insertion - Matriz ${matriz}"$) Log("#####################################################################") Log("############# Main/ruteoNearestInsertion ####################") Log("#####################################################################") Log(punteoLista) If final = "" Then 'Si no esta especificado un destino final, se toman las coordenadas del punto mas cercano al punto de inicio. Private a As ResultSet = db.ExecQuery($"Select idt, ${punteoLista.Get(0)} as laCol, nombre, lat, lon from ${ruta}_matriz${matriz} join ${ruta}_puntos on idT = id where idT <> '${punteoLista.Get(0)}' order by ${punteoLista.Get(0)} asc limit 1"$) Log($"Select idt, ${punteoLista.Get(0)} as laCol, nombre, lat, lon from ${ruta}_matriz${matriz} join ${ruta}_puntos on idT = id where idT <> '${punteoLista.Get(0)}' order by ${punteoLista.Get(0)} asc limit 1"$) Log(a.GetString("idt")) If punteoLista.IndexOf(a.GetString("idt")) = -1 Then Log($"Agregamos ${a.GetString("idt")}"$) punteoLista.Add(a.GetString("idt")) 'Agregamos el punto mas cercano al almacen. End If End If Private d As ResultSet = db.ExecQuery($"select count(id) as regs from ${ruta}_puntos"$) 'Obtenemos el total de puntos. Log(lis2string(punteoLista)) Private b, c, e As ResultSet 'ignore ' Log(d.GetInt("regs")) For k = 0 To d.GetInt("regs") - 1 'Bucle por el total de puntos en la ruta. Private minimo As Double = 100000000 'Inicializamos con un numero alto para que asigne el primer "minimo" que encuentre. Private elMasCercano = "", elAnterior = "", estePar = "" As String 'ignore ' Log(punteoLista.Size &"|"&d.GetInt("regs")) Private cuantosPuntos As Int = d.GetInt("regs") ' cuantosPuntos = 21 Log(punteoLista) If punteoLista.Size < cuantosPuntos Then 'Si hay puntos fuera de la ruta ... For j = 0 To punteoLista.Size - 2 ' Log(">>>>>>>>>>>>>>>>>>>>>> ${j} | ${j-2}") 'Buscamos el punto mas cercano (de los que no estan en la lista) a los dos puntos que estamos usando en esta vuelta del bucle. Private b1 As ResultSet = db.ExecQuery($"Select idT, ${punteoLista.Get(j)} as elMinimo from ${ruta}_matriz${matriz} where idT Not in (${lis2string(punteoLista)}) order by ${punteoLista.Get(j)} Asc limit 1"$) ' Log($"Select idT, ${punteoLista.Get(j)} as elMinimo from ${ruta}_matriz${matriz} where idT Not in (${lis2string(punteoLista)}) order by ${punteoLista.Get(j)} Asc limit 1"$) ' Log(b1.GetString("elMinimo")) c = db.ExecQuery($"Select idT, "${punteoLista.Get(j+1)}" as elMinimo from ${ruta}_matriz${matriz} where idT Not in (${lis2string(punteoLista)}) order by "${punteoLista.Get(j+1)}" Asc limit 1"$) ' Log($"Select idT, "${punteoLista.Get(j)}" as elMinimo from ${ruta}_matriz${matriz} where idT Not in (${lis2string(punteoLista)}) order by "${punteoLista.Get(j)}" Asc limit 1"$) ' Log($"Select idT, "${punteoLista.Get(j+1)}" as elMinimo from ${ruta}_matriz${matriz} where idT Not in (${lis2string(punteoLista)}) order by "${punteoLista.Get(j+1)}" Asc limit 1"$) ' Log(b1.NextRow) Do While b1.NextRow 'Si b1 regresa registro ' Log("yyy") If b1.GetDouble("elMinimo") < minimo Or c.GetDouble("elMinimo") < minimo Then minimo = b1.GetDouble("elMinimo") If c.GetDouble("elMinimo") < minimo Then minimo = c.GetDouble("elMinimo") elMasCercano = b1.GetString("idT") elAnterior = punteoLista.Get(j) estePar = $"${punteoLista.Get(j)}|${punteoLista.Get(j+1)}"$ End If Loop Next End If If elMasCercano <> "" Then Log($"${elMasCercano}, ${estePar}"$) punteoLista.InsertAt(punteoLista.IndexOf(elAnterior)+1, elMasCercano) End If Next Log(punteoLista) db.ExecNonQuery($"delete from ${ruta}_punteo"$) For h = 0 To punteoLista.Size - 1 e = db.ExecQuery($"select * from ${ruta}_puntos where id = '${punteoLista.Get(h)}'"$) Do While e.NextRow db.ExecNonQuery($"insert into ${ruta}_punteo (pos, id, nombre, lat, lon) values (${h}, '${e.GetString("id")}', '${e.GetString("nombre")}', '${e.GetString("lat")}', '${e.GetString("lon")}')"$) ' Log($"insert into ${ruta}_punteo (pos, id, nombre, lat, lon) values (${h}, '${e.GetString("id")}', '${e.GetString("nombre")}', '${e.GetString("lat")}', '${e.GetString("lon")}')"$) Loop Next Log("Terminamos Nearest Insertion") End Sub 'Nearest Insertion 'The insertion algorithms add new points between existing points on a tour As it grows. 'One implementation of Nearest Insertion begins with two cities. 'It then repeatedly finds the city not already in the tour that Is closest to any city in the tour, 'and places it between whichever two cities would cause the resulting tour to be the shortest possible. 'It stops when no more insertions remain. Sub ruteoNearestInsertion2 'ignore ' Log("Usamos Nearest Insertion 2") '' Log($"Select idt, "${punteoLista.Get(0)}" as laCol, nombre, lat, lon from R1_matriz join R1_puntos on idT = id where idT <> ${punteoLista.Get(0)} order by "${punteoLista.Get(0)}" desc limit 1"$) ' Private a As ResultSet = db.ExecQuery($"Select idt, "${punteoLista.Get(0)}" as laCol, nombre, lat, lon from R1_matriz${matriz} join R1_puntos on idT = id where idT <> ${punteoLista.Get(0)} order by "${punteoLista.Get(0)}" asc limit 1"$) ' If punteoLista.IndexOf(a.GetString("idt")) = -1 Then punteoLista.Add(a.GetString("idt")) 'Agregamos el punto mas cercano al almacen. ' Private d As ResultSet = db.ExecQuery("select count(id) as regs from R1_puntos") 'Obtenemos el total de puntos. '' Log(lis2string(punteoLista)) ' Private b, c, e As ResultSet '' Log(d.GetInt("regs")) ' For k = 0 To d.GetInt("regs") - 1 'Bucle por el total de puntos en la ruta. ' Private minimo As Double = 100000000 'Inicializamos con un numero alto para que asigne el primer "minimo" que encuentre. ' Private elMasCercano = "", elAnterior = "", estePar = "" As String ' Log(punteoLista.Size &"|"&d.GetInt("regs")) ' Private cuantosPuntos As Int = d.GetInt("regs") '' cuantosPuntos = 21 ' If punteoLista.Size < cuantosPuntos Then 'Si hay puntos fuera de la ruta ... ' For j = 0 To punteoLista.Size - 2 ' 'Buscamos el punto mas cercano (de los que no estan en la lista) a los dos puntos que estamos usando en esta vuelta del bucle. ' b = db.ExecQuery($"Select idT, "${punteoLista.Get(j)}" as elMinimo from R1_matriz${matriz} where idT Not in (${lis2string(punteoLista)}) order by "${punteoLista.Get(j)}" Asc limit 1"$) ' c = db.ExecQuery($"Select idT, "${punteoLista.Get(j+1)}" as elMinimo from R1_matriz${matriz} where idT Not in (${lis2string(punteoLista)}) order by "${punteoLista.Get(j+1)}" Asc limit 1"$) ' If b.NextRow Then 'Si b regresa registro ' If b.GetDouble("elMinimo") < minimo Or c.GetDouble("elMinimo") < minimo Then ' minimo = b.GetDouble("elMinimo") ' If c.GetDouble("elMinimo") < minimo Then minimo = c.GetDouble("elMinimo") ' elMasCercano = b.GetString("idT") ' elAnterior = punteoLista.Get(j) ' estePar = $"${punteoLista.Get(j)}|${punteoLista.Get(j+1)}"$ ' End If ' End If ' Next ' End If ' If elMasCercano <> "" Then '' Log($"${elMasCercano}, ${estePar}"$) ' punteoLista.InsertAt(punteoLista.IndexOf(elAnterior)+1, elMasCercano) ' End If ' Next ' Log(punteoLista) ' db.ExecNonQuery("delete from R1_punteo") ' For h = 0 To punteoLista.Size - 1 ' e = db.ExecQuery($"select * from R1_puntos where id = '${punteoLista.Get(h)}'"$) ' Do While e.NextRow ' db.ExecNonQuery($"insert into R1_punteo (pos, id, nombre, lat, lon) values (${h}, '${e.GetString("id")}', '${e.GetString("nombre")}', '${e.GetString("lat")}', '${e.GetString("lon")}')"$) ' Loop ' Next End Sub 'Calculate distance - Haversine 'Using average radius of earth 6378.137 km. Sub calculateDistance1(Latitude1 As Double, Longitude1 As Double, Latitude2 As Double, Longitude2 As Double) As Double 'ignore Return NumberFormat2(2 * 6378137 * ASin (Sqrt (SinD ((Latitude2 - Latitude1) * 0.5) * SinD ((Latitude2 - Latitude1) * 0.5) + CosD (Latitude1) * CosD (Latitude2) * SinD ((Longitude2 - Longitude1) * 0.5) * SinD ((Longitude2 - Longitude1) * 0.5))), 1, 2, 2, False) End Sub Sub calculateDistance2(Latitude1 As Double, Longitude1 As Double, Latitude2 As Double, Longitude2 As Double) As Double 'ignore Dim EarthRadius, Angle, distance As Double EarthRadius = 6378.137 ' WGS -84 kilometers? Angle = ACos(SinD(Latitude1) * SinD(Latitude2) + CosD(Latitude1) * CosD(Latitude2) * CosD(Longitude2 - Longitude1)) distance = EarthRadius * Angle Return distance * 1000 End Sub Public Sub calculateDistance3(lat1 As Double, lon1 As Double, lat2 As Double, lon2 As Double) As Double 'ignore Try Dim Miles As Double Dim Yards As Double Dim X As Double Dim Coeff As Double= 1760.0 X = Sin(lat1 * 0.01745) * Sin(lat2 * 0.01745) + Cos(lat1 * 0.01745)* Cos(lat2 * 0.01745) * Cos(( lon2 - lon1 ) * 0.01745) Miles = 1.15 * 3963 * ( ATan(-X / Sqrt(-X * X+ 1.0000000000001)) + 2* ATan(1) ) ' Miles = Round2(Miles, 2) Yards = Miles * Coeff Return Round(Yards) Catch Log("CalcDistance " & LastException) if error = "" then error = LastException Return -1 End Try End Sub Sub lis2string(l As List) As String 'ignore Private s As String = "" For i = 0 To l.Size - 1 If s = "" Then s = $"'${l.get(i)}'"$ Else s = $"${s}, '${l.get(i)}'"$ End If Next Return s End Sub Private Sub cb_algorithm_SelectedIndexChanged(Index As Int, Value As Object) '' Log(Index) ' algoritmo = Index End Sub Private Sub cb_api_SelectedIndexChanged(Index As Int, Value As Object) ' api = Index ' If Index = 0 Then matriz = "" Else matriz = "OSRM" End Sub 'Revisamos que la tabla exista. Sub checkIfTableExists(table As String) As Boolean ' B4XPages.MainPage.db.InitializeSQLite(File.DirApp, "kmt.db", True) Private r As ResultSet = 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