199 lines
5.5 KiB
Plaintext
199 lines
5.5 KiB
Plaintext
---
|
|
import Layout from 'layouts/PageLayout.astro'
|
|
import 'leaflet/dist/leaflet.css'
|
|
import 'leaflet-geosearch/dist/geosearch.css'
|
|
import CheckBox from 'components/CheckBox.astro'
|
|
import Radios from 'components/Radios.astro'
|
|
|
|
const metadata = {
|
|
title: 'Maps',
|
|
ignoreTitleTemplate: true,
|
|
}
|
|
---
|
|
|
|
<Layout metadata={metadata}>
|
|
|
|
<div class="h-[calc(100vh-16rem)] flex flex-row">
|
|
<div class="w-1/5 flex flex-col">
|
|
<p id="message" class="hidden text-center mb-3">pouet</p>
|
|
<p class="text-center text-2xl mb-3">Filtre :</p>
|
|
<div class="grow">
|
|
<p>note minimal :</p>
|
|
<Radios
|
|
values={[
|
|
{name: "1", label: "1", checked: true},
|
|
{name: "2", label: "2"},
|
|
{name: "3", label: "3"},
|
|
{name: "1h", label: "1h"},
|
|
{name: "2h", label: "2h"},
|
|
{name: "3h", label: "3h"},
|
|
]}
|
|
/>
|
|
<p class="text-center text-xl mb-3">Type POI :</p>
|
|
<CheckBox
|
|
label="Bar, Pub, Café,..."
|
|
name="drink"
|
|
checked
|
|
/>
|
|
</div>
|
|
<div class="mb-3">
|
|
<p class="text-center text-xl mb-3">Source :</p>
|
|
<CheckBox
|
|
label="Open Trip Maps"
|
|
name="otm"
|
|
checked
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div class="flex flex-col grow">
|
|
<div class="w-full h-96 grow" id="map" />
|
|
</div>
|
|
</div>
|
|
<!-- TODO: faire en sort que le style soit propre -->
|
|
|
|
<!-- for remouve footer -->
|
|
<!-- <div slot="footer"></div> -->
|
|
<!-- penser a rm 11 au rem au dessus pour la taille -->
|
|
</Layout>
|
|
|
|
<script>
|
|
import L, {Popup} from 'leaflet'
|
|
import markerShadow from "leaflet/dist/images/marker-shadow.png"
|
|
import markerIcon from "leaflet/dist/images/marker-icon.png"
|
|
import { OpenStreetMapProvider } from 'leaflet-geosearch'
|
|
import { GeoSearchControl } from 'leaflet-geosearch'
|
|
|
|
const icon = {icon: new L.Icon({iconUrl: markerIcon.src, shadowUrl: markerShadow.src, iconAnchor: [13,41]})}
|
|
|
|
const BACK_URL = "http://localhost:3001/" //XXX : mettre url de prod
|
|
|
|
// declare map
|
|
const map = L.map('map', {
|
|
center: [51.5, -0.09],
|
|
zoom: 13,
|
|
preferCanvas: true,
|
|
zoomControl: false
|
|
})
|
|
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
|
maxZoom: 19,
|
|
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
|
|
}).addTo(map)
|
|
|
|
// move zoom ctl to bottom
|
|
L.control.zoom({
|
|
position: 'bottomleft'
|
|
}).addTo(map)
|
|
|
|
const provider = new OpenStreetMapProvider()
|
|
|
|
map.addControl(
|
|
GeoSearchControl({
|
|
notFoundMessage: 'Adresse introuvable !',
|
|
provider,
|
|
showMarker: false,
|
|
style: 'bar',
|
|
}),
|
|
)
|
|
|
|
let poiMarkers = new Array<L.Marker>
|
|
let minimalNote = "1"
|
|
let drink = true
|
|
let otm = true
|
|
|
|
// run api search
|
|
function searchBox(){
|
|
const nordWest = map.getBounds().getNorthWest()
|
|
const southEast = map.getBounds().getSouthEast()
|
|
const params: URLSearchParams = new URLSearchParams()
|
|
|
|
params.append("lon1", nordWest.lng.toString())
|
|
params.append("lat1", nordWest.lat.toString())
|
|
params.append("lon2", southEast.lng.toString())
|
|
params.append("lat2", southEast.lat.toString())
|
|
params.append("rate", minimalNote)
|
|
|
|
if(drink && otm){
|
|
fetch(`${BACK_URL}otm/box?${params.toString()}`,{method: 'GET',headers: {'Content-Type': 'application/json'}}).then(function (response) {
|
|
return response.json()
|
|
}).then(function (data) {
|
|
poiMarkers.forEach(element => {
|
|
element.remove()
|
|
})
|
|
console.log(data)
|
|
data.features.forEach(element => {
|
|
const prop = element.properties
|
|
const popup: Popup = new Popup()
|
|
let tags = new String()
|
|
prop.kinds.split(",").forEach(element => {
|
|
tags += "- " + element + "<br/>"
|
|
})
|
|
const poiMarker = L.marker([element.geometry.coordinates[1],element.geometry.coordinates[0]],icon)
|
|
.bindPopup(`<b>${prop.name}</b><br/>note : ${prop.rate} <br/>tags:<br/> ${tags}`)
|
|
poiMarker.addTo(map)
|
|
poiMarkers.push(poiMarker)
|
|
})
|
|
}).catch(function (err) {
|
|
console.warn('Something went wrong.', err)
|
|
})
|
|
}
|
|
}
|
|
|
|
// fonciton pour lancer la recherche de box sur l'api
|
|
function sender(){
|
|
if(map.getZoom() >= 13){
|
|
console.log("zoom OKAY")
|
|
//TODO: mettre un message de recherche en cour
|
|
searchBox()
|
|
}else{
|
|
console.log("zoom more to see result")
|
|
}
|
|
}
|
|
// envent pour lancer la recherche
|
|
const cooldown = 1000
|
|
sender()
|
|
let timeoutHandle = window.setTimeout(sender, cooldown)
|
|
|
|
window.clearTimeout(timeoutHandle)
|
|
|
|
map.addEventListener("move",() =>{
|
|
window.clearTimeout(timeoutHandle)
|
|
timeoutHandle = window.setTimeout(sender, cooldown)
|
|
})
|
|
|
|
map.addEventListener("zoom", () => {
|
|
if(map.getZoom() <= 11){
|
|
poiMarkers.forEach(element => {
|
|
element.remove()
|
|
})
|
|
}
|
|
})
|
|
|
|
document.querySelectorAll<HTMLInputElement>("input[type='checkbox']").forEach(e =>{
|
|
e.addEventListener("click", () => {
|
|
switch (e.name) {
|
|
case "drink":
|
|
drink = e.checked
|
|
break;
|
|
|
|
case "otm":
|
|
otm = e.checked
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
poiMarkers.forEach(element => {
|
|
element.remove()
|
|
})
|
|
searchBox()
|
|
})
|
|
})
|
|
|
|
document.querySelectorAll<HTMLInputElement>('input[name="note-min"]').forEach(e => {
|
|
e.addEventListener("click", () => {
|
|
minimalNote = e.value
|
|
})
|
|
searchBox()
|
|
})
|
|
</script>
|