1.在官网进行注册 https://lbs.amap.com/
2.在main.js
中引入配置,按需引入插件
import VueAMap from 'vue-amap';
Vue.use(VueAMap)
VueAMap.initAMapApiLoader({
// 高德的key
key: 'af3036364576bf0fb5572996ef9f4850',
// 插件集合
plugin:[
'AMap.Autocomplete',
'AMap.PlaceSearch'
],
// 高德 sdk 版本,默认为 1.4.4
v: '1.4.4',
uiVersion: '1.0.11' // 版本号
});
3.安装 :npm install vue-amap --save
使用示例
代码中的接口文件没放上去
// workbench.vue
<template>
<div class="amap-page-container">
<el-amap
:vid="'amap-vue'"
:zoom="zoom"
:events="mapEvents"
:center="[center.lng, center.lat]"
>
<div class="button-style">
<el-button type="success">月安装数:{{ monthInstall }}</el-button>
<el-button type="success">年安装数:{{ yearInstall }}</el-button>
<el-button type="danger">月拆装数:{{ monthUninstall }}</el-button>
<el-button type="danger">年拆装数:{{ yearUninstall }}</el-button>
</div>
<el-amap-marker
v-for="marker in markers"
:position="marker.position"
:key="marker.id"
:events="marker.events"
:icon="marker.icon"
>
</el-amap-marker>
</el-amap>
<infoWindowComponent ref="infoWindowComponent"></infoWindowComponent>
<detailInfo ref="detailInfo"></detailInfo>
</div>
</template>
<script>
const workbenchApi = require("../api/workbench");
import infoWindowComponent from "../components/infoWindow.vue";
import detailInfo from "../components/detailInfo.vue";
export default {
components: {
infoWindowComponent,
detailInfo,
},
data() {
let self = this;
return {
showInfoWindow: false,
infoMsg: {},
search: "",
zoom: 6,
mapEvents: {
init(map) {
self.map = map;
self.setMap();
},
},
map: "",
center: {
lng: 107.989207,
lat: 34.996855,
},
markers: [],
windows: [],
window: "",
dataSource: [],
monthInstall: "", //月安装数
monthUninstall: "", //月拆装数
yearInstall: "", //年安装数
yearUninstall: "", //年拆装数
};
},
activated() {
this.loadData();
},
methods: {
loadData() {
workbenchApi.detail().then((data) => {
this.dataSource = data.craneInfos;
this.monthInstall = data.monthInstall;
this.monthUninstall = data.monthUninstall;
this.yearInstall = data.yearInstall;
this.yearUninstall = data.yearUninstall;
this.setMarkers();
});
},
setMarkers() {
let markers = [];
let that = this;
this.dataSource.forEach((item, index) => {
//未进场: 使用中:绿色 维修中: 已拆除:灰色 拆装报停: 临时报停:
//图标
item.icon = new AMap.Icon({
size: new AMap.Size(40, 40),
image: getImage(),
imageSize: new AMap.Size(40, 40),
anchor: "center",
});
function getImage() {
if (item.status=="未进场") {
return require("../icons/blue.png")
}
else if (item.status=="使用中") {
return require("../icons/green.png")
}
else if (item.status=="维修中") {
return require("../icons/red.png")
}
else if (item.status=="已拆除") {
return require("../icons/grey.png")
}
else if (item.status=="拆装报停") {
return require("../icons/yellow.png")
}
else if (item.status=="临时报停") {
return require("../icons/yellow.png")
}
else{
return require("../icons/abnormal.png")
}
}
markers.push({
position: [item.longitude, item.latitude],
icon: item.icon,
events: {
click() {
that.$nextTick(() => {
that.setInfoWindows(item);
that.center = {
lat: item.latitude,
lng: item.longitude,
};
});
},
mouseover(){
that.$nextTick(() => {
that.getDetailWindow(item);
});
},
mouseout(){
that.$nextTick(() => {
that.$refs.detailInfo.close();
});
},
},
});
});
//加窗体
this.markers = markers;
},
setMap() {
//行政区域划分
let self = this;
AMapUI.load(
["ui/geo/DistrictCluster", "lib/$"],
function (DistrictCluster, $) {
//启动页面
initPage(DistrictCluster, $);
}
);
function initPage(DistrictCluster, $) {
var distCluster = new DistrictCluster({
map: self.map, //所属的地图实例
zIndex: 11,
getPosition: function (item) {
if (!item) {
return null;
}
//返回经纬度
return item.position;
},
renderOptions: {
//基础样式
featureStyle: {
fillStyle: "rgba(102,170,0,0.5)", //填充色
lineWidth: 2, //描边线宽
strokeStyle: "rgb(31, 119, 180)", //描边色
//鼠标Hover后的样式
hoverOptions: {
fillStyle: "rgba(255,255,255,0.2)",
},
},
//特定区划级别的默认样式
featureStyleByLevel: {
//全国
country: {
fillStyle: "rgba(49, 163, 84, 0.8)",
},
//省
province: {
fillStyle: "rgba(116, 196, 118, 0.7)",
},
//市
city: {
fillStyle: "rgba(161, 217, 155, 0.6)",
},
//区县
district: {
fillStyle: "rgba(199, 233, 192, 0.5)",
},
},
//直接定义某写区划面的样式
getFeatureStyle: function (feature, dataItems) {
if (dataItems.length > 10) {
return {
fillStyle: "rgba(116, 196, 118, 0.7)",
};
} else if (dataItems.length > 0) {
return {
fillStyle: "rgba(161, 217, 155, 0.6)",
};
} else if (dataItems.length == 0) {
return {
fillStyle: "rgba(0,0,0,0.0)",
};
}
return {};
},
},
});
distCluster.setData(self.markers);
}
},
getDetailWindow(e){
let self = this;
self.showInfoWindow = true;
self.infoMsg = e;
var infoWindow = new AMap.InfoWindow({
isCustom: true, //使用自定义窗体
content: self.$refs.detailInfo.$el,
offset: new AMap.Pixel(16, -50),
});
infoWindow.open(self.map, [e.longitude, e.latitude]);
self.$refs.detailInfo.initialize({
infoWindow: infoWindow,
infoMsg: e,
});
},
setInfoWindows(e) {
let self = this;
self.showInfoWindow = true;
self.infoMsg = e;
var infoWindow = new AMap.InfoWindow({
isCustom: true, //使用自定义窗体
content: self.$refs.infoWindowComponent.$el,
offset: new AMap.Pixel(16, -50),
});
infoWindow.open(self.map, [e.longitude, e.latitude]);
self.$refs.infoWindowComponent.initialize({
infoWindow: infoWindow,
infoMsg: e,
});
},
},
};
</script>
<style lang="scss" scoped="">
.amap-page-container {
width: 100%;
height: 100%;
}
.button-style {
position: absolute;
top: 65px;
left: 20px;
}
.search-input {
position: absolute;
top: 65px;
}
/deep/.amap-logo {
display: none;
opacity: 0;
}
/deep/.amap-copyright {
opacity: 0;
}
</style>
// 信息弹窗文件infoWindow.vue
<template>
<div>
<el-card
class="box-card"
style="width: 200px; border-radius: 10px"
>
<div class="del-div">
<el-link type="primary" icon="el-icon-close" @click="close()"></el-link>
</div>
<div v-if="!showDetail">
<div class="button-style">
<el-button size="small" type="primary" @click="showDetail = true"
>信息明细</el-button
>
</div>
<div class="button-style">
<el-button size="small" type="primary"
><router-link
:to="{
name: 'MaintenanceIndex',
params: {
search: infoMsg.sn,
},
}"
>维保记录</router-link
></el-button
>
</div>
<div class="button-style">
<el-button size="small" type="primary"><router-link
:to="{
name: 'RepairReport',
params: {
search: infoMsg.sn,
},
}"
>维修记录</router-link
></el-button>
</div>
<!-- <div class="button-style">
<el-button size="small" type="primary">预警信息</el-button>
</div>
<div class="button-style">
<el-button size="small" type="primary">视频监控</el-button>
</div> -->
</div>
<div v-else>
<div class="text item">
<span>项目名称:{{ infoMsg.name }}</span>
</div>
<div class="text item">
<span>项目负责人:{{ infoMsg.principalName }}</span>
</div>
<div class="text item">
<span>机长:{{ captainName }}</span>
</div>
<div class="text item">
<span>塔机型号:{{ infoMsg.model }}</span>
</div>
<div class="text item">
<span>塔机编号:{{ infoMsg.sn }}</span>
</div>
<div class="text item">
<span>动力源:{{ infoMsg.powerSource }}</span>
</div>
<div class="text item">
<span>使用方式:{{ infoMsg.type }}</span>
</div>
<div class="text item">
<span>状态:{{ infoMsg.status }}</span>
</div>
</div>
</el-card>
</div>
</template>
<script>
export default {
data() {
return {
infoWindow: "",
infoMsg: "",
showDetail: false,
captainName:"",
};
},
methods: {
initialize(e) {
console.log(e);
this.infoWindow = e.infoWindow;
this.infoMsg = e.infoMsg;
const members = this.infoMsg.workers
if (members.length>0) {
let captain = members.find(obj => obj.type==0)
this.captainName = captain.username
}
},
close() {
// 高德地图信息窗关闭的api
this.infoWindow.close();
this.showDetail = false;
},
},
};
</script>
<style lang="css" scoped>
.del-div {
position: absolute;
transform: scale(1.2);
margin-left: 153px;
margin-top: -15px;
}
.button-style {
text-align: center;
margin-bottom: 5px;
margin-top: 5px;
}
.text {
font-size: 14px;
}
.item {
margin-bottom: 5px;
margin-top: 5px;
}
</style>
// 查看定位和修改定位功能
// 父组件调用该文件的openPosition,并传入三个参数:
// 1.obj:定位的坐标和其他参数。2.bol:标识判断是编辑还是修改。3.title:弹窗标题
// 代码中数据参数由父组件调用该文件的openPosition。
<template>
<div>
<el-dialog
:title="title"
:visible.sync="mapDialog"
width="1000px"
v-dialogDrag
>
<div class="amap-page-container">
<div v-if="isCheck">
<el-amap-search-box
class="search-box"
:search-option="searchOption"
:on-search-result="onSearchResult"
></el-amap-search-box>
</div>
<el-amap
:vid="'amap-vue'"
:zoom="zoom"
:center="[marker.lng, marker.lat]"
:events="events"
>
<el-amap-marker
:position="[marker.lng, marker.lat]"
></el-amap-marker>
</el-amap>
</div>
<div v-if="isCheck">
<el-form ref="editForm" :model="editForm" label-width="100px">
<el-form-item
label="塔机地址"
prop="address"
:rules="[
{
required: true,
message: '请输入塔机地址',
trigger: 'bulr',
},
]"
>
<el-input type="text" v-model="editForm.address"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="mapDialog = false">取消</el-button>
<el-button type="primary" @click="confirmPosition('editForm')"
>确定</el-button
>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
const craneApi = require("../api/craneManage");
export default {
data() {
let self = this
return {
mapDialog: false,
marker: {
lng: "",
lat: "",
},
zoom: 15,
searchOption: {
citylimit: false,
},
events: {
click: (e) => {
if (self.isCheck) {
self.marker.lng = e.lnglat.lng;
self.marker.lat = e.lnglat.lat;
let lnglat = [self.marker.lng,self.marker.lat]
self.getaddress(lnglat)
}
},
},
editForm: {
id: "",
longitude: "",
latitude: "",
address: "",
},
isCheck: true,
title: "",
formattedAddress:"",
};
},
methods: {
//逆地理编码,在地图中点击点图获取该点的详细结构化的地址。
//例如:116.480881,39.989410 转换地址描述后:北京市朝阳区阜通东大街6号
getaddress: function (lnglat) {
let self = this;
AMap.plugin("AMap.Geocoder", function () {
var geocoder = new AMap.Geocoder({
// city 指定进行编码查询的城市,支持传入城市名、adcode 和 citycode
city: "010",
});
geocoder.getAddress(lnglat, function (status, result) {
if (status === "complete" && result.info === "OK") {
self.editForm.address = result.regeocode.formattedAddress;
// result为对应的地理位置详细信息
}
});
});
},
openPosition(obj, bol, title) {
this.isCheck = bol;
this.title = title;
if (obj.latitude != "" && obj.longitude != "") {
this.marker.lat = obj.latitude;
this.marker.lng = obj.longitude;
} else {
this.marker.lat = 39.909104;
this.marker.lng = 116.397453;
}
this.mapDialog = true;
},
editPosition(obj, bol, title) {
this.isCheck = bol;
this.title = title;
if (obj.latitude != "" && obj.longitude != "") {
this.marker.lat = obj.latitude;
this.marker.lng = obj.longitude;
} else {
this.marker.lat = 39.909104;
this.marker.lng = 116.397453;
}
this.mapDialog = true;
this.editForm.id = obj.eid;
this.editForm.address = ""
},
onSearchResult(pois) {
this.marker.lng = pois[0].lng;
this.marker.lat = pois[0].lat;
},
confirmPosition(editForm) {
this.editForm.longitude = this.marker.lng;
this.editForm.latitude = this.marker.lat;
this.$refs[editForm].validate((v) => {
if (v) {
craneApi
.position(this.editForm)
.then(() => {
this.$refs[editForm].resetFields();
this.mapDialog = false;
this.$parent.loadData();
this.$message({
showClose: true,
message: "编辑成功",
type: "success",
});
})
.catch(() => {});
}
});
},
},
};
</script>
<style lang="scss" scoped="">
// .el-form-item {
// margin-bottom: -20px;
// margin-top: 20px;
// }
.amap-page-container {
width: 100%;
height: 600px;
}
.search-box {
position: absolute;
top: 65px;
left: 20px;
}
/deep/.amap-logo {
display: none;
opacity: 0;
}
/deep/.amap-copyright {
opacity: 0;
}
</style>