mi-map.vue 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  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. lonlatData:''
  62. };
  63. },
  64. mounted() {
  65. this.getLocation()
  66. this.initMapH()
  67. this.initPositionIcon()
  68. },
  69. methods: {
  70. // 初始化地图中心位置的定位图片
  71. initPositionIcon() {
  72. setTimeout(() => {
  73. this.controls = [{
  74. iconPath: this.positionIcon,
  75. position: {
  76. left: uni.getSystemInfoSync().windowWidth/2-15,
  77. top: (uni.getSystemInfoSync().windowHeight-240)/2-15,
  78. width: 30,
  79. height: 30,
  80. },
  81. clickable: false
  82. }]
  83. }, 100)
  84. },
  85. // 查询现在的位置
  86. getLocation() {
  87. let this_ = this
  88. uni.getLocation({
  89. type: 'gcj02', // 返回国测局坐标
  90. geocode: true,
  91. success: function(res) {
  92. this_.initMap(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. let point = new plus.maps.Point(res.longitude,res.latitude);
  116. plus.maps.Map.convertCoordinates(point, {},event=> {
  117. this.lonlatData= event.coord; // 转换后的坐标值
  118. });
  119. this.addressObj = Object.assign({}, this.addressObj, {
  120. longitude: res.longitude,
  121. latitude: res.latitude,
  122. address: await this.getAddressName(res)
  123. })
  124. },
  125. // 监听地图位置变化
  126. mapChange(e) {
  127. let that = this
  128. clearTimeout(this.timer)
  129. this.timer = setTimeout(() => {
  130. if (e.type == 'regionchange' || e.type == 'end') {
  131. that.mapCtx = uni.createMapContext('map', this)
  132. that.mapCtx.getCenterLocation({
  133. success: res => {
  134. this.checkMap(res)
  135. },
  136. fail: err => {
  137. console.log(err);
  138. }
  139. })
  140. }
  141. }, 200)
  142. },
  143. // 查询地图中心点的名称
  144. getAddressName(addressObj) {
  145. return new Promise((res) => {
  146. // #ifdef APP-PLUS
  147. qqmapsdk.reverseGeocoder({
  148. location: {
  149. latitude: addressObj.latitude,
  150. longitude: addressObj.longitude
  151. },
  152. get_poi: 1,
  153. poi_options: "page_size=1;page_index=1",
  154. output: 'jsonp',
  155. success: (e) => {
  156. 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,});
  157. },
  158. fail: err => {
  159. res(err);
  160. }
  161. })
  162. // #endif
  163. // #ifndef APP-PLUS
  164. // ======================== jsonp跨域 ========================
  165. const KEY = 'LXCBZ-NNIKD-UZ64F-H6AFI-UNJLH-OCFGE'
  166. let locationObj = addressObj.latitude + ',' + addressObj.longitude
  167. let url =
  168. 'https://apis.map.qq.com/ws/geocoder/v1?coord_type=5&get_poi=1&output=jsonp&poi_options=page_size=1;page_index=1';
  169. this.$jsonp(url, {
  170. key: KEY,
  171. location: locationObj
  172. }).then(e => {
  173. res(e.result.formatted_addresses.recommend);
  174. })
  175. .catch(err => {
  176. res(err);
  177. })
  178. // #endif
  179. })
  180. },
  181. // 计算地图的高度
  182. initMapH() {
  183. this.mapH = uni.getSystemInfoSync().windowHeight-210;
  184. },
  185. // 移动到我的位置
  186. toMyLocation() {
  187. this.getLocation()
  188. },
  189. // 提交
  190. submitAdress() {
  191. this.addressObj.longitude=this.lonlatData.longitude
  192. this.addressObj.latitude=this.lonlatData.latitude
  193. this.controls = []
  194. setTimeout(() => {
  195. this.$emit('updateAddress', this.addressObj)
  196. }, 100)
  197. }
  198. },
  199. }
  200. </script>
  201. <style lang="scss" scoped>
  202. .server-place {
  203. height: 100vh;
  204. width: 100%;
  205. z-index: 999;
  206. .map-tools {
  207. width: 750rpx;
  208. display: flex;
  209. justify-content: center;
  210. align-items: center;
  211. flex-direction: column;
  212. .my-location {
  213. width: 700rpx;
  214. height: 100rpx;
  215. box-shadow: 0rpx 3rpx 20rpx rgba(0, 0, 0, 0.2);
  216. background: #fff;
  217. border-radius: 10rpx;
  218. display: flex;
  219. justify-content: flex-start;
  220. align-items: center;
  221. overflow: hidden;
  222. margin-top: 10rpx;
  223. .left {
  224. background: #3384ff;
  225. // flex: 20%;
  226. width: 100rpx;
  227. height: 100%;
  228. }
  229. .right {
  230. font-size: 26rpx;
  231. margin-left: 10rpx;
  232. color: #111;
  233. // flex: 80%;
  234. display: flex;
  235. justify-content: center;
  236. align-items: flex-start;
  237. flex-direction: column;
  238. .text {
  239. width: 500rpx;
  240. overflow: hidden;
  241. white-space: nowrap;
  242. text-overflow: ellipsis;
  243. color: #3384FF;
  244. margin-top: 10rpx;
  245. }
  246. }
  247. }
  248. .start-place {
  249. width: 700rpx;
  250. height: 100rpx;
  251. box-shadow: 0rpx 3rpx 20rpx rgba(0, 0, 0, 0.2);
  252. background: #fff;
  253. border-radius: 10rpx;
  254. margin-top: 20rpx;
  255. .place {
  256. margin-left: 20rpx;
  257. .title {
  258. font-size: 24rpx;
  259. font-weight: bold;
  260. color: #111;
  261. }
  262. .text {
  263. margin-top: 20rpx;
  264. font-size: 24rpx;
  265. color: #3384FF;
  266. font-weight: bold;
  267. width: 700rpx;
  268. vertical-align: middle;
  269. display: inline-block;
  270. overflow: hidden;
  271. white-space: nowrap;
  272. text-overflow: ellipsis;
  273. }
  274. }
  275. .tip {
  276. margin-left: 20rpx;
  277. font-size:20rpx;
  278. color: #666;
  279. }
  280. }
  281. .sure {
  282. font-weight: 600;
  283. width: 700rpx;
  284. margin-top: 20rpx;
  285. }
  286. }
  287. }
  288. </style>