avance ver buses y paraderos de ruta
After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 9.7 KiB After Width: | Height: | Size: 9.7 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 1.8 KiB |
|
@ -0,0 +1,86 @@
|
||||||
|
<script>
|
||||||
|
import { getLineas } from "$/services/lineas";
|
||||||
|
import { getOperadores } from "$/services/operadores";
|
||||||
|
|
||||||
|
export let id_operador;
|
||||||
|
export let id_linea;
|
||||||
|
export let codigo;
|
||||||
|
export let ver_buses;
|
||||||
|
export let ver_paraderos;
|
||||||
|
|
||||||
|
let operadores = []
|
||||||
|
let lineas = []
|
||||||
|
let lineas_operador = []
|
||||||
|
|
||||||
|
getOperadores({ vigente: 1 })
|
||||||
|
.then(data => data.sort((a,b) => a.nombre_operador < b.nombre_operador? -1 : 1))
|
||||||
|
.then(data => operadores = data)
|
||||||
|
.catch(error => alert(error))
|
||||||
|
|
||||||
|
getLineas({ vigente: 1 })
|
||||||
|
.then(data => data.sort((a,b) => a.nombre_linea < b.nombre_linea? -1 : 1))
|
||||||
|
.then(data => lineas = data)
|
||||||
|
.catch(error => alert(error))
|
||||||
|
|
||||||
|
function onChangeOperador() {
|
||||||
|
id_linea = ''
|
||||||
|
ver_paraderos = false
|
||||||
|
ver_buses = false
|
||||||
|
if (!id_operador) {
|
||||||
|
lineas_operador = []
|
||||||
|
} else {
|
||||||
|
const lineas_filtradas = lineas.filter(el => el.id_operador === id_operador);
|
||||||
|
const lineas_ordenadas = lineas_filtradas.sort((a,b) => a.route_short_name < b.route_short_name ? -1 : 1);
|
||||||
|
lineas_operador = lineas_ordenadas;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onChangeLinea() {
|
||||||
|
codigo = lineas.find(el => el.id_linea === id_linea)?.route_short_name || null
|
||||||
|
ver_paraderos = false
|
||||||
|
ver_buses = false
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md">
|
||||||
|
|
||||||
|
<div class="input-group mb-3">
|
||||||
|
<div class="input-group-text">Operador</div>
|
||||||
|
<select bind:value={id_operador} class="form-select" on:change={onChangeOperador}>
|
||||||
|
<option value=""></option>
|
||||||
|
{#each operadores as operador}
|
||||||
|
<option value={operador.id_operador}>{operador.nombre_operador}</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-group mb-3">
|
||||||
|
<div class="input-group-text">Linea</div>
|
||||||
|
<select bind:value={id_linea} class="form-select" style="font-family: monospace;" on:change={onChangeLinea}>
|
||||||
|
<option value=""></option>
|
||||||
|
{#each lineas_operador as linea}
|
||||||
|
<option value={linea.id_linea}>{@html linea.route_short_name.padEnd(6).replace(/ /g,' ')} {linea.route_long_name}</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col-md-auto">
|
||||||
|
|
||||||
|
<div class="form-check form-switch mb-3">
|
||||||
|
<input class="form-check-input" type="checkbox" role="switch" id="check-ver-buses-recorrido"
|
||||||
|
disabled={!id_linea}
|
||||||
|
bind:checked={ver_buses}>
|
||||||
|
<label class="form-check-label" for="check-ver-buses-recorrido">Ver Buses del Recorrido</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-check form-switch mb-3">
|
||||||
|
<input class="form-check-input" type="checkbox" role="switch" id="check-ver-paraderos"
|
||||||
|
disabled={!id_linea}
|
||||||
|
bind:checked={ver_paraderos}>
|
||||||
|
<label class="form-check-label" for="check-ver-paraderos">Ver Paraderos</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -12,7 +12,7 @@
|
||||||
// libs
|
// libs
|
||||||
import { onMount } from 'svelte'
|
import { onMount } from 'svelte'
|
||||||
import { storeParaderos } from "$/stores/global"
|
import { storeParaderos } from "$/stores/global"
|
||||||
import imagenParada from '$/assets/parada-de-autobus.png'
|
import imagenParada from '$/assets/parada.png'
|
||||||
|
|
||||||
let myMap = null
|
let myMap = null
|
||||||
let elMap = null
|
let elMap = null
|
||||||
|
@ -41,9 +41,9 @@
|
||||||
if (!iconParada) {
|
if (!iconParada) {
|
||||||
iconParada = L.icon({
|
iconParada = L.icon({
|
||||||
iconUrl: imagenParada,
|
iconUrl: imagenParada,
|
||||||
iconSize: [64, 64],
|
iconSize: [32, 32],
|
||||||
iconAnchor: [32, 64],
|
iconAnchor: [16, 32],
|
||||||
popupAnchor: [0, -32]
|
popupAnchor: [0, -16]
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (!myMap) {
|
if (!myMap) {
|
||||||
|
|
|
@ -2,54 +2,40 @@
|
||||||
// componentes
|
// componentes
|
||||||
import PageTitle from "$/components/PageTitle.svelte";
|
import PageTitle from "$/components/PageTitle.svelte";
|
||||||
|
|
||||||
import IconLoading from "$/components/IconLoading.svelte";
|
|
||||||
import imagenPartida from '$/assets/partida.png'
|
import imagenPartida from '$/assets/partida.png'
|
||||||
import imagenTermino from '$/assets/termino.png'
|
import imagenTermino from '$/assets/termino.png'
|
||||||
|
import imagenParada from '$/assets/parada.png'
|
||||||
|
import imagenAutobus from '$/assets/autobus.png'
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
|
|
||||||
// servicios
|
// servicios
|
||||||
import { getOperadores } from "$/services/operadores";
|
|
||||||
import { getLineas } from "$/services/lineas";
|
|
||||||
import { getRutas } from "$/services/mapas";
|
import { getRutas } from "$/services/mapas";
|
||||||
import ModalLetreroLUR from "./ModalLetreroLUR.svelte";
|
import ModalLetreroLUR from "./ModalLetreroLUR.svelte";
|
||||||
|
import FiltroRutas from "./FiltroRutas.svelte";
|
||||||
|
import { getBusesLinea, getParaderosLinea } from "$/services/lineas";
|
||||||
|
|
||||||
let myMap = null
|
let myMap = null
|
||||||
let elMap = null
|
let elMap = null
|
||||||
let operadores = []
|
|
||||||
let lineas = []
|
|
||||||
let lineas_operador = []
|
|
||||||
let id_operador = ''
|
|
||||||
let id_linea = ''
|
|
||||||
let loading = false
|
let loading = false
|
||||||
let polyline = null
|
let polyline = null
|
||||||
let iconPartida = null
|
let iconPartida = null
|
||||||
let iconTermino = null
|
let iconTermino = null
|
||||||
let L = null
|
let iconParada = null
|
||||||
|
let L = null // leaflet.js
|
||||||
let marker1 = null
|
let marker1 = null
|
||||||
let marker2 = null
|
let marker2 = null
|
||||||
|
|
||||||
let showLetrero = false
|
let showLetrero = false
|
||||||
|
|
||||||
|
let id_operador = ''
|
||||||
|
let id_linea = ''
|
||||||
let codigo = null
|
let codigo = null
|
||||||
|
let ver_buses = false
|
||||||
|
let ver_paraderos = false
|
||||||
|
let markers = []
|
||||||
|
|
||||||
$: codigo = lineas.find(el => el.id_linea === id_linea)?.route_short_name || null
|
onMount(() => { create_map() })
|
||||||
$: lineas_operador = id_operador ?
|
|
||||||
lineas.filter(el => el.id_operador === id_operador)
|
|
||||||
.sort((a,b) => a.route_short_name < b.route_short_name ? -1 : 1) : [];
|
|
||||||
|
|
||||||
getOperadores({ vigente: 1 })
|
|
||||||
.then(data => data.sort((a,b) => a.nombre_operador < b.nombre_operador? -1 : 1))
|
|
||||||
.then(data => operadores = data)
|
|
||||||
.catch(error => alert(error))
|
|
||||||
getLineas({ vigente: 1 })
|
|
||||||
.then(data => data.sort((a,b) => a.nombre_linea < b.nombre_linea? -1 : 1))
|
|
||||||
.then(data => lineas = data)
|
|
||||||
.catch(error => alert(error))
|
|
||||||
|
|
||||||
$: cargar_coordenadas(id_operador, id_linea)
|
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
create_map()
|
|
||||||
})
|
|
||||||
|
|
||||||
function create_map() {
|
function create_map() {
|
||||||
if (!elMap || !globalThis.L) return;
|
if (!elMap || !globalThis.L) return;
|
||||||
|
@ -66,10 +52,18 @@
|
||||||
iconTermino = L.icon({
|
iconTermino = L.icon({
|
||||||
iconUrl: imagenTermino,
|
iconUrl: imagenTermino,
|
||||||
iconSize: [64, 64],
|
iconSize: [64, 64],
|
||||||
iconAnchor: [32, 64],
|
iconAnchor: [0, 64],
|
||||||
popupAnchor: [0, -32]
|
popupAnchor: [0, -32]
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
if (!iconParada) {
|
||||||
|
iconParada = L.icon({
|
||||||
|
iconUrl: imagenParada,
|
||||||
|
iconSize: [32, 32],
|
||||||
|
iconAnchor: [16, 32],
|
||||||
|
popupAnchor: [0, -16]
|
||||||
|
})
|
||||||
|
}
|
||||||
if (!myMap) {
|
if (!myMap) {
|
||||||
myMap = L.map(elMap)
|
myMap = L.map(elMap)
|
||||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
|
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||||
|
@ -88,8 +82,7 @@
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function onMostrarRuta(id_operador, id_linea) {
|
||||||
async function cargar_coordenadas(id_operador, id_linea) {
|
|
||||||
try {
|
try {
|
||||||
loading = true
|
loading = true
|
||||||
polyline && polyline.remove()
|
polyline && polyline.remove()
|
||||||
|
@ -105,7 +98,9 @@
|
||||||
|
|
||||||
if (coordenadas) {
|
if (coordenadas) {
|
||||||
marker1 = L.marker(coordenadas[0], { icon: iconPartida }).addTo(myMap)
|
marker1 = L.marker(coordenadas[0], { icon: iconPartida }).addTo(myMap)
|
||||||
|
marker1.bindTooltip('Inicio')
|
||||||
marker2 = L.marker(coordenadas[coordenadas.length -1], { icon: iconTermino }).addTo(myMap)
|
marker2 = L.marker(coordenadas[coordenadas.length -1], { icon: iconTermino }).addTo(myMap)
|
||||||
|
marker2.bindTooltip('Termino')
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -114,6 +109,54 @@
|
||||||
loading = false;
|
loading = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function onMostrarParaderos(ver_paraderos) {
|
||||||
|
// 1. eliminar marcadores anteriores
|
||||||
|
markers.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.push(marker)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onMostrarBuses(ver_buses) {
|
||||||
|
// 1. eliminar marcadores anteriores
|
||||||
|
// markers.forEach(marker => marker.remove())
|
||||||
|
|
||||||
|
if (!ver_buses || !id_linea) return;
|
||||||
|
|
||||||
|
const buses = await getBusesLinea(id_linea)
|
||||||
|
console.log({ buses })
|
||||||
|
|
||||||
|
// 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.push(marker)
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$: onMostrarRuta(id_operador, id_linea)
|
||||||
|
$: onMostrarParaderos(ver_paraderos)
|
||||||
|
$: onMostrarBuses(ver_buses)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
|
@ -123,37 +166,27 @@
|
||||||
|
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md">
|
<div class="col-md-auto">
|
||||||
<PageTitle {loading}>
|
<PageTitle {loading}>
|
||||||
Rutas
|
Rutas
|
||||||
</PageTitle>
|
</PageTitle>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-auto">
|
<div class="col-md">
|
||||||
<div class="input-group">
|
<FiltroRutas
|
||||||
<div class="input-group-text">Operador</div>
|
bind:id_operador={id_operador}
|
||||||
<select bind:value={id_operador} class="form-select" on:change={() => id_linea = ''}>
|
bind:id_linea={id_linea}
|
||||||
<option value=""></option>
|
bind:codigo={codigo}
|
||||||
{#each operadores as operador}
|
bind:ver_buses={ver_buses}
|
||||||
<option value={operador.id_operador}>{operador.nombre_operador}</option>
|
bind:ver_paraderos={ver_paraderos}
|
||||||
{/each}
|
/>
|
||||||
</select>
|
|
||||||
|
|
||||||
<div class="input-group-text">Linea</div>
|
|
||||||
<select bind:value={id_linea} class="form-select" style="font-family: monospace;">
|
|
||||||
<option value=""></option>
|
|
||||||
{#each lineas_operador as linea}
|
|
||||||
<option value={linea.id_linea}>{@html linea.route_short_name.padEnd(6).replace(/ /g,' ')} {linea.route_long_name}</option>
|
|
||||||
{/each}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if id_operador && codigo}
|
{#if id_operador && codigo}
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
<button class="btn btn-secondary"
|
<button class="btn btn-secondary" on:click|preventDefault={() => showLetrero = true}>
|
||||||
on:click|preventDefault={() => showLetrero = true}
|
Ver Letrero
|
||||||
>Ver Letrero</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -46,3 +46,19 @@ export async function deleteLinea(id) {
|
||||||
if (!res.ok) throw await res.text()
|
if (!res.ok) throw await res.text()
|
||||||
return res.json()
|
return res.json()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getParaderosLinea(id_linea) {
|
||||||
|
const res = await fetch(`${base}/lineas/${id_linea}/paraderos`, {
|
||||||
|
headers: { "Authorization": `Bearer ${getToken()}`, "Content-Type": "application/json" }
|
||||||
|
})
|
||||||
|
if (!res.ok) throw await res.text()
|
||||||
|
return res.json()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getBusesLinea(id_linea) {
|
||||||
|
const res = await fetch(`${base}/lineas/${id_linea}/buses`, {
|
||||||
|
headers: { "Authorization": `Bearer ${getToken()}`, "Content-Type": "application/json" }
|
||||||
|
})
|
||||||
|
if (!res.ok) throw await res.text()
|
||||||
|
return res.json()
|
||||||
|
}
|
||||||
|
|