mirror of
https://github.com/KeymonSoft/Izca_Reparto_Creditos.git
synced 2026-04-17 12:56:21 +00:00
688 lines
29 KiB
QBasic
688 lines
29 KiB
QBasic
B4A=true
|
|
Group=Default Group
|
|
ModulesStructureVersion=1
|
|
Type=Class
|
|
Version=12.2
|
|
@EndOfDesignText@
|
|
Sub Class_Globals
|
|
Private Root As B4XView 'ignore
|
|
Private xui As XUI 'ignore
|
|
Dim q_buscar As String
|
|
' Dim skmt As SQL
|
|
Dim entro As String
|
|
Dim c As Cursor
|
|
Dim c2 As Cursor
|
|
Dim ListView1 As ListView
|
|
' Dim gest As Button
|
|
Dim lfila As Label
|
|
Dim busca As EditText
|
|
Private p_colonia As Panel
|
|
' Dim distList As List
|
|
' Dim distMap As Map
|
|
Dim laRuta As String
|
|
Private b_GetDirs As Button
|
|
Private distOrderedMap, clientesMapaO As B4XOrderedMap
|
|
Private img_getDirs As ImageView
|
|
Private l_rutaInfo As Label
|
|
Private b_getRutaInfo As Button
|
|
Private conMapa As Boolean = False
|
|
Dim listaWayPoints As List
|
|
Dim lv1Top As String
|
|
Private b_limpiarRuta As Button
|
|
Dim rutaGenerada As Boolean = False
|
|
Dim rutaacambiar As String
|
|
End Sub
|
|
|
|
'You can add more parameters here.
|
|
Public Sub Initialize As Object
|
|
Return Me
|
|
End Sub
|
|
|
|
'This event will be called once, before the page becomes visible.
|
|
Private Sub B4XPage_Created (Root1 As B4XView)
|
|
Root = Root1
|
|
'load the layout to Root
|
|
Root.LoadLayout("clientes")
|
|
entro ="2"
|
|
lv1Top = ListView1.Top
|
|
clientesMapaO.Initialize
|
|
Starter.skmt.ExecNonQuery("delete from waypoints")
|
|
Log("Coordenadas del almacen: " & Starter.cedisLocation.Longitude & "," & Starter.cedisLocation.Latitude)
|
|
End Sub
|
|
|
|
'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.
|
|
|
|
Sub B4XPage_Appear
|
|
busca.Text = ""
|
|
b_GetDirs.Visible = False
|
|
' skmt.Initialize(Starter.ruta,"kmt.db", True)
|
|
entro ="2"
|
|
' esto es para rutas se quito por colonia
|
|
'SE COMENTA EL SIGUIENTE CODIGO PARA QUE TODAS LAS TIENDAS APAREZCAN.
|
|
'c=skmt.ExecQuery("select CAT_CL_COLONIA, count(*) as cuantos from kmt_info where gestion = 0 group by CAT_CL_COLONIA order by CAT_CL_COLONIA asc")
|
|
p_colonia.Width = Root.Width
|
|
p_colonia.Height = Root.Height
|
|
p_colonia.Top = 0
|
|
p_colonia.Left = 0
|
|
Subs.centraListView(ListView1, p_colonia.Width)
|
|
ListView1.Height = p_colonia.Height * 0.75
|
|
Subs.SetDivider(ListView1, Colors.LightGray, 2)
|
|
If Not(l_rutaInfo.Visible) Then
|
|
ListView1.Top = lv1Top
|
|
Else
|
|
ListView1.Top = lv1Top + 100
|
|
End If
|
|
c=Starter.skmt.ExecQuery("select codigo, indice, CAT_CL_NOMBRE, CAT_CL_CALLE, CAT_CL_NOEXT from waypoints inner join kmt_info on waypoints.codigo = kmt_info.CAT_CL_CODIGO where gestion = 0 AND CAT_CL_RUTA <> 1000 order by indice")
|
|
If c.RowCount > 0 Then 'Ya hay waypoints en la base de datos
|
|
c.Position = 0
|
|
' Log("Ya hay waypoints.")
|
|
conMapa = True
|
|
' Private t1 As Map
|
|
ListView1.Clear
|
|
Dim cs, cs2 As CSBuilder
|
|
entro = 3
|
|
' Log("Generamos ListView1 en Activity_Resume")
|
|
For i=0 To c.RowCount -1 'Generamos el listView con la lista ordenada.
|
|
c.Position=i
|
|
cs.Initialize
|
|
cs2.Initialize
|
|
' t1 = Starter.waypointsOrdered.Get(k)
|
|
' c.GetString("codigo")
|
|
' Log(c.GetString("indice"))
|
|
ListView1.AddTwoLines(cs.Color(Colors.RGB(100,149,237)).Append(c.GetString("codigo")).PopAll, cs2.append(c.GetString("CAT_CL_NOMBRE")).Color(Colors.RGB(100,149,237)).Append(" Calle: ").Pop.Append(c.GetString("CAT_CL_CALLE").Trim & " " & c.GetString("CAT_CL_NOEXT")).PopAll )
|
|
Next
|
|
Else
|
|
generaListViewRutas
|
|
End If
|
|
c.Close
|
|
p_colonia.Width = Root.Width
|
|
p_colonia.Height = Root.Height
|
|
Subs.centraEtiqueta(l_rutaInfo, Root.Width)
|
|
Subs.centraListView(ListView1, p_colonia.Width)
|
|
ListView1.Height = p_colonia.Height * 0.70
|
|
Subs.centraEtiqueta(lfila, Root.Width)
|
|
b_getRutaInfo.Visible = True
|
|
b_getRutaInfo.BringToFront
|
|
If Starter.cedisLocation.Latitude = "0" Then
|
|
Private x As Cursor = Starter.skmt.ExecQuery("select * from CAT_VARIABLES where CAT_VA_DESCRIPCION = 'COORDS_ALMACEN'")
|
|
If x.RowCount > 0 Then
|
|
x.Position = 0
|
|
Private y() As String
|
|
Starter.cedisLocation.Latitude = Regex.Split(",", x.GetString("CAT_VA_VALOR"))(1)
|
|
Starter.cedisLocation.Longitude = Regex.Split(",", x.GetString("CAT_VA_VALOR"))(0)
|
|
End If
|
|
End If
|
|
Log(Starter.cedisLocation)
|
|
End Sub
|
|
|
|
|
|
Private Sub B4XPage_CloseRequest As ResumableSub
|
|
' BACK key pressed
|
|
'Return True to close, False to cancel
|
|
Log(entro)
|
|
If rutaGenerada Or entro = 3 Then ' Si ya generamos el ruteo o entramos a una de las rutas, nos regresamos!
|
|
b_limpiarRuta_Click
|
|
l_rutaInfo.Text = ""
|
|
rutaGenerada = False
|
|
else if entro = 2 Then ' Si estamos mostrando las rutas, nos regresamos a la principal.
|
|
B4XPages.ShowPage("Principal")
|
|
End If
|
|
Return False
|
|
End Sub
|
|
|
|
Sub ListView1_ItemClick (Position As Int, Value As Object)
|
|
' Log($"Entro= ${entro}"$)
|
|
Log(Value)
|
|
ListView1.Clear
|
|
Sleep(50)
|
|
Subs.SetDivider(ListView1, Colors.LightGray, 2)
|
|
If Not(l_rutaInfo.Visible) Then
|
|
ListView1.Top = lv1Top
|
|
Else
|
|
ListView1.Top = lv1Top + 100
|
|
End If
|
|
l_rutaInfo.Visible = False
|
|
b_GetDirs.Visible = False
|
|
If entro = "2" Then
|
|
' b_GetDirs.Visible = True
|
|
' img_getDirs.Visible = True
|
|
' b_getRutaInfo.Visible = False
|
|
Private lrt As String
|
|
lrt = Value
|
|
laRuta = lrt.SubString(6) 'Quitamos el texto "Ruta: " para obtener el numero de la ruta.
|
|
Log($"Original: ${Value} - Mod: |${lrt.SubString(6)}| - laRuta: ${laRuta}"$)
|
|
rutaacambiar = laRuta
|
|
c2 = Starter.skmt.ExecQuery2("select CAT_CL_NOMBRE, CAT_CL_CALLE, CAT_CL_CODIGO, CAT_CL_LAT, CAT_CL_LONG from kmt_info where CAT_CL_RUTA = ? and gestion = 0 AND CAT_CL_RUTA <> 1000 order by CAT_CL_NOMBRE ", Array As String(laRuta))
|
|
Private thisLoc As Location
|
|
Private label1 As Label
|
|
Private label2 As Label
|
|
label1 = ListView1.TwoLinesLayout.Label
|
|
label1.TextSize = 15
|
|
label1.TextColor = Colors.black
|
|
label2 = ListView1.TwoLinesLayout.SecondLabel
|
|
label2.TextSize = 15
|
|
label2.TextColor = Colors.black
|
|
label2.Height = 57dip
|
|
thisLoc.Initialize
|
|
If entro = 2 Then ListView1.TwoLinesLayout.ItemHeight = 90dip
|
|
lfila.text = "Nombre y Calle"
|
|
distOrderedMap.Initialize
|
|
If c2.RowCount > 0 Then
|
|
For i = 0 To c2.RowCount -1 'Generamos mapa de clientes
|
|
c2.Position = i
|
|
thisLoc.Latitude = c2.GetString("CAT_CL_LAT")
|
|
thisLoc.Longitude = c2.GetString("CAT_CL_LONG")
|
|
' Log(Tracker.UUGCoords)
|
|
Private distancia As Int = Tracker.UUGCoords.DistanceTo(thisLoc) 'Calculamos la distancia de la posicion ACTUAL a la tienda.
|
|
Private esteCliente As Map = CreateMap("distancia": distancia, "ubicacion": thisLoc.Longitude&","&thisLoc.Latitude, "codigo": c2.GetString("CAT_CL_CODIGO"), "nomDirDist": $"${c2.GetString("CAT_CL_NOMBRE")} CALLE: ${c2.GetString("CAT_CL_CALLE")} ${CRLF}Distancia: $1.1{(distancia/1000)} kms"$)
|
|
distOrderedMap.Put(distancia, esteCliente)
|
|
Next
|
|
distOrderedMap.Keys.Sort(True) 'Ordenamos la mapa de clientes por distancia.
|
|
ListView1.Clear
|
|
Private m1 As Map
|
|
For Each k As Object In distOrderedMap.Keys 'Generamos el listView con el mapa ordenada.
|
|
m1 = distOrderedMap.Get(k)
|
|
m1.Get("codigo")
|
|
' Log(m1.Get("nomDirDist"))
|
|
ListView1.AddTwoLines(m1.Get("codigo"), m1.Get("nomDirDist"))
|
|
Next
|
|
End If
|
|
c2.Close
|
|
entro = "3"
|
|
Else If entro = "3" Then
|
|
' LogColor("Guardamos CLIENTE " & Value, Colors.red)
|
|
Starter.skmt.ExecNonQuery("delete from CUENTAA")
|
|
Starter.skmt.ExecNonQuery2("INSERT INTO CUENTAA VALUES (?)", Array As Object(Value))
|
|
B4XPages.ShowPage("Cliente")
|
|
End If
|
|
End Sub
|
|
|
|
'Genera el listview que muestra las rutas y clientes a visitar por ruta.
|
|
Sub generaListViewRutas
|
|
ListView1.Clear
|
|
Sleep(110)
|
|
lfila.Text = "RUTA PREVENTA"
|
|
Dim label1 As Label
|
|
label1 = ListView1.TwoLinesLayout.Label
|
|
label1.TextSize = 15
|
|
label1.TextColor = Colors.Black
|
|
Dim label2 As Label
|
|
label2 = ListView1.TwoLinesLayout.SecondLabel
|
|
label2.TextSize = 15
|
|
label2.TextColor = Colors.Black
|
|
ListView1.TwoLinesLayout.ItemHeight = 60dip
|
|
c=Starter.skmt.ExecQuery("select CAT_CL_RUTA, count(*) as cuantos from kmt_info where gestion = 0 AND CAT_CL_RUTA <> 1000 group by CAT_CL_RUTA order by CAT_CL_RUTA asc")
|
|
If c.RowCount>0 Then
|
|
ListView1.Clear
|
|
For i=0 To c.RowCount -1
|
|
c.Position=i
|
|
ListView1.AddTwoLines("Ruta: " & c.GetString("CAT_CL_RUTA"), "Por visitar: " & c.GetString("cuantos"))
|
|
Next
|
|
End If
|
|
c.Close
|
|
End Sub
|
|
|
|
Sub Activity_KeyPress (key As Int) As Boolean 'ignore
|
|
' BACK key pressed
|
|
If key=KeyCodes.KEYCODE_BACK Then
|
|
If entro = 3 And Not(conMapa) Then
|
|
b_GetDirs.Visible = False
|
|
' StartActivity(Activity_Create(False))
|
|
B4XPage_Created(Root)
|
|
Return True
|
|
End If
|
|
B4XPages.ShowPage("Principal")
|
|
Return False
|
|
'End If
|
|
End If
|
|
' Returning False signals the system to handle the key
|
|
End Sub
|
|
|
|
Sub BUSCA_TextChanged (Old As String, New As String)
|
|
q_buscar = "%" & busca.Text & "%"
|
|
c2=Starter.skmt.ExecQuery2("select CAT_CL_NOMBRE, CAT_CL_CALLE, CAT_CL_CODIGO from kmt_info where CAT_CL_NOMBRE like ? and gestion = 0 AND CAT_CL_RUTA <> 1000 order by CAT_CL_CODIGO ", Array As String(q_buscar))
|
|
ListView1.Clear
|
|
lfila.text = "Nombre y Calle"
|
|
Subs.SetDivider(ListView1, Colors.LightGray, 2)
|
|
If c2.RowCount>0 Then
|
|
For i=0 To c2.RowCount -1
|
|
c2.Position=i
|
|
Dim label1 As Label
|
|
label1 = ListView1.TwoLinesLayout.Label
|
|
label1.TextSize = 15
|
|
label1.TextColor = Colors.Black
|
|
Dim label2 As Label
|
|
label2 = ListView1.TwoLinesLayout.SecondLabel
|
|
label2.TextSize = 15
|
|
label2.TextColor = Colors.Black
|
|
ListView1.AddTwoLines(c2.GetString("CAT_CL_CODIGO"), c2.GetString("CAT_CL_NOMBRE") &" CALLE: "& c2.GetString("CAT_CL_CALLE"))
|
|
Next
|
|
End If
|
|
entro = "3"
|
|
c2.Close
|
|
End Sub
|
|
|
|
'Regresa la distancia y tiempo de la ruta entre dos puntos, usa el API del projecto OSRM. (Parte de la funcionalidad OSRM)
|
|
'Para mas información ir a esta liga:
|
|
'http://project-osrm.org/docs/v5.24.0/api/?language=cURL#route-service
|
|
Sub distanciaEntreCoords(id As String, coords1 As String, coords2 As String) As ResumableSub 'ignore
|
|
Sleep(1050)
|
|
Private distanciaTotal As String = "0"
|
|
Private tiempo As String = "0"
|
|
Dim j As HttpJob
|
|
j.Initialize("", Me)
|
|
j.Download("https://router.project-osrm.org/route/v1/driving/"&coords1&";"&coords2&"?overview=false")
|
|
Wait For (j) JobDone(j As HttpJob)
|
|
If j.Success Then
|
|
Dim jp As JSONParser
|
|
jp.Initialize(j.GetString)
|
|
Dim m As Map = jp.NextObject
|
|
Log($"Respuesta: ${m.Get("code")}"$)
|
|
If m.Get("code") = "Ok" Then
|
|
' Log(m)
|
|
Dim rutas As List = m.Get("routes")
|
|
Dim rutas2 As Map = rutas.Get(0)
|
|
' Log(rutas2)
|
|
' Dim legs As List = rutas2.Get("legs")
|
|
' Log(legs)
|
|
distanciaTotal = rutas2.Get("distance")
|
|
tiempo = rutas2.Get("duration")
|
|
Log($"Distancia total: ${distanciaTotal}, Tiempo: ${tiempo}"$ )
|
|
End If
|
|
Else
|
|
Log("Error!")
|
|
End If
|
|
j.Release
|
|
Private r As List
|
|
r.Initialize
|
|
r.Add(id)
|
|
r.Add(distanciaTotal)
|
|
r.Add(tiempo)
|
|
Return r
|
|
End Sub
|
|
|
|
'Regresa la distancia y tiempo estimado de la ruta del repartidor, utiliza el API del projecto OSRM
|
|
'para calcular la distancia y tiempo de la ruta de un mapa de coordenadas a visitar dado. (Parte de la funcionalidad OSRM)
|
|
Sub traeRutaDia(aVisitar As B4XOrderedMap)
|
|
Private coordsInicio As String = $"${Starter.cedisLocation.Longitude},${Starter.cedisLocation.Latitude}"$
|
|
Log($"Coordenadas de inicio: ${Starter.cedisLocation.Longitude},${Starter.cedisLocation.Latitude}"$)
|
|
Private rutaCompleta As String = coordsInicio
|
|
Private preRuta As String = coordsInicio
|
|
Private distanciaTotal, distanciaTotal0, tiempo0, tiempo As Double
|
|
Private masDe100 As Boolean
|
|
Private m4 As Map
|
|
Private visitaActual As Int = 0
|
|
Private cuantosAntes As Int = 0
|
|
listaWayPoints.Initialize
|
|
If aVisitar.Keys.Size > 98 Then 'Si los clientes a visitar son mas de 100 entonces hacemos 2 rutas, una inicial con pocas visitas (las que pasen de 100) y la final con el resto ...
|
|
cuantosAntes = aVisitar.Keys.Size - 98 'Definimos de cuantos clientes va a ser la ruta inicial.
|
|
preRuta = coordsInicio 'Ponemos las coordenadas de inicio (Las del CEDIS).
|
|
rutaCompleta = ""
|
|
masDe100 = True
|
|
End If
|
|
Log($"a visitar: ${aVisitar.Keys.Size}"$)
|
|
For Each k As Object In aVisitar.Keys
|
|
visitaActual = visitaActual + 1
|
|
m4 = aVisitar.Get(k)
|
|
' Log($"visitaActual: ${visitaActual} - cuantosAntes: ${cuantosAntes}"$)
|
|
If visitaActual < cuantosAntes + 2 Then 'Si estas coordenadas son de la ruta inicial las agregamos ...
|
|
preRuta = preRuta & ";" & m4.Get("coords")
|
|
' LogColor($"PreRuta - visitaActual: ${visitaActual} - coords: ${m4.Get("coords")}"$, Colors.Magenta)
|
|
End If
|
|
If visitaActual >= cuantosAntes + 2 Then 'Si estas coordenadas son de la ruta final las agregamos ...
|
|
rutaCompleta = rutaCompleta & ";" & m4.Get("coords")
|
|
' LogColor($"RutaCompleta - visitaActual: ${visitaActual} - coords: ${m4.Get("coords")} - testRuta Size: ${testRutaCompleta.size}"$, Colors.Green)
|
|
End If
|
|
Next
|
|
rutaCompleta = rutaCompleta & ";" & coordsInicio 'Agregamos las coordenadas del CEDIS al final para que sea viaje ida y vuelta.
|
|
' rutaCompleta = rutaCompleta & ";" & coordsInicio
|
|
If rutaCompleta.StartsWith(";") Then rutaCompleta = rutaCompleta.SubString(1) 'Si las cooredenadas tienen ";" al principio se lo quitamos.
|
|
' LogColor(preRuta, Colors.magenta)
|
|
' LogColor(rutaCompleta, Colors.Green)
|
|
ProgressDialogShow2("Calculando distancia y tiempo, un momento por favor.", False)
|
|
Private tiempoVisitas As Double 'TIMEPO DE 4 MINUTOS PROMEDIO POR TIENDA ESTO SE CAMBIA SEGUN EL CLIENTE
|
|
tiempoVisitas = aVisitar.Keys.Size * 4 * 60 'Aqui se calcula el tiempo que duran las visitas x 4 mins cada una en segundos.
|
|
tiempo0 = 0
|
|
distanciaTotal0 = 0
|
|
If masDe100 Then 'Si son mas de 100, entonces primero calculamos la ruta inicial.
|
|
Dim j0 As HttpJob
|
|
j0.Initialize("trip0", Me)
|
|
j0.Download("https://router.project-osrm.org/trip/v1/driving/"&preRuta&"?source=first&destination=last&roundtrip=false&geometries=geojson")
|
|
' LogColor("https://router.project-osrm.org/trip/v1/driving/"&preRuta&"?source=first&destination=last&roundtrip=false&geometries=geojson", Colors.Magenta)
|
|
Wait For (j0) JobDone(j0 As HttpJob)
|
|
If j0.Success Then
|
|
Dim jp0 As JSONParser
|
|
jp0.Initialize(j0.GetString)
|
|
Dim m0 As Map = jp0.NextObject
|
|
If m0.Get("code") = "Ok" Then
|
|
Dim puntos0 As List = m0.Get("waypoints")
|
|
Private esteWayPoint0 As Map
|
|
For p = 0 To puntos0.Size -1
|
|
esteWayPoint0 = puntos0.Get(p)
|
|
' LogColor("WP:" & esteWayPoint0, Colors.magenta)
|
|
' LogColor("WP: " & esteWayPoint0.Get("waypoint_index") & ", loc: " & esteWayPoint0.Get("location") & ", name: " & esteWayPoint0.Get("name"), Colors.Magenta)
|
|
esteWayPoint0.Remove("hint")
|
|
esteWayPoint0.Remove("distance")
|
|
esteWayPoint0.Remove("trips_index")
|
|
listaWayPoints.Add(esteWayPoint0)
|
|
' LogColor("estewaypoint: "&esteWayPoint0, Colors.Magenta)
|
|
Next
|
|
Dim rutas0 As List = m0.Get("trips")
|
|
Dim rutas20 As Map = rutas0.Get(0)
|
|
' Dim geometry0 As Map = rutas20.Get("geometry")
|
|
' Private coords0 As List = geometry0.Get("coordinates")
|
|
distanciaTotal0 = rutas20.Get("distance")
|
|
tiempo0 = rutas20.Get("duration")
|
|
tiempo0 = ((tiempo0 * 2) ) 'Tiempo X 2 (es muy corto porque no toma encuenta el trafico).
|
|
Log($"Distancia total ruta inicial: $1.1{distanciaTotal0/1000} kms, tiempo aprox: $1.1{tiempo0/60} mins. ($1.1{tiempo0/60/60} hrs)"$)
|
|
' l_rutaInfo.Text = $"Distancia total: $1.1{distanciaTotal0/1000} kms, tiempo aprox: $1.1{tiempo0/60/60} hrs"$
|
|
End If
|
|
Else
|
|
Log("Error!")
|
|
End If
|
|
j0.Release
|
|
End If
|
|
|
|
Dim j As HttpJob
|
|
j.Initialize("trip", Me) 'Calculamos el resto de la ruta.
|
|
j.Download("https://router.project-osrm.org/trip/v1/driving/"&rutaCompleta&"?source=first&destination=last&roundtrip=false&geometries=geojson")
|
|
' LogColor("https://router.project-osrm.org/trip/v1/driving/"&rutaCompleta&"?source=first&destination=last&roundtrip=false&geometries=geojson", Colors.Green)
|
|
Wait For (j) JobDone(j As HttpJob)
|
|
If j.Success Then
|
|
Dim jp As JSONParser
|
|
jp.Initialize(j.GetString)
|
|
Dim m As Map = jp.NextObject
|
|
If m.Get("code") = "Ok" Then
|
|
Dim puntos As List = m.Get("waypoints")
|
|
Private esteWayPoint As Map
|
|
Dim twpi As Int
|
|
For p = 0 To puntos.Size -1
|
|
esteWayPoint = puntos.Get(p)
|
|
' LogColor("WP:" & esteWayPoint, Colors.green)
|
|
' LogColor("WP: " & esteWayPoint.Get("waypoint_index") & ", loc: " & esteWayPoint.Get("location") & ", name: " & esteWayPoint.Get("name"), Colors.Green)
|
|
esteWayPoint.Remove("hint")
|
|
esteWayPoint.Remove("distance")
|
|
esteWayPoint.Remove("trips_index")
|
|
twpi = esteWayPoint.Get("waypoint_index")
|
|
esteWayPoint.Remove("waypoint_index")
|
|
esteWayPoint.Put("waypoint_index", (twpi + cuantosAntes + 2))
|
|
listaWayPoints.Add(esteWayPoint)
|
|
' LogColor("estewaypoint: "&esteWayPoint, Colors.Green)
|
|
Next
|
|
Dim rutas As List = m.Get("trips")
|
|
Dim rutas2 As Map = rutas.Get(0)
|
|
distanciaTotal = rutas2.Get("distance")
|
|
Log("distancia ruta 2:" & (distanciaTotal) & "|" & rutas2.Get("distance"))
|
|
distanciaTotal = distanciaTotal + distanciaTotal0
|
|
tiempo = rutas2.Get("duration")
|
|
tiempo = (((tiempo + tiempo0) * 2) + tiempoVisitas) 'Tiempo X 2 (es muy corto porque no toma encuenta el trafico) + tiempoVisitas.
|
|
Log($"Distancia total: $1.1{distanciaTotal/1000} kms, tiempo aprox: $1.1{tiempo/60} mins. ($1.1{tiempo/60/60} hrs)"$)
|
|
l_rutaInfo.Text = $"Distancia: $1.1{distanciaTotal/1000} kms, tiempo aprox: $1.1{tiempo/60/60} hrs${CRLF}Visitas restantes: ${aVisitar.Keys.Size}"$
|
|
l_rutaInfo.Width = Root.Width * 0.9
|
|
Subs.centraEtiqueta(l_rutaInfo, Root.Width)
|
|
l_rutaInfo.Visible = True
|
|
l_rutaInfo.BringToFront
|
|
ListView1.Top = lv1Top + 100
|
|
End If
|
|
Else
|
|
LogColor("**************** Error! ******************", Colors.red)
|
|
End If
|
|
j.Release
|
|
ProgressDialogHide
|
|
' LogColor("clientesMapaO size: " & clientesMapaO.Size & "|" & listaWayPoints.Size, Colors.Blue)
|
|
Private r As Int = 1
|
|
Private r1, wps As Map
|
|
Starter.skmt.ExecNonQuery("delete from waypoints")
|
|
Log("BORRAMOS WAYPOINTS")
|
|
For Each k As Object In clientesMapaO.Keys 'Guardamos en la BD el orden de los waypoints para luego generar el listview.
|
|
If listaWayPoints.Size > 0 Then
|
|
r1 = clientesMapaO.Get(k)
|
|
r1.Get("codigo")
|
|
Log(listaWayPoints.Get(r) & "|" & r1.Get("coords") & "|" & r1.Get("calle"))
|
|
wps = listaWayPoints.Get(r)
|
|
Starter.skmt.ExecNonQuery($"update kmt_info set SECUENCIA = ${wps.get("waypoint_index")} where CAT_CL_CODIGO = '${r1.Get("codigo")}'"$)
|
|
Starter.skmt.ExecNonQuery2("insert into waypoints values (?,?)", Array As Object(r1.Get("codigo"), wps.get("waypoint_index")))
|
|
r = r + 1
|
|
End If
|
|
Next
|
|
ListView1.Clear
|
|
Sleep(100)
|
|
Dim label2 As Label
|
|
label2 = ListView1.TwoLinesLayout.SecondLabel
|
|
label2.TextSize = 15
|
|
label2.Height = 100dip
|
|
ListView1.TwoLinesLayout.ItemHeight = 70dip
|
|
Dim cs, cs2 As CSBuilder
|
|
entro = 3
|
|
Log("Generamos ListView1 en traeRutaDia")
|
|
'Traemos las visitas restantes ordenadas por el indice de waypoints (este indice nos indica el orden en la ruta calculada).
|
|
c=Starter.skmt.ExecQuery("select codigo, indice, CAT_CL_NOMBRE, CAT_CL_CALLE, CAT_CL_NOEXT from waypoints inner join kmt_info on waypoints.codigo = kmt_info.CAT_CL_CODIGO where gestion = 0 AND CAT_CL_RUTA <> 1000 order by indice")
|
|
If c.RowCount > 0 Then
|
|
For i=0 To c.RowCount -1 'Generamos el listView con la lista ordenada.
|
|
c.Position=i
|
|
cs.Initialize
|
|
cs2.Initialize
|
|
ListView1.AddTwoLines(cs.Color(Colors.RGB(100,149,237)).Append(c.GetString("codigo")).PopAll, cs2.append(c.GetString("CAT_CL_NOMBRE")).Color(Colors.RGB(100,149,237)).Append(" Calle: ").Pop.Append(c.GetString("CAT_CL_CALLE").Trim & " " & c.GetString("CAT_CL_NOEXT")).PopAll )
|
|
Next
|
|
End If
|
|
c.Close
|
|
End Sub
|
|
|
|
'Calcula distancia y tiempo de la ubicacion ACTUAL a las 8 primeras tiendas de la lista usando el API de OSRM. (Parte de la funcionalidad OSRM)
|
|
Private Sub b_GetDirs_Click
|
|
ProgressDialogShow("Calculando distancias y tiempos ...")
|
|
Private m2 As Map
|
|
Private f As Int = 0
|
|
For Each k As Object In distOrderedMap.Keys 'Traemos la distancia y tiempo desde OSRM (2 puntos)
|
|
m2 = distOrderedMap.Get(k)
|
|
Private distancia2 As String = m2.Get("distancia")
|
|
Private thisLoc1 As String = m2.Get("ubicacion")
|
|
Private locActual As String = Tracker.UUGCoords.Longitude&","&Tracker.UUGCoords.Latitude
|
|
If locActual = "0,0" Then 'Si no tenemos ubicacion actual de GPS, buscamos la ultima guardada en la base de datos.
|
|
c = Starter.skmt.ExecQuery("select * from hist_gps")
|
|
If c.RowCount > 0 Then
|
|
c.Position = 0
|
|
locActual = c.GetString("hglon") & "," & c.GetString("hglat")
|
|
End If
|
|
c.Close
|
|
End If
|
|
f = f+1
|
|
If f < 8 Then
|
|
If locActual = "0,0" Then 'Si todavia no tenemos ubicacion actual, entonces avisamos.
|
|
ToastMessageShow("No se pudo obtener la ubicacion actual!!", True)
|
|
f = 8
|
|
End If
|
|
Log($"locActual: ${locActual}, thisLoc1: ${thisLoc1}"$)
|
|
Wait For(distanciaEntreCoords(distancia2, locActual, thisLoc1)) Complete (r As List)
|
|
LogColor($"R: ${r.Get(0)} - ${r.Get(1)} - ${r.Get(2)}"$, Colors.Green)
|
|
Private tId As Int = r.Get(0)
|
|
Private tMap As Map = distOrderedMap.Get(tId)
|
|
LogColor("|" & tId & "| - " &distOrderedMap.Get(tId), Colors.Blue)
|
|
Private tempNDD As String = tMap.Get("nomDirDist")
|
|
Private indexD As Int = tempNDD.IndexOf("Distancia:")
|
|
If indexD > -1 Then tempNDD = tempNDD.SubString2(0, indexD)
|
|
Log(tempNDD)
|
|
tempNDD = tempNDD & $"Dist: $1.1{(r.Get(1)/1000)} kms, Tiempo aprox: $1.0{((r.Get(2)*2)/60)} min."$ 'Multiplicamos el tiempo X 2 porque el tiempo estimado siempre es muy corto, X2 es mucho mas real con trafico.
|
|
Private esteCliente As Map = CreateMap("distancia": distancia2, "ubicacion": tMap.Get("ubicacion"), "codigo": tMap.Get("codigo"), "nomDirDist": tempNDD)
|
|
distOrderedMap.Put(tId, esteCliente)
|
|
ListView1.Clear
|
|
Private m3 As Map
|
|
For Each k As Object In distOrderedMap.Keys 'Generamos el listView con la lista ordenada.
|
|
m3 = distOrderedMap.Get(k)
|
|
m3.Get("codigo")
|
|
ListView1.AddTwoLines(m3.Get("codigo"), m3.Get("nomDirDist"))
|
|
Next
|
|
End If
|
|
Next
|
|
ProgressDialogHide
|
|
End Sub
|
|
|
|
'Regresa un mapa (B4XOrderedMap) con todos los clientes que tiene que visitar el repartidor. (Parte de la funcionalidad OSRM)
|
|
Sub traeTodosAVisitar As B4XOrderedMap 'ignore
|
|
Log("Iniciamos traeTodosAVisitar")
|
|
' If Starter.waypointsOrdered.isInitialized Then Log(Starter.waypointsOrdered.Size)
|
|
' Private rutaCompleta As String = ""
|
|
Private thisLoc, ubicacionInicial As Location
|
|
ubicacionInicial = Starter.cedisLocation
|
|
LogColor(ubicacionInicial, Colors.Gray)
|
|
c=Starter.skmt.ExecQuery("select sum(gestion) as hayVisitados from kmt_info")
|
|
If c.RowCount > 0 Then
|
|
c.Position = 0
|
|
' Log(c.GetString("hayVisitados"))
|
|
If c.GetString("hayVisitados") > 0 Then ubicacionInicial = Tracker.UUGCoords 'Si ya hay clientes visitados, entonces ya no estamos en el CEDIS y la ubicacion inicial debe de ser la ACTUAL.
|
|
End If
|
|
c.Close
|
|
LogColor(ubicacionInicial, Colors.Red)
|
|
thisLoc.Initialize
|
|
clientesMapaO.Clear
|
|
'Traemos las rutas asignadas al repartidor.
|
|
c=Starter.skmt.ExecQuery("select CAT_CL_RUTA, count(*) as cuantos from kmt_info where gestion = 0 AND CAT_CL_RUTA <> 1000 group by CAT_CL_RUTA order by CAT_CL_RUTA asc")
|
|
If c.RowCount>0 Then
|
|
'Traemos los clientes de cada ruta.
|
|
For i=0 To c.RowCount -1
|
|
c.Position=i
|
|
' Log($"Renglones ruta: ${c.RowCount} - i=${i} - Ruta: ${c.GetString("CAT_CL_RUTA")}"$)
|
|
c2=Starter.skmt.ExecQuery2("select CAT_CL_NOMBRE, CAT_CL_CALLE, CAT_CL_CODIGO, CAT_CL_LAT, CAT_CL_LONG from kmt_info where CAT_CL_RUTA = ? and gestion = 0 AND CAT_CL_RUTA <> 1000 order by CAT_CL_NOMBRE ", Array As String(c.GetString("CAT_CL_RUTA")))
|
|
If c2.RowCount>0 Then
|
|
For j=0 To c2.RowCount -1 'Generamos lista de clientes
|
|
c2.Position=j
|
|
' Log($"Renglones clientes: ${c2.RowCount} - j=${j} - Ruta: ${c2.GetString("CAT_CL_CODIGO")}"$)
|
|
thisLoc.Latitude = c2.GetString("CAT_CL_LAT")
|
|
thisLoc.Longitude = c2.GetString("CAT_CL_LONG")
|
|
If Not(thisLoc.Latitude = 0.0) And Not(thisLoc.Latitude = 0) Then 'Este IF es para que si las coordenadas no son válidas, entonces no las agregue al mapeo, porque el API de OSRM nos manda error.
|
|
Private distancia As Int = ubicacionInicial.DistanceTo(thisLoc) 'Calculamos la distancia del cedis a la tienda.
|
|
If clientesMapaO.ContainsKey(distancia) Then distancia = distancia + 1 'Si por alguna extraña razon hay dos tiendas a la misma distancia del CEDIS, le sumamos 1 para que sea diferente.
|
|
Private esteCliente As Map = CreateMap("distancia": distancia, "ordenDist": j, "coords": c2.GetString("CAT_CL_LONG")&","&c2.GetString("CAT_CL_LAT"), "codigo": c2.GetString("CAT_CL_CODIGO"), "nombre": c2.GetString("CAT_CL_NOMBRE"), "calle": c2.GetString("CAT_CL_CALLE"))
|
|
clientesMapaO.Put(distancia, esteCliente)
|
|
Else
|
|
ToastMessageShow("Hay tiendas SIN coordenadas, fueron excluidas!!", False)
|
|
End If
|
|
' Log($"${thisLoc}"$)
|
|
' rutaCompleta = rutaCompleta & ";" & c2.GetString("CAT_CL_LONG")&","&c2.GetString("CAT_CL_LAT")
|
|
Next
|
|
End If
|
|
Next
|
|
End If
|
|
clientesMapaO.Keys.Sort(True) 'Ordenamos la lista de clientes por distancia.
|
|
c.Close
|
|
c2.Close
|
|
Log(c.RowCount & " rutas, " & clientesMapaO.Size & " clientes")
|
|
' LogColor(rutaCompleta, Colors.Magenta)
|
|
' Log(clientesMapaO)
|
|
Return clientesMapaO
|
|
End Sub
|
|
|
|
'Traemos la ruta de visitas via el API de OSRM usando el sub "traeRutaDia(traeTodosAVisitar)".
|
|
Private Sub b_getRutaInfo_Click
|
|
' traeRutaDia(traeTodosAVisitar)
|
|
caculaRutaGPS(todosAVisitar)
|
|
End Sub
|
|
|
|
'Mostramos u ocultamos el boton para borrar los waypoints de la ruta.
|
|
Private Sub b_getRutaInfo_LongClick
|
|
If b_limpiarRuta.Visible Then
|
|
b_limpiarRuta.Visible = False
|
|
Else
|
|
b_limpiarRuta.Visible = True
|
|
End If
|
|
End Sub
|
|
|
|
'Borramos los waypoints de la ruta.
|
|
Private Sub b_limpiarRuta_Click
|
|
Starter.skmt.ExecNonQuery("delete from waypoints")
|
|
b_limpiarRuta.Visible = False
|
|
B4XPage_Appear
|
|
End Sub
|
|
|
|
Sub caculaRutaGPS(coords As List)
|
|
Private tmpList As List
|
|
Dim cs, cs2 As CSBuilder
|
|
tmpList.Initialize
|
|
tmpList.AddAll(Array As String("ACTUAL", Tracker.UUGCoords.Longitude, Tracker.UUGCoords.Latitude))
|
|
coords.InsertAt(0,tmpList)
|
|
Log("=================================")
|
|
' Log(coords)
|
|
Private coordsStr As String = ""
|
|
For Each tienda As List In coords
|
|
' Log(tienda)
|
|
If coordsStr = "" Then
|
|
coordsStr = $"${tienda.get(0)},${tienda.get(1)},${tienda.get(2)}"$
|
|
Else
|
|
coordsStr = $"${coordsStr};${tienda.get(0)},${tienda.get(1)},${tienda.get(2)}"$
|
|
End If
|
|
Next
|
|
Log(coordsStr)
|
|
ProgressDialogShow2("Calculando distancia y tiempo, un momento por favor.", False)
|
|
Dim j As HttpJob
|
|
j.Initialize("trip", Me) 'Calculamos el resto de la ruta.
|
|
j.Download($"http://keymon.net:9002/ruteador?m=OSRM&r=${Subs.traeRutaReparto}&a=${Subs.traeAlmacen}&f=CEDIS,${Starter.cedisLocation.Longitude},${Starter.cedisLocation.Latitude}&c=${coordsStr}"$)
|
|
Log($"http://keymon.net:9002/ruteador?m=OSRM&r=${Subs.traeRutaReparto}&a=${Subs.traeAlmacen}&f=CEDIS,${Starter.cedisLocation.Longitude},${Starter.cedisLocation.Latitude}&c=${coordsStr}"$)
|
|
Wait For (j) JobDone(j As HttpJob)
|
|
If j.Success Then
|
|
Dim jp As JSONParser
|
|
jp.Initialize(j.GetString)
|
|
Dim m As Map = jp.NextObject
|
|
Log(m)
|
|
If m.Get("code") = "OK" Then
|
|
Log("===== OK")
|
|
rutaGenerada = True
|
|
Dim puntos As Int = m.Get("puntos")
|
|
Private coords As List = m.Get("coords")
|
|
Private duration As String = m.Get("duration")
|
|
Private distance As String = m.Get("distance")
|
|
Private mensaje As String = m.Get("mensaje")
|
|
Starter.skmt.ExecNonQuery("delete from waypoints")
|
|
Starter.skmt.ExecNonQuery("update kmt_info set SECUENCIA = 0")
|
|
For i = 0 To coords.Size - 1
|
|
Private ti As Map = coords.Get(i)
|
|
Starter.skmt.ExecNonQuery($"update kmt_info set SECUENCIA = ${ti.Get("pos")} where CAT_CL_CODIGO = '${ti.Get("id").As(String).SubString(1)}'"$) ' Ponemos la secuencia con el orden del ruteo para poder verla en el mapa.
|
|
Starter.skmt.ExecNonQuery($"insert into waypoints (codigo, indice) values ('${ti.Get("id").As(String).SubString(1)}', '${ti.Get("pos")}')"$)
|
|
Next
|
|
c = Starter.skmt.ExecQuery("select codigo, indice, CAT_CL_NOMBRE, CAT_CL_CALLE, CAT_CL_NOEXT from waypoints inner join kmt_info on waypoints.codigo = kmt_info.CAT_CL_CODIGO where gestion = 0 AND CAT_CL_RUTA <> 1000 order by indice")
|
|
If c.RowCount > 0 Then 'Ya hay waypoints en la base de datos.
|
|
c.Position = 0
|
|
conMapa = True
|
|
ListView1.Clear
|
|
Dim cs, cs2 As CSBuilder
|
|
entro = 3
|
|
For i=0 To c.RowCount -1 'Generamos el listView con la lista ordenada.
|
|
c.Position = i
|
|
cs.Initialize
|
|
cs2.Initialize
|
|
ListView1.AddTwoLines(cs.Color(Colors.RGB(100,149,237)).Append(c.GetString("codigo")).PopAll, cs2.append(c.GetString("CAT_CL_NOMBRE")).Color(Colors.RGB(100,149,237)).Append(" Calle: ").Pop.Append(c.GetString("CAT_CL_CALLE").Trim & " " & c.GetString("CAT_CL_NOEXT")).PopAll )
|
|
Next
|
|
End If
|
|
c.Close
|
|
Log($"Distancia total: $1.1{distance/1000} kms, tiempo aprox: $1.1{duration/60} mins. ($1.1{duration/60/60} hrs)"$)
|
|
l_rutaInfo.Text = $"Distancia: $1.1{distance/1000} kms, tiempo aprox: $1.1{duration/60/60} hrs${CRLF}Visitas restantes: ${puntos - 1}"$
|
|
l_rutaInfo.Width = Root.Width * 0.9
|
|
Subs.centraEtiqueta(l_rutaInfo, Root.Width)
|
|
l_rutaInfo.Visible = True
|
|
l_rutaInfo.BringToFront
|
|
ListView1.Top = lv1Top + 100
|
|
End If
|
|
Else
|
|
LogColor("**************** Error! ******************", Colors.red)
|
|
End If
|
|
j.Release
|
|
ProgressDialogHide
|
|
End Sub
|
|
|
|
'Regresa lista de los clientes a visitar y sus coordenadas, iniciando con el cedis.
|
|
Sub todosAVisitar As List
|
|
Log(laRuta)
|
|
Log(entro)
|
|
Private sqlDeRuta As String = ""
|
|
If entro = 3 Then sqlDeRuta = $"and CAT_CL_RUTA = '${laRuta}'"$
|
|
Private aVisitar, tmpList As List
|
|
aVisitar.Initialize
|
|
Private coords As ResultSet = Starter.skmt.ExecQuery($"select CAT_CL_CODIGO, CAT_CL_LAT, CAT_CL_LONG from kmt_info where gestion = 0 AND CAT_CL_RUTA <> 1000 ${sqlDeRuta}"$)
|
|
Do While coords.NextRow
|
|
tmpList.Initialize
|
|
tmpList.AddAll(Array As String(coords.GetString("CAT_CL_CODIGO"), coords.GetString("CAT_CL_LONG"), coords.GetString("CAT_CL_LAT")))
|
|
aVisitar.Add(tmpList)
|
|
Loop
|
|
Log(aVisitar)
|
|
Return aVisitar
|
|
End Sub
|