index.vue 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. <template>
  2. <view>
  3. <map
  4. id="Mymap"
  5. class="Mymap"
  6. :longitude="choose.longitude"
  7. :latitude="choose.latitude"
  8. show-location
  9. scale="16"
  10. :markers="markers"
  11. />
  12. <view class="search-box">
  13. <picker
  14. v-if="area.show"
  15. :value="area.name"
  16. mode="region"
  17. @change="regionChange"
  18. level='city'
  19. >
  20. <view class="picker">
  21. <view class="name">
  22. {{ area.name[1] }}
  23. </view>
  24. <view class="iconfont icon-a-wodetiaozhuan" />
  25. </view>
  26. </picker>
  27. <view style="flex: 1; margin-left: 10px">
  28. <My_search @onSearch="onSearch" isInput />
  29. </view>
  30. </view>
  31. <My_listbox boxBackground="#fff" bottomHeight="70" :pullDown="false">
  32. <view v-if="list.length == 0" style="padding-top: 6vw">
  33. <u-empty mode="search" />
  34. </view>
  35. <view
  36. class="item"
  37. @click="changeChoose(item)"
  38. :style="{
  39. background: choose.lonlat == item.lonlat ? '#F8FBFF' : '#fff',
  40. }"
  41. v-for="item in list"
  42. :key="item.lonlat"
  43. hover-class="navigator-hover"
  44. >
  45. <view class="name">
  46. {{ item.name }}
  47. </view>
  48. <view class="address">
  49. {{ getCity(item) }}
  50. </view>
  51. </view>
  52. </My_listbox>
  53. <view class="footer">
  54. <view
  55. class="confirm"
  56. :class="choose.name ? '' : 'forbidden'"
  57. @click="choose.name ? submit() : ''"
  58. hover-class="navigator-hover"
  59. >
  60. 确定
  61. </view>
  62. </view>
  63. </view>
  64. </template>
  65. <script>
  66. import { tianditu } from "../../utils/tianditu.js";
  67. const api = new tianditu();
  68. export default {
  69. data() {
  70. return {
  71. keyWord: "",
  72. choose: {
  73. longitude: "",
  74. latitude: "",
  75. },
  76. area: {
  77. show: false,
  78. },
  79. markers: [],
  80. list: [],
  81. circumjacents: [],
  82. };
  83. },
  84. onLoad(options) {
  85. this.getLocation(true).then((location) => {
  86. this.choose = location;
  87. api.getPlace(location.longitude, location.latitude).then((place) => {
  88. console.log("逆解析", place);
  89. if (place.msg == "ok") {
  90. this.list = [
  91. {
  92. ...place.result.addressComponent,
  93. name: place.result.addressComponent.poi,
  94. lonlat: `${location.longitude},${location.latitude}`,
  95. ...location,
  96. },
  97. ];
  98. this.choose = this.list[0];
  99. this.markers = [
  100. {
  101. longitude: this.choose.longitude - 0,
  102. latitude: this.choose.latitude - 0,
  103. width: "35",
  104. height: "50",
  105. },
  106. ];
  107. this.area = {
  108. show: true,
  109. name: [
  110. place.result.addressComponent.province,
  111. place.result.addressComponent.city,
  112. place.result.addressComponent.county,
  113. ],
  114. specify: [
  115. place.result.addressComponent.province_code,
  116. place.result.addressComponent.city_code,
  117. place.result.addressComponent.county_code,
  118. ],
  119. };
  120. this.getCircumjacent(place.result);
  121. } else {
  122. uni.showModal({
  123. title: "提示",
  124. content: "获取位置失败",
  125. showCancel: false,
  126. });
  127. }
  128. });
  129. });
  130. uni.setNavigationBarTitle({
  131. title: options.title || "选择地点",
  132. });
  133. },
  134. methods: {
  135. getCircumjacent(place) {
  136. api
  137. .placeNameSearch({
  138. keyWord: place.addressComponent.road,
  139. queryRadius: "1000",
  140. pointLonlat: `${place.location.lon},${place.location.lat}`,
  141. queryType: 3,
  142. start: 0,
  143. count: 5,
  144. dataTypes:
  145. "公司,标志性建筑物,家装建材零售,家居用品,五金,电器零售,工业园",
  146. show: 2,
  147. })
  148. .then((res) => {
  149. console.log("地址", res);
  150. for (const key in res) {
  151. if (key != "keyWord" && res[key].pois) {
  152. this.list = this.unique(
  153. this.list.concat(
  154. res[key].pois.map((v) => {
  155. let lonlat = v.lonlat.split(",");
  156. v.longitude = lonlat[0];
  157. v.latitude = lonlat[1];
  158. return v;
  159. })
  160. ),
  161. "lonlat"
  162. );
  163. this.circumjacents = JSON.parse(JSON.stringify(this.list));
  164. }
  165. }
  166. });
  167. },
  168. regionChange({ detail }) {
  169. this.area = {
  170. show: true,
  171. name: detail.value,
  172. specify: detail.code.map((v) => "156" + v),
  173. };
  174. if (this.keyWord) this.onSearch(this.keyWord);
  175. },
  176. unique(arr, key) {
  177. for (let i = 0; i < arr.length; i++) {
  178. for (let j = i + 1; j < arr.length; j++) {
  179. if (arr[i][key] == arr[j][key]) {
  180. arr.splice(j, 1);
  181. j--;
  182. }
  183. }
  184. }
  185. return arr;
  186. },
  187. changeChoose(item) {
  188. this.choose = item;
  189. this.markers = [
  190. {
  191. longitude: item.longitude - 0,
  192. latitude: item.latitude - 0,
  193. width: "35",
  194. height: "50",
  195. },
  196. ];
  197. },
  198. onSearch(keyWord) {
  199. this.keyWord = keyWord;
  200. if (!keyWord) {
  201. this.list = this.circumjacents;
  202. } else {
  203. api
  204. .placeNameSearch({
  205. keyWord: keyWord,
  206. specify: this.area.specify[1],
  207. queryType: 12,
  208. start: 0,
  209. count: 30,
  210. show: 2,
  211. })
  212. .then((res) => {
  213. console.log("搜索地址", res);
  214. if (res.pois) {
  215. this.list = this.unique(
  216. res.pois.map((v) => {
  217. let lonlat = v.lonlat.split(",");
  218. v.longitude = lonlat[0];
  219. v.latitude = lonlat[1];
  220. return v;
  221. }),
  222. "lonlat"
  223. );
  224. } else {
  225. this.list = [];
  226. this.markers = [];
  227. this.choose = {
  228. longitude: "",
  229. latitude: "",
  230. };
  231. }
  232. });
  233. }
  234. if (this.list.length) {
  235. this.choose = this.list[0];
  236. this.markers = [
  237. {
  238. longitude: this.choose.longitude - 0,
  239. latitude: this.choose.latitude - 0,
  240. width: "35",
  241. height: "50",
  242. },
  243. ];
  244. }
  245. },
  246. submit() {
  247. this.$Http.routeSelected(this.choose);
  248. },
  249. },
  250. };
  251. </script>
  252. <style lang="scss" scoped>
  253. .Mymap {
  254. width: 100vw;
  255. height: 37vh;
  256. }
  257. .search-box {
  258. display: flex;
  259. align-items: center;
  260. width: 100vw;
  261. padding: 10px;
  262. box-sizing: border-box;
  263. background: #fff;
  264. .picker {
  265. display: flex;
  266. flex-direction: row;
  267. align-items: center;
  268. .icon-a-wodetiaozhuan {
  269. transform: rotate(90deg);
  270. margin-left: 4px;
  271. }
  272. }
  273. }
  274. .item {
  275. width: 100vw;
  276. margin: 0 auto;
  277. // border-bottom: .5px solid #ddd;
  278. padding: 10px;
  279. box-sizing: border-box;
  280. .name {
  281. line-height: 20px;
  282. font-family: Source Han Sans SC, Source Han Sans SC;
  283. font-weight: bold;
  284. font-size: 14px;
  285. color: #333333;
  286. margin-bottom: 5px;
  287. }
  288. .address {
  289. line-height: 17px;
  290. font-family: Source Han Sans SC, Source Han Sans SC;
  291. font-size: 12px;
  292. color: #999999;
  293. }
  294. }
  295. .footer {
  296. position: fixed;
  297. bottom: 0;
  298. width: 100vw;
  299. height: 65px;
  300. background: #ffffff;
  301. box-shadow: 0px -2px 6px 1px rgba(0, 0, 0, 0.16);
  302. box-sizing: border-box;
  303. padding: 5px 10px;
  304. z-index: 2;
  305. .confirm {
  306. display: flex;
  307. align-items: center;
  308. justify-content: center;
  309. width: 100%;
  310. height: 45px;
  311. background: #c30d23;
  312. border-radius: 5px;
  313. font-family: PingFang SC, PingFang SC;
  314. font-size: 14px;
  315. color: #ffffff;
  316. }
  317. .forbidden {
  318. opacity: 0.6;
  319. }
  320. }
  321. </style>