se agrega mapa de rutas
parent
518d07d736
commit
50c6f252b3
|
@ -1,80 +0,0 @@
|
||||||
<script>
|
|
||||||
import { onMount, createEventDispatcher } from 'svelte'
|
|
||||||
const dispatch = createEventDispatcher();
|
|
||||||
|
|
||||||
export let google_api_key = null;
|
|
||||||
export let center = null;
|
|
||||||
export let zoom = 4;
|
|
||||||
export let marks = [];
|
|
||||||
|
|
||||||
let mapEl = null;
|
|
||||||
let google = null;
|
|
||||||
let google_window = null;
|
|
||||||
let google_map = null;
|
|
||||||
let google_marks = []
|
|
||||||
|
|
||||||
$: cargarMarcadores(marks)
|
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
if (!globalThis.google) {
|
|
||||||
const el = document.createElement('script')
|
|
||||||
el.src = "https://maps.googleapis.com/maps/api/js?key=" + google_api_key + "&callback=initMap&v=weekly"
|
|
||||||
document.body.appendChild(el)
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
globalThis.initMap = function() {
|
|
||||||
google = globalThis.google;
|
|
||||||
google_window = new google.maps.InfoWindow();
|
|
||||||
google_map = new google.maps.Map(mapEl, { zoom, center });
|
|
||||||
cargarMarcadores(marks)
|
|
||||||
}
|
|
||||||
|
|
||||||
function cargarMarcadores(marks) {
|
|
||||||
if (!google_map) return;
|
|
||||||
|
|
||||||
dispatch('loading', true)
|
|
||||||
|
|
||||||
for (const mark of google_marks) {
|
|
||||||
mark.setMap(null)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (marks.length) google_map.setCenter(marks[0].position)
|
|
||||||
|
|
||||||
google_marks = []
|
|
||||||
for (const mark of marks) {
|
|
||||||
const { position, title, location, url_image, id_paradero } = mark;
|
|
||||||
const marker = new google.maps.Marker({ position, map: google_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="onEdita(${id_paradero})">Editar</button>
|
|
||||||
<hr>
|
|
||||||
${imagen}
|
|
||||||
`
|
|
||||||
google_window.setContent(html);
|
|
||||||
google_window.open(marker.getMap(), marker);
|
|
||||||
});
|
|
||||||
|
|
||||||
google_marks.push(marker)
|
|
||||||
}
|
|
||||||
|
|
||||||
// google.maps.event.addListener(google_map, "zoom_changed", function () {
|
|
||||||
// console.log({ zoom: google_map.zoom });
|
|
||||||
// });
|
|
||||||
|
|
||||||
dispatch('loading', false)
|
|
||||||
};
|
|
||||||
|
|
||||||
globalThis.onEdita = function(id_paradero) {
|
|
||||||
google_window.close();
|
|
||||||
dispatch('edita', id_paradero)
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div bind:this={mapEl} style="height: 800px; max-height: 90vh;">Cargando...</div>
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
<script>
|
||||||
|
import { onMount, createEventDispatcher } from 'svelte'
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
|
export let google_api_key = ''
|
||||||
|
let mapEl = null
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
if (!globalThis.google) {
|
||||||
|
const el = document.createElement('script')
|
||||||
|
el.src = "https://maps.googleapis.com/maps/api/js?key=" + google_api_key + "&callback=initMap&v=weekly"
|
||||||
|
document.body.appendChild(el)
|
||||||
|
} else {
|
||||||
|
globalThis.initMap()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
globalThis.initMap = function() {
|
||||||
|
const google = globalThis.google;
|
||||||
|
const google_map = new google.maps.Map(mapEl);
|
||||||
|
dispatch('start', google_map)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div bind:this={mapEl} style="height: 800px; max-height: 90vh;">Cargando...</div>
|
|
@ -1,13 +1,18 @@
|
||||||
<script>
|
<script>
|
||||||
|
import { onMount } from 'svelte';
|
||||||
import PageTitle from "$/components/PageTitle.svelte";
|
import PageTitle from "$/components/PageTitle.svelte";
|
||||||
import { getMarcasParaderos } from "$/services/mapas";
|
import { getMarcasParaderos } from "$/services/mapas";
|
||||||
import { storeParaderos } from "$/stores/global";
|
import { storeParaderos } from "$/stores/global";
|
||||||
import GoogleMap from '$/components/GoogleMap.svelte'
|
import GoogleMap from '$/components/MyMap.svelte'
|
||||||
import IconLoading from "$/components/IconLoading.svelte";
|
import IconLoading from "$/components/IconLoading.svelte";
|
||||||
import ModalParadero from "./ModalParadero.svelte";
|
import ModalParadero from "./ModalParadero.svelte";
|
||||||
import { getRegiones } from "$/services/regiones";
|
import { getRegiones } from "$/services/regiones";
|
||||||
import { getComunas } from "$/services/comunas";
|
import { getComunas } from "$/services/comunas";
|
||||||
|
|
||||||
|
let google_api_key = null
|
||||||
|
let google_marks = []
|
||||||
|
let google_window = null
|
||||||
|
let google_map = null
|
||||||
let data_map = null
|
let data_map = null
|
||||||
let paradero = null
|
let paradero = null
|
||||||
let id_comuna = ''
|
let id_comuna = ''
|
||||||
|
@ -20,11 +25,14 @@
|
||||||
let search_paraderos = []
|
let search_paraderos = []
|
||||||
let loading = false
|
let loading = false
|
||||||
|
|
||||||
$: init_google_map($storeParaderos)
|
|
||||||
$: onSearch(search)
|
$: onSearch(search)
|
||||||
|
|
||||||
cargar_regiones_comunas()
|
cargar_regiones_comunas()
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
cargar_paraderos_todos($storeParaderos)
|
||||||
|
})
|
||||||
|
|
||||||
async function cargar_regiones_comunas() {
|
async function cargar_regiones_comunas() {
|
||||||
try {
|
try {
|
||||||
regiones = await getRegiones()
|
regiones = await getRegiones()
|
||||||
|
@ -34,22 +42,26 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function cargar_paraderos_todos(data_default) {
|
||||||
|
try {
|
||||||
|
loading = true
|
||||||
|
const paraderos = data_default || await getMarcasParaderos()
|
||||||
|
storeParaderos.set(paraderos);
|
||||||
|
data_map = paraderos;
|
||||||
|
google_api_key = paraderos.google_api_key;
|
||||||
|
runSearch()
|
||||||
|
} catch (error) {
|
||||||
|
alert(error)
|
||||||
|
} finally {
|
||||||
|
loading = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function onChangeRegion() {
|
function onChangeRegion() {
|
||||||
comunas_region = comunas.filter(el => el.id_region === Number(id_region))
|
comunas_region = comunas.filter(el => el.id_region === Number(id_region))
|
||||||
runSearch()
|
runSearch()
|
||||||
}
|
}
|
||||||
|
|
||||||
async function init_google_map(data_inicial) {
|
|
||||||
const paraderos = data_inicial || await getMarcasParaderos()
|
|
||||||
storeParaderos.set(paraderos);
|
|
||||||
data_map = paraderos;
|
|
||||||
runSearch()
|
|
||||||
}
|
|
||||||
|
|
||||||
function onEdita(id_paradero) {
|
|
||||||
paradero = { id_paradero }
|
|
||||||
}
|
|
||||||
|
|
||||||
function onSearch(search) {
|
function onSearch(search) {
|
||||||
if (!data_map) return;
|
if (!data_map) return;
|
||||||
search_time && clearTimeout(search_time)
|
search_time && clearTimeout(search_time)
|
||||||
|
@ -57,6 +69,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function runSearch() {
|
function runSearch() {
|
||||||
|
console.log('runSearch()')
|
||||||
search_paraderos = data_map.marks.filter(el => {
|
search_paraderos = data_map.marks.filter(el => {
|
||||||
if (id_region && !id_comuna) {
|
if (id_region && !id_comuna) {
|
||||||
const existe = comunas_region.findIndex(com => com.id_comuna === el.id_comuna) !== -1;
|
const existe = comunas_region.findIndex(com => com.id_comuna === el.id_comuna) !== -1;
|
||||||
|
@ -65,6 +78,55 @@
|
||||||
if (id_comuna && el.id_comuna !== Number(id_comuna)) return false;
|
if (id_comuna && el.id_comuna !== Number(id_comuna)) return false;
|
||||||
return !search || el.location.toUpperCase().indexOf(search.toUpperCase()) !== -1;
|
return !search || el.location.toUpperCase().indexOf(search.toUpperCase()) !== -1;
|
||||||
})
|
})
|
||||||
|
|
||||||
|
onMostrarParaderos(google_map)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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.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.fitBounds(bounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
globalThis.onEditaParada = function(id_paradero) {
|
||||||
|
paradero = { id_paradero }
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -74,7 +136,7 @@
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-auto">
|
<div class="col-md-auto">
|
||||||
<button class="btn btn-outline-secondary" on:click|preventDefault={() => init_google_map(null)}><i class="bi bi-arrow-repeat"></i> Refrescar</button>
|
<button class="btn btn-outline-secondary" on:click|preventDefault={() => cargar_paraderos_todos(null)}><i class="bi bi-arrow-repeat"></i> Refrescar</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-auto">
|
<div class="col-md-auto">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
|
@ -106,23 +168,18 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md">
|
<div class="col-md">
|
||||||
{#if loading}
|
{#if loading}
|
||||||
|
<IconLoading />
|
||||||
<span>Cargando ubicaciones...</span>
|
<span>Cargando ubicaciones...</span>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
{#if data_map}
|
{#if google_api_key}
|
||||||
<GoogleMap
|
<GoogleMap
|
||||||
google_api_key={data_map.google_api_key}
|
{google_api_key}
|
||||||
center={data_map.center}
|
on:start={ev => onMostrarParaderos(ev.detail)}
|
||||||
zoom={data_map.zoom}
|
|
||||||
marks={search_paraderos}
|
|
||||||
on:edita={ev => onEdita(ev.detail)}
|
|
||||||
on:loading={ev => loading = ev.detail}
|
|
||||||
/>
|
/>
|
||||||
{:else}
|
|
||||||
<IconLoading />
|
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import PageTitle from "$/components/PageTitle.svelte";
|
import PageTitle from "$/components/PageTitle.svelte";
|
||||||
import GoogleMap from '$/components/GoogleMap.svelte'
|
import GoogleMap from '$/components/MyMap.svelte'
|
||||||
import IconLoading from "$/components/IconLoading.svelte";
|
import IconLoading from "$/components/IconLoading.svelte";
|
||||||
import { getServicios } from "$/services/lineas";
|
import { getServicios } from "$/services/lineas";
|
||||||
import { getRutasServicio } from "$/services/mapas";
|
import { getRutasServicio } from "$/services/mapas";
|
||||||
|
@ -8,12 +8,16 @@
|
||||||
let data_map = null
|
let data_map = null
|
||||||
let lineas = []
|
let lineas = []
|
||||||
let servicios = []
|
let servicios = []
|
||||||
|
let positions = []
|
||||||
let id_linea = '';
|
let id_linea = '';
|
||||||
let id_servicio = '';
|
let id_servicio = '';
|
||||||
let loading = false
|
let loading = false;
|
||||||
|
let google_api_key = null;
|
||||||
|
let google_map = null;
|
||||||
|
let polyline = null;
|
||||||
|
|
||||||
cargar_servicios()
|
cargar_servicios()
|
||||||
$: cargar_rutas(id_linea, id_servicio)
|
$: cargar_coordenadas(id_linea, id_servicio)
|
||||||
|
|
||||||
async function cargar_servicios() {
|
async function cargar_servicios() {
|
||||||
try {
|
try {
|
||||||
|
@ -24,19 +28,72 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function cargar_rutas(id_linea, service_id) {
|
async function cargar_coordenadas(id_linea, servicio_direccion) {
|
||||||
try {
|
try {
|
||||||
if (!id_linea || !service_id) return;
|
loading = true
|
||||||
const data = await getRutasServicio({ id_linea, service_id })
|
polyline && polyline.setMap(null);
|
||||||
console.log({ data })
|
polyline = null;
|
||||||
|
|
||||||
|
if (!id_linea || !servicio_direccion) return;
|
||||||
|
const [ service_id, direction_id] = servicio_direccion.split('-');
|
||||||
|
const data = await getRutasServicio({ id_linea, service_id, direction_id })
|
||||||
|
if (!google_api_key) google_api_key = data.google_api_key;
|
||||||
|
|
||||||
|
positions = data.positions.map(el => ({ lat: el.shape_pt_lat, lng: el.shape_pt_lon }))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
alert(error)
|
alert(error)
|
||||||
|
} finally {
|
||||||
|
loading = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function init_google_map(data_inicial) {
|
function onPolyline(map) {
|
||||||
|
google_map = map;
|
||||||
|
// map.setZoom(8)
|
||||||
|
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>
|
</script>
|
||||||
|
|
||||||
<PageTitle>Paraderos</PageTitle>
|
<PageTitle>Paraderos</PageTitle>
|
||||||
|
@ -44,9 +101,6 @@
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-auto">
|
|
||||||
<button class="btn btn-outline-secondary" on:click|preventDefault={() => init_google_map(null)}><i class="bi bi-arrow-repeat"></i> Refrescar</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-auto">
|
<div class="col-md-auto">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<div class="input-group-text">Linea</div>
|
<div class="input-group-text">Linea</div>
|
||||||
|
@ -60,33 +114,29 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-auto">
|
<div class="col-md-auto">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<div class="input-group-text">Comuna</div>
|
<div class="input-group-text">Servicio</div>
|
||||||
<select bind:value={id_servicio} class="form-select">
|
<select bind:value={id_servicio} class="form-select">
|
||||||
<option value=""></option>
|
<option value=""></option>
|
||||||
{#each servicios.filter(el => el.id_linea === id_linea) as servicio}
|
{#each servicios.filter(el => el.id_linea === id_linea) as servicio}
|
||||||
<option value={servicio.service_id}>{servicio.service_id}</option>
|
<option value={`${servicio.service_id}-${servicio.direction_id}`}>{servicio.service_id} - {servicio.trip_headsign}</option>
|
||||||
{/each}
|
{/each}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md">
|
<div class="col-md">
|
||||||
{#if loading}
|
{#if loading}
|
||||||
|
<IconLoading />
|
||||||
<span>Cargando rutas...</span>
|
<span>Cargando rutas...</span>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
{#if data_map}
|
{#if google_api_key}
|
||||||
<GoogleMap
|
<GoogleMap
|
||||||
google_api_key={data_map.google_api_key}
|
{google_api_key}
|
||||||
center={data_map.center}
|
on:start={ev => onPolyline(ev.detail)}
|
||||||
zoom={data_map.zoom}
|
|
||||||
marks={[]}
|
|
||||||
on:loading={ev => loading = ev.detail}
|
|
||||||
/>
|
/>
|
||||||
{:else}
|
|
||||||
<IconLoading />
|
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
import { writable } from 'svelte/store'
|
import { writable } from 'svelte/store'
|
||||||
|
|
||||||
|
const cacheParaderos = JSON.parse(sessionStorage.getItem('cache-paraderos') || 'null') || null;
|
||||||
|
|
||||||
export const storeMessages = writable([]);
|
export const storeMessages = writable([]);
|
||||||
export const storeParaderos = writable(null);
|
export const storeParaderos = writable(cacheParaderos);
|
||||||
export const storeSession = writable({});
|
export const storeSession = writable({});
|
||||||
export const storeLayout = writable({ showSidebar: true });
|
export const storeLayout = writable({ showSidebar: true });
|
||||||
|
|
||||||
|
storeParaderos.subscribe(val => sessionStorage.setItem('cache-paraderos', JSON.stringify(val)))
|
Loading…
Reference in New Issue