se usa openstreetmap
parent
170950014c
commit
cad292e25a
Binary file not shown.
After Width: | Height: | Size: 8.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 9.7 KiB |
|
@ -0,0 +1,111 @@
|
|||
<script>
|
||||
import IconParada from '$/assets/parada-de-autobus.png'
|
||||
import ImagenParadero from '$/assets/imagen.png'
|
||||
import { getParadero } from '$/services/paraderos'
|
||||
import { createEventDispatcher } from "svelte"
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
export let parada = null
|
||||
let canvas = null
|
||||
let form = {}
|
||||
|
||||
$: init(!!parada)
|
||||
|
||||
async function init(show) {
|
||||
if (!canvas) return;
|
||||
!show && canvas.classList.remove('show')
|
||||
show && canvas.classList.add('show')
|
||||
|
||||
try {
|
||||
if (parada) {
|
||||
form = await getParadero(parada.id_paradero)
|
||||
}
|
||||
} catch(error) {
|
||||
alert(error)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="offcanvas offcanvas-end" tabindex="-1" bind:this={canvas} aria-labelledby="offcanvasParaderoLabel" style="visibility: inherit;">
|
||||
<div class="offcanvas-header">
|
||||
<h5 class="offcanvas-title text-info" id="offcanvasParaderoLabel">
|
||||
<img src={IconParada} alt="Icono de Paradero" width="64">
|
||||
Paradero
|
||||
</h5>
|
||||
<button type="button" class="btn-close" aria-label="Close" on:click|preventDefault={() => dispatch('close')}></button>
|
||||
</div>
|
||||
<div class="offcanvas-body">
|
||||
Coordenadas:
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-text">Latitud</div>
|
||||
<div class="form-control">{form.stop_lat}</div>
|
||||
</div>
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-text">Longitud</div>
|
||||
<div class="form-control">{form.stop_lon}</div>
|
||||
</div>
|
||||
|
||||
Propiedades:
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-text">Nombre</div>
|
||||
<input type="text" bind:value={form.stop_name} class="form-control">
|
||||
</div>
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-text">Descripción</div>
|
||||
<input type="text" bind:value={form.stop_desc} class="form-control">
|
||||
</div>
|
||||
<hr>
|
||||
<div class="text-center">
|
||||
<button class="btn btn-primary"><i class="bi bi-save"></i> Guardar</button>
|
||||
</div>
|
||||
<div class="my-3"></div>
|
||||
|
||||
<!-- imagenes -->
|
||||
<div class="seccion-imagen mb-3">
|
||||
<img src={ImagenParadero} alt="imagen paradero" class="img-fluid">
|
||||
<a href={"#"} class="btn btn-danger">
|
||||
<i class="bi bi-trash"></i> Eliminar
|
||||
</a>
|
||||
</div>
|
||||
<div class="seccion-imagen mb-3">
|
||||
<img src={ImagenParadero} alt="imagen paradero" class="img-fluid">
|
||||
<a href={"#"} class="btn btn-danger">
|
||||
<i class="bi bi-trash"></i> Eliminar
|
||||
</a>
|
||||
</div>
|
||||
<div class="seccion-imagen mb-3">
|
||||
<img src={ImagenParadero} alt="imagen paradero" class="img-fluid">
|
||||
<a href={"#"} class="btn btn-danger">
|
||||
<i class="bi bi-trash"></i> Eliminar
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- agregar imagen -->
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="form-control" style="overflow: hidden">
|
||||
<input type="file" accept="*.png,*.jpg,*.jpeg">
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer text-center">
|
||||
<button class="btn btn-primary">
|
||||
<i class="bi bi-plus-lg"></i> Agregar imagen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if parada}
|
||||
<div class="offcanvas-backdrop fade show" on:click|preventDefault={() => dispatch('close')}></div>
|
||||
{/if}
|
||||
|
||||
|
||||
{#if parada}
|
||||
<style>
|
||||
html { overflow-y: hidden; }
|
||||
.seccion-imagen { position: relative; }
|
||||
.seccion-imagen > a { position: absolute; bottom: .5rem; right: .5rem; }
|
||||
</style>
|
||||
{/if}
|
|
@ -1,38 +1,70 @@
|
|||
<script>
|
||||
import { onMount } from 'svelte';
|
||||
import PageTitle from "$/components/PageTitle.svelte";
|
||||
import { getMarcasParaderos } from "$/services/mapas";
|
||||
import { storeParaderos } from "$/stores/global";
|
||||
import GoogleMap from '$/components/MyMap.svelte'
|
||||
import IconLoading from "$/components/IconLoading.svelte";
|
||||
import ModalParadero from "./ModalParadero.svelte";
|
||||
import { getRegiones } from "$/services/regiones";
|
||||
import { getComunas } from "$/services/comunas";
|
||||
// components
|
||||
import PageTitle from "$/components/PageTitle.svelte"
|
||||
import IconLoading from "$/components/IconLoading.svelte"
|
||||
import FormParadero from "./FormParadero.svelte"
|
||||
|
||||
let google_api_key = null
|
||||
let google_marks = []
|
||||
let google_window = null
|
||||
let google_map = null
|
||||
let data_map = null
|
||||
let paradero = null
|
||||
let id_comuna = ''
|
||||
let id_region = ''
|
||||
// services
|
||||
import { getRegiones } from "$/services/regiones"
|
||||
import { getComunas } from "$/services/comunas"
|
||||
import { getMarcasParaderos } from "$/services/mapas"
|
||||
|
||||
// libs
|
||||
import { onMount } from 'svelte'
|
||||
import { storeParaderos } from "$/stores/global"
|
||||
import imagenParada from '$/assets/parada-de-autobus.png'
|
||||
|
||||
let myMap = null
|
||||
let elMap = null
|
||||
let loading = false
|
||||
let regiones = []
|
||||
let comunas = []
|
||||
let comunas_region = []
|
||||
let search = ''
|
||||
let search_time = null;
|
||||
let search_paraderos = []
|
||||
let loading = false
|
||||
|
||||
$: onSearch(search)
|
||||
let comunas_x_region = []
|
||||
let L = null
|
||||
let iconParada = null
|
||||
let markers = []
|
||||
let form = {}
|
||||
let parada = null
|
||||
|
||||
cargar_regiones_comunas()
|
||||
|
||||
$: myMap && crear_marcadores_por_criterio()
|
||||
|
||||
onMount(() => {
|
||||
if(globalThis.L) create_map();
|
||||
cargar_paraderos_todos($storeParaderos)
|
||||
})
|
||||
|
||||
function create_map() {
|
||||
if (!elMap) return;
|
||||
if (!L) L = globalThis.L;
|
||||
if (!iconParada) {
|
||||
iconParada = L.icon({
|
||||
iconUrl: imagenParada,
|
||||
iconSize: [64, 64],
|
||||
iconAnchor: [32, 64],
|
||||
popupAnchor: [0, -32]
|
||||
})
|
||||
}
|
||||
if (!myMap) {
|
||||
myMap = L.map(elMap)
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||
{ attribution: '© <a 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 cargar_regiones_comunas() {
|
||||
try {
|
||||
regiones = await getRegiones()
|
||||
|
@ -46,10 +78,7 @@
|
|||
try {
|
||||
loading = true
|
||||
const paraderos = data_default || await getMarcasParaderos()
|
||||
storeParaderos.set(paraderos);
|
||||
data_map = paraderos;
|
||||
google_api_key = paraderos.google_api_key;
|
||||
runSearch()
|
||||
storeParaderos.set(paraderos)
|
||||
} catch (error) {
|
||||
alert(error)
|
||||
} finally {
|
||||
|
@ -57,134 +86,113 @@
|
|||
}
|
||||
}
|
||||
|
||||
function onChangeRegion() {
|
||||
comunas_region = comunas.filter(el => el.id_region === Number(id_region))
|
||||
runSearch()
|
||||
function crear_marcadores_por_criterio() {
|
||||
if (form.id_region) {
|
||||
comunas_x_region = comunas.filter(comuna => comuna.id_region === form.id_region)
|
||||
}
|
||||
if (!$storeParaderos?.marks) {
|
||||
setTimeout(crear_marcadores_por_criterio, 1000)
|
||||
return
|
||||
}
|
||||
// 1. eliminar los marcadores anteriores
|
||||
markers.forEach(marker => marker.remove())
|
||||
|
||||
// 2. filtrar resultado de marcadores
|
||||
const paraderos = $storeParaderos.marks.filter(m => {
|
||||
// filtrar por comunas de la region
|
||||
if (form.id_region && !form.id_comuna) {
|
||||
const existe = comunas_x_region.findIndex(com => com.id_comuna === m.id_comuna) !== -1
|
||||
if (!existe) return false
|
||||
}
|
||||
|
||||
function onSearch(search) {
|
||||
if (!data_map) return;
|
||||
search_time && clearTimeout(search_time)
|
||||
search_time = setTimeout(runSearch, 1000)
|
||||
}
|
||||
// filtrar por comuna seleccionada
|
||||
if (form.id_comuna && m.id_comuna !== form.id_comuna) return false
|
||||
|
||||
function runSearch() {
|
||||
console.log('runSearch()')
|
||||
search_paraderos = data_map.marks.filter(el => {
|
||||
if (id_region && !id_comuna) {
|
||||
const existe = comunas_region.findIndex(com => com.id_comuna === el.id_comuna) !== -1;
|
||||
if (!existe) return false;
|
||||
}
|
||||
if (id_comuna && el.id_comuna !== Number(id_comuna)) return false;
|
||||
return !search || el.location.toUpperCase().indexOf(search.toUpperCase()) !== -1;
|
||||
// filtrar por texto de busqueda
|
||||
if (form.search && m.location.toUpperCase().indexOf(form.search.toUpperCase()) === -1) return false
|
||||
|
||||
// filtro coincide a criterio
|
||||
return true
|
||||
})
|
||||
|
||||
onMostrarParaderos(google_map)
|
||||
// 3. crear marcadores
|
||||
for (let mark of paraderos) {
|
||||
const { lat, lng } = mark.position
|
||||
const marker = L.marker([lat, lng], { icon: iconParada }).addTo(myMap)
|
||||
const { title, location } = mark;
|
||||
const html = `${title}<br>${location}`
|
||||
|
||||
marker.bindTooltip(html)
|
||||
|
||||
marker.on('click', function() {
|
||||
parada = { ...mark }
|
||||
})
|
||||
markers.push(marker)
|
||||
}
|
||||
|
||||
// 4. centrar mapa
|
||||
if (myMap && paraderos.length) {
|
||||
const { lat, lng } = paraderos[0].position
|
||||
myMap.setView([ lat, lng ],16)
|
||||
const bounds = myMap.getBounds()
|
||||
paraderos.forEach(el => bounds.extend(el.position))
|
||||
myMap.fitBounds(bounds)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function onMostrarParaderos(map) {
|
||||
const google = globalThis.google;
|
||||
if (!google) return;
|
||||
|
||||
console.log('onMostrarParaderos', map)
|
||||
if (!google_map) google_map = map;
|
||||
|
||||
// elimina las marcas anteriores en el mapa
|
||||
google_marks.forEach(mark => mark.setMap(null))
|
||||
|
||||
if (!google_window) google_window = new google.maps.InfoWindow();
|
||||
|
||||
google_marks = [];
|
||||
for (const nuevaMarca of search_paraderos) {
|
||||
const { position, title, location, url_image, id_paradero } = nuevaMarca;
|
||||
const marker = new google.maps.Marker({ position, map: map, title });
|
||||
|
||||
marker.addListener("click", () => {
|
||||
google_window.close();
|
||||
const imagen = url_image ? `<img alt="Imagen" src="${url_image}" width="200">` : ''
|
||||
const html = `
|
||||
<h1>${title}</h1>
|
||||
<p>${location}</p>
|
||||
<button class="btn btn-primary" onclick="onEditaParada(${id_paradero})">Editar</button>
|
||||
<hr>
|
||||
${imagen}
|
||||
`
|
||||
google_window.setContent(html);
|
||||
google_window.open(marker.getMap(), marker);
|
||||
});
|
||||
|
||||
google_marks.push(marker)
|
||||
}
|
||||
|
||||
map && map.setCenter(search_paraderos[0].position)
|
||||
|
||||
// aplicar zoom en base a las coordenadas
|
||||
const bounds = new google.maps.LatLngBounds();
|
||||
search_paraderos.forEach(el => bounds.extend(el.position))
|
||||
google_map && google_map.fitBounds(bounds);
|
||||
}
|
||||
|
||||
globalThis.onEditaParada = function(id_paradero) {
|
||||
paradero = { id_paradero }
|
||||
function run_search_text() {
|
||||
form.time_search && clearTimeout(form.time_search)
|
||||
form.time_search = setTimeout(() => crear_marcadores_por_criterio(), 1000)
|
||||
}
|
||||
</script>
|
||||
|
||||
<PageTitle>Paraderos</PageTitle>
|
||||
<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="card">
|
||||
<div class="card-header">
|
||||
<div class="row">
|
||||
<div class="col-md-auto">
|
||||
<button class="btn btn-outline-secondary" on:click|preventDefault={() => cargar_paraderos_todos(null)}><i class="bi bi-arrow-repeat"></i> Refrescar</button>
|
||||
<div class="col-md">
|
||||
<PageTitle>
|
||||
{#if loading}<IconLoading />{/if}
|
||||
Paraderos
|
||||
</PageTitle>
|
||||
</div>
|
||||
<div class="col-md-auto">
|
||||
<div class="input-group">
|
||||
<div class="input-group mb-sm-3">
|
||||
<div class="input-group-text">Región</div>
|
||||
<select bind:value={id_region} class="form-select" on:change={onChangeRegion}>
|
||||
<select bind:value={form.id_region} class="form-select" on:change={crear_marcadores_por_criterio}>
|
||||
<option value=""></option>
|
||||
{#each regiones as region}
|
||||
<option value={region.id_region}>{region.nombre_region}</option>
|
||||
{#each regiones as r}
|
||||
<option value={r.id_region}>{r.nombre_region}</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-auto">
|
||||
<div class="input-group">
|
||||
<div class="input-group mb-sm-3">
|
||||
<div class="input-group-text">Comuna</div>
|
||||
<select bind:value={id_comuna} class="form-select" on:change={runSearch}>
|
||||
<select bind:value={form.id_comuna} class="form-select" on:change={crear_marcadores_por_criterio}>
|
||||
<option value=""></option>
|
||||
{#each comunas_region as comuna}
|
||||
<option value={comuna.id_comuna}>{comuna.nombre_comuna}</option>
|
||||
{#each comunas_x_region as c}
|
||||
<option value={c.id_comuna}>{c.nombre_comuna}</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-auto">
|
||||
<div class="input-group">
|
||||
<input type="search" bind:value={search} placeholder="busqueda..." class="form-control">
|
||||
<div class="input-group mb-sm-3">
|
||||
<input type="search" bind:value={form.search} class="form-control" on:input={run_search_text}>
|
||||
<div class="input-group-text"><i class="bi bi-search"></i></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
{#if loading}
|
||||
<IconLoading />
|
||||
<span>Cargando ubicaciones...</span>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
{#if google_api_key}
|
||||
<GoogleMap
|
||||
{google_api_key}
|
||||
on:start={ev => onMostrarParaderos(ev.detail)}
|
||||
/>
|
||||
{/if}
|
||||
<div bind:this={elMap} style="height: 100vh;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{#if paradero}
|
||||
<ModalParadero {paradero} on:close={() => paradero = null} />
|
||||
{/if}
|
||||
<FormParadero {parada} on:close={() => parada = null} />
|
|
@ -1,104 +1,108 @@
|
|||
<script>
|
||||
// componentes
|
||||
import PageTitle from "$/components/PageTitle.svelte";
|
||||
import GoogleMap from '$/components/MyMap.svelte'
|
||||
|
||||
import IconLoading from "$/components/IconLoading.svelte";
|
||||
import imagenParada from '$/assets/parada-de-autobus.png'
|
||||
import { onMount } from "svelte";
|
||||
|
||||
// servicios
|
||||
import { getOperadores } from "$/services/operadores";
|
||||
import { getLineas } from "$/services/lineas";
|
||||
import { getRutas } from "$/services/mapas";
|
||||
|
||||
let myMap = null
|
||||
let elMap = null
|
||||
let operadores = []
|
||||
let lineas = []
|
||||
let positions = []
|
||||
let id_operador = '';
|
||||
let id_linea = '';
|
||||
let loading = false;
|
||||
let google_api_key = null;
|
||||
let google_map = null;
|
||||
let polyline = null;
|
||||
let id_operador = ''
|
||||
let id_linea = ''
|
||||
let loading = false
|
||||
let polyline = null
|
||||
let iconParada = null
|
||||
let L = null
|
||||
let marker1 = null
|
||||
let marker2 = null
|
||||
|
||||
getOperadores().then(data => operadores = data).catch(error => alert(error))
|
||||
getLineas().then(data => lineas = data).catch(error => alert(error))
|
||||
|
||||
$: cargar_coordenadas(id_operador, id_linea)
|
||||
|
||||
Promise.all([ getOperadores(), getLineas() ])
|
||||
.then(res => {
|
||||
operadores = res[0]
|
||||
lineas = res[1]
|
||||
onMount(() => {
|
||||
create_map()
|
||||
})
|
||||
.catch(error => alert(error))
|
||||
|
||||
function create_map() {
|
||||
if (!elMap) return;
|
||||
if (!L) L = globalThis.L;
|
||||
if (!iconParada) {
|
||||
iconParada = L.icon({
|
||||
iconUrl: imagenParada,
|
||||
iconSize: [64, 64],
|
||||
iconAnchor: [32, 64],
|
||||
popupAnchor: [0, -32]
|
||||
})
|
||||
}
|
||||
if (!myMap) {
|
||||
myMap = L.map(elMap)
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||
{ attribution: '© <a 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 cargar_coordenadas(id_operador, id_linea) {
|
||||
try {
|
||||
loading = true
|
||||
polyline && polyline.setMap(null);
|
||||
polyline = null;
|
||||
polyline && polyline.remove()
|
||||
marker1 && marker1.remove()
|
||||
marker2 && marker2.remove()
|
||||
|
||||
if (!id_operador || !id_linea) return;
|
||||
const data = await getRutas({ id_linea })
|
||||
if (!google_api_key) google_api_key = data.google_api_key;
|
||||
|
||||
positions = data.positions
|
||||
// .sort((a,b) => a.shape_pt_sequence < b.shape_pt_sequence? -1 : 1)
|
||||
.map(el => ({ lat: el.shape_pt_lat, lng: el.shape_pt_lon }))
|
||||
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: iconParada }).addTo(myMap)
|
||||
marker2 = L.marker(coordenadas[coordenadas.length -1], { icon: iconParada }).addTo(myMap)
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
alert(error)
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
function onPolyline(map) {
|
||||
google_map = map;
|
||||
map.setZoom(0)
|
||||
onMostrarCoordenadas(positions)
|
||||
}
|
||||
|
||||
$: onMostrarCoordenadas(positions)
|
||||
|
||||
function onMostrarCoordenadas(positions) {
|
||||
if (!google_map) return;
|
||||
const google = globalThis.google;
|
||||
|
||||
const minmax = positions.reduce((acum, el) => {
|
||||
if (acum.min_lat === 0 || el.lat < acum.min_lat) acum.min_lat = el.lat;
|
||||
if (acum.max_lat === 0 || el.lat > acum.max_lat) acum.max_lat = el.lat;
|
||||
if (acum.min_lng === 0 || el.lng < acum.min_lng) acum.min_lng = el.lng;
|
||||
if (acum.max_lng === 0 || el.lng > acum.max_lng) acum.max_lng = el.lng;
|
||||
return { ...acum }
|
||||
}, { min_lat: 0, max_lat: 0, min_lng: 0, max_lng: 0 })
|
||||
|
||||
// centrar el mapa
|
||||
const pos_center = {
|
||||
lat: minmax.min_lat + (minmax.max_lat - minmax.min_lat) / 2,
|
||||
lng: minmax.min_lng + (minmax.max_lng - minmax.min_lng) / 2,
|
||||
}
|
||||
google_map.setCenter(pos_center)
|
||||
|
||||
// aplicar zoom en base a las coordenadas
|
||||
const bounds = new google.maps.LatLngBounds();
|
||||
positions.forEach(el => bounds.extend(el))
|
||||
google_map.fitBounds(bounds);
|
||||
|
||||
polyline && polyline.setMap(null);
|
||||
polyline = null;
|
||||
|
||||
polyline = new google.maps.Polyline({
|
||||
path: positions,
|
||||
geodesic: true,
|
||||
strokeColor: "#FF0000",
|
||||
strokeOpacity: 1.0,
|
||||
strokeWeight: 2,
|
||||
// editable: true,
|
||||
// draggable: true
|
||||
});
|
||||
polyline.setMap(google_map);
|
||||
}
|
||||
</script>
|
||||
|
||||
<PageTitle>Paraderos</PageTitle>
|
||||
<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="card">
|
||||
<div class="card-header">
|
||||
<div class="row">
|
||||
<div class="col-md">
|
||||
<PageTitle>
|
||||
{#if loading}<IconLoading />{/if}
|
||||
Rutas
|
||||
</PageTitle>
|
||||
</div>
|
||||
<div class="col-md-auto">
|
||||
<div class="input-group">
|
||||
<div class="input-group-text">Operador</div>
|
||||
|
@ -121,22 +125,10 @@
|
|||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
{#if loading}
|
||||
<IconLoading />
|
||||
<span>Cargando rutas...</span>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
{#if google_api_key}
|
||||
<div class={id_linea ? "d-block" : "d-none"}>
|
||||
<GoogleMap
|
||||
{google_api_key}
|
||||
on:start={ev => onPolyline(ev.detail)}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
<div bind:this={elMap} style="height: 100vh;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue