Moving the map center to the current location when required.
This commit is contained in:
parent
0ba385c476
commit
1555c00fe8
|
@ -8,6 +8,7 @@
|
|||
"name": "dyomedeaOl",
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"@awesome-cordova-plugins/geolocation": "^6.2.0",
|
||||
"@capacitor/android": "4.5.0",
|
||||
"@capacitor/app": "4.1.1",
|
||||
"@capacitor/core": "4.5.0",
|
||||
|
@ -27,6 +28,10 @@
|
|||
"@types/react-router-dom": "^5.1.7",
|
||||
"history": "^4.9.0",
|
||||
"ionicons": "^6.0.3",
|
||||
"jotai": "^1.10.0",
|
||||
"jotai-location": "^0.2.0",
|
||||
"jotai-utils": "^0.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
"ol": "^7.1.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
|
@ -48,7 +53,8 @@
|
|||
"workbox-streams": "^5.1.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@capacitor/cli": "4.5.0"
|
||||
"@capacitor/cli": "4.5.0",
|
||||
"@types/lodash": "^4.14.189"
|
||||
}
|
||||
},
|
||||
"node_modules/@adobe/css-tools": {
|
||||
|
@ -68,6 +74,30 @@
|
|||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@awesome-cordova-plugins/core": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@awesome-cordova-plugins/core/-/core-6.2.0.tgz",
|
||||
"integrity": "sha512-z5rKlTuQpLLPEIgzOmomQdoiRw5Sal2blh5CJRcjqh8ktspefbNC81Ni0MykPdV78/UlRORTHEzxugpcEcl1RQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/cordova": "latest"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rxjs": "^5.5.0 || ^6.5.0 || ^7.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@awesome-cordova-plugins/geolocation": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@awesome-cordova-plugins/geolocation/-/geolocation-6.2.0.tgz",
|
||||
"integrity": "sha512-EGUwTOrH4GjFHH4Zt0pzExg2TasJqQdYDcV4qpW8lY41fJBEFJCAB8KmSsD60hi25S5DxHQSJjsTuGBq2bq6DA==",
|
||||
"dependencies": {
|
||||
"@types/cordova": "latest"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@awesome-cordova-plugins/core": "^6.0.1",
|
||||
"rxjs": "^5.5.0 || ^6.5.0 || ^7.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame": {
|
||||
"version": "7.18.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
|
||||
|
@ -3669,6 +3699,11 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/cordova": {
|
||||
"version": "0.0.34",
|
||||
"resolved": "https://registry.npmjs.org/@types/cordova/-/cordova-0.0.34.tgz",
|
||||
"integrity": "sha512-rkiiTuf/z2wTd4RxFOb+clE7PF4AEJU0hsczbUdkHHBtkUmpWQpEddynNfJYKYtZFJKbq4F+brfekt1kx85IZA=="
|
||||
},
|
||||
"node_modules/@types/eslint": {
|
||||
"version": "8.4.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.10.tgz",
|
||||
|
@ -3825,6 +3860,12 @@
|
|||
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
|
||||
"integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="
|
||||
},
|
||||
"node_modules/@types/lodash": {
|
||||
"version": "4.14.189",
|
||||
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.189.tgz",
|
||||
"integrity": "sha512-kb9/98N6X8gyME9Cf7YaqIMvYGnBSWqEci6tiettE6iJWH1XdJz/PO8LB0GtLCG7x8dU3KWhZT+lA1a35127tA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/mime": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz",
|
||||
|
@ -10277,6 +10318,72 @@
|
|||
"url": "https://github.com/chalk/supports-color?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/jotai": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/jotai/-/jotai-1.10.0.tgz",
|
||||
"integrity": "sha512-3Q8kQU3Ktds+80Ku4dVcvnwSXEcK0Fg0b6mC1+4wz3rmF64lOGNUySKXQ4njvYCWodR8bw2HygOKYSYkHxQQmA==",
|
||||
"engines": {
|
||||
"node": ">=12.7.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "*",
|
||||
"@babel/template": "*",
|
||||
"jotai-immer": "*",
|
||||
"jotai-optics": "*",
|
||||
"jotai-redux": "*",
|
||||
"jotai-tanstack-query": "*",
|
||||
"jotai-urql": "*",
|
||||
"jotai-valtio": "*",
|
||||
"jotai-xstate": "*",
|
||||
"jotai-zustand": "*",
|
||||
"react": ">=16.8"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@babel/core": {
|
||||
"optional": true
|
||||
},
|
||||
"@babel/template": {
|
||||
"optional": true
|
||||
},
|
||||
"jotai-immer": {
|
||||
"optional": true
|
||||
},
|
||||
"jotai-optics": {
|
||||
"optional": true
|
||||
},
|
||||
"jotai-redux": {
|
||||
"optional": true
|
||||
},
|
||||
"jotai-tanstack-query": {
|
||||
"optional": true
|
||||
},
|
||||
"jotai-urql": {
|
||||
"optional": true
|
||||
},
|
||||
"jotai-valtio": {
|
||||
"optional": true
|
||||
},
|
||||
"jotai-xstate": {
|
||||
"optional": true
|
||||
},
|
||||
"jotai-zustand": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/jotai-location": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/jotai-location/-/jotai-location-0.2.0.tgz",
|
||||
"integrity": "sha512-SS4HyCf+PUKtyUZ7ge820ti92NUDRx4AvSuINTFx8kuAxbusMYjNSntcTJy2Fg+R0YPO2RtvV5INzzlUQ+1oGw==",
|
||||
"peerDependencies": {
|
||||
"jotai": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/jotai-utils": {
|
||||
"version": "0.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jotai-utils/-/jotai-utils-0.0.0.tgz",
|
||||
"integrity": "sha512-z/gS7iuWWwXY/JnvsYmcDpcFLnDsJVqkIFJ66h060LY5+cte8S7SDKEVEFPcoM6UQjyy3mj6eEKjcxb1+7OqZw=="
|
||||
},
|
||||
"node_modules/js-sdsl": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz",
|
||||
|
@ -13700,6 +13807,15 @@
|
|||
"resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz",
|
||||
"integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ=="
|
||||
},
|
||||
"node_modules/rxjs": {
|
||||
"version": "7.5.7",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.7.tgz",
|
||||
"integrity": "sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@awesome-cordova-plugins/geolocation": "^6.2.0",
|
||||
"@capacitor/android": "4.5.0",
|
||||
"@capacitor/app": "4.1.1",
|
||||
"@capacitor/core": "4.5.0",
|
||||
|
@ -22,6 +23,10 @@
|
|||
"@types/react-router-dom": "^5.1.7",
|
||||
"history": "^4.9.0",
|
||||
"ionicons": "^6.0.3",
|
||||
"jotai": "^1.10.0",
|
||||
"jotai-location": "^0.2.0",
|
||||
"jotai-utils": "^0.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
"ol": "^7.1.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
|
@ -67,7 +72,8 @@
|
|||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@capacitor/cli": "4.5.0"
|
||||
"@capacitor/cli": "4.5.0",
|
||||
"@types/lodash": "^4.14.189"
|
||||
},
|
||||
"description": "An Ionic project"
|
||||
}
|
||||
|
|
|
@ -1,36 +1,29 @@
|
|||
import React from 'react';
|
||||
|
||||
// import { Geolocation } from '@awesome-cordova-plugins/geolocation';
|
||||
import { Geolocation } from '@awesome-cordova-plugins/geolocation';
|
||||
|
||||
import style from './GetLocation.module.css';
|
||||
import style from './GetLocation.module.css';
|
||||
import { IonButton, IonIcon } from '@ionic/react';
|
||||
import { locateOutline } from 'ionicons/icons';
|
||||
// import { useAtom } from 'jotai';
|
||||
// import { setCenterAtom } from '../../App';
|
||||
import { useAtom } from 'jotai';
|
||||
import { stateAtom } from '../map';
|
||||
|
||||
// import { locationAtom } from '../map/CurrentLocation';
|
||||
|
||||
const GetLocation: React.FC<{}> = () => {
|
||||
// const [, setCenter] = useAtom(setCenterAtom);
|
||||
// const [, setLocation] = useAtom(locationAtom);
|
||||
const [state, setState] = useAtom(stateAtom);
|
||||
|
||||
// const onClickHandler = (event: any) => {
|
||||
// console.log('Click handler');
|
||||
// Geolocation.getCurrentPosition().then((position) => {
|
||||
// console.log(
|
||||
// `Click handler, position: ${position.coords.latitude}, ${position.coords.longitude}`
|
||||
// );
|
||||
// setCenter({
|
||||
// lat: position.coords.latitude,
|
||||
// lon: position.coords.longitude,
|
||||
// });
|
||||
// setLocation({
|
||||
// lat: position.coords.latitude,
|
||||
// lon: position.coords.longitude,
|
||||
// });
|
||||
// });
|
||||
// };
|
||||
|
||||
// onClick={onClickHandler}
|
||||
const onClickHandler = (event: any) => {
|
||||
console.log('Click handler');
|
||||
Geolocation.getCurrentPosition().then((position) => {
|
||||
console.log({ caller: 'GetLocation/onClickHandler', position, state });
|
||||
setState({
|
||||
zoom: state.zoom,
|
||||
rotation: state.rotation,
|
||||
center: [position.coords.longitude, position.coords.latitude],
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<IonButton
|
||||
|
@ -38,6 +31,7 @@ const GetLocation: React.FC<{}> = () => {
|
|||
shape='round'
|
||||
size='small'
|
||||
fill='solid'
|
||||
onClick={onClickHandler}
|
||||
>
|
||||
<IonIcon slot='icon-only' icon={locateOutline} color='white' />
|
||||
</IonButton>
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
import React, { useEffect, useRef } from 'react';
|
||||
|
||||
import { atom, useAtom } from 'jotai';
|
||||
import { atomWithHash } from 'jotai-location';
|
||||
|
||||
import OlMap from 'ol/Map';
|
||||
import View from 'ol/View';
|
||||
import TileLayer from 'ol/layer/Tile';
|
||||
|
@ -7,37 +11,95 @@ import Rotate from 'ol/control/Rotate';
|
|||
import ScaleLine from 'ol/control/ScaleLine';
|
||||
import Control from 'ol/control/Control';
|
||||
import OSM from 'ol/source/OSM';
|
||||
import { useGeographic as olUseGeographic } from 'ol/proj';
|
||||
|
||||
import { isEqual } from 'lodash';
|
||||
|
||||
import './Map.css';
|
||||
import Collection from 'ol/Collection';
|
||||
import { createPortal } from 'react-dom';
|
||||
import GetLocation from '../get-location';
|
||||
|
||||
export interface MapProperties {}
|
||||
|
||||
export const Map: React.FC<MapProperties> = (props: MapProperties) => {
|
||||
const target = useRef<HTMLDivElement>(null);
|
||||
olUseGeographic();
|
||||
|
||||
const mapAtom = atom<OlMap | null>(null);
|
||||
|
||||
export const stateAtom = atomWithHash<any>('map', null);
|
||||
//atom(
|
||||
// (get) => {
|
||||
// const map = get(mapAtom);
|
||||
// const view = map?.getView();
|
||||
// return {
|
||||
// center: view?.getCenter(),
|
||||
// zoom: view?.getZoom(),
|
||||
// rotation: view?.getRotation(),
|
||||
// };
|
||||
// },
|
||||
// (get, set, state: any) => {
|
||||
// const map = get(mapAtom);
|
||||
// const view = map?.getView();
|
||||
// view?.setCenter(state.center);
|
||||
// view?.setZoom(state.zoom);
|
||||
// view?.setRotation(state.rotation);
|
||||
// }
|
||||
//);
|
||||
|
||||
export const Map: React.FC<MapProperties> = (props: MapProperties) => {
|
||||
const [map, setMap] = useAtom(mapAtom);
|
||||
const [state, setState] = useAtom(stateAtom);
|
||||
|
||||
const target = useRef<HTMLDivElement>(null);
|
||||
const getLocation = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
// const getLocation = target.current
|
||||
// ? createPortal(<GetLocation />, target.current)
|
||||
// : null;
|
||||
const previousState = useRef<any>(null);
|
||||
|
||||
if (state && map) {
|
||||
if (!isEqual(state, previousState.current)) {
|
||||
console.log({ caller: 'Map / updateView', state });
|
||||
previousState.current = state;
|
||||
map.getView().animate(state);
|
||||
}
|
||||
// const view = map.getView();
|
||||
// view.setCenter(state.center);
|
||||
// view.setZoom(state.zoom);
|
||||
// view.setRotation(state.rotation);
|
||||
// map.renderSync();
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
console.log({ caller: 'Map / useEffect', target, getLocation });
|
||||
|
||||
const changeListener = (event: any) => {
|
||||
const view = olMap?.getView();
|
||||
const newState = {
|
||||
center: view?.getCenter(),
|
||||
zoom: view?.getZoom(),
|
||||
rotation: view?.getRotation(),
|
||||
};
|
||||
setState(newState);
|
||||
|
||||
console.log({
|
||||
caller: 'Map / changeListener',
|
||||
event,
|
||||
newState,
|
||||
olMap,
|
||||
});
|
||||
};
|
||||
|
||||
const controls = new Collection([
|
||||
new Attribution({ collapsible: true }),
|
||||
new Rotate(),
|
||||
new ScaleLine({ bar: true }),
|
||||
new Control({ element: getLocation.current ?? undefined }),
|
||||
]);
|
||||
const map = new OlMap({
|
||||
view: new View({
|
||||
center: [0, 0],
|
||||
zoom: 1,
|
||||
}),
|
||||
const olMap = new OlMap({
|
||||
view: new View(
|
||||
state ?? {
|
||||
center: [0, 0],
|
||||
zoom: 1,
|
||||
}
|
||||
),
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new OSM(),
|
||||
|
@ -46,6 +108,8 @@ export const Map: React.FC<MapProperties> = (props: MapProperties) => {
|
|||
target: target.current ?? undefined,
|
||||
controls,
|
||||
});
|
||||
olMap.on(['change', 'moveend'], changeListener);
|
||||
setMap(olMap);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
|
|
|
@ -1 +1 @@
|
|||
export { default } from './Map';
|
||||
export { default, stateAtom } from './Map';
|
||||
|
|
Loading…
Reference in New Issue