Browse Source

starting the transition to OpenStreetMap with a test example

master
GabrielTrettel 4 years ago
parent
commit
b6f7eb5d3c
  1. 68
      src/app/components/map/Map.html
  2. 90
      src/app/components/map/OpenStreetMap.js
  3. 138
      src/app/screens/MapFeedScreen.js
  4. 3
      src/package.json

68
src/app/components/map/Map.html

@ -0,0 +1,68 @@
<!DOCTYPE html>
<html>
<head>
<title>Mobile tutorial - Leaflet</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" type="image/x-icon" href="docs/images/favicon.ico" />
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js" integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA==" crossorigin=""></script>
<style>
html, body {
height: 100%;
margin: 0;
}
#map {
width: 600px;
height: 400px;
}
</style>
<style>body { padding: 0; margin: 0; } #map { height: 100%; width: 100vw; }</style>
</head>
<body>
<div id='map'></div>
<script>
var mymap = L.map('map').setView([51.505, -0.09], 13);
L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiZ2FicmllbC10cmV0dGVsIiwiYSI6ImNrb2RjNWIzYjAwczIyd25yNnUweDNveTkifQ.xRASmGTYm0ieS-FjVrXSjA', {
maxZoom: 18,
attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, ' +
'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
id: 'mapbox/streets-v11',
tileSize: 512,
zoomOffset: -1
}).addTo(mymap);
L.circle([51.508, -0.11], 500, {
color: 'red',
fillColor: '#f03',
fillOpacity: 0.5
}).addTo(mymap).bindPopup("I am a circle.");
L.polygon([
[51.509, -0.08],
[51.503, -0.06],
[51.51, -0.047]
]).addTo(mymap).bindPopup("I am a polygon.");
var popup = L.popup();
function onMapClick(e) {
var payload = {
code: 1,
content: {
latitude: e.latlng.lat.toString().slice(0,8),
longitude: e.latlng.lng.toString().slice(0,8),
}
}
window.ReactNativeWebView.postMessage(JSON.stringify(payload));
}
function onPopupClick(e) {
var payload = {
code: 2,
content: "marker selecionado"
}
window.ReactNativeWebView.postMessage(JSON.stringify(payload));
}
mymap.on("popupopen", onPopupClick);
mymap.on('click', onMapClick);
</script>
</body>
</html>

90
src/app/components/map/OpenStreetMap.js

@ -0,0 +1,90 @@
import React, { useEffect, useState } from "react";
import { View } from "react-native";
import WebView from "react-native-webview";
import { Asset } from "expo-asset";
import * as FileSystem from "expo-file-system";
const HTML_FILE_PATH = require(`./Map.html`);
const loadHTMLFile = async () => {
try {
const [{ localUri }] = await Asset.loadAsync(HTML_FILE_PATH);
const fileString = await FileSystem.readAsStringAsync(localUri);
return fileString;
} catch (error) {
console.warn(error);
console.warn("Unable to resolve index file");
}
};
const code_to_function = {
"1": clickCallback,
"2": clickCallback,
};
function clickCallback(payload, props) {
console.log(payload.content);
props.clickListener(JSON.stringify(payload.content));
}
function parseInput(event, props) {
// console.log(event);
const payload = JSON.parse(event);
// console.log(payload);
code_to_function[payload.code](payload, props);
}
function insertMarker(mapRef, props) {
console.log(props);
mapRef.injectJavaScript(`
var layer = L.marker([${props.cords.lat}, ${props.cords.long}], {ID: ${props.ID}} )
layer.ID = ${props.ID}
layer.addTo(mymap).bindPopup("<b>${props.title}</b><br />I am a popup.");`);
}
function goToPosition(mapRef, lat, long) {
mapRef.injectJavaScript(`mymap.setView([${lat}, ${long}], 13);`);
}
export default function OpenStreetMap(props) {
const [mapRef, setMapRef] = useState(null);
const [finishedLoad, setFinishedLoad] = useState(false);
const [webviewContent, setWebviewContent] = useState(null);
loadHTMLFile()
.then((html) => setWebviewContent(html))
.catch((e) => console.warn(e));
props.animateToPosition != null &&
goToPosition(mapRef, ...props.animateToPosition);
const onLoad = () => {
props.markersList != null &&
props.markersList.length > 0 &&
props.markersList.map((m) => insertMarker(mapRef, m));
};
useEffect(() => {
mapRef != null && onLoad();
}, [finishedLoad]);
return (
<View flex={1}>
<WebView
ref={(webViewRef) => {
setMapRef(webViewRef);
}}
onMessage={(event) => {
parseInput(event.nativeEvent.data, props);
}}
javaScriptEnabled={true}
source={{ html: webviewContent }}
onLoad={() => {
setFinishedLoad(true);
}}
/>
</View>
);
}

138
src/app/screens/MapFeedScreen.js

