Don't use useGeographic anymore since it doesn't work with clusters.

This commit is contained in:
Eric van der Vlist 2023-01-20 21:11:18 +01:00
parent 6e796f88c7
commit 9ade878deb
6 changed files with 69 additions and 51 deletions

View File

@ -10,12 +10,16 @@ import Attribution from 'ol/control/Attribution';
import Rotate from 'ol/control/Rotate'; import Rotate from 'ol/control/Rotate';
import ScaleLine from 'ol/control/ScaleLine'; import ScaleLine from 'ol/control/ScaleLine';
import Control from 'ol/control/Control'; import Control from 'ol/control/Control';
import { toLonLat, useGeographic as olUseGeographic } from 'ol/proj'; import {
fromLonLat,
toLonLat,
useGeographic as olUseGeographic,
} from 'ol/proj';
import DragRotate from 'ol/interaction/DragRotate'; import DragRotate from 'ol/interaction/DragRotate';
import 'ol/ol.css'; import 'ol/ol.css';
import './Map.css'; import './Map.css';
import { Collection, VectorTile } from 'ol'; import { Collection } from 'ol';
import { Point } from 'ol/geom'; import { Point } from 'ol/geom';
import { Style, Icon, Circle, Fill } from 'ol/style'; import { Style, Icon, Circle, Fill } from 'ol/style';
import GetLocation, { getCurrentLocation } from '../get-location'; import GetLocation, { getCurrentLocation } from '../get-location';
@ -39,7 +43,7 @@ import Infos, { clickHandler } from '../infos';
import GpxDialog from '../gpx-dialog'; import GpxDialog from '../gpx-dialog';
import GpxRecord from '../gpx-record'; import GpxRecord from '../gpx-record';
import dispatch from '../../workers/dispatcher-main'; import dispatch from '../../workers/dispatcher-main';
import { debounce, floor } from 'lodash'; import { debounce } from 'lodash';
import { AndroidFullScreen } from '@awesome-cordova-plugins/android-full-screen'; import { AndroidFullScreen } from '@awesome-cordova-plugins/android-full-screen';
import Account from '../account'; import Account from '../account';
@ -48,10 +52,6 @@ import VectorTileLayer from 'ol/layer/VectorTile';
import VectorTileSource from 'ol/source/VectorTile.js'; import VectorTileSource from 'ol/source/VectorTile.js';
import MVT from 'ol/format/MVT.js'; import MVT from 'ol/format/MVT.js';
import style from '../gpx/styles'; import style from '../gpx/styles';
import { DepartureBoard } from '@suid/icons-material';
import deTileVectorSource from '../../lib/de-tile-vector-source';
import ClusterableVectorTileSource from '../../lib/ClusterableVectorTileSource';
import clusterableVectorTileSourceProxy from '../../lib/ClusterableVectorTileSourceProxy';
import ClusterableVectorTileSourceProxy from '../../lib/ClusterableVectorTileSourceProxy'; import ClusterableVectorTileSourceProxy from '../../lib/ClusterableVectorTileSourceProxy';
const [getState, setState] = createSignal({ const [getState, setState] = createSignal({
@ -159,7 +159,7 @@ const Map: Component = () => {
const view = map?.getView(); const view = map?.getView();
view?.animate({ view?.animate({
center: [getState().lon, getState().lat], center: fromLonLat([getState().lon, getState().lat]),
rotation: getState().rotation, rotation: getState().rotation,
zoom: getState().zoom, zoom: getState().zoom,
duration: 1000, duration: 1000,
@ -178,7 +178,7 @@ const Map: Component = () => {
.at(1) .at(1)
?.getSource() as VectorSource; ?.getSource() as VectorSource;
source!.clear(true); source!.clear(true);
const point = new Point([location.lon, location.lat]); const point = new Point(fromLonLat([location.lon, location.lat]));
const style = new Style({ const style = new Style({
image: new Icon({ image: new Icon({
// size: [20, 20], // size: [20, 20],
@ -209,16 +209,17 @@ const Map: Component = () => {
}); });
onMount(async () => { onMount(async () => {
olUseGeographic(); // olUseGeographic();
const changeListener = (event: any) => { const changeListener = (event: any) => {
const map = getMap(); const map = getMap();
const view = map?.getView(); const view = map?.getView();
const center = view?.getCenter(); const center = view?.getCenter();
if (center) { if (center) {
const centerLonLat = toLonLat(center);
navigate( navigate(
`/map/${getState().provider}/${center[0]}/${ `/map/${getState().provider}/${centerLonLat[0]}/${
center[1] centerLonLat[1]
}/${view?.getZoom()}/${view?.getRotation()}` }/${view?.getZoom()}/${view?.getRotation()}`
); );
} }
@ -229,6 +230,7 @@ const Map: Component = () => {
...params, ...params,
}, },
map, map,
center,
}); });
}; };
@ -250,7 +252,7 @@ const Map: Component = () => {
const olMap = new OlMap({ const olMap = new OlMap({
view: new View({ view: new View({
center: [+getState().lon, +getState().lat], center: fromLonLat([+getState().lon, +getState().lat]),
zoom: +getState().zoom, zoom: +getState().zoom,
rotation: +getState().rotation, rotation: +getState().rotation,
}), }),
@ -297,8 +299,8 @@ const Map: Component = () => {
const clusterSource = new Cluster({ const clusterSource = new Cluster({
source: clusterableVectorTileSource, source: clusterableVectorTileSource,
distance: 4000000, distance: 50,
//minDistance: 200, minDistance: 10,
geometryFunction: (feature: Feature) => { geometryFunction: (feature: Feature) => {
// console.log({ // console.log({
// caller: 'Map / Cluster / geometryFunction', // caller: 'Map / Cluster / geometryFunction',
@ -325,13 +327,13 @@ const Map: Component = () => {
// }); // });
return new Feature({ return new Feature({
geometry: new Point( // geometry: new Point(
toLonLat( // toLonLat(
olExtent.getCenter(point.getExtent()), // olExtent.getCenter(point.getExtent()),
olMap.getView().getProjection() // olMap.getView().getProjection()
) // )
), // ),
// point, geometry: point,
features: features, features: features,
type: 'cluster', type: 'cluster',
}); });

View File

@ -7,6 +7,7 @@ import {
createCachedSignal, createCachedSignal,
destroyCachedSignal, destroyCachedSignal,
} from '../../workers/cached-signals'; } from '../../workers/cached-signals';
import { fromLonLat } from 'ol/proj';
interface Props { interface Props {
rteId: string; rteId: string;
@ -43,7 +44,10 @@ export const Rte: Component<Props> = ({ vectorSource, rteId, context }) => {
type: 'Feature', type: 'Feature',
geometry: { geometry: {
type: 'Point', type: 'Point',
coordinates: [rte().rtept[0].$.lon, rte().rtept[0].$.lat], coordinates: fromLonLat([
rte().rtept[0].$.lon,
rte().rtept[0].$.lat,
]),
}, },
properties: { properties: {
type: 'rte-start', type: 'rte-start',
@ -56,10 +60,9 @@ export const Rte: Component<Props> = ({ vectorSource, rteId, context }) => {
type: 'Feature', type: 'Feature',
geometry: { geometry: {
type: 'LineString', type: 'LineString',
coordinates: rte().rtept.map((rtept: any) => [ coordinates: rte().rtept.map((rtept: any) =>
rtept.$.lon, fromLonLat([rtept.$.lon, rtept.$.lat])
rtept.$.lat, ),
]),
}, },
properties: { properties: {
type: 'rte', type: 'rte',
@ -72,7 +75,10 @@ export const Rte: Component<Props> = ({ vectorSource, rteId, context }) => {
type: 'Feature', type: 'Feature',
geometry: { geometry: {
type: 'Point', type: 'Point',
coordinates: [rte().rtept.at(-1).$.lon, rte().rtept.at(-1).$.lat], coordinates: fromLonLat([
rte().rtept.at(-1).$.lon,
rte().rtept.at(-1).$.lat,
]),
}, },
properties: { properties: {
type: 'rte-finish', type: 'rte-finish',

View File

@ -7,6 +7,7 @@ import {
createCachedSignal, createCachedSignal,
destroyCachedSignal, destroyCachedSignal,
} from '../../workers/cached-signals'; } from '../../workers/cached-signals';
import { fromLonLat } from 'ol/proj';
interface Props { interface Props {
trksegId: string; trksegId: string;
@ -56,7 +57,10 @@ export const Trkseg: Component<Props> = ({
type: 'Feature', type: 'Feature',
geometry: { geometry: {
type: 'Point', type: 'Point',
coordinates: [trkseg().trkpt[0].$.lon, trkseg().trkpt[0].$.lat], coordinates: fromLonLat([
trkseg().trkpt[0].$.lon,
trkseg().trkpt[0].$.lat,
]),
}, },
properties: { properties: {
type: 'trkseg-start', type: 'trkseg-start',
@ -69,10 +73,9 @@ export const Trkseg: Component<Props> = ({
type: 'Feature', type: 'Feature',
geometry: { geometry: {
type: 'LineString', type: 'LineString',
coordinates: trkseg().trkpt.map((trkpt: any) => [ coordinates: trkseg().trkpt.map((trkpt: any) =>
trkpt.$.lon, fromLonLat([trkpt.$.lon, trkpt.$.lat])
trkpt.$.lat, ),
]),
}, },
properties: { properties: {
type: 'trkseg', type: 'trkseg',
@ -85,10 +88,10 @@ export const Trkseg: Component<Props> = ({
type: 'Feature', type: 'Feature',
geometry: { geometry: {
type: 'Point', type: 'Point',
coordinates: [ coordinates: fromLonLat([
trkseg().trkpt.at(-1).$.lon, trkseg().trkpt.at(-1).$.lon,
trkseg().trkpt.at(-1).$.lat, trkseg().trkpt.at(-1).$.lat,
], ]),
}, },
properties: { properties: {
type: 'trkseg-finish', type: 'trkseg-finish',

View File

@ -8,6 +8,7 @@ import {
createCachedSignal, createCachedSignal,
destroyCachedSignal, destroyCachedSignal,
} from '../../workers/cached-signals'; } from '../../workers/cached-signals';
import { fromLonLat } from 'ol/proj';
interface Props { interface Props {
wptId: string; wptId: string;
@ -61,7 +62,7 @@ export const Wpt: Component<Props> = ({
type: 'Feature', type: 'Feature',
geometry: { geometry: {
type: 'Point', type: 'Point',
coordinates: [wpt()?.$.lon, wpt()?.$.lat], coordinates: fromLonLat([wpt()?.$.lon, wpt()?.$.lat]),
}, },
properties: { properties: {
type: 'wpt', type: 'wpt',

View File

@ -14,29 +14,35 @@ export const put = async (
) => { ) => {
const targetDb = local ? localDb : db; const targetDb = local ? localDb : db;
let current; let current;
let putDoc;
try { try {
current = await targetDb.get(_id); current = await targetDb.get(_id);
} catch { } catch {
current = { _rev: undefined, doc: cloneDeep(defaultDoc) }; current = { _rev: undefined, doc: cloneDeep(defaultDoc) };
} }
try { try {
await targetDb.put({ putDoc = {
_id, _id,
_rev: current._rev, _rev: current._rev,
type, type,
doc: update(current.doc), doc: update(current.doc),
}); };
await targetDb.put(putDoc);
} catch (error: any) { } catch (error: any) {
if (error.name === 'conflict') { if (error.name === 'conflict') {
console.log({ caller: 'db.put', _id, type, defaultDoc, error }); console.log({ caller: 'db.put', _id, type, putDoc, defaultDoc, error });
await put(_id, type, update, defaultDoc, local); await put(_id, type, update, defaultDoc, local);
} else { } else {
console.error({ caller: 'db.put', _id, type, defaultDoc, error }); console.error({ caller: 'db.put', _id, type, putDoc, defaultDoc, error });
} }
} }
}; };
export const getFamily = async (key: string, options: any = {}, local: boolean = false) => { export const getFamily = async (
key: string,
options: any = {},
local: boolean = false
) => {
const targetDb = local ? localDb : db; const targetDb = local ? localDb : db;
return await targetDb.allDocs({ return await targetDb.allDocs({
startkey: key, startkey: key,

View File

@ -9,7 +9,7 @@ interface Options {
class ClusterableVectorTileSourceProxy { class ClusterableVectorTileSourceProxy {
extent?: Extent; extent?: Extent;
resolution?: number; resolution?: number;
extentProjected?: Extent; // extentProjected?: Extent;
featuresSent: boolean = false; featuresSent: boolean = false;
proxy?: typeof Proxy; proxy?: typeof Proxy;
@ -19,13 +19,13 @@ class ClusterableVectorTileSourceProxy {
this.resolution = resolution; this.resolution = resolution;
if (this.extent === undefined || !equals(this.extent, extent)) { if (this.extent === undefined || !equals(this.extent, extent)) {
this.extent = extent; this.extent = extent;
const projection = target.getProjection(); // const projection = target.getProjection();
if (projection != null) { // if (projection != null) {
this.extentProjected = fromLonLat( // this.extentProjected = fromLonLat(
extent.slice(0, 2), // extent.slice(0, 2),
projection // projection
).concat(fromLonLat(extent.slice(2), this.projection)); // ).concat(fromLonLat(extent.slice(2), this.projection));
} // }
} }
if (!this.featuresSent) { if (!this.featuresSent) {
target.dispatchEvent('change'); target.dispatchEvent('change');
@ -46,8 +46,8 @@ class ClusterableVectorTileSourceProxy {
getFeatures: (target: VectorTileSource) => { getFeatures: (target: VectorTileSource) => {
return () => { return () => {
const result = const result =
this.extentProjected !== undefined this.extent !== undefined
? target.getFeaturesInExtent(this.extentProjected) ? target.getFeaturesInExtent(this.extent)
: []; : [];
this.featuresSent = true; this.featuresSent = true;
// console.log({ // console.log({