folk-canvas/demo/proximity-maps.html

195 lines
5.0 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Proximity Maps</title>
<style>
* {
box-sizing: border-box;
}
html {
height: 100%;
}
body {
min-height: 100%;
position: relative;
margin: 0;
}
folk-map,
geo-wiki {
display: block;
height: 100%;
width: 100%;
}
geo-wiki {
display: block;
background: white;
border: solid 2px black;
border-radius: 5px;
ul {
height: 100%;
overflow: auto;
margin: 0;
scroll-padding-block-end: 1rem;
}
}
folk-cluster {
display: block;
position: absolute;
inset: 0 0 0 0;
pointer-events: none;
background-color: #b4d8f63b;
}
folk-weather {
display: block;
background: white;
border: solid 2px black;
border-radius: 5px;
padding: 1rem;
}
</style>
</head>
<body>
<folk-proximity>
<fc-geometry id="g1" x="25" y="100" width="400" height="200">
<folk-map coordinates="40.76845173617708, -73.97983074188234" zoom="15"></folk-map>
</fc-geometry>
<fc-geometry id="g2" x="50" y="600" width="400" height="250">
<folk-map coordinates="51.50404120260676, -0.14007568359375003" zoom="13"></folk-map>
</fc-geometry>
<fc-geometry id="g3" x="500" y="500" width="500" height="300">
<geo-wiki></geo-wiki>
</fc-geometry>
<fc-geometry id="g4" x="450" y="100">
<folk-weather></folk-weather>
</fc-geometry>
</folk-proximity>
<script type="module">
import { FolkGeometry } from '../src/canvas/fc-geometry.ts';
import { FolkMap } from '../src/folk-map.ts';
import { FolkWeather } from '../src/folk-weather.ts';
import { FolkCluster, FolkProximity } from '../src/folk-proximity.ts';
class GeoWiki extends HTMLElement {
static tagName = 'geo-wiki';
static define() {
customElements.define(this.tagName, this);
}
static observedAttributes = ['coordinates'];
#coordinates = [0, 0];
#results = [];
get coordinates() {
return this.#coordinates;
}
set coordinates(coordinates) {
this.setAttribute('coordinates', coordinates.join(', '));
}
attributeChangedCallback(name, oldValue, newValue) {
if (name === 'coordinates') {
this.#coordinates = newValue.split(',').map((str) => Number(str)) || [0, 0];
this.searchWiki(this.#coordinates);
}
}
async searchWiki([lat, long]) {
const params = new URLSearchParams({
action: 'query',
format: 'json',
list: 'geosearch',
gscoord: `${lat}|${long}`,
gsradius: '1000',
gslimit: '50',
origin: '*',
});
// https://www.mediawiki.org/wiki/API:Geosearch
this.#results = await fetch(`https://en.wikipedia.org/w/api.php?${params}`)
.then((response) => response.json())
.then((data) => data?.query?.geosearch ?? []);
this.#renderResults();
}
#renderResults() {
this.firstElementChild?.remove();
const list = document.createElement('ul');
for (const result of this.#results) {
const li = document.createElement('li');
const a = document.createElement('a');
a.href = `https://en.wikipedia.org/wiki/${result.title}`;
a.textContent = result.title;
li.appendChild(a);
list.appendChild(li);
}
this.appendChild(list);
}
}
FolkCluster.registerElement({
constructor: FolkMap,
events: {
recenter: (e) => ({
lat: e.target.coordinates.lat,
lng: e.target.coordinates.lng,
}),
},
onAdd: (element) => ({
lat: element.coordinates.lat,
lng: element.coordinates.lng,
}),
});
FolkCluster.registerElement({
constructor: FolkWeather,
onAdd: console.log,
onUpdate(element, data, changes) {
const lat = data.get('lat');
const lng = data.get('lng');
if (lat && lng) {
element.coordinates = [lat, lng];
}
},
});
FolkCluster.registerElement({
constructor: GeoWiki,
onUpdate(element, data, changes) {
const lat = data.get('lat');
const lng = data.get('lng');
if (lat && lng) {
element.coordinates = [lat, lng];
}
},
});
FolkGeometry.define();
FolkMap.define();
FolkCluster.define();
FolkProximity.define();
FolkWeather.define();
GeoWiki.define();
</script>
</body>
</html>