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",
|
"name": "dyomedeaOl",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@awesome-cordova-plugins/geolocation": "^6.2.0",
|
||||||
"@capacitor/android": "4.5.0",
|
"@capacitor/android": "4.5.0",
|
||||||
"@capacitor/app": "4.1.1",
|
"@capacitor/app": "4.1.1",
|
||||||
"@capacitor/core": "4.5.0",
|
"@capacitor/core": "4.5.0",
|
||||||
|
@ -27,6 +28,10 @@
|
||||||
"@types/react-router-dom": "^5.1.7",
|
"@types/react-router-dom": "^5.1.7",
|
||||||
"history": "^4.9.0",
|
"history": "^4.9.0",
|
||||||
"ionicons": "^6.0.3",
|
"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",
|
"ol": "^7.1.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
@ -48,7 +53,8 @@
|
||||||
"workbox-streams": "^5.1.4"
|
"workbox-streams": "^5.1.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@capacitor/cli": "4.5.0"
|
"@capacitor/cli": "4.5.0",
|
||||||
|
"@types/lodash": "^4.14.189"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@adobe/css-tools": {
|
"node_modules/@adobe/css-tools": {
|
||||||
|
@ -68,6 +74,30 @@
|
||||||
"node": ">=6.0.0"
|
"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": {
|
"node_modules/@babel/code-frame": {
|
||||||
"version": "7.18.6",
|
"version": "7.18.6",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
|
||||||
|
@ -3669,6 +3699,11 @@
|
||||||
"@types/node": "*"
|
"@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": {
|
"node_modules/@types/eslint": {
|
||||||
"version": "8.4.10",
|
"version": "8.4.10",
|
||||||
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.10.tgz",
|
"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",
|
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
|
||||||
"integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="
|
"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": {
|
"node_modules/@types/mime": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz",
|
"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"
|
"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": {
|
"node_modules/js-sdsl": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz",
|
"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",
|
"resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz",
|
||||||
"integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ=="
|
"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": {
|
"node_modules/safe-buffer": {
|
||||||
"version": "5.2.1",
|
"version": "5.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@awesome-cordova-plugins/geolocation": "^6.2.0",
|
||||||
"@capacitor/android": "4.5.0",
|
"@capacitor/android": "4.5.0",
|
||||||
"@capacitor/app": "4.1.1",
|
"@capacitor/app": "4.1.1",
|
||||||
"@capacitor/core": "4.5.0",
|
"@capacitor/core": "4.5.0",
|
||||||
|
@ -22,6 +23,10 @@
|
||||||
"@types/react-router-dom": "^5.1.7",
|
"@types/react-router-dom": "^5.1.7",
|
||||||
"history": "^4.9.0",
|
"history": "^4.9.0",
|
||||||
"ionicons": "^6.0.3",
|
"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",
|
"ol": "^7.1.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
@ -67,7 +72,8 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@capacitor/cli": "4.5.0"
|
"@capacitor/cli": "4.5.0",
|
||||||
|
"@types/lodash": "^4.14.189"
|
||||||
},
|
},
|
||||||
"description": "An Ionic project"
|
"description": "An Ionic project"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,36 +1,29 @@
|
||||||
import React from 'react';
|
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 { IonButton, IonIcon } from '@ionic/react';
|
||||||
import { locateOutline } from 'ionicons/icons';
|
import { locateOutline } from 'ionicons/icons';
|
||||||
// import { useAtom } from 'jotai';
|
import { useAtom } from 'jotai';
|
||||||
// import { setCenterAtom } from '../../App';
|
import { stateAtom } from '../map';
|
||||||
|
|
||||||
// import { locationAtom } from '../map/CurrentLocation';
|
// import { locationAtom } from '../map/CurrentLocation';
|
||||||
|
|
||||||
const GetLocation: React.FC<{}> = () => {
|
const GetLocation: React.FC<{}> = () => {
|
||||||
// const [, setCenter] = useAtom(setCenterAtom);
|
const [state, setState] = useAtom(stateAtom);
|
||||||
// const [, setLocation] = useAtom(locationAtom);
|
|
||||||
|
|
||||||
// const onClickHandler = (event: any) => {
|
const onClickHandler = (event: any) => {
|
||||||
// console.log('Click handler');
|
console.log('Click handler');
|
||||||
// Geolocation.getCurrentPosition().then((position) => {
|
Geolocation.getCurrentPosition().then((position) => {
|
||||||
// console.log(
|
console.log({ caller: 'GetLocation/onClickHandler', position, state });
|
||||||
// `Click handler, position: ${position.coords.latitude}, ${position.coords.longitude}`
|
setState({
|
||||||
// );
|
zoom: state.zoom,
|
||||||
// setCenter({
|
rotation: state.rotation,
|
||||||
// lat: position.coords.latitude,
|
center: [position.coords.longitude, position.coords.latitude],
|
||||||
// lon: position.coords.longitude,
|
});
|
||||||
// });
|
});
|
||||||
// setLocation({
|
};
|
||||||
// lat: position.coords.latitude,
|
|
||||||
// lon: position.coords.longitude,
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
// };
|
|
||||||
|
|
||||||
// onClick={onClickHandler}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IonButton
|
<IonButton
|
||||||
|
@ -38,6 +31,7 @@ const GetLocation: React.FC<{}> = () => {
|
||||||
shape='round'
|
shape='round'
|
||||||
size='small'
|
size='small'
|
||||||
fill='solid'
|
fill='solid'
|
||||||
|
onClick={onClickHandler}
|
||||||
>
|
>
|
||||||
<IonIcon slot='icon-only' icon={locateOutline} color='white' />
|
<IonIcon slot='icon-only' icon={locateOutline} color='white' />
|
||||||
</IonButton>
|
</IonButton>
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
import React, { useEffect, useRef } from 'react';
|
import React, { useEffect, useRef } from 'react';
|
||||||
|
|
||||||
|
import { atom, useAtom } from 'jotai';
|
||||||
|
import { atomWithHash } from 'jotai-location';
|
||||||
|
|
||||||
import OlMap from 'ol/Map';
|
import OlMap from 'ol/Map';
|
||||||
import View from 'ol/View';
|
import View from 'ol/View';
|
||||||
import TileLayer from 'ol/layer/Tile';
|
import TileLayer from 'ol/layer/Tile';
|
||||||
|
@ -7,37 +11,95 @@ 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 OSM from 'ol/source/OSM';
|
import OSM from 'ol/source/OSM';
|
||||||
|
import { useGeographic as olUseGeographic } from 'ol/proj';
|
||||||
|
|
||||||
|
import { isEqual } from 'lodash';
|
||||||
|
|
||||||
import './Map.css';
|
import './Map.css';
|
||||||
import Collection from 'ol/Collection';
|
import Collection from 'ol/Collection';
|
||||||
import { createPortal } from 'react-dom';
|
|
||||||
import GetLocation from '../get-location';
|
import GetLocation from '../get-location';
|
||||||
|
|
||||||
export interface MapProperties {}
|
export interface MapProperties {}
|
||||||
|
|
||||||
export const Map: React.FC<MapProperties> = (props: MapProperties) => {
|
olUseGeographic();
|
||||||
const target = useRef<HTMLDivElement>(null);
|
|
||||||
|
|
||||||
|
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);
|
const getLocation = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
const previousState = useRef<any>(null);
|
||||||
// const getLocation = target.current
|
|
||||||
// ? createPortal(<GetLocation />, target.current)
|
|
||||||
// : 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 });
|
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([
|
const controls = new Collection([
|
||||||
new Attribution({ collapsible: true }),
|
new Attribution({ collapsible: true }),
|
||||||
new Rotate(),
|
new Rotate(),
|
||||||
new ScaleLine({ bar: true }),
|
new ScaleLine({ bar: true }),
|
||||||
new Control({ element: getLocation.current ?? undefined }),
|
new Control({ element: getLocation.current ?? undefined }),
|
||||||
]);
|
]);
|
||||||
const map = new OlMap({
|
const olMap = new OlMap({
|
||||||
view: new View({
|
view: new View(
|
||||||
center: [0, 0],
|
state ?? {
|
||||||
zoom: 1,
|
center: [0, 0],
|
||||||
}),
|
zoom: 1,
|
||||||
|
}
|
||||||
|
),
|
||||||
layers: [
|
layers: [
|
||||||
new TileLayer({
|
new TileLayer({
|
||||||
source: new OSM(),
|
source: new OSM(),
|
||||||
|
@ -46,6 +108,8 @@ export const Map: React.FC<MapProperties> = (props: MapProperties) => {
|
||||||
target: target.current ?? undefined,
|
target: target.current ?? undefined,
|
||||||
controls,
|
controls,
|
||||||
});
|
});
|
||||||
|
olMap.on(['change', 'moveend'], changeListener);
|
||||||
|
setMap(olMap);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export { default } from './Map';
|
export { default, stateAtom } from './Map';
|
||||||
|
|
Loading…
Reference in New Issue