- 安装插件
//高德地图插件
npm install vue-amap --save
//高德vue组件库
npm install @vuemap/vue-amap --save
2.官网
申请高德地图账号和key。高德官网入门指南
@vuemap/vue-amap是基于高德JSAPI2.0、Loca2.0封装的vue组件库。组件库网址
- main.js中引入
import VueAMap from 'vue-amap';
Vue.use(VueAMap);
// 初始化vue-amap
VueAMap.initAMapApiLoader({
// 高德的key
key: '',
// 插件集合 (插件按需引入)
plugin: ['AMap.Autocomplete', 'AMap.PlaceSearch', 'AMap.Scale', 'AMap.OverView', 'AMap.ToolBar', 'AMap.MapType',
'AMap.PolyEditor', 'AMap.Circle', 'AMap.CircleEditor', 'AMap.DistrictSearch','AMap.CircleMarker','AMap.Polyline','AMap.RangingTool'
,'AMap.CitySearch','AMap.MoveAnimation','AMap.RectangleEditor','AMap.Rectangle','AMap.LngLat','AMap.Bounds','AMap.Map',
'AMap.Polygon'
// 'AMap.Object3DLayer', 'AMap.Object3D'
],
viewMode:'3D',//开启3D视图,默认为关闭
});
//高德的安全密钥
window._AMapSecurityConfig = {
securityJsCode: '',
}
- 地图选点
<template>
<div>
<div style="height: 500px;">
<el-amap
ref="map"
vid="amapDemo"
:amap-manager="amapManager"
:center="center"
:zoom="zoom"
viewMode="3D"
:plugin="plugin"
:events="events"
class="amap-demo"
>
<el-amap-marker :position="marker.position">
<div
style="color: #eee;width: 20px;height: 20px;text-align: center;position: relative">
<i class="iconfont icon-xiaoshuidifuzhi"
style="color:#009cf9;font-size: 30px;"
></i>
</div>
</el-amap-marker>
</el-amap>
</div>
<div>
坐标:{{ address }}
</div>
</div>
</template>
<script>
import { AMapManager } from "vue-amap";
let amapManager = new AMapManager();
export default {
components: {},
props: {},
data: function (){
const self = this;
return {
amapManager,
plugin: [
{
pName: 'MapType',
defaultType: 1,//初始化默认图层类型。 取值为0:默认底图 取值为1:卫星图 默认值:0
showTraffic:false,//叠加实时交通图层 默认值:false
showRoad:false,//叠加路网图层 默认值:false
events: {
init(o) {
// 初始化后隐藏地图切换控件
o.hide();
}
},
},{
pName: 'OverView',//地图鹰眼插件
isOpen:false,//鹰眼是否展开,默认为false
visible:false,//鹰眼是否显示,默认为true
events: {
init(o) {
console.log(o);
}
}
},
{
//地图定位按钮
pName: "Geolocation",
enableHighAccuracy: true, //是否使用高精度定位,默认:true
timeout: 100, //超过10秒后停止定位,默认:无穷大
maximumAge: 0, //定位结果缓存0毫秒,默认:0
convert: true, //自动偏移坐标,偏移后的坐标为高德坐标,默认:true
showButton: true, //显示定位按钮,默认:true
buttonPosition: "LB", //定位按钮停靠位置,默认:'LB',左下角
showMarker: true, //定位成功后在定位到的位置显示点标记,默认:true
showCircle: true, //定位成功后用圆圈表示定位精度范围,默认:true
panToLocation: false, //定位成功后将定位到的位置作为地图中心点,默认:true
zoomToAccuracy: true, //定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:f
extensions: "all",
init(o) {
// o 是高德地图定位插件实例
o.getCurrentPosition((status, result) => {
console.log(result);
if (result && result.position) {
self.lng = result.position.lng;
self.lat = result.position.lat;
self.center = [self.lng, self.lat];
self.loaded = true;
self.$nextTick();
}
});
},
},
{
//地图工具条
pName: "ToolBar",
init(o) {},
},
{
//左下角缩略图插件 比例尺
pName: "Scale",
position:'LT',//控件停靠位置 LT:左上角; RT:右上角; LB:左下角; RB:右下角; 默认位置:LT
ruler:true,//标尺键盘是否可见,默认为true
noIpLocate:false,//定位失败后,是否开启IP定位,默认为false
locate:false,//是否显示定位按钮,默认为false
liteStyle:false,//是否使用精简模式,默认为false
direction:true,//方向键盘是否可见,默认为true
autoPosition:false,//是否自动定位,即地图初始化加载完成后,是否自动定位的用户所在地,仅在支持HTML5的浏览器中有效,默认为false
useNative:false,//是否使用高德定位sdk用来辅助优化定位效果,默认:fa
init(o) {},
},
],
address:null,
center: [121.59996, 31.197646],
zoom: 12,
events: {
init: (o) => {
o.setDefaultCursor("crosshair");
},
moveend: () => {},
zoomchange: () => {},
click: (e) => {
self.address = e.lnglat.lng + "," + e.lnglat.lat
// 将设定的航点展示在地图上
self.marker = {
position: [e.lnglat.lng, e.lnglat.lat],
}
},
},
marker: {
position: [121.5273285, 31.21515044],
},
};
},
watch: {},
computed: {},
created() {},
mounted() {},
methods: {},
};
</script>
<style lang="scss" scoped>
</style>
5. 电子围栏
<template>
<div>
<div style="height: 500px;">
<el-amap
ref="map"
vid="amapDemo"
:amap-manager="amapManager"
:center="center"
:zoom="zoom"
viewMode="3D"
:plugin="plugin"
:events="events"
class="amap-demo"
>
<el-amap-circle
v-if="circles.visible"
:center="circles.circleCenter"
:radius="circles.radius"
:editable="circles.edit"
:draggable="circles.draggable"
:fillColor="circles.fillColor"
:strokeColor="circles.strokeColor"
></el-amap-circle>
<el-amap-rectangle
v-if="rectangles.visible"
:bounds="rectangles.path"
:editable="rectangles.edit"
:draggable="rectangles.draggable"
:fillColor="rectangles.fillColor"
:strokeColor="rectangles.strokeColor"
></el-amap-rectangle>
<el-amap-polygon
v-if="polygons.visible"
:path="polygons.path"
:editable="polygons.edit"
:draggable="polygons.draggable"
:fillColor="polygons.fillColor"
:strokeColor="polygons.strokeColor"
/>
</el-amap>
</div>
<div>
<el-button @click="draw('circle')">绘制圆形</el-button>
<el-button @click="draw('rectangle')">绘制矩形</el-button>
<el-button @click="draw('polygon')">绘制多边形</el-button>
</div>
</div>
</template>
<script>
import { AMapManager } from "vue-amap";
let amapManager = new AMapManager();
export default {
components: {},
props: {},
data: function (){
const self = this;
return {
amapManager,
type:null,
plugin: [
"ToolBar",
{
pName: "MapType",
defaultType: 0,
events: {
init(o) {},
},
},
],
center: [121.59996, 31.197646],
zoom: 12,
clicksNum:0,//点击次数
circles:{
center: [121.5273285, 31.21515044],
draggable: false,
visible: true,
edit: false,
circleCenter: [0, 0],
radius: 0,
strokeColor:'#F56C6C',
fillColor:'#F56C6C'
},
rectangles:{
firstPoint:[],
visible: true,
path:[[0, 0], [0, 0]],
edit: false,
draggable: false,
fillColor:'#F56C6C',
strokeColor:'#F56C6C',
},
polygons:{
visible: true,
path:[],
edit: false,
draggable: false,
fillColor:'#F56C6C',
strokeColor:'#F56C6C',
},
events: {
init: (o) => {
o.setDefaultCursor("crosshair");
},
moveend: () => {},
zoomchange: () => {},
click: (e) => {
if(self.type == 'circle'){
self.clicksNum = self.clicksNum + 1//点击次数
if(self.clicksNum%2===0){
self.circles = {
...self.circles,
radius: self.getDistanceBmarker(self.circles.circleCenter,[e.lnglat.lng, e.lnglat.lat]),
}
}else{
self.circles.radius = 0
self.circles.circleCenter = [e.lnglat.lng, e.lnglat.lat]
}
}else if(self.type == 'rectangle'){
self.clicksNum = self.clicksNum + 1//点击次数
if(self.clicksNum%2===0){
self.rectangles = {
...self.rectangles,
path: [self.firstPoint, [e.lnglat.lng, e.lnglat.lat]]
}
}else{
self.firstPoint = [e.lnglat.lng, e.lnglat.lat]
}
}else if(self.type == 'polygon'){
self.polygons.path.push(
[e.lnglat.lng, e.lnglat.lat]
)
}
},
},
};
},
watch: {},
computed: {},
created() {},
mounted() {},
methods: {
draw(type){
this.clicksNum = 0,//点击次数
this.type = type
},
//算出两个点坐标间的直线距离
getDistanceBmarker(m1, m2) {
// AMap.LngLat
let p1 = new window.AMap.LngLat(m1[0], m1[1]);
var distance = Math.round(p1.distance(m2));
return distance;
},
},
};
</script>
<style lang="scss" scoped>
</style>
- 3D地图(鼠标右键可拖拽调整方向)
<template>
<div>
<div style="height: 500px;">
<el-amap
ref="map"
vid="amapDemo"
:amap-manager="amapManager"
:center="center"
:zoom="zoom"
<!-- 3D -->
:pitchEnable="true"
:rotateEnable="true"
:pitch="50" 地图俯仰角度,有效范围 0 度- 83 度
viewMode="3D"
<!-- 3D -->
:plugin="plugin"
:events="events"
class="amap-demo"
>
<el-amap-marker :position="marker.position">
<div
style="color: #eee;width: 20px;height: 20px;text-align: center;position: relative">
<i class="iconfont icon-xiaoshuidifuzhi"
style="color:#009cf9;font-size: 30px;"
></i>
</div>
</el-amap-marker>
</el-amap>
</div>
<div>
坐标:{{ address }}
</div>
</div>
</template>
<script>
import { AMapManager } from "vue-amap";
let amapManager = new AMapManager();
export default {
components: {},
props: {},
data: function (){
const self = this;
return {
amapManager,
plugin: [
"ToolBar",
{
pName: "MapType",
defaultType: 0,
events: {
init(o) {},
},
},
],
address:null,
center: [121.59996, 31.197646],
zoom: 12,
events: {
init: (o) => {
o.setDefaultCursor("crosshair");
},
moveend: () => {},
zoomchange: () => {},
click: (e) => {
self.address = e.lnglat.lng + "," + e.lnglat.lat
// 将设定的航点展示在地图上
self.marker = {
position: [e.lnglat.lng, e.lnglat.lat],
}
},
},
marker: {
position: [121.5273285, 31.21515044],
},
};
},
watch: {},
computed: {},
created() {},
mounted() {},
methods: {},
};
</script>
<style lang="scss" scoped>
</style>
7. 折线(判断折现是否交叉)
<template>
<div>
<div style="height: 500px">
<el-amap
ref="map"
vid="amapDemo"
:amap-manager="amapManager"
:center="center"
:zoom="zoom"
viewMode="3D"
:plugin="plugin"
:events="events"
class="amap-demo"
>
<div v-for="(item, index) in tableData" :key="index">
<el-amap-marker :position="[item.lng, item.lat]">
<div
style="
color: #eee;
width: 20px;
height: 20px;
text-align: center;
position: relative;
"
>
<i
class="iconfont icon-xiaoshuidifuzhi"
style="color: #009cf9; font-size: 30px"
></i>
<span style="color: #fff; position: absolute; top: 10px; left: 10px">{{
index + 1
}}</span>
</div>
</el-amap-marker>
<el-amap-polyline
:editable="polyline.editable"
:visible="polyline.visible"
:draggable="polyline.draggable"
:path="polyline.path"
:strokeColor="polyline.strokeColor"
></el-amap-polyline>
</div>
<div v-for="(item, index) in tableData1" :key="index">
<el-amap-marker :position="[item.lng, item.lat]">
<div
style="
color: #eee;
width: 20px;
height: 20px;
text-align: center;
position: relative;
"
>
<i
class="iconfont icon-xiaoshuidifuzhi"
style="color: #3657ff; font-size: 30px"
></i>
<span style="color: #fff; position: absolute; top: 10px; left: 10px">{{
index + 1
}}</span>
</div>
</el-amap-marker>
<el-amap-polyline
:editable="polyline1.editable"
:visible="polyline1.visible"
:draggable="polyline1.draggable"
:path="polyline1.path"
:strokeColor="polyline1.strokeColor"
></el-amap-polyline>
</div>
</el-amap>
</div>
<el-button style="margin: 10px 0" type="primary" size="mini" @click="compare()"
>比较</el-button
>
<span style="color: red">{{ result }}</span>
<div style="display: flex">
<div>
<el-button type="primary" size="mini" @click="getlnglat('left')">取点</el-button>
<el-table :data="tableData" style="width: 500px">
<el-table-column type="index" label="序号" width="180"> </el-table-column>
<el-table-column prop="lng" label="经度" width="180"> </el-table-column>
<el-table-column prop="lat" label="纬度"> </el-table-column>
</el-table>
</div>
<div>
<el-button type="primary" size="mini" @click="getlnglat('right')">取点</el-button>
<el-table :data="tableData1" style="width: 500px; margin-left: 10px">
<el-table-column type="index" label="序号" width="180"> </el-table-column>
<el-table-column prop="lng" label="经度" width="180"> </el-table-column>
<el-table-column prop="lat" label="纬度"> </el-table-column>
</el-table>
</div>
</div>
</div>
</template>
<script>
import { AMapManager } from "vue-amap";
let amapManager = new AMapManager();
export default {
components: {},
props: {},
data: function () {
const self = this;
return {
amapManager,
plugin: [
"ToolBar",
{
pName: "MapType",
defaultType: 0,
events: {
init(o) {},
},
},
],
center: [121.59996, 31.197646],
zoom: 12,
events: {
init: (o) => {
o.setDefaultCursor("crosshair");
},
moveend: () => {},
zoomchange: () => {},
click: (e) => {
if (self.flag) {
self.tableData.push({
lng: e.lnglat.lng,
lat: e.lnglat.lat,
});
self.polyline.path.push([e.lnglat.lng, e.lnglat.lat]);
} else {
self.tableData1.push({
lng: e.lnglat.lng,
lat: e.lnglat.lat,
});
self.polyline1.path.push([e.lnglat.lng, e.lnglat.lat]);
}
},
},
polyline: {
path: [],
editable: false, //折线当前是否可编辑
visible: true, //是否可见
draggable: false, //是否可拖拽移动
strokeColor: "#009cf9",
},
polyline1: {
path: [],
editable: false, //折线当前是否可编辑
visible: true, //是否可见
draggable: false, //是否可拖拽移动
strokeColor: "#3657FF",
},
tableData: [],
tableData1: [],
flag: false,
result: "",
};
},
watch: {},
computed: {},
created() {},
mounted() {},
methods: {
getlnglat(type) {
if (type == "left") {
this.flag = true;
} else {
this.flag = false;
}
},
compare() {
if (this.isLineCross(this.tableData, this.tableData1)) {
return this.result = "航线交叉";
}
return this.result = "航线未交叉";
},
// 判断折现是否交叉
isLineCross(line1, line2) {
// 获取两条折线的所有点
const points1 = line1;
const points2 = line2;
// 遍历第一条折线的每个点
for (let i = 0; i < points1.length - 1; i++) {
// 判断每个点与第二条折线上的点的组合情况
for (let j = 0; j < points2.length - 1; j++) {
// 如果存在线段相交,则返回true
if (
this.isSegmentCross(points1[i], points1[i + 1], points2[j], points2[j + 1])
) {
return true;
}
}
}
return false;
},
isSegmentCross(p0, p1, p2, p3) {
const s1 = {
x: p1.lng - p0.lng,
y: p1.lat - p0.lat,
};
const s2 = {
x: p3.lng - p2.lng,
y: p3.lat - p2.lat,
};
const s =
(-s1.y * (p0.lng - p2.lng) + s1.x * (p0.lat - p2.lat)) /
(-s2.x * s1.y + s1.x * s2.y);
const t =
(s2.x * (p0.lat - p2.lat) - s2.y * (p0.lng - p2.lng)) /
(-s2.x * s1.y + s1.x * s2.y);
return s >= 0 && s <= 1 && t >= 0 && t <= 1;
},
},
};
</script>
<style lang="scss" scoped></style>
8. 两点测距、两点连线角度
<template>
<div>
<div style="height: 500px">
<el-amap
ref="map"
vid="amapDemo"
:amap-manager="amapManager"
:center="center"
:zoom="zoom"
viewMode="3D"
:plugin="plugin"
:events="events"
class="amap-demo"
>
<div v-for="(item, index) in rulerMakers" :key="index">
<el-amap-marker :position="item.lnglat">
<div
style="
color: #eee;
width: 20px;
height: 20px;
text-align: center;
position: relative;
"
>
<i
class="iconfont icon-xiaoshuidifuzhi"
style="color: #009cf9; font-size: 30px"
></i>
</div>
</el-amap-marker>
</div>
</el-amap>
</div>
<div style="background-color: #eee">
两点距离:{{ ruleFormInfo.distance }} 两点连线角度:{{ ruleFormInfo.angle }}
</div>
</div>
</template>
<script>
import { AMapManager } from "vue-amap";
let amapManager = new AMapManager();
export default {
components: {},
props: {},
data: function () {
const self = this;
return {
amapManager,
plugin: [
"ToolBar",
{
pName: "MapType",
defaultType: 0,
events: {
init(o) {},
},
},
],
address: null,
center: [121.59996, 31.197646],
zoom: 12,
events: {
init: (o) => {
o.setDefaultCursor("crosshair");
},
moveend: () => {},
zoomchange: () => {},
click: (e) => {
self.clickRuleMaker([e.lnglat.lng, e.lnglat.lat]);
},
},
rulerMakers: [],
ruleFormInfo: {
start: [],
ende: [],
distance: null,
angle: null,
},
};
},
watch: {
rulerMakers: {
handler(newValue) {
console.log(newValue);
if (newValue.length == 2) {
let start = this.rulerMakers[0].lnglat,
end = this.rulerMakers[1].lnglat;
this.ruleFormInfo.distance = this.getDistanceBmarker(start, end) + "m";
this.ruleFormInfo.angle = this.bearing(start, end) + "°";
}
},
},
},
computed: {},
created() {},
mounted() {},
methods: {
/**
* @method 点击地图出现点坐标
* @param
*/
clickRuleMaker(lnglat) {
if (this.rulerMakers.length < 2) {
this.rulerMakers.push({
type: 1,
lnglat: lnglat,
title: this.rulerMakers.length == 0 ? "" : "",
});
this.ruleFormInfo.start = this.rulerMakers[0].lnglat.join(",");
if (this.rulerMakers[1])
this.ruleFormInfo.end = this.rulerMakers[1].lnglat.join(",");
} else if (this.rulerMakers.length === 2) {
//如果点击地图时测距的点坐标已有两个就删除这两个重新开始测距
this.rulerMakers = [];
this.clickRuleMaker(lnglat);
}
},
/**
* @method 算出两个点坐标间的直线距离
* @param
*/
getDistanceBmarker(m1, m2) {
// AMap.LngLat
let p1 = new window.AMap.LngLat(m1[0], m1[1]);
var distance = Math.round(p1.distance(m2));
return distance;
},
/**
* @method 计算两个经纬度点连线后与正北线的角度
* @param
*/
bearing(start, end) {
let rad = Math.PI / 180,
lat1 = start[1] * rad,
lat2 = end[1] * rad,
lon1 = start[0] * rad,
lon2 = end[0] * rad;
const a = Math.sin(lon2 - lon1) * Math.cos(lat2);
const b =
Math.cos(lat1) * Math.sin(lat2) -
Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1);
return this.radiansToDegrees(Math.atan2(a, b)).toFixed(2);
},
/*
* 弧度转换为角度
*/
radiansToDegrees(radians) {
const degrees = radians % (2 * Math.PI);
return (degrees * 180) / Math.PI;
},
},
};
</script>
<style lang="scss" scoped></style>
9. 在高德地图API中,要判断一个点是否在矩形(多边形)内,可以使用contains方法。首先,你需要创建一个矩形(多边形)对象,然后使用该对象(多边形)的contains方法来判断点是否在矩形内。
// 创建高德地图实例(矩形)
var map = new AMap.Map('container', {
zoom: 11,
center: [116.397428, 39.90923]
});
// 创建矩形对象
var bounds = new AMap.Bounds(
// 左下角坐标
[116.365145, 39.906018],
// 右上角坐标
[116.418654, 39.940732]
);
// 创建一个点坐标
var point = new AMap.LngLat(116.401476, 39.920765);
// 使用contains方法判断点是否在矩形内
if (bounds.contains(point)) {
console.log('点在矩形内');
} else {
console.log('点不在矩形内');
}
// 创建地理坐标点
var point = new AMap.LngLat(116.397428, 39.90923); // 举例的点
// 创建多边形
var polygonPath = [
new AMap.LngLat(116.368904,39.913423),
new AMap.LngLat(116.382122,39.901176),
new AMap.LngLat(116.387271,39.912501),
new AMap.LngLat(116.398258,39.904600)
];
var polygon = new AMap.Polygon({
path: polygonPath,
strokeColor: 'red',
strokeWeight: 3
});
// 将多边形添加到地图
map.add(polygon);
// 使用contains方法判断点是否在多边形内
if (polygon.contains(point)) {
console.log('点在多边形内');
} else {
console.log('点在多边形外');
}