admin_transporte_frontend/src/pages/mapas/Rutas.svelte

248 lines
7.5 KiB
Svelte
Raw Normal View History

2023-12-05 10:37:40 -03:00
<script>
// componentes
import PageTitle from "$/components/PageTitle.svelte";
import imagenPartida from '$/assets/partida.png'
import imagenTermino from '$/assets/termino.png'
import imagenParada from '$/assets/parada.png'
import imagenAutobus from '$/assets/autobus.png'
import { onMount } from "svelte";
// servicios
import { getRutas } from "$/services/mapas";
import ModalLetreroLUR from "./ModalLetreroLUR.svelte";
import FiltroRutas from "./FiltroRutas.svelte";
import { getBusesLinea, getParaderosLinea } from "$/services/lineas";
let myMap = null
let elMap = null
let loading = false
let polyline = null
let iconPartida = null
let iconTermino = null
let iconParada = null
let iconAutobus = null
let L = null // leaflet.js
let marker1 = null
let marker2 = null
let showLetrero = false
let id_operador = ''
let id_linea = ''
let codigo = null
let ver_buses = false
let ver_paraderos = false
let markers_paraderos = []
let markers_buses = []
let timeInterval = null
let fileproto = null
let loading_proto = false
2023-12-05 10:37:40 -03:00
onMount(() => {
create_map()
return () => {
timeInterval && globalThis.clearInterval(timeInterval)
}
})
2023-12-05 10:37:40 -03:00
function create_map() {
if (!elMap || !globalThis.L) return;
if (!L) L = globalThis.L;
if (!iconPartida) {
iconPartida = L.icon({
iconUrl: imagenPartida,
iconSize: [40, 40],
iconAnchor: [20, 40],
popupAnchor: [0, -20]
})
}
if (!iconTermino) {
iconTermino = L.icon({
iconUrl: imagenTermino,
iconSize: [40, 40],
iconAnchor: [20, 40],
popupAnchor: [0, -20]
})
}
if (!iconParada) {
iconParada = L.icon({
iconUrl: imagenParada,
iconSize: [32, 32],
iconAnchor: [16, 32],
popupAnchor: [0, -16]
})
}
if (!iconAutobus) {
iconAutobus = L.icon({
iconUrl: imagenAutobus,
iconSize: [32, 32],
iconAnchor: [16, 32],
popupAnchor: [0, -16]
})
}
if (!myMap) {
myMap = L.map(elMap)
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
{ attribution: '&copy; <a target="_blank" href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' }
).addTo(myMap);
}
// obtener coordenadas actuales
// centrar mapa en coordenadas del navegador
navigator.geolocation.getCurrentPosition(
({ coords }) => {
const { latitude, longitude } = coords;
myMap.setView([latitude, longitude], 16);
},
(error) => console.log({ error })
)
}
async function onMostrarRuta(id_operador, id_linea) {
try {
loading = true
timeInterval && globalThis.clearInterval(timeInterval)
2023-12-05 10:37:40 -03:00
polyline && polyline.remove()
marker1 && marker1.remove()
marker2 && marker2.remove()
if (!id_operador || !id_linea) return;
const data = await getRutas({ id_linea })
const coordenadas = data.positions.map(({ shape_pt_lat, shape_pt_lon}) => [shape_pt_lat, shape_pt_lon])
polyline = L.polyline(coordenadas, { color: 'red' }).addTo(myMap)
myMap.fitBounds(polyline.getBounds());
if (coordenadas) {
marker1 = L.marker(coordenadas[0], { icon: iconPartida }).addTo(myMap)
marker1.bindTooltip('Inicio')
marker2 = L.marker(coordenadas[coordenadas.length -1], { icon: iconTermino }).addTo(myMap)
marker2.bindTooltip('Termino')
}
} catch (error) {
alert(error)
} finally {
loading = false;
}
}
async function onMostrarParaderos(ver_paraderos) {
// 1. eliminar marcadores anteriores
markers_paraderos.forEach(marker => marker.remove())
if (!ver_paraderos || !id_linea) return;
const paraderos = await getParaderosLinea(id_linea)
// 2. crear marcadores
for (let mark of paraderos) {
const { stop_lat: lat, stop_lon: lng } = mark
const marker = L.marker([lat, lng], { icon: iconParada }).addTo(myMap)
const { id_paradero: title, stop_name: location } = mark;
const html = `${title}<br>${location}`
marker.bindTooltip(html)
markers_paraderos.push(marker)
}
}
async function onMostrarBuses(ver_buses) {
if (!ver_buses && timeInterval) {
globalThis.clearInterval(timeInterval)
timeInterval = null
}
if (!ver_buses || !id_linea) {
markers_buses.forEach(marker => marker.remove())
return;
}
2023-12-05 10:37:40 -03:00
loading_proto = true
try {
const { fileproto: nuevoNombre, buses } = await getBusesLinea(id_linea)
if (nuevoNombre !== fileproto) {
// guardo el nombre del archivo proto
fileproto = nuevoNombre
// 1. eliminar marcadores anteriores
markers_buses.forEach(marker => marker.remove())
// 2. crear marcadores
for (let mark of buses) {
const { latitude: lat, longitude: lng } = mark
const marker = L.marker([lat, lng], { icon: iconAutobus }).addTo(myMap)
const html = `${mark.Patente_vehiculo}<br>Velocidad: ${mark.speed}`
marker.bindTooltip(html)
markers_buses.push(marker)
}
}
} catch (error) {
console.log({ error })
} finally {
loading_proto = false
}
// actualizar posicion de buses cada 45 segundos
if (!timeInterval) {
timeInterval = globalThis.setInterval(() => onMostrarBuses(true), 45000)
2023-12-05 10:37:40 -03:00
}
2023-12-05 10:37:40 -03:00
}
$: onMostrarRuta(id_operador, id_linea)
$: onMostrarParaderos(ver_paraderos)
$: onMostrarBuses(ver_buses)
</script>
<svelte:head>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" on:load={create_map}></script>
</svelte:head>
<div class="row">
<div class="col-md-auto">
<PageTitle {loading}>
Rutas
</PageTitle>
</div>
<div class="col-md">
<FiltroRutas
bind:id_operador={id_operador}
bind:id_linea={id_linea}
bind:codigo={codigo}
bind:ver_buses={ver_buses}
bind:ver_paraderos={ver_paraderos}
loading={loading_proto}
2023-12-05 10:37:40 -03:00
/>
2023-12-05 10:37:40 -03:00
</div>
{#if id_operador && codigo}
<div class="col-auto">
<button class="btn btn-secondary" on:click|preventDefault={() => showLetrero = true}>
Ver Letrero
</button>
</div>
{/if}
</div>
<div class="card">
<div class="card-body">
<div bind:this={elMap} style="height: 100vh;"></div>
</div>
</div>
{#if showLetrero}
<ModalLetreroLUR {codigo} on:close={() => showLetrero = false} />
{/if}