Huge and dirty refactoring of the vector tile stuff.
This commit is contained in:
1 parent
36337623ca
commit
10a5f2fb18
8 files changed
+355
-90
No files matched your search
@@ -0,0 +1,103 @@
|
||||
import { Component, createEffect, onMount } from 'solid-js';
|
||||
import OlMap from 'ol/Map';
|
||||
|
||||
import {
|
||||
currentOverlayDefinition,
|
||||
currentOverlayHighlightedDefinition,
|
||||
isHighlighted,
|
||||
} from '../map-tile-provider';
|
||||
import { Feature } from 'ol';
|
||||
import MVT from 'ol/format/MVT';
|
||||
import { Point } from 'ol/geom';
|
||||
import VectorLayer from 'ol/layer/Vector';
|
||||
import VectorTileLayer from 'ol/layer/VectorTile';
|
||||
import VectorTileSource from 'ol/source/VectorTile.js';
|
||||
import Cluster from 'ol/source/Cluster';
|
||||
import { style } from '../gpx/styles';
|
||||
import ClusterableVectorTileSourceProxy from '../../lib/ClusterableVectorTileSourceProxy';
|
||||
import { getMap, getZoomInteger } from '../map/Map';
|
||||
import { getCenter } from 'ol/extent';
|
||||
|
||||
interface Props {
|
||||
map: () => OlMap | null;
|
||||
}
|
||||
|
||||
let clusterLayer: VectorLayer;
|
||||
let vectorTileLayer: VectorTileLayer;
|
||||
|
||||
export const Overlays: Component<Props> = ({ map }) => {
|
||||
onMount(() => {
|
||||
const vectorTileSource = new VectorTileSource({
|
||||
url: 'https://geo.dyomedea.com/services/spain/tiles/{z}/{x}/{y}.pbf',
|
||||
format: new MVT({ featureClass: Feature }),
|
||||
maxZoom: 14,
|
||||
});
|
||||
|
||||
vectorTileLayer = new VectorTileLayer({
|
||||
source: vectorTileSource,
|
||||
style,
|
||||
declutter: false,
|
||||
});
|
||||
|
||||
const clusterableVectorTileSource = new ClusterableVectorTileSourceProxy({
|
||||
source: vectorTileSource,
|
||||
});
|
||||
|
||||
const clusterSource = new Cluster({
|
||||
source: clusterableVectorTileSource,
|
||||
distance: 30,
|
||||
minDistance: 10,
|
||||
geometryFunction: (feature: Feature) => {
|
||||
if (
|
||||
getZoomInteger() < 14 &&
|
||||
feature.get('type') === 'poi' &&
|
||||
isHighlighted(feature)
|
||||
) {
|
||||
// console.log({
|
||||
// caller: 'Map / Cluster / geometryFunction / true',
|
||||
// feature,
|
||||
// });
|
||||
return new Point(getCenter(feature.getGeometry().getExtent()));
|
||||
}
|
||||
return null;
|
||||
},
|
||||
createCluster: (point: Point, features: Feature[]) => {
|
||||
// console.log({
|
||||
// caller: 'Map / Cluster / createCluster',
|
||||
// point,
|
||||
// features,
|
||||
// });
|
||||
|
||||
return new Feature({
|
||||
geometry: point,
|
||||
features: features,
|
||||
type: 'cluster',
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
clusterLayer = new VectorLayer({
|
||||
source: clusterSource,
|
||||
zIndex: Infinity,
|
||||
style,
|
||||
});
|
||||
});
|
||||
|
||||
createEffect(() => {
|
||||
const overlayDefinition = currentOverlayDefinition();
|
||||
const overlayHighlightedDefinition = currentOverlayHighlightedDefinition();
|
||||
const olMap = getMap();
|
||||
if (olMap) {
|
||||
olMap.removeLayer(clusterLayer);
|
||||
olMap.removeLayer(vectorTileLayer);
|
||||
if (Object.keys(overlayDefinition).length > 0) {
|
||||
vectorTileLayer.changed();
|
||||
clusterLayer.changed();
|
||||
olMap.addLayer(vectorTileLayer);
|
||||
olMap.addLayer(clusterLayer);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return <></>;
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
import { overlayDefinitions, overlayCategories } from './overlay-definitions';
|
||||
@@ -0,0 +1,107 @@
|
||||
import { indexOf } from 'lodash';
|
||||
|
||||
export const overlayDefinitions = {
|
||||
amenity: {
|
||||
bar: { hiking: { drinking: true } },
|
||||
fast_food: { hiking: { eating: true } },
|
||||
food_court: { hiking: { eating: true } },
|
||||
pub: { hiking: { eating: true } },
|
||||
restaurant: { hiking: { eating: true } },
|
||||
cafe: { hiking: { drinking: true } },
|
||||
atm: { hiking: { money: true, dayToDay: true } },
|
||||
bank: { hiking: { money: true, dayToDay: true } },
|
||||
doctors: { hiking: { health: true } },
|
||||
hospital: { hiking: { health: true } },
|
||||
pharmacy: { hiking: { health: true } },
|
||||
police: { hiking: { security: true } },
|
||||
fire_station: { hiking: { security: true } },
|
||||
drinking_water: { hiking: { drinking: true } },
|
||||
water_point: { hiking: { drinking: true } },
|
||||
waste_basket: { hiking: { dayToDay: true } },
|
||||
waste_disposal: { hiking: { dayToDay: true } },
|
||||
vending_machine: { hiking: { dayToDay: true } },
|
||||
},
|
||||
shop: {
|
||||
bakery: { hiking: { eating: true } },
|
||||
butcher: { hiking: { eating: true } },
|
||||
cheese: { hiking: { eating: true } },
|
||||
chocolate: { hiking: { eating: true } },
|
||||
convenience: { hiking: { eating: true } },
|
||||
dairy: { hiking: { eating: true } },
|
||||
farm: { hiking: { eating: true } },
|
||||
greengrocer: { hiking: { eating: true } },
|
||||
health_food: { hiking: { eating: true } },
|
||||
pasta: { hiking: { eating: true } },
|
||||
pastry: { hiking: { eating: true } },
|
||||
seafood: { hiking: { eating: true } },
|
||||
water: { hiking: { drinking: true } },
|
||||
department_store: { hiking: { dayToDay: true } },
|
||||
general: { hiking: { dayToDay: true } },
|
||||
mall: { hiking: { dayToDay: true } },
|
||||
supermarket: { hiking: { eating: true } },
|
||||
wholesale: { hiking: { eating: true } },
|
||||
outdoor: { hiking: { material: true } },
|
||||
laundry: { hiking: { dayToDay: true } },
|
||||
},
|
||||
tourism: {
|
||||
hotel: { hiking: { sleeping: true } },
|
||||
alpine_hut: { hiking: { sleeping: true } },
|
||||
apartment: { hiking: { sleeping: true } },
|
||||
camp_site: { hiking: { sleeping: true } },
|
||||
chalet: { hiking: { sleeping: true } },
|
||||
guest_house: { hiking: { sleeping: true } },
|
||||
hostel: { hiking: { sleeping: true } },
|
||||
motel: { hiking: { sleeping: true } },
|
||||
wilderness_hut: { hiking: { sleeping: true } },
|
||||
viewpoint: { hiking: { naturalSites: true } },
|
||||
},
|
||||
waterway: { waterfall: { hiking: { naturalSites: true } } },
|
||||
natural: {
|
||||
peak: { hiking: { naturalSites: true } },
|
||||
cave_entrance: { hiking: { naturalSites: true } },
|
||||
volcano: { hiking: { naturalSites: true } },
|
||||
arch: { hiking: { naturalSites: true } },
|
||||
arete: { hiking: { naturalSites: true } },
|
||||
fumarole: { hiking: { naturalSites: true } },
|
||||
rock: { hiking: { naturalSites: true } },
|
||||
saddle: { hiking: { naturalSites: true } },
|
||||
sinkhole: { hiking: { naturalSites: true } },
|
||||
stone: { hiking: { naturalSites: true } },
|
||||
glacier: { hiking: { naturalSites: true } },
|
||||
spring: { hiking: { naturalSites: true } },
|
||||
hot_spring: { hiking: { naturalSites: true } },
|
||||
geyser: { hiking: { naturalSites: true } },
|
||||
},
|
||||
};
|
||||
|
||||
let _flat: any = [];
|
||||
Object.values(overlayDefinitions).forEach((category) => {
|
||||
Object.values(category).forEach((subCategory) => {
|
||||
_flat = [..._flat, subCategory];
|
||||
});
|
||||
});
|
||||
|
||||
type Categories = { string: Set<string> };
|
||||
|
||||
export let overlayCategories: Categories = {};
|
||||
|
||||
_flat.forEach((obj: any) => {
|
||||
Object.keys(obj).forEach((catName: string) => {
|
||||
const catValue = obj[catName];
|
||||
const previous =
|
||||
overlayCategories[catName] === undefined
|
||||
? []
|
||||
: overlayCategories[catName];
|
||||
overlayCategories[catName] = new Set([
|
||||
...previous,
|
||||
...Object.keys(catValue),
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
console.log({
|
||||
caller: 'overlay-definitions',
|
||||
overlayDefinitions,
|
||||
_flat,
|
||||
overlayCategories,
|
||||
});
|
||||
Reference in new issue
Block a user