82 lines
2.7 KiB
TypeScript
82 lines
2.7 KiB
TypeScript
|
import { IconButton, SvgIcon } from '@suid/material';
|
||
|
import { Component, createEffect } from 'solid-js';
|
||
|
import style from './OsmFetch.module.css';
|
||
|
import { style as olStyle } from '../gpx/styles';
|
||
|
|
||
|
import OsmIcon from '../../icons/OpenStreetMap-logo.svg?component-solid';
|
||
|
import { Map } from 'ol';
|
||
|
import VectorLayer from 'ol/layer/Vector';
|
||
|
import VectorSource from 'ol/source/Vector';
|
||
|
import osmtogeojson from 'osmtogeojson';
|
||
|
import { getBottomLeft, getBottomRight, getTopRight } from 'ol/extent';
|
||
|
import GeoJSON from 'ol/format/GeoJSON';
|
||
|
|
||
|
interface Props {
|
||
|
map: () => Map;
|
||
|
}
|
||
|
|
||
|
const OsmFetch: Component<Props> = ({ map }) => {
|
||
|
const vectorSource = new VectorSource();
|
||
|
const vectorLayer = new VectorLayer({
|
||
|
source: vectorSource,
|
||
|
style: olStyle,
|
||
|
declutter: true,
|
||
|
});
|
||
|
createEffect(() => map()?.addLayer(vectorLayer));
|
||
|
|
||
|
const handleClick = async () => {
|
||
|
const view = map().getView();
|
||
|
const extent = view.calculateExtent();
|
||
|
const sw = getBottomLeft(extent);
|
||
|
const ne = getTopRight(extent);
|
||
|
|
||
|
const query = `[out:json][timeout:25];
|
||
|
(
|
||
|
relation["route"="hiking"]["network"="nwn"](${sw[1]}, ${ne[0]}, ${ne[1]}, ${sw[0]});
|
||
|
);
|
||
|
out body;
|
||
|
>;
|
||
|
out skel qt;`;
|
||
|
|
||
|
console.log({ caller: 'OsmFetch / handleClick', query, extent });
|
||
|
|
||
|
const response = await fetch(
|
||
|
'https://overpass-api.de/api/interpreter?contact=vdv@dyomedea.com',
|
||
|
{
|
||
|
method: 'POST', // *GET, POST, PUT, DELETE, etc.
|
||
|
mode: 'cors', // no-cors, *cors, same-origin
|
||
|
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
|
||
|
credentials: 'same-origin', // include, *same-origin, omit
|
||
|
headers: {
|
||
|
'Content-Type': 'text/plain',
|
||
|
// 'Content-Type': 'application/x-www-form-urlencoded',
|
||
|
},
|
||
|
redirect: 'follow', // manual, *follow, error
|
||
|
referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
|
||
|
body: query, // body data type must match "Content-Type" header
|
||
|
}
|
||
|
);
|
||
|
const osmJson = await response.json(); // parses JSON response into native JavaScript objects
|
||
|
const geoJson = osmtogeojson(osmJson, {});
|
||
|
console.log({
|
||
|
caller: 'OsmFetch / handleClick / osmJson',
|
||
|
osmJson,
|
||
|
geoJson,
|
||
|
});
|
||
|
const features = new GeoJSON().readFeatures(geoJson);
|
||
|
vectorSource.addFeatures(features);
|
||
|
};
|
||
|
|
||
|
return (
|
||
|
<>
|
||
|
<div class={style.control}>
|
||
|
<IconButton onClick={handleClick}>
|
||
|
<OsmIcon width={24} height={24} viewBox='0 0 240 240' />
|
||
|
</IconButton>
|
||
|
</div>
|
||
|
</>
|
||
|
);
|
||
|
};
|
||
|
|
||
|
export default OsmFetch;
|