mi-map.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. <template>
  2. <view class="server-place">
  3. <map id='map' ref='map' v-bind:style="{height: mapH + 'px'}" style="width: 100%;" :latitude="latitude" :longitude="longitude"
  4. :controls='controls' scale="18" @regionchange='mapChange'>
  5. </map>
  6. <view class="map-tools">
  7. <view class="my-location" @tap="toMyLocation">
  8. <image class="left" :src="myPositionIcon" mode=""></image>
  9. <view class="right">
  10. <text class="title">我的位置</text>
  11. <text class="text">{{myAddress}}</text>
  12. </view>
  13. </view>
  14. <view class="start-place">
  15. <view class="place">
  16. <text class="text">{{addressObj.address}}</text>
  17. </view>
  18. <view class="tip">{{descText}}</view>
  19. </view>
  20. <button @tap="submitAdress" class="sure" type="primary">确认选择</button>
  21. </view>
  22. </view>
  23. </template>
  24. <script>
  25. const app = getApp()
  26. var QQMapWX = require('./qqmap-wx-jssdk.min.js')
  27. var qqmapsdk = new QQMapWX({
  28. key: 'LXCBZ-NNIKD-UZ64F-H6AFI-UNJLH-OCFGE'
  29. })
  30. export default {
  31. props: {
  32. tipText: {
  33. type: String,
  34. default: '选择位置'
  35. },
  36. descText: {
  37. type: String,
  38. default: '使用当前定位或在地图上标记位置'
  39. },
  40. positionIcon: {
  41. type: String,
  42. default: 'https://s2.ax1x.com/2020/03/10/8CvKmt.png'
  43. },
  44. myPositionIcon: {
  45. type: String,
  46. default: 'https://s2.ax1x.com/2020/03/10/8CjxSJ.png'
  47. }
  48. },
  49. data() {
  50. return {
  51. mapH: 0, // 地图高度,可在initMapH()中设置高度
  52. longitude: 0, // 初始经度
  53. latitude: 0, // 初始纬度
  54. myAddress: '', // 初始地址信息
  55. addressObj: { // 地图选点信息
  56. longitude: '',
  57. latitude: '',
  58. address: '请选择集合地点'
  59. },
  60. controls: [], // 地图中心点图标, 可更换iconPath, 详情见官方文档关于map组件的介绍
  61. };
  62. },
  63. mounted() {
  64. this.getLocation()
  65. this.initMapH()
  66. this.initPositionIcon()
  67. },
  68. methods: {
  69. // 初始化地图中心位置的定位图片
  70. initPositionIcon() {
  71. setTimeout(() => {
  72. this.controls = [{
  73. iconPath: this.positionIcon,
  74. position: {
  75. left: uni.getSystemInfoSync().screenWidth/2-15,
  76. top: uni.getSystemInfoSync().screenHeight/2-225,
  77. width: 30,
  78. height: 30,
  79. },
  80. clickable: false
  81. }]
  82. }, 100)
  83. },
  84. // 查询现在的位置
  85. getLocation() {
  86. let this_ = this
  87. uni.getLocation({
  88. // type: 'gcj02', // 返回国测局坐标
  89. geocode: true,
  90. success: function(res) {
  91. this_.initMap(res)
  92. console.log(res);
  93. },
  94. fail: function(e) {
  95. uni.showToast({
  96. icon: 'none',
  97. title: '获取地址失败, 请检查是否开启定位权限~~'
  98. })
  99. }
  100. })
  101. },
  102. // 初始化我的位置
  103. async initMap(res) {
  104. this.longitude = res.longitude;
  105. this.latitude = res.latitude;
  106. this.myAddress = await this.getAddressName(res);
  107. this.addressObj = Object.assign({}, this.addressObj, {
  108. longitude: res.longitude,
  109. latitude: res.latitude,
  110. address: this.myAddress
  111. })
  112. },
  113. // 地图选择位置后 查询地点名称
  114. async checkMap(res) {
  115. this.addressObj = Object.assign({}, this.addressObj, {
  116. longitude: res.longitude,
  117. latitude: res.latitude,
  118. address: await this.getAddressName(res)
  119. })
  120. console.log('当前位置:' + res.latitude + '|' + res.longitude);
  121. },
  122. // 监听地图位置变化
  123. mapChange(e) {
  124. let that = this
  125. clearTimeout(this.timer)
  126. this.timer = setTimeout(() => {
  127. if (e.type == 'regionchange' || e.type == 'end') {
  128. that.mapCtx = uni.createMapContext('map', this)
  129. that.mapCtx.getCenterLocation({
  130. success: res => {
  131. this.checkMap(res)
  132. console.log(res);
  133. },
  134. fail: err => {
  135. console.log(err);
  136. }
  137. })
  138. }
  139. }, 200)
  140. },
  141. // 查询地图中心点的名称
  142. getAddressName(addressObj) {
  143. return new Promise((res) => {
  144. // #ifdef APP-PLUS
  145. qqmapsdk.reverseGeocoder({
  146. location: {
  147. latitude: addressObj.latitude,
  148. longitude: addressObj.longitude
  149. },
  150. get_poi: 1,
  151. poi_options: "page_size=1;page_index=1",
  152. output: 'jsonp',
  153. success: (e) => {
  154. res(e.result.formatted_addresses.recommend);
  155. },
  156. fail: err => {
  157. res(err);
  158. }
  159. })
  160. // #endif
  161. // #ifndef APP-PLUS
  162. // ======================== jsonp跨域 ========================
  163. const KEY = 'LXCBZ-NNIKD-UZ64F-H6AFI-UNJLH-OCFGE'
  164. let locationObj = addressObj.latitude + ',' + addressObj.longitude
  165. let url =
  166. 'https://apis.map.qq.com/ws/geocoder/v1?coord_type=5&get_poi=1&output=jsonp&poi_options=page_size=1;page_index=1';
  167. this.$jsonp(url, {
  168. key: KEY,
  169. location: locationObj
  170. }).then(e => {
  171. res(e.result.formatted_addresses.recommend);
  172. })
  173. .catch(err => {
  174. res(err);
  175. })
  176. // #endif
  177. })
  178. },
  179. // 计算地图的高度
  180. initMapH() {
  181. // #ifdef APP-PLUS
  182. this.mapH = uni.getSystemInfoSync().windowHeight - 210;
  183. // #endif
  184. // // #ifndef APP-PLUS
  185. // this.mapH = uni.getSystemInfoSync().windowHeight - 170;
  186. // // #endif
  187. },
  188. // 移动到我的位置
  189. toMyLocation() {
  190. this.getLocation()
  191. },
  192. // 提交
  193. submitAdress() {
  194. this.controls = []
  195. setTimeout(() => {
  196. this.$emit('updateAddress', this.addressObj)
  197. }, 100)
  198. }
  199. },
  200. }
  201. </script>
  202. <style lang="scss" scoped>
  203. .server-place {
  204. position: fixed;
  205. left: 0;
  206. top: 0;
  207. height: 100vh;
  208. width: 100%;
  209. z-index: 999;
  210. .map-tools {
  211. width: 750rpx;
  212. display: flex;
  213. justify-content: center;
  214. align-items: center;
  215. flex-direction: column;
  216. .my-location {
  217. width: 700rpx;
  218. height: 100rpx;
  219. box-shadow: 0rpx 3rpx 20rpx rgba(0, 0, 0, 0.2);
  220. background: #fff;
  221. border-radius: 10rpx;
  222. display: flex;
  223. justify-content: flex-start;
  224. align-items: center;
  225. overflow: hidden;
  226. margin-top: 10rpx;
  227. .left {
  228. background: #3384ff;
  229. // flex: 20%;
  230. width: 100rpx;
  231. height: 100%;
  232. }
  233. .right {
  234. font-size: 26rpx;
  235. margin-left: 10rpx;
  236. color: #111;
  237. // flex: 80%;
  238. display: flex;
  239. justify-content: center;
  240. align-items: flex-start;
  241. flex-direction: column;
  242. .text {
  243. width: 500rpx;
  244. overflow: hidden;
  245. white-space: nowrap;
  246. text-overflow: ellipsis;
  247. color: #3384FF;
  248. margin-top: 10rpx;
  249. }
  250. }
  251. }
  252. .start-place {
  253. width: 700rpx;
  254. height: 100rpx;
  255. margin: 0 auto;
  256. margin: 0 auto;
  257. box-shadow: 0rpx 3rpx 20rpx rgba(0, 0, 0, 0.2);
  258. background: #fff;
  259. border-radius: 10rpx;
  260. margin-top: 20rpx;
  261. .place {
  262. margin-left: 10rpx;
  263. .title {
  264. font-size: 24rpx;
  265. font-weight: bold;
  266. color: #111;
  267. }
  268. .text {
  269. margin-top: 20rpx;
  270. font-size: 20rpx;
  271. color: #3384FF;
  272. font-weight: bold;
  273. width: 700rpx;
  274. vertical-align: middle;
  275. display: inline-block;
  276. overflow: hidden;
  277. white-space: nowrap;
  278. text-overflow: ellipsis;
  279. }
  280. }
  281. .tip {
  282. font-size: 0.57rem;
  283. color: #666;
  284. }
  285. }
  286. .sure {
  287. font-weight: 600;
  288. width: 700rpx;
  289. margin-top: 20rpx;
  290. }
  291. }
  292. }
  293. </style>