1import * as Location from 'expo-location';
2import React from 'react';
3import { Platform, ScrollView, StyleSheet, Text, View } from 'react-native';
4
5import SimpleActionDemo from '../../components/SimpleActionDemo';
6import TitleSwitch from '../../components/TitledSwitch';
7import usePermissions from '../../utilities/usePermissions';
8
9// Provide your own Google Maps API Key here to verify.  Note: this requires a
10// paid Google Maps API plan. It is not required to test this during QA.
11const GOOGLE_MAPS_API_KEY = null;
12
13if (GOOGLE_MAPS_API_KEY) {
14  Location.setGoogleApiKey(GOOGLE_MAPS_API_KEY);
15}
16
17const forwardGeocodingAddresses = [
18  '1 Hacker Way, CA',
19  'Palo Alto Caltrain Station',
20  'Rogers Arena, Vancouver',
21  'Zabłocie 43b, Kraków',
22  'Amsterdam Centraal',
23  ':-(',
24];
25
26const reverseGeocodingCoords = [
27  { latitude: 49.28, longitude: -123.12 }, // Seymour St, Vancouver
28  { latitude: 50.0615298, longitude: 19.9372142 }, // Main Square, Kraków
29  { latitude: 52.3730983, longitude: 4.8909126 }, // Dam Square, Amsterdam
30  { latitude: 0, longitude: 0 }, // North Atlantic Ocean
31];
32
33export default function GeocodingScreen() {
34  usePermissions(Location.requestForegroundPermissionsAsync);
35
36  const [useGoogleMaps, setGoogleMaps] = React.useState(false);
37
38  const toggleGoogleMaps = () => {
39    if (!GOOGLE_MAPS_API_KEY) {
40      throw new Error(
41        'Must supply GOOGLE_MAPS_API_KEY in GeocodingScreen.tsx to use Google Maps API'
42      );
43    } else {
44      setGoogleMaps((value) => !value);
45    }
46  };
47
48  return (
49    <ScrollView style={styles.container}>
50      <TitleSwitch
51        style={styles.switch}
52        title="Use Google Maps API"
53        value={useGoogleMaps}
54        setValue={toggleGoogleMaps}
55      />
56
57      <View style={styles.headerContainer}>
58        <Text style={styles.headerText}>Forward-Geocoding</Text>
59      </View>
60      {forwardGeocodingAddresses.map((address, index) => (
61        <SimpleActionDemo
62          key={index}
63          title={address}
64          action={() => Location.geocodeAsync(address, { useGoogleMaps })}
65        />
66      ))}
67
68      <View style={styles.headerContainer}>
69        <Text style={styles.headerText}>Reverse-Geocoding</Text>
70      </View>
71      {reverseGeocodingCoords.map((coords, index) => (
72        <SimpleActionDemo
73          key={index}
74          title={`${coords.latitude}, ${coords.longitude}`}
75          action={() => Location.reverseGeocodeAsync(coords, { useGoogleMaps })}
76        />
77      ))}
78      <SimpleActionDemo
79        title="Where am I?"
80        action={async () => {
81          const location = await Location.getCurrentPositionAsync({
82            accuracy: Location.LocationAccuracy.Lowest,
83          });
84          return Location.reverseGeocodeAsync(location.coords, { useGoogleMaps });
85        }}
86      />
87    </ScrollView>
88  );
89}
90
91const styles = StyleSheet.create({
92  container: {
93    flex: 1,
94  },
95  switch: {
96    paddingTop: 10,
97    paddingLeft: 10,
98    justifyContent: 'flex-start',
99  },
100  separator: {
101    height: 1,
102    backgroundColor: '#eee',
103    marginTop: 10,
104    marginBottom: 5,
105  },
106  headerText: {
107    fontSize: 18,
108    fontWeight: '600',
109    marginBottom: 5,
110  },
111  headerContainer: {
112    borderBottomWidth: 1,
113    borderBottomColor: '#eee',
114    marginHorizontal: 10,
115    marginBottom: 0,
116    marginTop: 30,
117  },
118  exampleText: {
119    fontSize: 15,
120    color: '#ccc',
121    marginVertical: 10,
122  },
123  examplesContainer: {
124    paddingTop: 15,
125    paddingBottom: 5,
126    paddingHorizontal: 20,
127  },
128  selectedExampleText: {
129    color: 'black',
130  },
131  resultText: {
132    padding: 20,
133  },
134  actionContainer: {
135    flexDirection: 'row',
136    alignItems: 'center',
137    justifyContent: 'center',
138    marginVertical: 10,
139  },
140  errorResultText: {
141    padding: 20,
142    color: 'red',
143  },
144  button: {
145    ...Platform.select({
146      android: {
147        marginBottom: 10,
148      },
149    }),
150  },
151});
152