B4A=true Group=Default Group ModulesStructureVersion=1 Type=Activity Version=7.01 @EndOfDesignText@ #Region Activity Attributes #FullScreen: False #IncludeTitle: True #End Region Sub Process_Globals 'These global variables will be declared once when the application starts. 'These variables can be accessed from all modules. ' Dim ruta As String Dim q_buscar As String ' Dim skmt As SQL Dim entro As String End Sub Sub Globals 'These global variables will be redeclared each time the activity is created. 'These variables can only be accessed from this module. 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 End Sub Sub Activity_Create(FirstTime As Boolean) 'Do not forget to load the layout file created with the visual designer. For example: 'Activity.LoadLayout("Layout1") Activity.LoadLayout("fila") entro ="2" lv1Top = ListView1.Top ' valido donde escribo el archivo de la base de datos de kmt ' ruta = Starter.ruta ' se crea o no el archivo de la base de ddatos de kmt 'NOTAS SI SE MODIFICA LA ESTRUCTURA SE QUITA EL IF Y SE VA DIRECTO A LA SENTENCIA FILE.COPY PARA QUE 'TOME LA NUEVA ESTRUCTURA ES MUY IMPORTANTE TENER EL IF DE LO CONTRARIO SOLO LO ESCRIBE UNA VEZ Y LO BORRA 'SI SE REGRESA A ESTE ACTIVIDAD. ' If File.Exists(Starter.ruta, "kmt.db") = False Then ' File.Copy(File.DirAssets, "kmt.db", Starter.ruta, "kmt.db") ' End If ' 19.48118148992086,-99.15295579261536 ' Starter.cedisLocation.Latitude = "19.48118148992086" ' Starter.cedisLocation.Longitude = "-99.15295579261536" clientesMapaO.Initialize If FirstTime Then Starter.skmt.ExecNonQuery("delete from waypoints") Log("Coordenadas del almacen: " & Starter.cedisLocation.Longitude & "," & Starter.cedisLocation.Latitude) End Sub Sub Activity_Resume busca.Text = "" ' 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("selecTIJ01t 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 = Activity.Width p_colonia.Height = Activity.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 Private label1 As Label = ListView1.TwoLinesLayout.Label Private label2 As Label = ListView1.TwoLinesLayout.SecondLabel label1.Height = 15dip label2.Height = 50dip label1.top = 10dip label2.Top = label1.Height + 12dip ListView1.TwoLinesLayout.ItemHeight = label1.Height+label2.Height+5dip 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 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") 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 ' ESTE FUE EL FIN DEL CODIGO COMENTADO 'c2=skmt.ExecQuery("select CAT_CL_NOMBRE, CAT_CL_CALLE, CAT_CL_CODIGO from kmt_info where gestion = 0 order by CAT_CL_NOMBRE ") ' ListView1.Clear 'lfila.text = "Nombre y Calle" '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 = 9 ' label1.TextColor = Colors.White ' Dim label2 As Label ' label2 = ListView1.TwoLinesLayout.SecondLabel ' label2.TextSize = 17 ' label2.TextColor = Colors.White ' ListView1.AddTwoLines(c2.GetString("CAT_CL_CODIGO"), c2.GetString("CAT_CL_NOMBRE") &" CALLE: "& c2.GetString("CAT_CL_CALLE")) ' Next ' End If ' entro = "3" p_colonia.Width = Activity.Width p_colonia.Height = Activity.Height Subs.centraEtiqueta(l_rutaInfo, Activity.Width) Subs.centraListView(ListView1, p_colonia.Width) ListView1.Height = p_colonia.Height * 0.70 Subs.centraEtiqueta(lfila, Activity.Width) b_getRutaInfo.Visible = True b_getRutaInfo.BringToFront End Sub Sub Activity_Pause (UserClosed As Boolean) End Sub Sub ListView1_ItemClick (Position As Int, Value As Object) ' Log($"Entro= ${entro}"$) 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}"$) 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 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 ' label1.Height = 70dip ' label1.Color = Colors.Gray label2.Height = 55dip thisLoc.Initialize If entro = 2 Then ListView1.TwoLinesLayout.ItemHeight = 75dip ListView1.TwoLinesLayout.ItemHeight = label1.Height+label2.Height+15dip 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 = 0 thisLoc.Longitude = 0 If c2.GetString("CAT_CL_LAT").Length > 3 Then thisLoc.Latitude = c2.GetString("CAT_CL_LAT") If c2.GetString("CAT_CL_LONG").Length > 3 Then thisLoc.Longitude = c2.GetString("CAT_CL_LONG") 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"$) If c2.GetString("CAT_CL_LAT").Length < 3 Then distancia = i End If 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") ListView1.AddTwoLines(m1.Get("codigo"), m1.Get("nomDirDist")) Next End If c2.Close entro = "3" Else If entro = "3" Then Starter.skmt.ExecNonQuery("delete from CUENTAA") Starter.skmt.ExecNonQuery2("INSERT INTO CUENTAA VALUES (?)", Array As Object(Value)) StartActivity(fila) 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 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)) Return True End If StartActivity(seleccion) 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 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 = Activity.Width * 0.9 Subs.centraEtiqueta(l_rutaInfo, Activity.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") If listaWayPoints.Size > 0 Then For Each k As Object In clientesMapaO.Keys 'Guardamos en la BD el orden de los waypoints para luego generar el listview. r1 = clientesMapaO.Get(k) r1.Get("codigo") ' Log(listaWayPoints.Get(r) & "|" & r1.Get("coords") & "|" & r1.Get("calle")) wps = listaWayPoints.Get(r) Starter.skmt.ExecNonQuery2("insert into waypoints values (?,?)", Array As Object(r1.Get("codigo"), wps.get("waypoint_index"))) r = r + 1 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 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 Else ToastMessageShow("Hubo un error al generar el ruteo, por favor revise las coordenadas del cedis.", True) End If 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") <> Null And 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 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 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 = 0 thisLoc.Longitude = 0 If c2.GetString("CAT_CL_LAT").Length > 3 Then thisLoc.Latitude = c2.GetString("CAT_CL_LAT") If c2.GetString("CAT_CL_LONG").Length > 3 Then 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) 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 Activity_Resume End Sub