Porównaj commity

...

4 Commity

Autor SHA1 Wiadomość Data
Anthony Catel 1b8e97ed82 Fix searchbox css 2022-03-30 12:08:14 +02:00
Anthony Catel 018168af8d Map: add comments 2022-03-30 11:17:30 +02:00
Anthony Catel ba573ed2fd Add support for compressed URL 2022-03-30 10:28:20 +02:00
Anthony Catel 633033b4d1 Various type fix 2022-03-30 09:33:56 +02:00
3 zmienionych plików z 93 dodań i 16 usunięć

Wyświetl plik

@ -10,6 +10,7 @@
"@types/google.maps": "^3.48.3",
"@vitejs/plugin-vue": "^2.2.4",
"@vueuse/core": "^8.2.0",
"fflate": "^0.7.3",
"js-base64": "^3.5.2",
"tailwindcss": "^3.0.23",
"tatween": "^0.2.0",

Wyświetl plik

@ -1,7 +1,7 @@
<template>
<div class="w-full h-full">
<input ref="pacinput" class="controls" :class="[mapLoaded ? '' : 'hidden']" type="text" placeholder="Search Box">
<div class="w-full h-full" id="map"></div>
<input ref="pacinput" id="pac-input" class="controls" :class="[mapLoaded ? '' : 'hidden']" type="text" placeholder="Search Box">
<div class="w-full h-full" ref="mapel"></div>
</div>
</template>
@ -10,7 +10,7 @@
import { Base64 } from 'js-base64'
import { onMounted, ref, watch, computed } from 'vue';
import { watchDebounced } from '@vueuse/core'
import { zlibSync, unzlibSync } from 'fflate';
const DEFAULT_MAP_POSITION = [48.862895, 2.286978, 18]
@ -35,9 +35,10 @@
const arrPoly = ref<google.maps.LatLng[]>([])
const mapLoaded = ref(false);
const pacinput = ref()
const mapel = ref()
let currentMap : google.maps.Map | undefined;
let currentPolygon : google.maps.Polygon | undefined;
let currentMap : google.maps.Map;
let currentPolygon : google.maps.Polygon;
onMounted(() => {
loader.loadCallback(e => {
@ -46,7 +47,7 @@
return;
}
currentMap = new google.maps.Map(document.getElementById("map"), {
currentMap = new google.maps.Map(mapel.value, {
zoom: mapPosition.value[2],
center: {
lat: mapPosition.value[0],
@ -62,20 +63,23 @@
searchBox.addListener('places_changed', () => {
const places = searchBox.getPlaces();
if (places.length == 0) {
if (!places || places.length == 0) {
return;
}
const place = places[0];
currentMap.setCenter(place.geometry.location);
if (place.geometry?.location) {
currentMap.setCenter(place.geometry.location);
}
currentMap.setZoom(17);
reset();
});
currentMap.addListener('bounds_changed', function() {
searchBox.setBounds(currentMap.getBounds());
searchBox.setBounds(currentMap.getBounds()!);
});
currentMap.addListener('center_changed', mapUpdated);
currentMap.addListener('zoom_changed', mapUpdated);
@ -107,13 +111,21 @@
["insert_at", "remove_at", "set_at"].forEach(ev => google.maps.event.addListener(poly.getPath(), ev, surfaceUpdated));
updatePolygonColor();
mapLoaded.value = true;
});
})
/*
Get the polygon color from the density value.
This is a simple linear interpolation between
green and red on the Hue space.
*/
const getHue = (val: number) => {
const min = 0.1;
/*
Clamp "max density" because any value
above 3.0 should be considered "red"
*/
const max = 3.0;
// inv lerp from the density
@ -138,9 +150,17 @@
const pos = currentMap.getCenter();
const zoom = currentMap.getZoom();
if (!pos || !zoom) {
return;
}
mapPosition.value = [pos.lat(), pos.lng(), zoom];
}
/*
Add a new point to our polygon
using the lat/lng position clicked on the map.
*/
const mapClicked = (ev: any) => {
currentPolygon.getPath().push(ev.latLng);
}
@ -148,6 +168,10 @@
const surfaceUpdated = () => {
arrPoly.value = currentPolygon.getPath().getArray().slice();
/*
Compute the surface area of our polygon.
google.maps.geometry.spherical.computeArea() returns the area in square meters
*/
emits('surfaceUpdate', google.maps.geometry.spherical.computeArea(currentPolygon.getPath()));
}
@ -159,23 +183,34 @@
updatePolygonColor();
}
/*
Deserialize out URL hash
*/
const loadHash = (hash: string) => {
if (hash[0] != 'b') {
if (hash[0] != 'b' && hash[0] != 'c') {
return loadLegacyHash(hash);
}
const buf = Base64.toUint8Array(hash.substr(1));
const isCompressed = hash[0] == 'c';
let buf = Base64.toUint8Array(hash.substr(1));
if (!buf) {
return;
}
if (isCompressed) {
buf = unzlibSync(buf)
}
/* Extract meta data (density, position & zoom) */
const meta = new Float32Array(buf.buffer, 0, 4);
/* Extract polygon path */
const data = new Float32Array(buf.buffer, 4*4);
currentMap.setCenter({lat: meta[1], lng: meta[2]});
currentMap.setZoom(meta[3]);
const path = [];
const path : google.maps.LatLngLiteral[] = [];
for (let i = 0; i < data.length; i += 2) {
path.push({
lat: data[i],
@ -191,6 +226,11 @@
emits('densityChange', meta[0]);
}
/*
This is the legacy hash decoder.
We keep it around so that original
links posted online keep working
*/
const loadLegacyHash = (hash: string) => {
const opt = hash.split(';');
const curPosition = opt.pop();
@ -201,8 +241,8 @@
currentMap.setZoom(parseInt(cursetting[2]));
}
const density = parseFloat(opt.pop()) || 1;
const path = [];
const density = parseFloat(opt.pop() ?? '') || 1;
const path : google.maps.LatLngLiteral[] = [];
for (let i = 0; i < opt.length; i++) {
const coord = opt[i].split(',');
@ -224,6 +264,21 @@
currentPolygon.getPath().clear();
}
/*
Generate URL hash from various data.
- density
- Map position (center position as lat/lng & zoom value)
- Our polygon path as lat/lng points
The generated buffer is then compressed (if needed) and Base64'd.
We consider every value to be a float and serialize
our data into a binary array with no extra information.
0 4 8 12 16 ....
[density][position lat][position long][zoom][...polygon points]
*/
const hash = computed(() => {
const buf = new Float32Array(arrPoly.value.length*2+4);
buf[0] = props.density;
@ -233,11 +288,27 @@
buf[4+i*2] = arrPoly.value[i].lat();
buf[4+i*2+1] = arrPoly.value[i].lng();
}
return 'b' + Base64.fromUint8Array(new Uint8Array(buf.buffer), true);
let outbuf = new Uint8Array(buf.buffer);
const isCompressed = outbuf.byteLength >= 150;
if (isCompressed) {
outbuf = zlibSync(outbuf, { level: 9 });
}
/*
*/
return (isCompressed ? 'c' : 'b') + Base64.fromUint8Array(outbuf, true);
})
watch(() => props.density, () => updatePolygonColor());
/*
Debounce the URL hash update
otherwise it would flood the browser history whenever the user
moves the polygon around
*/
watchDebounced(hash,
(hashval: string) => emits('hashChange', hashval),
{ debounce: 300 })

Wyświetl plik

@ -596,6 +596,11 @@ fastq@^1.6.0:
dependencies:
reusify "^1.0.4"
fflate@^0.7.3:
version "0.7.3"
resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.7.3.tgz#288b034ff0e9c380eaa2feff48c787b8371b7fa5"
integrity sha512-0Zz1jOzJWERhyhsimS54VTqOteCNwRtIlh8isdL0AXLo0g7xNTfTL7oWrkmCnPhZGocKIkWHBistBrrpoNH3aw==
fill-range@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"