172 lines
4.9 KiB
HTML
172 lines
4.9 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>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 {
|
|
border: solid 2px black;
|
|
border-radius: 5px;
|
|
ul {
|
|
height: 100%;
|
|
overflow: auto;
|
|
margin: 0;
|
|
scroll-padding-block-end: 1rem;
|
|
}
|
|
}
|
|
|
|
olk-hull {
|
|
display: block;
|
|
position: absolute;
|
|
inset: 0 0 0 0;
|
|
pointer-events: none;
|
|
background-color: #b4d8f63b;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<fc-geometry id="1" x="25" y="100" width="400" height="200">
|
|
<folk-map coordinates="52.09, 5.12" zoom="13"></folk-map>
|
|
</fc-geometry>
|
|
|
|
<fc-geometry id="2" x="50" y="550" width="400" height="250">
|
|
<folk-map coordinates="51.50404120260676, -0.14007568359375003" zoom="13"></folk-map>
|
|
</fc-geometry>
|
|
|
|
<fc-geometry id="3" x="500" y="400" width="500" height="300">
|
|
<geo-wiki coordinates="51.50404120260676, -0.14007568359375003"></geo-wiki>
|
|
</fc-geometry>
|
|
|
|
<script type="module">
|
|
import { FolkGeometry } from '../src/canvas/fc-geometry.ts';
|
|
import { FolkMap } from '../src/folk-map.ts';
|
|
import { FolkHull } from '../src/folk-hull.ts';
|
|
import { collisionDetection } from '../src/collision.ts';
|
|
|
|
FolkGeometry.register();
|
|
FolkMap.register();
|
|
FolkHull.register();
|
|
|
|
const geometries = Array.from(document.querySelectorAll('fc-geometry'));
|
|
|
|
const proximityMap = new Map(geometries.map((el) => [el, new Set()]));
|
|
|
|
function handleProximity(e) {
|
|
proximityMap.forEach((set, el) => {
|
|
if (el !== e.target) {
|
|
const alreadyIntersection = set.has(e.target);
|
|
// TODO: refactor this hack once resizing and the vertices API are figured out
|
|
const isNowIntersecting = collisionDetection(el.getClientRect(), e.target.getClientRect(), 100);
|
|
if (isNowIntersecting && !alreadyIntersection) {
|
|
set.add(e.target);
|
|
proximityMap.get(e.target)?.add(el);
|
|
} else if (alreadyIntersection && !isNowIntersecting) {
|
|
set.delete(e.target);
|
|
proximityMap.get(e.target)?.delete(el);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
document.addEventListener('move', handleProximity);
|
|
document.addEventListener('resize', handleProximity);
|
|
document.addEventListener('recenter', (e) => {
|
|
proximityMap.get(e.target.parentElement)?.forEach((el) => {
|
|
const content = el.firstElementChild;
|
|
if (content instanceof GeoWiki) {
|
|
const { lat, lng } = e.target.coordinates;
|
|
content.coordinates = [lat, lng];
|
|
}
|
|
});
|
|
});
|
|
|
|
class GeoWiki extends HTMLElement {
|
|
static tagName = 'geo-wiki';
|
|
|
|
static register() {
|
|
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);
|
|
}
|
|
}
|
|
|
|
GeoWiki.register();
|
|
</script>
|
|
</body>
|
|
</html>
|