104 lines
3.1 KiB
TypeScript
104 lines
3.1 KiB
TypeScript
import { useAssets } from "expo-asset";
|
|
import { useState, useRef, useEffect } from "react";
|
|
import { useWindowDimensions, Alert, Button } from "react-native";
|
|
import WebView, { WebViewMessageEvent } from "react-native-webview";
|
|
import * as Location from "expo-location";
|
|
import { fromLatLon, toLatLon } from "../UTM_converter";
|
|
|
|
const Map = () => {
|
|
const [assets] = useAssets([require("../assets/index.html")]);
|
|
const [htmlString, setHtmlString] = useState<string>();
|
|
|
|
const dimensions = useWindowDimensions();
|
|
const webViewRef = useRef<WebView | null>();
|
|
|
|
// gets location
|
|
useEffect(() => {
|
|
(async () => {
|
|
const { status } = await Location.requestForegroundPermissionsAsync();
|
|
if (status !== "granted") return;
|
|
const location = await Location.getCurrentPositionAsync({
|
|
distanceInterval: 0, // for IOS
|
|
accuracy: Location.Accuracy.High,
|
|
timeInterval: 3000, // for Android
|
|
});
|
|
// makes injectable javascript string
|
|
const str = `window.passLocation(${location.coords.longitude}, ${location.coords.latitude}); true()`;
|
|
// passes string to webview - there it is handled by OpenLayers to change the current location
|
|
webViewRef.current?.injectJavaScript(str);
|
|
})();
|
|
}, []);
|
|
|
|
// loads assets
|
|
useEffect(() => {
|
|
if (assets) {
|
|
fetch(assets[0].localUri || "")
|
|
.then((res) => res.text())
|
|
.then((html) => setHtmlString(html));
|
|
}
|
|
}, [assets]);
|
|
|
|
// exits if no map passed in
|
|
if (!htmlString) {
|
|
return <></>;
|
|
}
|
|
|
|
const messageHandler = (event: WebViewMessageEvent) => {
|
|
if (typeof event.nativeEvent.data == "string") {
|
|
const message = event.nativeEvent.data;
|
|
if (message === "new pin start") {
|
|
Alert.alert(
|
|
"New Pin",
|
|
`Please select location for new pin then press "OK"`,
|
|
[
|
|
{
|
|
text: "OK",
|
|
onPress: () => {
|
|
// makes injectable javascript string
|
|
const str = `window.placePin(); true()`;
|
|
// passes string to webview - there it is handled by OpenLayers to change the current location
|
|
webViewRef.current?.injectJavaScript(str);
|
|
},
|
|
},
|
|
]
|
|
);
|
|
} else if (message.startsWith(`@`)) {
|
|
const coords = message.slice(1).split(",");
|
|
const lon = Number(coords[0]);
|
|
const lat = Number(coords[1]);
|
|
const UTM = fromLatLon(lat, lon);
|
|
Alert.alert(
|
|
"Coords",
|
|
`${UTM.easting}, ${UTM.northing}, ${UTM.zoneNum}`
|
|
);
|
|
}
|
|
}
|
|
};
|
|
|
|
return (
|
|
<WebView
|
|
ref={(currentRef) => (webViewRef.current = currentRef)}
|
|
injectedJavascript=""
|
|
source={{
|
|
html: htmlString,
|
|
}}
|
|
javaScriptEnabled
|
|
style={{
|
|
width: dimensions.width,
|
|
height: dimensions.height,
|
|
}}
|
|
scrollEnabled={false}
|
|
overScrollMode="never"
|
|
showsVerticalScrollIndicator={false}
|
|
showsHorizontalScrollIndicator={false}
|
|
scalesPageToFit={false}
|
|
containerStyle={{
|
|
flex: 1,
|
|
}}
|
|
onMessage={messageHandler}
|
|
webviewDebuggingEnabled={true}
|
|
/>
|
|
);
|
|
};
|
|
|
|
export default Map;
|