mi-map.vue 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  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">
  8. <image class="left" :src="myPositionIcon" mode="" @tap="toMyLocation"></image>
  9. <view class="right">
  10. <text class="title">我的位置</text>
  11. <text class="text">{{myAddress.addressInfo}}</text>
  12. </view>
  13. </view>
  14. <view class="start-place">
  15. <view class="place">
  16. <text class="text">{{addressObj.address.addressInfo}}</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: '../../static/sailun/gps-icon.png'
  43. },
  44. myPositionIcon: {
  45. type: String,
  46. default: '../../static/sailun/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().windowWidth/2-15,
  76. top: (uni.getSystemInfoSync().windowHeight-240)/2-15,
  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. },
  93. fail: function(e) {
  94. uni.showToast({
  95. icon: 'none',
  96. title: '获取地址失败, 请检查是否开启定位权限'
  97. })
  98. }
  99. })
  100. },
  101. // 初始化我的位置
  102. async initMap(res) {
  103. this.longitude = res.longitude;
  104. this.latitude = res.latitude;
  105. this.myAddress = await this.getAddressName(res);
  106. this.addressObj = Object.assign({}, this.addressObj, {
  107. longitude: res.longitude,
  108. latitude: res.latitude,
  109. address: this.myAddress
  110. })
  111. },
  112. // 地图选择位置后 查询地点名称
  113. async checkMap(res) {
  114. this.addressObj = Object.assign({}, this.addressObj, {
  115. longitude: res.longitude,
  116. latitude: res.latitude,
  117. address: await this.getAddressName(res)
  118. })
  119. },
  120. // 监听地图位置变化
  121. mapChange(e) {
  122. let that = this
  123. clearTimeout(this.timer)
  124. this.timer = setTimeout(() => {
  125. if (e.type == 'regionchange' || e.type == 'end') {
  126. that.mapCtx = uni.createMapContext('map', this)
  127. that.mapCtx.getCenterLocation({
  128. success: res => {
  129. this.checkMap(res)
  130. },
  131. fail: err => {
  132. console.log(err);
  133. }
  134. })
  135. }
  136. }, 200)
  137. },
  138. // 查询地图中心点的名称
  139. getAddressName(addressObj) {
  140. return new Promise((res) => {
  141. // #ifdef APP-PLUS
  142. qqmapsdk.reverseGeocoder({
  143. location: {
  144. latitude: addressObj.latitude,
  145. longitude: addressObj.longitude
  146. },
  147. get_poi: 1,
  148. poi_options: "page_size=1;page_index=1",
  149. output: 'jsonp',
  150. success: (e) => {
  151. res({addressInfo:e.result.formatted_addresses.recommend,province:e.result.address_component.province,city:e.result.address_component.city,district:e.result.address_component.district,});
  152. },
  153. fail: err => {
  154. res(err);
  155. }
  156. })
  157. // #endif
  158. // #ifndef APP-PLUS
  159. // ======================== jsonp跨域 ========================
  160. const KEY = 'LXCBZ-NNIKD-UZ64F-H6AFI-UNJLH-OCFGE'
  161. let locationObj = addressObj.latitude + ',' + addressObj.longitude
  162. let url =
  163. 'https://apis.map.qq.com/ws/geocoder/v1?coord_type=5&get_poi=1&output=jsonp&poi_options=page_size=1;page_index=1';
  164. this.$jsonp(url, {
  165. key: KEY,
  166. location: locationObj
  167. }).then(e => {
  168. res(e.result.formatted_addresses.recommend);
  169. })
  170. .catch(err => {
  171. res(err);
  172. })
  173. // #endif
  174. })
  175. },
  176. // 计算地图的高度
  177. initMapH() {
  178. this.mapH = uni.getSystemInfoSync().windowHeight-210;
  179. },
  180. // 移动到我的位置
  181. toMyLocation() {
  182. this.getLocation()
  183. },
  184. // 提交
  185. submitAdress() {
  186. this.controls = []
  187. setTimeout(() => {
  188. this.$emit('updateAddress', this.addressObj)
  189. }, 100)
  190. }
  191. },
  192. }
  193. </script>
  194. <style lang="scss" scoped>
  195. .server-place {
  196. height: 100vh;
  197. width: 100%;
  198. z-index: 999;
  199. .map-tools {
  200. width: 750rpx;
  201. display: flex;
  202. justify-content: center;
  203. align-items: center;
  204. flex-direction: column;
  205. .my-location {
  206. width: 700rpx;
  207. height: 100rpx;
  208. box-shadow: 0rpx 3rpx 20rpx rgba(0, 0, 0, 0.2);
  209. background: #fff;
  210. border-radius: 10rpx;
  211. display: flex;
  212. justify-content: flex-start;
  213. align-items: center;
  214. overflow: hidden;
  215. margin-top: 10rpx;
  216. .left {
  217. background: #3384ff;
  218. // flex: 20%;
  219. width: 100rpx;
  220. height: 100%;
  221. }
  222. .right {
  223. font-size: 26rpx;
  224. margin-left: 10rpx;
  225. color: #111;
  226. // flex: 80%;
  227. display: flex;
  228. justify-content: center;
  229. align-items: flex-start;
  230. flex-direction: column;
  231. .text {
  232. width: 500rpx;
  233. overflow: hidden;
  234. white-space: nowrap;
  235. text-overflow: ellipsis;
  236. color: #3384FF;
  237. margin-top: 10rpx;
  238. }
  239. }
  240. }
  241. .start-place {
  242. width: 700rpx;
  243. height: 100rpx;
  244. box-shadow: 0rpx 3rpx 20rpx rgba(0, 0, 0, 0.2);
  245. background: #fff;
  246. border-radius: 10rpx;
  247. margin-top: 20rpx;
  248. .place {
  249. margin-left: 20rpx;
  250. .title {
  251. font-size: 24rpx;
  252. font-weight: bold;
  253. color: #111;
  254. }
  255. .text {
  256. margin-top: 20rpx;
  257. font-size: 24rpx;
  258. color: #3384FF;
  259. font-weight: bold;
  260. width: 700rpx;
  261. vertical-align: middle;
  262. display: inline-block;
  263. overflow: hidden;
  264. white-space: nowrap;
  265. text-overflow: ellipsis;
  266. }
  267. }
  268. .tip {
  269. margin-left: 20rpx;
  270. font-size:20rpx;
  271. color: #666;
  272. }
  273. }
  274. .sure {
  275. font-weight: 600;
  276. width: 700rpx;
  277. margin-top: 20rpx;
  278. }
  279. }
  280. }
  281. </style>