mi-map.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  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. }
  133. })
  134. }
  135. }, 200)
  136. },
  137. // 查询地图中心点的名称
  138. getAddressName(addressObj) {
  139. return new Promise((res) => {
  140. // #ifdef APP-PLUS
  141. qqmapsdk.reverseGeocoder({
  142. location: {
  143. latitude: addressObj.latitude,
  144. longitude: addressObj.longitude
  145. },
  146. get_poi: 1,
  147. poi_options: "page_size=1;page_index=1",
  148. output: 'jsonp',
  149. success: (e) => {
  150. 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,});
  151. },
  152. fail: err => {
  153. res(err);
  154. }
  155. })
  156. // #endif
  157. // #ifndef APP-PLUS
  158. // ======================== jsonp跨域 ========================
  159. const KEY = 'LXCBZ-NNIKD-UZ64F-H6AFI-UNJLH-OCFGE'
  160. let locationObj = addressObj.latitude + ',' + addressObj.longitude
  161. let url =
  162. 'https://apis.map.qq.com/ws/geocoder/v1?coord_type=5&get_poi=1&output=jsonp&poi_options=page_size=1;page_index=1';
  163. this.$jsonp(url, {
  164. key: KEY,
  165. location: locationObj
  166. }).then(e => {
  167. res(e.result.formatted_addresses.recommend);
  168. })
  169. .catch(err => {
  170. res(err);
  171. })
  172. // #endif
  173. })
  174. },
  175. // 计算地图的高度
  176. initMapH() {
  177. this.mapH = uni.getSystemInfoSync().windowHeight-210;
  178. },
  179. // 移动到我的位置
  180. toMyLocation() {
  181. this.getLocation()
  182. },
  183. // 提交
  184. submitAdress() {
  185. if(this.addressObj.address.message=="request:fail abort statusCode:-1"){
  186. this.$u.toast('正在解析地址,请稍候');
  187. return
  188. }
  189. // console.log(this.addressObj)
  190. this.controls = []
  191. setTimeout(() => {
  192. this.$emit('updateAddress', this.addressObj)
  193. }, 100)
  194. }
  195. },
  196. }
  197. </script>
  198. <style lang="scss" scoped>
  199. .server-place {
  200. height: 100vh;
  201. width: 100%;
  202. z-index: 999;
  203. .map-tools {
  204. width: 750rpx;
  205. display: flex;
  206. justify-content: center;
  207. align-items: center;
  208. flex-direction: column;
  209. .my-location {
  210. width: 700rpx;
  211. height: 100rpx;
  212. box-shadow: 0rpx 3rpx 20rpx rgba(0, 0, 0, 0.2);
  213. background: #fff;
  214. border-radius: 10rpx;
  215. display: flex;
  216. justify-content: flex-start;
  217. align-items: center;
  218. overflow: hidden;
  219. margin-top: 10rpx;
  220. .left {
  221. background: #3384ff;
  222. // flex: 20%;
  223. width: 100rpx;
  224. height: 100%;
  225. }
  226. .right {
  227. font-size: 26rpx;
  228. margin-left: 10rpx;
  229. color: #111;
  230. // flex: 80%;
  231. display: flex;
  232. justify-content: center;
  233. align-items: flex-start;
  234. flex-direction: column;
  235. .text {
  236. width: 500rpx;
  237. overflow: hidden;
  238. white-space: nowrap;
  239. text-overflow: ellipsis;
  240. color: #3384FF;
  241. margin-top: 10rpx;
  242. }
  243. }
  244. }
  245. .start-place {
  246. width: 700rpx;
  247. height: 100rpx;
  248. box-shadow: 0rpx 3rpx 20rpx rgba(0, 0, 0, 0.2);
  249. background: #fff;
  250. border-radius: 10rpx;
  251. margin-top: 20rpx;
  252. .place {
  253. margin-left: 20rpx;
  254. .title {
  255. font-size: 24rpx;
  256. font-weight: bold;
  257. color: #111;
  258. }
  259. .text {
  260. margin-top: 20rpx;
  261. font-size: 24rpx;
  262. color: #3384FF;
  263. font-weight: bold;
  264. width: 700rpx;
  265. vertical-align: middle;
  266. display: inline-block;
  267. overflow: hidden;
  268. white-space: nowrap;
  269. text-overflow: ellipsis;
  270. }
  271. }
  272. .tip {
  273. margin-left: 20rpx;
  274. font-size:20rpx;
  275. color: #666;
  276. }
  277. }
  278. .sure {
  279. font-weight: 600;
  280. width: 700rpx;
  281. margin-top: 20rpx;
  282. }
  283. }
  284. }
  285. </style>