提交 91f9d1e0 编写于 作者: Shine-zwj's avatar Shine-zwj

add:新增地图定位控件

上级 fb8415ee
......@@ -145,6 +145,10 @@ export const AppComponents = {
v.component('app-mob-actionsheet',() => import('@/components/app-mob-actionsheet/app-mob-actionsheet.vue'));
// 地图定位
v.component('app-mob-map',() => import('@/components/app-mob-map/app-mob-map.vue'));
// 地图定位控件
v.component('app-mob-map-position',() => import('@/components/app-mob-map-position/app-mob-map-position.vue'));
// 地图
v.component('app-mob-map-page',() => import('@/components/app-mob-map-page/app-mob-map-page.vue'));
// 树已选择列表
v.component('app-select-tree-list',() => import('@/components/app-select-tree-list/app-select-tree-list.vue'));
// 上下文菜单
......
.app-mob-map-page {
.app-map {
width: 100vw;
height: 100vh !important;
}
}
<template>
<ion-page class="app-mob-map-page">
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-button @click="onCancel">取消</ion-button>
</ion-buttons>
<ion-title>地图</ion-title>
<ion-buttons slot="end">
<ion-button @click="onOK">确认</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-header>
<ion-searchbar :value="address" @ionChange="search($event)"></ion-searchbar>
<div id="map__result" class="content-result"></div>
</ion-header>
<ion-content>
<el-amap
zoom="12"
vid="amap"
ref="map"
class="app-map"
:plugin="plugin"
:center="center"
:events="events"
:amap-manager="amapManager">
<el-amap-marker
class="map-marker"
vid="component-marker"
:icon="marker.icon"
:position="marker.position">
</el-amap-marker>
</el-amap>
</ion-content>
</ion-content>
</ion-page>
</template>
<script lang="ts">
import { AMapManager } from 'vue-amap';
import { Vue, Component, Prop, Watch } from "vue-property-decorator";
@Component({
components: {
},
})
export default class AppMobMapPage extends Vue {
/**
* 视图上下文参数
*
* @type {*}
* @memberof AppMobMapPage
*/
@Prop() context: any;
/**
* 视图参数
*
* @type {*}
* @memberof AppMobMapPage
*/
@Prop() viewparams: any;
/**
* 关闭
*
* @type {*}
* @memberof AppMobMapPage
*/
@Prop() close: any;
/**
* 地址
*
* @type {*}
* @memberof AppMobMapPage
*/
public address: string = '';
/**
* AMap SDK对象
*
* @type {*}
* @memberof AppMobMapPage
*/
public amapManager: any = new AMapManager();
/**
* 地图中心点
*
* @type {*}
* @memberof AppMobMapPage
*/
public center: any[] = [104.09427199999999, 30.660396];
/**
* 地图标点信息
*
* @type {*}
* @memberof AppMobMapPage
*/
public marker: any = {
position: [104.09427199999999, 30.660396],
address: '成都',
icon: '//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png',
visible: false
};
/**
* 事件集合
*
* @type {*}
* @memberof AppMobMapPage
*/
public events: any = {};
/**
* 获取地址需求AMap插件对象
*
* @type {*}
* @memberof AppMobMapPage
*/
public geocoder: any;
/**
* 当前 window
*
* @type {*}
* @memberof AppMobMapPage
*/
public win: any;
/**
* 地图配置
*
* @type {*}
* @memberof AppMobMapPage
*/
public plugin = [{
maximumAge: 0, //定位结果缓存0毫秒,默认:0
buttonPosition: 'RB', //定位按钮停靠位置,默认:'LB',左下角
showButton: false, //显示定位按钮,默认:true
showMarker: false, //定位成功后在定位到的位置显示点标记,默认:true
showCircle: false, //定位成功后用圆圈表示定位精度范围,默认:true
panToLocation: false, //定位成功后将定位到的位置作为地图中心点,默认:true
zoomToAccuracy: true, //定位成功后调整地图视野范围使定位位置及精度范围视野内可见
extensions: 'all',
pName: 'Geolocation',
events: {
init: (o: any) => {
// o 是高德地图定位插件实例
this.initCurAddress(o);
}
}
}]
/**
* 初始化当前位置
*
* @type {*}
* @memberof AppMobMapPage
*/
initCurAddress(o: any) {
if (!this.marker.visible) {
o.getCurrentPosition((status: any, result: any) => {
if (result && result.position) {
this.center = [result.position.lng, result.position.lat];
this.address = result.formattedAddress;
Object.assign(this.marker, { position: this.center, address: this.address, visible: true });
}
});
}
}
/**
* 生命周期
*
* @type {*}
* @memberof AppMobMapPage
*/
public created() {
this.win = window as any;
let amap: any = this.win.AMap;
amap.plugin(["AMap.Geocoder"], () => {
this.geocoder = new amap.Geocoder({
extensions: "all",
})
});
if(this.viewparams) {
this.initAddress();
}
this.initMapEvents();
}
/**
* 初始化地图事件
*
* @memberof AppMapPosition
*/
public initMapEvents() {
const that: any = this;
that.events = {
click($event: any) {
that.mapClick($event);
},
};
}
/**
* 初始化地址
*
* @memberof AppMapPosition
*/
public async initAddress() {
const viewparams = this.viewparams;
this.address = viewparams.address;
const longitude = viewparams.longitude;
const latitude = viewparams.latitude;
if(longitude && latitude) {
const position = [longitude, latitude];
Object.assign(this.marker, {
position: position,
address: this.address,
visible: true
});
this.center = position;
if (this.marker.address) {
this.address = this.marker.address;
} else {
const address = await this.getAddress(longitude, latitude).catch((error) => {
console.warn(error);
});
if(address) {
this.address = address as string;
}
}
}
}
/**
* 搜索
*
* @type {*}
* @memberof AppMobMapPage
*/
public search($event: any) {
const searchValue = $event.detail?.value;
if (!Object.is(searchValue, this.address)) {
this.address = searchValue;
this.handleSearch();
}
}
/**
* 搜索地址
*
* @memberof AppMapPosition
*/
public handleSearch() {
this.center = [];
const that = this;
let placeSearch: any;
// 调用服务搜索结果
that.win.AMap.service(["AMap.PlaceSearch"], () => {
placeSearch = new this.win.AMap.PlaceSearch({
pageSize: 5,
city: '成都',
citylimit: false,
panel: 'map__result',
})
placeSearch.search(that.address, (status: any, result: any) => {
if (status == 'complete' && result.info == 'OK') {
if(result.poiList.pois) {
that.handleMarker(result.poiList.pois[0].location.R, result.poiList.pois[0].location.Q, that, false);
}
}
})
})
// 监听搜索结果列表点击事件
that.win.AMap.event.addListener(placeSearch,"listElementClick", (e: any) => {
if(e.data.location) {
that.handleMarker(e.data.location.R, e.data.location.Q, that, false);
}
})
}
/**
* 地图点击事件
*
* @memberof AppMapPosition
*/
public mapClick($event: any) {
if(!$event && !$event.lnglat) {
return;
}
const that = this;
that.handleMarker($event.lnglat.lng, $event.lnglat.lat, that, false);
}
/**
* 处理地图标点
*
* @param {*} lng 经度
* @param {*} lat 纬度
* @param {*} that this指针
* @param {boolean} flag 是否更新结果集
* @memberof AppMapPosition
*/
public async handleMarker(lng: any, lat: any, that: any, flag: boolean = true) {
if (!lng && !lat) {
return
}
const address = await this.getAddress(lng, lat).catch((error) => {
console.warn(error);
});
if(!address) {
return;
}
Object.assign(that.marker, { position: [lng, lat], address: address, visible: true });
that.address = address;
that.center = [lng, lat];
}
/**
* 调用服务,根据经纬度获取地址信息
*
* @param {*} lng 经度
* @param {*} lat 纬度
* @memberof AppMapPosition
*/
public getAddress(lng: any, lat: any) {
return new Promise((resolve, reject) => {
this.geocoder.getAddress([lng,lat],(status: any, result: any) => {
let address = null;
if (status === 'complete' && result.info === 'OK') {
if (result && result.regeocode) {
address = result.regeocode.formattedAddress;
}
}
resolve(address);
})
})
}
/**
* 确认
*
* @type {*}
* @memberof AppMobMapPage
*/
public onOK() {
const data ={
address: this.address,
longitude: this.marker.position[0],
latitude: this.marker.position[1],
}
if (this.close && this.close instanceof Function) {
this.close(data);
}
}
/**
* 取消
*
* @type {*}
* @memberof AppMobMapPage
*/
public onCancel() {
if (this.close && this.close instanceof Function) {
this.close();
}
}
}
</script>
<style lang="less">
@import "./app-mob-map-page.less";
</style>
\ No newline at end of file
<template>
<div class="app-mob-map-position">
<ion-icon name="location" @click="openMap"></ion-icon>
</div>
</template>
<script lang="ts">
import { Util } from "@/ibiz-core/utils";
import i18n from "@/locale";
import store from "@/store";
import { Vue, Component, Prop } from "vue-property-decorator";
@Component({
components: {
},
})
export default class AppMobMapPosition extends Vue {
/**
* 视图上下文参数
*
* @type {*}
* @memberof AppMobMapPosition
*/
@Prop() context: any;
/**
* 视图参数
*
* @type {*}
* @memberof AppMobMapPosition
*/
@Prop() viewparams: any;
/**
* 视图参数
*
* @type {*}
* @memberof AppMobMapPosition
*/
@Prop() data?: any;
/**
* 地址
*
* @type {*}
* @memberof AppMobMapPosition
*/
@Prop() address?: any;
/**
* 经度
*
* @type {*}
* @memberof AppMobMapPosition
*/
@Prop() latitude?: any;
/**
* 纬度
*
* @type {*}
* @memberof AppMobMapPosition
*/
@Prop() longitude?: any;
/**
* 地图
*
* @type {*}
* @memberof AppMobMapPosition
*/
public map: any;
/**
* 打开地图
*
* @type {*}
* @memberof AppMobMapPosition
*/
public openMap() {
const props = {
context: Util.deepCopy(this.context),
viewparams: {
address: this.data ? this.data[this.address] : null,
longitude: this.data ? this.data[this.longitude] : null,
latitude: this.data ? this.data[this.latitude] : null,
},
close: (data?: any) => {
this.closeMap(data);
}
}
let map: any = new Vue({
store: store,
i18n: i18n,
render(h) {
return h('app-mob-map-page',{
props
});
},
}).$mount();
this.map = map;
document.getElementById('app')?.appendChild(map.$el);
}
/**
* 打开地图
*
* @type {*}
* @memberof AppMobMapPosition
*/
public closeMap(data: any) {
document.getElementById('app')?.removeChild(this.map.$el);
if (data) {
if (this.address) {
this.$emit('change', {name: this.address, value: data.address});
}
if (this.latitude) {
this.$emit('change', {name: this.latitude, value: data.latitude});
}
if (this.longitude) {
this.$emit('change', {name: this.longitude, value: data.longitude});
}
}
}
}
</script>
<style lang="less">
@import "./app-mob-map-position.less";
</style>
\ No newline at end of file
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册