Trying different ways to select and potentially update OL features

This commit is contained in:
Eric van der Vlist 2022-11-29 14:59:57 +01:00
parent 400711eb80
commit ab1d644e8e
3 changed files with 55 additions and 9 deletions

View File

@ -1,4 +1,5 @@
import { Component, createEffect, createSignal, onMount } from 'solid-js'; import { Component, createEffect, createSignal, onMount } from 'solid-js';
import { createStore, produce, unwrap } from 'solid-js/store';
import { useParams, useNavigate } from '@solidjs/router'; import { useParams, useNavigate } from '@solidjs/router';
import OlMap from 'ol/Map'; import OlMap from 'ol/Map';
import View from 'ol/View'; import View from 'ol/View';
@ -35,6 +36,7 @@ import KeyboardZoom from 'ol/interaction/KeyboardZoom';
import MouseWheelZoom from 'ol/interaction/MouseWheelZoom'; import MouseWheelZoom from 'ol/interaction/MouseWheelZoom';
import DragZoom from 'ol/interaction/DragZoom'; import DragZoom from 'ol/interaction/DragZoom';
import Select from 'ol/interaction/Select'; import Select from 'ol/interaction/Select';
import Layer from 'ol/layer/Layer';
const [getState, setState] = createSignal({ const [getState, setState] = createSignal({
lon: 0, lon: 0,
@ -46,6 +48,23 @@ const [getState, setState] = createSignal({
export { getState }; export { getState };
interface Branch {
vectorLayer?: VectorLayer;
features?: Feature[];
hidden?: boolean;
updateHandler?: (feature: Feature) => void;
}
interface Tree {
[key: string]: Branch;
}
const [tree, setTree] = createStore<Tree>({});
export { tree };
export const setBranch = (key: string, branch: Branch) => {
setTree({ ...tree, [key]: branch });
};
const Map: Component = () => { const Map: Component = () => {
const [getMap, setMap] = createSignal<OlMap | null>(null); const [getMap, setMap] = createSignal<OlMap | null>(null);
const params = useParams(); const params = useParams();
@ -102,7 +121,7 @@ const Map: Component = () => {
image: new Icon({ image: new Icon({
// size: [20, 20], // size: [20, 20],
imgSize: [24, 24], imgSize: [24, 24],
declutterMode: 'declutter', declutterMode: 'obstacle',
// @ts-ignore // @ts-ignore
src: ShowLocationIcon, src: ShowLocationIcon,
}), }),
@ -126,8 +145,21 @@ const Map: Component = () => {
} }
}); });
const selectHandler = (event: any) => { const clickHandler = (event: any) => {
console.log({ caller: 'selectHandler', event }); const pixel = [event.originalEvent.x, event.originalEvent.y];
const features = event.map.getFeaturesAtPixel(pixel, { hitTolerance: 30 });
console.log({
caller: 'clickHandler',
event,
features,
tree: unwrap(tree),
});
features.map((feature) => {
const id = feature.get('id');
console.log({ caller: 'clickHandler / feature', event, feature, id });
const branch = tree[id];
if (branch?.updateHandler) branch.updateHandler(feature);
});
}; };
onMount(() => { onMount(() => {
@ -159,8 +191,10 @@ const Map: Component = () => {
}); });
tileLayer.set('provider', params.provider, true); tileLayer.set('provider', params.provider, true);
const selectInteraction = new Select({ multi: true }); const vectorLayer = new VectorLayer({
selectInteraction.on('select', selectHandler); source: new VectorSource(),
zIndex: Infinity,
});
const olMap = new OlMap({ const olMap = new OlMap({
view: new View({ view: new View({
@ -168,7 +202,7 @@ const Map: Component = () => {
zoom: +getState().zoom, zoom: +getState().zoom,
rotation: +getState().rotation, rotation: +getState().rotation,
}), }),
layers: [tileLayer, new VectorLayer({ source: new VectorSource() })], layers: [tileLayer, vectorLayer],
target: target, target: target,
controls: new Collection<Control>([ controls: new Collection<Control>([
new Attribution({ collapsible: true }), new Attribution({ collapsible: true }),
@ -185,12 +219,13 @@ const Map: Component = () => {
new KeyboardZoom(), new KeyboardZoom(),
new MouseWheelZoom(), new MouseWheelZoom(),
new DragZoom(), new DragZoom(),
selectInteraction,
]), ]),
}); });
olMap.on(['moveend'], changeListener); olMap.on(['moveend'], changeListener);
olMap.on(['click'], clickHandler);
setMap(olMap); setMap(olMap);
setBranch('/', { vectorLayer: vectorLayer });
}); });
return ( return (

View File

@ -1 +1 @@
export { default, getState } from './Map'; export { default, getState, tree, setBranch } from './Map';

View File

@ -6,6 +6,9 @@ import dispatch from '../../workers/dispatcher-main';
import getUri from '../../lib/ids'; import getUri from '../../lib/ids';
import VectorSource from 'ol/source/Vector'; import VectorSource from 'ol/source/Vector';
import GeoJSON from 'ol/format/GeoJSON'; import GeoJSON from 'ol/format/GeoJSON';
import { setBranch, tree } from '../map';
import { unwrap } from 'solid-js/store';
import { Feature } from 'ol';
interface Props { interface Props {
trksegId: string; trksegId: string;
@ -27,7 +30,7 @@ export const Trkseg: Component<Props> = ({ vectorSource, trksegId }) => {
createEffect(() => { createEffect(() => {
console.log({ caller: 'Trkseg', vectorSource, trksegId, trkseg: trkseg() }); console.log({ caller: 'Trkseg', vectorSource, trksegId, trkseg: trkseg() });
if (trkseg()) { if (trkseg() && !tree[trksegId]) {
let geo: any = { let geo: any = {
type: 'FeatureCollection', type: 'FeatureCollection',
features: [ features: [
@ -67,9 +70,17 @@ export const Trkseg: Component<Props> = ({ vectorSource, trksegId }) => {
const features = new GeoJSON().readFeatures(geo); const features = new GeoJSON().readFeatures(geo);
console.log({ caller: 'Trkseg', features }); console.log({ caller: 'Trkseg', features });
vectorSource.addFeatures(features); vectorSource.addFeatures(features);
setBranch(trksegId, { features, updateHandler });
} }
}); });
const updateHandler = (feature: Feature) => {
console.log({
caller: 'Trkseg / updateHandler / clicked',
feature,
});
};
return <></>; return <></>;
}; };