|
@@ -0,0 +1,281 @@
|
|
|
+<template>
|
|
|
+ <div class="map">
|
|
|
+ <!-- 搜索 -->
|
|
|
+ <el-form inline size="mini">
|
|
|
+ <el-form-item label="关键词:">
|
|
|
+ <el-autocomplete popper-class="map-popper" v-model="keywords" placeholder="请输入关键词"
|
|
|
+ :fetch-suggestions="getKeyWords" @select="handleSelect" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item style="float: right;">
|
|
|
+ <el-button type="primary" :disabled="activeItem === null" @click="getEmit">确定</el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <div class="main">
|
|
|
+ <!-- 地图 -->
|
|
|
+ <div id="container" />
|
|
|
+ <!-- poi列表 -->
|
|
|
+ <div class="poi">
|
|
|
+ <div class="list" v-for="item in poiList" :key="item.id" @click="handleCheck(item)">
|
|
|
+ <div class="name">{{ item.name }}</div>
|
|
|
+ <div class="address">{{ item.address }}</div>
|
|
|
+ <i v-show="activeItem == item" class="el-icon-check" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+// 安全密钥
|
|
|
+import AMapLoader from '@amap/amap-jsapi-loader'
|
|
|
+import axios from 'axios'
|
|
|
+window._AMapSecurityConfig = {
|
|
|
+ securityJsCode: 'fd78b73eba80ab3f887c9ba60744048f'
|
|
|
+}
|
|
|
+export default {
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ // 地图
|
|
|
+ map: null,
|
|
|
+ // 定位
|
|
|
+ geolocation: null,
|
|
|
+ // 中心坐标
|
|
|
+ location: '',
|
|
|
+ // 关键词
|
|
|
+ keywords: '',
|
|
|
+ // poi列表
|
|
|
+ poiList: [],
|
|
|
+ // 选中的数据
|
|
|
+ activeItem: null
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.initAMap()
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ async initAMap() {
|
|
|
+ const that = this
|
|
|
+ // 调用高德
|
|
|
+ const AMap = await this.getMapLoader()
|
|
|
+ // 自定义定位按钮
|
|
|
+ this.geolocation = new AMap.Geolocation({
|
|
|
+ enableHighAccuracy: true, // 高精度定位
|
|
|
+ timeout: 3000, // 定位超时时间
|
|
|
+ zoomToAccuracy: true, // 定位成功后再调整视野
|
|
|
+ showCircle: false, // 定位成功有个圆形范围
|
|
|
+ buttonPosition: 'RB', // 按钮位置
|
|
|
+ })
|
|
|
+ const locationRes = await this.getLocation(AMap)
|
|
|
+ // 当前定位
|
|
|
+ const lnglat = locationRes.status === 'complete' ? [locationRes.data.position.lng, locationRes.data.position.lat] : [116.397428, 39.90923]
|
|
|
+ this.location = lnglat.join(',')
|
|
|
+ // 获取城市信息
|
|
|
+ this.getGeocoder(AMap, lnglat)
|
|
|
+ // 绘制地图
|
|
|
+ this.map = new AMap.Map('container', {
|
|
|
+ resizeEnable: true,
|
|
|
+ zoom: 16,
|
|
|
+ resizeEnable: true,
|
|
|
+ center: lnglat
|
|
|
+ })
|
|
|
+ // 调用插件
|
|
|
+ this.map.addControl(this.geolocation)
|
|
|
+ // 地图加载完
|
|
|
+ this.map.on('complete', function () {
|
|
|
+ // 自动定位一次
|
|
|
+ that.geolocation.getCurrentPosition()
|
|
|
+ that.getPOI()
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ // 调用高德
|
|
|
+ getMapLoader() {
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ AMapLoader.load({
|
|
|
+ key: '5dcf4cf0260059dade51d0d9b5e3c1ef',
|
|
|
+ version: '2.0',
|
|
|
+ plugins: ['AMap.Geolocation', 'AMap.Geocoder']
|
|
|
+ }).then((AMap) => {
|
|
|
+ resolve(AMap)
|
|
|
+ }).catch((err) => {
|
|
|
+ reject(err)
|
|
|
+ })
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ // 获取定位
|
|
|
+ getLocation(AMap) {
|
|
|
+ const that = this
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ AMap.plugin('AMap.Geolocation', function () {
|
|
|
+ that.geolocation.getCurrentPosition(function (status, res) {
|
|
|
+ resolve({
|
|
|
+ status: status,
|
|
|
+ data: res
|
|
|
+ })
|
|
|
+ })
|
|
|
+ })
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ // 获取城市信息
|
|
|
+ getGeocoder(AMap, lnglat) {
|
|
|
+ const that = this
|
|
|
+ AMap.plugin('AMap.Geocoder', function () {
|
|
|
+ var geocoder = new AMap.Geocoder()
|
|
|
+ geocoder.getAddress(lnglat, function (status, res) {
|
|
|
+ let e = res.regeocode.addressComponent
|
|
|
+ that.$emit('address', {
|
|
|
+ status: status,
|
|
|
+ data: e.city ? e.city : e.province
|
|
|
+ })
|
|
|
+ })
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ // 关键词
|
|
|
+ getKeyWords(query, callback) {
|
|
|
+ let pois = []
|
|
|
+ setTimeout(function () {
|
|
|
+ axios({
|
|
|
+ url: `https://restapi.amap.com/v5/place/text?parameters`,
|
|
|
+ method: 'get',
|
|
|
+ params: {
|
|
|
+ key: '4f11c381b38ea489461aac7451d353ca',
|
|
|
+ keywords: query
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ if (res.data.status === '1') {
|
|
|
+ res.data.pois.map(i => {
|
|
|
+ pois.push({
|
|
|
+ ...i,
|
|
|
+ value: `${i.name}(${i.cityname}${i.adname})`
|
|
|
+ })
|
|
|
+ })
|
|
|
+ callback(pois)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }, 500)
|
|
|
+ },
|
|
|
+
|
|
|
+ // 获取POI
|
|
|
+ getPOI() {
|
|
|
+ axios({
|
|
|
+ url: `https://restapi.amap.com/v5/place/around?parameters`,
|
|
|
+ method: 'get',
|
|
|
+ params: {
|
|
|
+ key: '4f11c381b38ea489461aac7451d353ca',
|
|
|
+ location: this.location
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ if (res.data.status === "1") {
|
|
|
+ this.poiList = res.data.pois
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ // 选中搜索结果
|
|
|
+ handleSelect(item) {
|
|
|
+ let lng = Number(item.location.split(',')[0])
|
|
|
+ let lat = Number(item.location.split(',')[1])
|
|
|
+ this.location = item.location
|
|
|
+ let marker = new AMap.Marker({
|
|
|
+ position: [lng, lat]
|
|
|
+ })
|
|
|
+ this.map.add(marker)
|
|
|
+ this.map.setCenter([lng, lat])
|
|
|
+ this.getPOI()
|
|
|
+ },
|
|
|
+
|
|
|
+ // 选中poi
|
|
|
+ handleCheck(item) {
|
|
|
+ this.activeItem = item
|
|
|
+ },
|
|
|
+
|
|
|
+ getEmit() {
|
|
|
+ this.$emit('data', this.activeItem)
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss">
|
|
|
+.map-popper {
|
|
|
+ width: 500px !important;
|
|
|
+}
|
|
|
+</style>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.map {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+
|
|
|
+ .el-form {
|
|
|
+ padding: 0 15px;
|
|
|
+
|
|
|
+ .el-form-item {
|
|
|
+ margin: 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .main {
|
|
|
+ display: flex;
|
|
|
+ border: 1px solid #e8e8e8;
|
|
|
+
|
|
|
+ #container {
|
|
|
+ padding: 0px;
|
|
|
+ margin: 0px;
|
|
|
+ width: 480px;
|
|
|
+ height: 400px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .poi {
|
|
|
+ overflow-y: auto;
|
|
|
+ width: 320px;
|
|
|
+ height: 400px;
|
|
|
+
|
|
|
+ .list {
|
|
|
+ padding: 8px 20px;
|
|
|
+ border-bottom: 1px solid #e8e8e8;
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ .name {
|
|
|
+ font-size: 14px;
|
|
|
+ color: #000;
|
|
|
+ }
|
|
|
+
|
|
|
+ .name,
|
|
|
+ .address {
|
|
|
+ line-height: 20px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .address {
|
|
|
+ font-size: 12px;
|
|
|
+ color: #666;
|
|
|
+ margin-top: 2px;
|
|
|
+ }
|
|
|
+
|
|
|
+ i {
|
|
|
+ position: absolute;
|
|
|
+ right: 5px;
|
|
|
+ top: 50%;
|
|
|
+ transform: translate(0, -50%);
|
|
|
+ color: #409EFF;
|
|
|
+ border: 1px solid #409EFF;
|
|
|
+ border-radius: 50%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+::-webkit-scrollbar {
|
|
|
+ width: 8px;
|
|
|
+ background: none;
|
|
|
+}
|
|
|
+
|
|
|
+::-webkit-scrollbar-thumb {
|
|
|
+ background-color: #cfcfcf;
|
|
|
+ border-radius: 50px;
|
|
|
+}
|
|
|
+</style>
|