十分钟玩转 vue3+高德地图AMap+geojson批量绘制Polygon地块数据展示【三、Geojson地图数据批量导入地图】
十分钟玩转 vue3+高德地图AMap+geojson批量绘制Polygon地块数据展示【三、Geojson地图数据批量导入地图】
本章节文末,付完整代码
在public/目录新建设一个data目录,里面存放geojson数据

这里我提供部分json数据给大家用于练习使用:
逻辑分析和处理:
1.开始处理控制面板勾选年份的事件
触发选中后,需要做个判断,是否第一次读取 geojson 数据。 如果是第一次读取,则使用getdata方法去跑axios,获取数据。如果不是第一次加载数据,则跑showpolygon 或者 hidepolygon 方法来进行显示或者隐藏地块。
polygonarr 为地块数组
polygondata 为地块数据
var map = shallowRef(null);
var amap = (null);
var checkobj ={}
const GetMassif = (aa:any) => {
var checkarr = [] // 年,颜色,当前状态,是否加载
checkarr= aa.split(',')
if (checkobj[checkarr[0]]){
// 不是第一次加载geojson数据
if (checkarr[2]==1){
showpolygon(checkarr[0])//展示地块
}else{
hidepolygon(checkarr[0])//隐藏地块
}
}else{
checkarr.push("1")//存入第四个参数,是否加载
checkobj[checkarr[0]]= checkarr
//如果是第一次加载,则需要用axios读取数据;
if (checkarr[2]==1){
getdata(checkarr[0],checkarr[1]) //首次加载数据
}
}
}
//隐藏覆盖物
const hidepolygon = (year:any)=>{
polygonarr.forEach(element => {//循环地块数组
if (element.id == year){
element.polygondata.hide()//隐藏地块
}
});
}
//显示覆盖物
const showpolygon = (year:any)=>{
polygonarr.forEach(element => {
if (element.id == year){
element.polygondata.show()
}
})
}
2.走 getdata 方法直接读取arcgis 转出来的geojson 数据,我这里的数据为gps84坐标数据,需要用高德的API的convertFrom函数,转换成高德高的坐标系。
//读取geojson数据
var dataarr = []
var datalt = {}
const getdata = (year :any,color:any) =>{
axios({
method: 'get',
url: 'public/data/dk'+year+'.json',
}).then((res) => {
datalt={
"year":year,
"data":res.data
}
dataarr.push(datalt)
// 走转换数据的方法
TransformationData(res.data,year,color)
console.log('GeoJSON 数据加载完成')
}).catch((msg) => {
console.log("msg", msg)
console.log('GeoJSON 服务请求失败')
})
}
备注:以下为geojson数据
{
"type": "FeatureCollection",
"crs": { "type": "name", "properties": { "name": "EPSG:4326" } },
"features": [
{
"type": "Feature",
"id": 1,
"geometry": {
"type": "Polygon",
"coordinates": [
[
[108.99980896100004, 22.999783316000048, 0],
[108.99946594000005, 22.999994280000067, 0],
[108.99925232000004, 22.999885560000052, 0],
[108.99980164000004, 22.999479290000068, 0],
[109.00005341000008, 22.999633790000075, 0],
[109.00004999100008, 22.999635879000039, 0],
[109.00004577600004, 22.999633789000029, 0],
[108.99980896100004, 22.999783316000048, 0]
]
]
},
"properties": {
"OBJECTID": 1,
"Name": "010101002.01.韦x圆.45130210120000142300",
"Shape_Length": 0.0019098079207306106,
"Shape_Area": 1.633144971052641e-7,
"MJ": 1854.2365449356753
}
},
{
"type": "Feature",
"id": 2,
"geometry": {
"type": "Polygon",
"coordinates": [
[
[109.00004999100008, 22.999635879000039, 0],
[109.00051116900005, 22.999864578000029, 0],
[109.00002288800005, 23.000301361000027, 0],
[108.99945068400007, 23.000009537000039, 0],
[108.99980896100004, 22.999783316000048, 0],
[109.00004577600004, 22.999633789000029, 0],
[109.00004999100008, 22.999635879000039, 0]
]
]
},
"properties": {
"OBJECTID": 2,
"Name": "010101002.02.韦x圆.45130210120000142200",
"Shape_Length": 0.0025207201232059599,
"Shape_Area": 3.5231640810777823e-7,
"MJ": 4000.1159183494574
}
},
{
"type": "Feature",
"id": 3,
"geometry": {
"type": "Polygon",
"coordinates": [
[
[109.31761472400007, 23.949700621000034, 0],
[109.31761932400008, 23.949712753000028, 0],
[109.31747588000007, 23.949779424000042, 0],
[109.31707763700007, 23.949964523000062, 0],
[109.31696319600007, 23.949409485000047, 0],
[109.31746673600009, 23.949310303000061, 0],
[109.31761472400007, 23.949700621000034, 0]
]
]
},
"properties": {
"OBJECTID": 3,
"Name": "010101034.03.覃x琼.45130210120000117200",
"Shape_Length": 0.0021076721802698456,
"Shape_Area": 2.7362659070145457e-7,
"MJ": 3084.9086846522196
}
},
{
"type": "Feature",
"id": 4,
"geometry": {
"type": "Polygon",
"coordinates": [
[
[109.32078552200005, 23.949838638000074, 0],
[109.32067871100008, 23.950061798000036, 0],
[109.32040405300006, 23.950031281000065, 0],
[109.31993103000008, 23.949953079000068, 0],
[109.31998443600008, 23.949731827000051, 0],
[109.32007598900009, 23.949575424000045, 0],
[109.32038116500007, 23.949661255000024, 0],
[109.32078552200005, 23.949838638000074, 0]
]
]
},
"properties": {
"OBJECTID": 4,
"Name": "010101155.01.韦x蕊.45130210120000147800",
"Shape_Length": 0.002170601077130315,
"Shape_Area": 2.6147622846426089e-7,
"MJ": 2947.9183812390702
}
},
{
"type": "Feature",
"id": 650,
"geometry": {
"type": "Polygon",
"coordinates": [
[
[109.30503082300004, 23.985090256000035, 0],
[109.30485641000007, 23.985118287000034, 0],
[109.30485190600007, 23.985119011000052, 0],
[109.30438995400004, 23.985193253000034, 0],
[109.30430603100007, 23.984498978000033, 0],
[109.30496978800005, 23.984447479000039, 0],
[109.30503082300004, 23.985090256000035, 0]
]
]
},
"properties": {
"OBJECTID": 650,
"Name": "010101487.09.黄x达.45130210120000127400",
"Shape_Length": 0.0026598417730435632,
"Shape_Area": 4.4168718365440911e-7,
"MJ": 4978.320637123189
}
}
]
}
3.在地块上批量添加地块,将地块数据转换成高德坐标之后,调用addpolygon方法开始画出地块;
如果只需要画1个地块,可以跳过这个方法,直接看四。
// 将GPS 84转换成高德坐标
const TransformationData = (data:any, year :any , color:any) => {
new amap.GeoJSON({
geoJSON: data,//这里是 geojson数据
// 还可以自定义getMarker和getPolyline
getPolygon: function (geojson:any, lnglats:any) {
// 计算面积
// var area = amap.GeometryUtil.ringArea(lnglats[0])
// 用convertFrom函数,将gps 84 转高德 gcj20坐标系
//lnglats[0] 是要转换的坐标
amap.convertFrom(lnglats[0], "gps", function(status:any, result:any) {
//转换成功
if (result.info === 'ok') {
var path2 = result.locations //转换好的坐标
// 添加覆盖物
addpolygon(path2,color,year,geojson.properties)//坐标,颜色,年,其他属性
}
})
}
});
}
4.我这里定义一个polygonobj对象用来装入年和地块对象。用于区分各个年份的地块,当然你们也可以用其他类型来处理。
画完地块之后,我们对地块添加一个点击事件,用于绑定自定义属性,点击地块之后能够显示其相关信息数据。
var polygonarr = []
var polygonobj = (null)
var infoWindow=(null)
// 添加覆盖物
const addpolygon=(path2:any,color:any,year:any,properties:any)=>{
// console.log(properties)
polygonobj={
"id":year,
"polygondata":new amap.Polygon({ //添加多边形覆盖物,设置opts属性
path: path2,//坐标,这里必须是首位相同的坐标点,才能够形成一个闭合的包围
// fillOpacity: 1 - Math.sqrt(area / 8000000000),// 面积越大透明度越高
fillOpacity:0.5,
strokeColor: 'white',//线条颜色
fillColor: color,//多边形填充颜色
height: 0, //是否离地绘制,默认值为0.0,等于0时贴地绘制。
strokeWeight : 1,//轮廓线宽度
strokeStyle: "dashed", // 轮廓线样式,实线:solid,虚线:dashed
strokeOpacity: 0.75, //轮廓线透明度,取值范围 [0,1] ,0表示完全透明,1表示不透明。默认为0.9
draggable : false, //设置多边形是否可拖拽移动,默认为false
strokeDasharray: [5, 5], //勾勒形状轮廓的虚线和间隙的样式
extData:{//用户自定义属性,支持JavaScript API任意数据类型,如Polygon的id等
"Name":properties.Name,
"MJ":properties.MJ,
"OBJECTID":properties.OBJECTID,
"Shape_Area":properties.Shape_Area,
"Shape_Length":properties.Shape_Length,
},
})
}
//绑定点击事件
polygonobj.polygondata.on('click', (e:any) => {
// console.log(e.target._opts.extData)'
var extresult_name = e.target._opts.extData.Name.split('.')
infoWindow = new amap.InfoWindow({
closeWhenClickMap:true,
content: "地块信息<hr /><Br>代码:"+extresult_name[0]+"<Br>地块序号:"+extresult_name[1]+"<Br>名字:"+extresult_name[2]+"<Br>地块编号:"+extresult_name[3]+"<Br>地块面积:"+(e.target._opts.extData.MJ).toFixed(2)+"平方米"
})
infoWindow.open(map, e.lnglat);
})
//触碰覆盖物
// polygonobj.polygondata.on('mouseover', () => {
// polygon2.setOptions({
// fillOpacity: 0.7,
// fillColor: '#7bccc4'
// })
// })
//离开覆盖物
// polygonobj.polygondata.on('mouseout', () => {
// polygon2.setOptions({
// fillOpacity: 0.5,
// fillColor: '#ccebc5'
// })
// })
polygonarr.push(polygonobj) // 把地块对象放进数组里面,方便后面循环读取展示。
map.add(polygonobj.polygondata); //添加地块
}
最后在这里放我这边的完整代码
<template>
<div id="container"></div>
<div class="state-text" >{{texta}}</div>
<div class="Console">
<h5>控制台</h5>
<hr>
<div class="Console_list">
<ul>
<li><span></span> <el-checkbox v-model="checked1" @change="GetMassif" true-label="2022,#ff2dc6,1" false-label="2022,#ff2dc6,0" label="2022年" size="large" /></li>
<li><span></span> <el-checkbox v-model="checked1" @change="GetMassif" true-label="2021,#1549cf,1" false-label="2021,#1549cf,0" label="2021年" size="large" /></li>
<li><span></span> <el-checkbox v-model="checked1" @change="GetMassif" true-label="2020,#e14915,1" false-label="2020,#e14915,0" label="2020年" size="large" /></li>
</ul>
</div>
</div>
</template>
<script setup lang='ts'>
import { onMounted, reactive, ref } from 'vue';
import {ElCheckbox} from "element-plus"
import { shallowRef } from '@vue/reactivity'
import AMapLoader from '@amap/amap-jsapi-loader';
import axios from 'axios';
onMounted(() => {
initMap()
})
var texta = ref()
var map = shallowRef(null);
var amap = (null);
var dataarr = []
var datalt = {}
var polygonarr = []
var polygonobj = (null)
var infoWindow=(null)
//加载地图
const initMap = () => {
AMapLoader.load({
key:"你的key", // 申请好的Web端开发者Key,首次调用 load 时必填
version:"2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
plugins:[
"AMap.Scale", //工具条,控制地图的缩放、平移等
"AMap.ToolBar", //比例尺,显示当前地图中心的比例尺
// "AMap.Geolocation", //定位,提供了获取用户当前准确位置、所在城市的方法
"AMap.HawkEye", //鹰眼,显示缩略图
"AMap.GeoJSON", //GeoJSON
"AMap.convertFrom", //坐标系转换
], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
}).then((AMap)=>{
amap = AMap
map = new AMap.Map("container",{ //设置地图容器id
viewMode:"2D", //是否为3D地图模式
zooms:[6,16.7],
zoom:15, //初始化地图级别
center:[109.314545,23.964934], //初始化地图中心点位置
mapStyle: 'amap://styles/whitesmoke', //设置地图的显示样式
layers: [
new AMap.TileLayer.Satellite(),
new AMap.TileLayer.RoadNet({
opacity:0.5
}),
],//地图图层
});
map.addControl(new AMap.Scale()); //异步同时加载多个插件
map.addControl(new AMap.ToolBar());
let HawkEye = new AMap.HawkEye({
position: "LT", //控件停靠位置(LT/RT/LB/RB)
});
map.addControl(HawkEye);
map.on('mousemove',showInfoMove)
}).catch(e=>{
console.log(e);
})
}
//移动鼠标事件
const showInfoMove = (e) =>{
texta.value = '当前经纬度:'+e.lnglat.getLng()+','+e.lnglat.getLat()
}
//读取geojson数据
const getdata = (year :any,color:any) =>{
axios({
method: 'get',
url: 'public/data/dk'+year+'.json',
}).then((res) => {
datalt={
"year":year,
"data":res.data
}
dataarr.push(datalt)
// 转换数据
TransformationData(res.data,year,color)
console.log('GeoJSON 数据加载完成')
}).catch((msg) => {
console.log("msg", msg)
console.log('GeoJSON 服务请求失败')
})
}
// 将GPS 84转换成高德坐标
const TransformationData = (data:any, year :any , color:any) => {
new amap.GeoJSON({
geoJSON: data,
// 还可以自定义getMarker和getPolyline
getPolygon: function (geojson:any, lnglats:any) {
// 计算面积
// var area = amap.GeometryUtil.ringArea(lnglats[0])
// gps 84 转高德 gcj20坐标系
// console.log(geojson.properties)
amap.convertFrom(lnglats[0], "gps", function(status:any, result:any) {
if (result.info === 'ok') {
var path2 = result.locations
// 添加覆盖物
addpolygon(path2,color,year,geojson.properties)//坐标,颜色,年,其他属性
}
})
}
});
}
// 添加覆盖物
const addpolygon=(path2:any,color:any,year:any,properties:any)=>{
// console.log(properties)
polygonobj={
"id":year,
"polygondata":new amap.Polygon({
path: path2,
// fillOpacity: 1 - Math.sqrt(area / 8000000000),// 面积越大透明度越高
fillOpacity:0.5,
strokeColor: 'white',//线条颜色
fillColor: color,//多边形填充颜色
height: 0, //是否离地绘制,默认值为0.0,等于0时贴地绘制。
strokeWeight : 1,//轮廓线宽度
strokeStyle: "dashed", // 轮廓线样式,实线:solid,虚线:dashed
strokeOpacity: 0.75, //轮廓线透明度,取值范围 [0,1] ,0表示完全透明,1表示不透明。默认为0.9
draggable : false, //设置多边形是否可拖拽移动,默认为false
strokeDasharray: [5, 5], //勾勒形状轮廓的虚线和间隙的样式
extData:{//用户自定义属性,支持JavaScript API任意数据类型,如Polygon的id等
"Name":properties.Name,
"MJ":properties.MJ,
"OBJECTID":properties.OBJECTID,
"Shape_Area":properties.Shape_Area,
"Shape_Length":properties.Shape_Length,
},
})
}
//绑定点击事件
polygonobj.polygondata.on('click', (e:any) => {
// console.log(e.target._opts.extData)'
var extresult_name = e.target._opts.extData.Name.split('.')
infoWindow = new amap.InfoWindow({
closeWhenClickMap:true,
content: "地块信息<hr /><Br>代码:"+extresult_name[0]+"<Br>地块序号:"+extresult_name[1]+"<Br>名字:"+extresult_name[2]+"<Br>地块编号:"+extresult_name[3]+"<Br>地块面积:"+(e.target._opts.extData.MJ).toFixed(2)+"平方米"
})
infoWindow.open(map, e.lnglat);
})
//触碰覆盖物
// polygonobj.polygondata.on('mouseover', () => {
// polygon2.setOptions({
// fillOpacity: 0.7,
// fillColor: '#7bccc4'
// })
// })
//离开覆盖物
// polygonobj.polygondata.on('mouseout', () => {
// polygon2.setOptions({
// fillOpacity: 0.5,
// fillColor: '#ccebc5'
// })
// })
polygonarr.push(polygonobj)
map.add(polygonobj.polygondata);
}
//隐藏覆盖物
const hidepolygon = (year:any)=>{
polygonarr.forEach(element => {
if (element.id == year){
element.polygondata.hide()
}
});
}
//显示
const showpolygon = (year:any)=>{
polygonarr.forEach(element => {
if (element.id == year){
element.polygondata.show()
}
})
}
var checkobj ={}
const GetMassif = (aa:any) => {
var checkarr = [] // 年,颜色,当前状态,是否加载
checkarr= aa.split(',')
if (checkobj[checkarr[0]]){
// 判断状态
if (checkarr[2]==1){
showpolygon(checkarr[0])
}else{
hidepolygon(checkarr[0])
}
}else{
checkarr.push("1")//存入第四个参数,是否加载
checkobj[checkarr[0]]= checkarr
//判断状态
if (checkarr[2]==1){
getdata(checkarr[0],checkarr[1]) //首次加载数据
}
}
}
</script>
<style scoped>
#container{
padding:0px;
margin: 0px;
width: 100%;
height: 100vh;
}
.state-text{
padding: 0.75rem 1.25rem;
margin-bottom: 1rem;
border-radius: 0.25rem;
position: fixed;
top: 1rem;
background-color: white;
width: auto;
min-width: 22rem;
border-width: 0;
right: 1rem;
box-shadow: 0 2px 6px 0 rgb(114 124 245 / 50%);
}
.Console {
padding: 0.75rem 1.25rem;
margin-bottom: 1rem;
border-radius: 0.25rem;
position: fixed;
top: calc( 1rem + 4rem);
background-color: white;
width: auto;
min-width: 11rem;
border-width: 0;
right: 1rem;
box-shadow: 0 2px 6px 0 rgb(114 124 245 / 50%);
}
.Console_list li{
list-style: none;
line-height: 28px;
}
.Console_list li:nth-child(1) span {
display: inline-block;
width: 12px;
height: 12px;
background-color: #ff2dc6;
}
.Console_list li:nth-child(2) span{
display: inline-block;
width: 12px;
height: 12px;
background-color: #1549cf;
}
.Console_list li:nth-child(3) span {
display: inline-block;
width: 12px;
height: 12px;
background-color: #e14915;
}
</style>
第一次在CSDN写文章,希望能帮到大家。
如果觉得有用请给我点个赞。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)