dyomedea/src/components/osm-fetch/OsmFetch.tsx

82 lines
2.7 KiB
TypeScript
Raw Normal View History

2023-01-09 19:51:17 +00:00
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;