Files
Mariana-Reparto-V5/B4A/C_Clientes.bas
Jose Alberto Guerra Ugalde 055cadd11b - VERSION 5.02.17
- Se cambio en MAPA_RUTAS el codigo de los marcadores (globitos), para que use una sola imagen y el numero sea dinamico.
- Se borarron las imagenes de marcadores que ya no se necesitan.
2025-02-18 13:19:28 -06:00

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.lat:9002/ruteador?m=OSRM&r=${Subs.traeRutaReparto}&a=${Subs.traeAlmacen}&f=CEDIS,${Starter.cedisLocation.Longitude},${Starter.cedisLocation.Latitude}&c=${coordsStr}"$)
Log($"http://keymon.lat: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