@ -1,74 +1,96 @@
import React, { useContext } from "react";
import { StyleSheet, View } from "react-native";
import MapView from "react-native-maps";
import React, { useRef, useState } from "react";
import { Button, StyleSheet, Text, TouchableOpacity, View } from "react-native";
import OpenStreetMap from "../components/map/OpenStreetMap";
import colors from "../config/colors";
import { screen_width, screen_height } from "../config/dimensions";
import attachFocusToQuery from "../hooks/useFocus";
import { CurrentLocationContext } from "../context/CurrentLocationContext";
import { MapMarkerList } from "../components/MapMarkerList";
import FloatButton from "../components/FloatButton";
import { MapDataContext } from "../context/MapDataContext";
import MapPolygons from "../components/MapPolygons";
export default function MapFeedScreen() {
const [position, setPosition] = useState(null);
const [clickListener, setClickListener] = useState("");
function MapFeedScreen(props) {
const context = useContext(CurrentLocationContext);
const datas = useContext(MapDataContext);
const location = context.currentCoordinates;
const focusChanged = attachFocusToQuery();
const markers = [
{
ID: "1",
title: "Casa da Lívia",
cords: {
lat: 51.505,
long: -0.09,
},
},
{
ID: "2",
title: "Casa do Daniel",
cords: {
lat: 51.5032,
long: -0.09589,
},
},
];
return (
<View style={styles.container}>
<OpenStreetMap
animateToPosition={position}
clickListener={setClickListener}
markersList={markers}
/>
const default_location = {
latitude: -12.901799,
longitude: -51.692116,
latitudeDelta: 70,
longitudeDelta: 70 * (screen_width / screen_height),
};
<View style={styles.btn}>
<TouchableOpacity
style={styles.btns}
onPress={() => {
setPosition([-23.644957, -46.528012]);
}}
>
<Text style={styles.txt}>UFABC</Text>
</TouchableOpacity>
const map_scale = 0.003;
const lat_long_delta = {
latitudeDelta: map_scale,
longitudeDelta: map_scale * (screen_width / screen_height),
};
<TouchableOpacity
style={styles.btns}
onPress={() => {
setPosition([51.505, -0.09]);
}}
>
<Text style={styles.txt}>Londres</Text>
</TouchableOpacity>
</View>
return (
<View style={styles.container}>
<MapView
style={styles.mapStyle}
showsUserLocation={true}
initialRegion={{ ...default_location }}
region={{
latitude: location["latitude"],
longitude: location["longitude"],
...lat_long_delta,
}}
>
<MapMarkerList
reload={focusChanged}
renderRain={datas.rain}
renderFlood={datas.flood}
renderPluviometer={datas.pluviometer}
renderRiver={datas.river}
renderOfficialPluviometer={datas.officialPluviometer}
/>
{datas.floodAreas && <MapPolygons />}
</MapView>
<FloatButton />
<View style={styles.callback}>
<Text style={styles.txt}>{clickListener}</Text>
</View>
</View> </View>
); );
} }
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
backgroundColor: colors.black,
flex: 1, flex: 1,
backgroundColor: "#FFF",
}, },
mapStyle: {
callback: {
position: "absolute", position: "absolute",
top: 0,
left: 0,
right: 0,
bottom: 0,
bottom: 30,
alignSelf: "center",
alignItems: "center",
backgroundColor: "gray",
width: "80%",
padding: 10,
},
btn: {
width: "80%",
position: "absolute",
top: 30,
flexDirection: "row",
justifyContent: "space-evenly",
alignItems: "center",
alignSelf: "center",
},
btns: {
backgroundColor: "dodgerblue",
borderRadius: 10,
width: 100,
padding: 10,
margin: 4,
alignItems: "center",
},
txt: {
color: "white",
}, },
}); });
export default MapFeedScreen;

3
src/package.json

@ -22,7 +22,7 @@
"@react-navigation/native": "^5.8.10", "@react-navigation/native": "^5.8.10",
"@react-navigation/stack": "^5.12.8", "@react-navigation/stack": "^5.12.8",
"expo": "^39.0.5", "expo": "^39.0.5",
"expo-asset": "^8.2.1",
"expo-asset": "~8.2.0",
"expo-file-system": "~9.2.0", "expo-file-system": "~9.2.0",
"expo-image-picker": "~9.1.1", "expo-image-picker": "~9.1.1",
"expo-location": "~9.0.0", "expo-location": "~9.0.0",
@ -55,6 +55,7 @@
"react-native-svg-uri": "^1.2.3", "react-native-svg-uri": "^1.2.3",
"react-native-walkthrough-tooltip": "^1.1.11", "react-native-walkthrough-tooltip": "^1.1.11",
"react-native-web": "~0.13.12", "react-native-web": "~0.13.12",
"react-native-webview": "^11.6.2",
"react-navigation": "^4.4.3", "react-navigation": "^4.4.3",
"react-navigation-header-buttons": "^7.0.1", "react-navigation-header-buttons": "^7.0.1",
"react-navigation-tabs": "^2.10.1", "react-navigation-tabs": "^2.10.1",

Loading…
Cancel
Save