mi-map.vue 7.0 KB

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