Files
Ruteador-NonUI/Ruteador-NonUI.b4j

675 lines
30 KiB
Plaintext

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