- 安装插件
//高德地图插件
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: [
"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>
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('点在多边形外');
}