map.tsx 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. import { StyleSheet, Linking, StatusBar } from "react-native";
  2. import { View,Image, Text } from "@tarojs/components";
  3. import './map.scss'
  4. import { useEffect, useRef, useState } from "react";
  5. import Taro from "@tarojs/taro";
  6. import { LeafletView } from 'react-native-leaflet-maps';
  7. import { useNavigation, useRoute } from "@react-navigation/native";
  8. import { TimeFormatter } from "@/utils/time_format";
  9. import { systemLocation } from "@/services/common";
  10. import { useTranslation } from "react-i18next";
  11. import showAlert from "@/components/basic/Alert";
  12. import { kIsAndroid, kIsIOS } from "@/utils/tools";
  13. import { AtActivityIndicator } from "taro-ui";
  14. // let LeafletView = require('react-native-leaflet-maps').LeafletView
  15. let location: any = null
  16. export default function map() {
  17. // const [location, setLocation] = useState<any>(null)
  18. const navigation = useNavigation()
  19. const [current, setCurrent] = useState<any>(null)
  20. const [centerLocation, setCenterLocation] = useState<any>(null)
  21. const { t } = useTranslation()
  22. const [show, setShow] = useState(false)
  23. const [isLoading, setIsLoading] = useState(false)
  24. const router = useRoute()
  25. const zoom = (router.params! as any).zoom || 12
  26. useEffect(() => {
  27. if (router.params && (router.params! as any).lat) {
  28. setCenterLocation({
  29. latitude: (router.params! as any).lat,
  30. longitude: (router.params! as any).lng
  31. })
  32. }
  33. else {
  34. setCenterLocation({
  35. latitude: 37.4221,
  36. longitude: -122.0853
  37. })
  38. }
  39. navigation.setOptions({
  40. headerTitle: t('time_of_day.index.pick_location'),
  41. headerRight: () => {
  42. return <View
  43. onClick={confirmChoose}
  44. style={{
  45. height: 30, backgroundColor: '#eae9e9', marginRight: 20,
  46. display: 'flex',
  47. alignItems: 'center',
  48. justifyContent: 'center',
  49. paddingLeft: 10,
  50. paddingRight: 10,
  51. borderRadius: 10
  52. }}>
  53. <Text style={{ color: '#000', fontSize: 14, fontWeight: 'bold' }}>{t('time_of_day.index.done')}</Text>
  54. </View>
  55. // return <View style={{height:30,backgroundColor:'red',marginRight:20}}>
  56. // <Text onClick={confirmChoose} style={{ color: (router.params! as any).source == 'time_of_day' ? '#000' : '#fff',fontSize:16,fontWeight:'bold', marginRight: 15, padding: 5 }}>{t('time_of_day.index.done')}</Text>
  57. // </View>
  58. }
  59. });
  60. // getCurrent()
  61. }, [])
  62. function confirmChoose() {
  63. if ((router.params! as any).source && (router.params! as any).source == 'time_of_day') {
  64. if ((router.params! as any).chooseLocation) {
  65. (router.params! as any).chooseLocation(location, 'PICK')
  66. }
  67. navigation.goBack()
  68. return;
  69. }
  70. var today = new Date()
  71. var yesterday = new Date(today.getTime() - 24 * 3600 * 1000)
  72. var tomorrow = new Date(today.getTime() + 24 * 3600 * 1000)
  73. var strYesterday = `${yesterday.getFullYear()}-${TimeFormatter.padZero(yesterday.getMonth() + 1)}-${TimeFormatter.padZero(yesterday.getDate())}`
  74. var strTomorrow = `${tomorrow.getFullYear()}-${TimeFormatter.padZero(tomorrow.getMonth() + 1)}-${TimeFormatter.padZero(tomorrow.getDate())}`
  75. if (location.lng < -180) {
  76. location.lng += 360
  77. }
  78. if (location.lng > 180) {
  79. location.lng -= 360
  80. }
  81. if (location.lat > 90) {
  82. location.lat -= 90
  83. }
  84. if (location.lat < -90) {
  85. location.lat += 90
  86. }
  87. systemLocation({
  88. lat: (location as any).lat,
  89. lng: (location as any).lng,
  90. date_start: strYesterday,
  91. date_end: strTomorrow,
  92. coordinate_system_standard: process.env.TARO_ENV == 'weapp' ? 'GCJ-02' : 'WGS-84'
  93. }).then(data => {
  94. global.locationDetail = data
  95. Taro.setStorage({
  96. key: 'gps',
  97. data: JSON.stringify(data as any)
  98. })
  99. if (global.swiperDayNightRefresh) {
  100. global.swiperDayNightRefresh()
  101. }
  102. if (global.updateSwiper) {
  103. global.updateSwiper()
  104. }
  105. global.refreshNight()
  106. global.refreshDay()
  107. navigation.goBack()
  108. })
  109. }
  110. function getCurrent() {
  111. if (kIsIOS) {
  112. requestLocation()
  113. return;
  114. }
  115. var Jto = require('react-native').NativeModules.NativeBridge;
  116. Jto.checkSystemLocationService().then(res => {
  117. if (res) {
  118. requestLocation()
  119. }
  120. else {
  121. showAlert({
  122. title: t('feature.auth_sys.location_title'),
  123. content: t('feature.auth_sys.device_location_desc'),
  124. showCancel: true,
  125. cancelText: t('feature.auth_sys.location_cancel'),
  126. confirmText: t('feature.auth_sys.device_confirm'),
  127. confirm: () => {
  128. Jto.openSystemLocationSettings()
  129. }
  130. })
  131. }
  132. })
  133. }
  134. function requestLocation() {
  135. setIsLoading(true)
  136. Taro.getLocation({
  137. success(res) {
  138. // showAlert({
  139. // title: 'location',
  140. // content: JSON.stringify(res)
  141. // })
  142. setShow(true)
  143. setCurrent(res)
  144. setCenterLocation(res)
  145. location = {
  146. lat: (res as any).latitude, lng: (res as any).longitude
  147. }
  148. setIsLoading(false)
  149. },
  150. fail(res) {
  151. console.log('location update failed reason', res)
  152. if (res.errMsg == 'Permissions denied!') {
  153. setIsLoading(false)
  154. showAlert({
  155. title: t('feature.auth_sys.location_title'),
  156. content: kIsIOS ? t('feature.auth_sys.location_desc') : t('feature.auth_sys.location_android_service_desc'),
  157. showCancel: true,
  158. cancelText: t('feature.auth_sys.location_cancel'),
  159. confirmText: kIsIOS ? t('feature.auth_sys.location_confirm') : t('feature.auth_sys.service_confirm'),
  160. confirm: () => {
  161. if (kIsIOS) {
  162. Linking.openURL('app-settings:')
  163. }
  164. else {
  165. Linking.openSettings()
  166. // var Jto = require('react-native').NativeModules.NativeBridge;
  167. // Jto.openNotificationSettings()
  168. }
  169. }
  170. })
  171. }
  172. else {
  173. if (kIsAndroid) {
  174. var Jto = require('react-native').NativeModules.NativeBridge;
  175. Jto.getLocation().then(result => {
  176. var res = JSON.parse(result)
  177. setCurrent(res)
  178. setCenterLocation(res)
  179. location = {
  180. lat: (res as any).latitude, lng: (res as any).longitude
  181. }
  182. setIsLoading(false)
  183. // showAlert({
  184. // title: 'location2',
  185. // content: JSON.stringify(res)
  186. // })
  187. }).catch(e => {
  188. setIsLoading(false)
  189. // showAlert({
  190. // title: 'location failed',
  191. // content: JSON.stringify(e)
  192. // })
  193. })
  194. }
  195. else {
  196. setIsLoading(false)
  197. }
  198. }
  199. }
  200. })
  201. }
  202. function showCurrent() {
  203. getCurrent()
  204. }
  205. function centerPosition() {
  206. if (centerLocation) {
  207. return { lat: centerLocation.latitude, lng: centerLocation.longitude }
  208. }
  209. return null
  210. }
  211. function mapMarkers() {
  212. const icon = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1721280834380" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8231" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M511.999097 511.999097m-486.524133 0a486.524133 486.524133 0 1 0 973.048266 0 486.524133 486.524133 0 1 0-973.048266 0Z" fill="#286FB7" opacity=".2" p-id="8232"></path><path d="M511.999097 511.999097m-307.200542 0a307.200542 307.200542 0 1 0 614.401084 0 307.200542 307.200542 0 1 0-614.401084 0Z" fill="#FFFFFF" p-id="8233"></path><path d="M511.999097 511.999097m-257.688367 0a257.688367 257.688367 0 1 0 515.376734 0 257.688367 257.688367 0 1 0-515.376734 0Z" fill="#4575F6" p-id="8234"></path></svg>'
  213. if (current) {
  214. return [{
  215. id: 9527,
  216. position: {
  217. lat: current.latitude,
  218. lng: current.longitude
  219. },
  220. icon: `<div style="width: 24px; height: 24px; background-color: #286FB752; border-radius: 50%;display:flex;align-items:center;justify-content:center;">
  221. <div style="width: 16px; height: 16px; background-color: #fff;; border-radius: 50%;display:flex;align-items:center;justify-content:center">
  222. <div style="width: 12px; height: 12px; background-color: #4575F6; border-radius: 50%;display:flex;align-items:center;justify-content:center">
  223. </div>
  224. </div>
  225. </div>`,
  226. // icon:
  227. // require('@/assets/images/current_location.png'),
  228. // icon: this.state.user_last_car,
  229. size: [32, 32],
  230. }]
  231. }
  232. return []
  233. }
  234. return <View style={{ flex: 1 }}>
  235. <LeafletView
  236. style={{ flex: 1 }}
  237. zoom={zoom}
  238. mapCenterPosition={centerPosition()}
  239. mapMarkers={mapMarkers()}
  240. onMessageReceived={e => {
  241. if (e.event == 'onZoomEnd' && e.payload && e.payload.zoom) {
  242. Taro.setStorage({ key: 'zoom', data: (e as any).payload.zoom })
  243. }
  244. if (e.payload && e.payload.mapCenterPosition)
  245. location = e.payload.mapCenterPosition
  246. // if (e.event && e.event == 'onMoveEnd') {
  247. // if (e.payload && e.payload.mapCenterPosition)
  248. // setLocation(e.payload.mapCenterPosition)
  249. // }
  250. // setTimeout(() => {
  251. // if (e.payload && e.payload.mapCenterPosition)
  252. // setLocation(e.payload.mapCenterPosition)
  253. // }, 500)
  254. // if (e.payload && e.payload.mapCenterPosition)
  255. // setLocation(e.payload.mapCenterPosition)
  256. }}
  257. />
  258. <View style={styles.overlayView}
  259. pointerEvents="none"
  260. >
  261. <Image src={require('@/assets/images/center.png')} style={styles.center} />
  262. </View>
  263. <View style={styles.location_btn}>
  264. {
  265. isLoading ? <View style={{ width: 20, height: 20, overflow: 'hidden' }}>
  266. <AtActivityIndicator size={20} color="#000" content="" />
  267. </View> :
  268. <Image src={require('@/assets/images/current_location.png')} onClick={showCurrent} style={styles.location_icon} />
  269. }
  270. </View>
  271. {/* <View style={styles.footer}>
  272. {
  273. location && <Text style={{ fontSize: 14, color: '#000' }}>Center位置:lat {(location as any).lat.toFixed(4)} lng {(location as any).lng.toFixed(4)}</Text>
  274. }
  275. </View> */}
  276. </View>
  277. }
  278. const styles = StyleSheet.create({
  279. container: {
  280. flex: 1,
  281. },
  282. scrollContent: {
  283. // 您的滚动内容样式
  284. },
  285. overlayView: {
  286. // 覆盖视图样式
  287. position: 'absolute',
  288. top: 0,
  289. left: 0,
  290. right: 0,
  291. bottom: 0,
  292. alignItems: 'center',
  293. justifyContent: 'center'
  294. },
  295. center: {
  296. width: 35,
  297. height: 35,
  298. marginBottom: 21
  299. },
  300. location_btn: {
  301. position: 'absolute',
  302. left: 40,
  303. bottom: 80,
  304. width: 50,
  305. height: 50,
  306. alignItems: 'center',
  307. justifyContent: 'center',
  308. backgroundColor: '#fff',
  309. borderRadius: 5
  310. },
  311. location_icon: {
  312. width: 30,
  313. height: 30
  314. },
  315. footer: {
  316. position: 'absolute',
  317. left: 50,
  318. right: 50,
  319. bottom: 30,
  320. backgroundColor: '#fff',
  321. alignItems: 'center',
  322. justifyContent: 'center',
  323. height: 30
  324. }
  325. });