基于Mapbox展示GDAL处理的3D行政区划展示实践

目录

前言

一、Gdal数据处理

1、数据展示

2、Java数据转换

 二、Mapbox可视化

1、定义Mapbox地图

2、地图初始化

3、创建地图

三、界面优化

1、区域颜色设置

2、高度自适应和边界区分 

3、中文标注

总结


前言

        最近有遇到一个需求,用户想在地图上把行政区划数据做成那种3D凸出的效果,同时支持各个行政区划按照不同颜色进行展示,在行政区划上还能展示不同的标注,各个行政区的立体高度可以动态设置。刚开始收到这个需求的时候想用cesium来实现或者threejs来实现,要想实现3D的凸出特效,传统的Leaflet和OpenLayers似乎都有没有这种组件进行支持。各位朋友如果有相应的组件,欢迎留言指导指导。最后查找了一些Mapbox的资料,发现在Mapbox中有直接的样式配置就可以满足上述的需求实现。

        由于这里要展示3D行政数据,因此首先准备一份北京的行政区划实例。作为演示数据,这里并不保证数据的准确性。重点演示软件的功能。行政区划数据刚开始拿到的是Shp数据,为了在Mapbox中方便展示,可以将shp数据处理成矢量瓦片,这里为了演示方便,直接处理成geojson,关于geojson的基本知识,以后有时间可以进行深入讲解。

        本文首先讲解使用Java语言调用Gdal将shp数据转为geojson数据,然后使用Mapbox将处理好的Geojson行政区划数据进行3D展示,同时将不同行政区划进行动态颜色标绘,可以对行政区划的名称进行中文标注,最后动态设置不同行政区划的高度。如果您在项目中也有这种需求,可以参考本文进行开发。

一、Gdal数据处理

        由于默认的行政区划数据是采用Shp格式存储,为了在前端展示的方便,我们预先将shp数据转换成geojson。关于Gdal的相关知识,这里不赘述,在java开发语言中使用GDAL,在之前的博客中有进行详细的说明,各位朋友可以简单进行了解。使用Gdal进行处理,主要是方便进行服务调用,方便进行程序扩展。如果您实在不了解gdal,为了进行下一步,也可以采用诸如Qgis、Arcgis、SuperMap等这样的地图软件,直接将shp数据处理成geojson也是可以的。并不影响后面的效果展示。

1、数据展示

        这里采用的数据默认是shp格式,我们在qgis中查看其空间位置和属性信息。

         上面本人已经默认进行中文标注以及颜色渲染,不过这是在qgis中进行标注实现的。下面来看一下数据的属性。

序号属性类型说明
1namestring行政区划名称

        在Qgis中,打开属性表可以看到以下的数据(ps:这里的数据不准确,仅供参考)。这里的数据比较老,与现行的行政区划是不一致的,同时北京市城区没有进行更详细的划分。

2、Java数据转换

        数据格式转换从shp到geojson,这里采用Gdal组件作为转换插件。这里将转换程序的源码进行详细分析说明,让大家对转化过程有一个详细的了解。下面项目配置采用Maven进行编译,jdk使用1.8。首先来看一下Pom的定义。

<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.yelang</groupId><artifactId>gdal_demo1</artifactId><version>1.0.0</version><name>gdal_demo1</name><description>gdal试验</description><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target></properties><dependencies><dependency><groupId>org.gdal</groupId><artifactId>gdal</artifactId><version>3.4.3</version><scope>system</scope><systemPath>${project.basedir}/lib/gdal.jar</systemPath></dependency><dependency><groupId>net.sf.ucanaccess</groupId><artifactId>ucanaccess</artifactId><version>4.0.4</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope></dependency></dependencies>
</project>

        为了演示方便,这里使用Junit的方式将处理过程以单元测试的构建方式给出,实际项目开发过程中,需要考虑更多的因素。详细的java转换代码如下:

@Testpublic void testShp2GeoJson() {// 注册所有的驱动  ogr.RegisterAll();// 为了支持中文路径,请添加下面这句代码  gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8","YES");  // 为了使属性表字段支持中文,请添加下面这句  gdal.SetConfigOption("SHAPE_ENCODING","");  //shp文件所在的位置String strVectorFile = "E:/ruanzhu_4326_vector/2019/GS(2019)1822/beijing.shp";  //打开数据  DataSource ds = ogr.Open(strVectorFile,0);  if (ds == null)  {  System.out.println("打开文件失败!" );  return;  }  System.out.println("打开文件成功!" );  Driver dv = ogr.GetDriverByName("GeoJSON");  if (dv == null)  {  System.out.println("打开驱动失败!" );  return;  }  System.out.println("打开驱动成功!" );  //输出geojson的位置及文件名dv.CopyDataSource(ds, "E:/shp2geojson/beijing.geojson");  System.out.println("转换成功!" );  }

        上述的核心API就是使用geojson的驱动,实现将shp转换成geojson。上述代码运行完成后即可完成数据的转换。转换后的数据列表如下:

        将beijing.json数据使用文本文件打开,可以看到以下结果,同时需要进行处理的还有行政区划的边界数据。

 二、Mapbox可视化

        经过上述的数据处理步骤后,即可得到可以直接用于展示的原始数据,将数据进行静态化发布后,即可为前端提供数据源服务。下面将重点对采用Mapbox进行行政区划的3D展示进行详细说明。尤其是在Mapbox中如何进行高度控制,如何结合属性进行动态参数注入控制等操作。要想实现这个需求,主要是需要使用fill-extrusion-xxx属性。通过这个属性来控制地图的可视化效果。

1、定义Mapbox地图

        首先新建Mapbox的html主体框架,关键代码如下所示:

<!doctype html>
<html lang="en">
<head><meta charset="utf-8"><meta http-equiv="x-ua-compatible" content="ie=edge"><title>基于Mapbox的3D行政区划立体展示</title><meta name="description" content=""><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><link href="css/common.css" rel="stylesheet" /><link href="lib/mapbox-gl.css" rel="stylesheet" /><style>#map,body,html {margin: 0;padding: 0;width: 100%;height: 100%;overflow: hidden;font-size: 16px; }</style>
</head>
<body>
<div id="map"></div><script src="lib/mapbox-gl.js"></script>
</body>
</html>

2、地图初始化

        在定义了基本的网页结构后,我们使用javascript进行地图的初始化,首先来添加一个基础栅格影像底图,同时在资源引用列表中,将行政区划geojson和行政区划边界的geojson数据进行引入。关键代码如下:

var mapStyle = {"version": 8,"name": "Dark","glyphs": "http://localhost:8086/2d/mapbox-gl-js-offline-example/font/{fontstack}/{range}.pbf","sources": {"geojson": {type: 'geojson',data: './assets/beijing.geojson'},"geojson-b": {type: 'geojson',data: './assets/beijing-b.geojson'},"raster-tiles": {"type": "raster","tiles": ['http://localhost:8086/data/xxgc/q0403/{z}/{x}/{y}.png'],"tileSize": 256,}},"layers": [{"id": "tdt-img-tiles","type": "raster","source": "raster-tiles","minzoom": 0,"maxzoom": 8}]};

3、创建地图

 map = new mapboxgl.Map({container: 'map',maxZoom: 18,minZoom: 0,zoom: 7.6,center: [116.56330634582548, 40.20241714634946],pitch: 35,style: mapStyle,attributionControl: false});

        使用上述代码对地图进行初始化后,我们把数据添加到地图中进行展示。

map.on('load', () => {map.loadImage('./assets/ground.PNG', function(error, image) {if (error) throw error;map.addLayer({id: 'geojson-fill',source: 'geojson',type: 'fill-extrusion',paint: {'fill-extrusion-height': 15000,'fill-extrusion-base': 0,'fill-extrusion-opacity': 0.85,'fill-extrusion-color': "#F84E2D"},})});})

        到这里已经完成地图的基础展示,也实现了高度的自动配置。只不过每个行政区划的高度是一致的。实际效果如下:

三、界面优化

        经过上面的可视化展示,基本已经实现了行政区划的3D立体展示。只是目前还存在一些明显的问题,比如行政区划边界不明显,各个行政区划无明显颜色区分,行政区划没有中文标注,各区域没有明显高度值差别。下面我们逐一来进行可视化调整优化。

1、区域颜色设置

        为了将各个行政区区分开来,我们采用不同的颜色进行标注。下面将fill-extrusio欧诺个n-color进行动态设置,根据属性列表中的name属性,不同的区域名称设置不同的颜色。下面的代表示,怀柔县采用#F84E2D展示,如果没有匹配的,最后一个是默认颜色#AAAAAA。关键设置如下:

fill-extrusion-color': [//根据数值中加载相对应颜色'match',['get', 'name'],'怀柔县', '#F84E2D','密云县','#44DEA3','平谷县','#ffd0a6','延庆县','#FFC544','顺义县','#ff704e','大兴县','#6C44FF','北京市', '#1372EC','#AAAAAA']

        经过以上调整,来看具体的效果:

2、高度自适应和边界区分 

        为了模拟各个行政区划的高度不一样,比如各区域的人口密度展示,我们会展示不同的高度,同时将行政区划的边界更加明显的展示出来。首先实现动态高度展示:

'fill-extrusion-height': [//根据数值中加载相对应颜色'match',['get', 'name'],'怀柔县', 15000,'密云县',17000,'延庆县',19000,'大兴县',21000,'北京市', 23000,15000],

        然后添加行政区划边界信息图层,使区域信息更加明显。添加后再来看具体的效果。

map.addLayer({id: 'geojson-fill-b',source: 'geojson-b',type: 'fill-extrusion',paint: {'fill-extrusion-height': [//根据数值中加载相对应颜色'match',['get', 'name'],'怀柔县', 16100,'密云县',17100,'延庆县',19100,'大兴县',21100,'北京市', 23100,16100],'fill-extrusion-base': 14950,'fill-extrusion-opacity': 1,'fill-extrusion-color': '#fff'},})

3、中文标注

        行政区划标注是最简单的,再添加图层后,指定symbol类型进行展示即可。来看核心代码:

map.addLayer({'id': 'geojson-label','type': 'symbol','source': 'geojson',layout: {'text-field': ['get', 'name'],'text-size': 14,'text-allow-overlap': true,'text-justify': 'center'},paint: {'text-color': 'rgb(159, 96, 55)','text-halo-color': '#fff','text-halo-width': 1.8,},});

        在地图上添加中文标注后,来看最后的实际效果。

        到此即实现了在Mapbox中实现对行政区划的3D展示,同时实现动态标注,边界展示,动态高度设置等需求。 

总结

        以上就是本文的主要内容,本文首先讲解使用Java语言调用Gdal将shp数据转为geojson数据,然后使用Mapbox将处理好的Geojson行政区划数据进行3D展示,同时将不同行政区划进行动态颜色标绘,可以对行政区划的名称进行中文标注,最后动态设置不同行政区划的高度。如果您在项目中也有这种需求,可以参考本文进行开发。在使用Mapbox展示的时候,主要是采用fill-extrusion-xx关键字,同时在进行属性动态设置时的匹配规则的合理采用。本案例在实现时重点参考了以下博客,并优化了数据的展示和属性的配置。站在前人的肩膀上,可以看到更远的地方。在此感谢以下博文。

1、牛老师讲gis mapboxGL中3d行政区实现。

2、mapboxgl绘制3D线教程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/263141.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android相机调用-libusbCamera【外接摄像头】【USB摄像头】 【多摄像头预览】

有的自定义系统&#xff0c;对于自己外接的USB摄像头&#xff0c;android原生的camera和camera2都无法打开&#xff0c;CameraX也用不了。这时候就要用libusbCamera&#xff0c;这个库可以打开摄像头&#xff0c;还可以多摄像头同时预览。本文主要是同时打开3个USB摄像头的项目…

《Docker 简易速速上手小册》第2章 容器和镜像(2024 最新版)

文章目录 2.1 理解 Docker 容器2.1.1 重点基础知识2.1.2 重点案例&#xff1a;使用 Docker 运行 Python 应用2.1.3 拓展案例 1&#xff1a;Docker 中的 Flask 应用2.1.4 拓展案例 2&#xff1a;Docker 容器中的数据分析 2.2 创建与管理 Docker 镜像2.2.1 重点基础知识2.2.2 重点…

异步框架Celery在Django中的运用

参考博客&#xff1a;https://www.cnblogs.com/pyedu/p/12461819.html 参考视频&#xff1a;01 celery的工作机制_哔哩哔哩_bilibili 定义&#xff1a;简单灵活、处理大量消息的分布式系统&#xff0c;专注于实时处理异步队列&#xff0c;支持任务调度 主要架构&#xff1a; …

5分钟JavaScript快速入门

目录 一.JavaScript基础语法 二.JavaScript的引入方式 三.JavaScript中的数组 四.BOM对象集合 五.DOM对象集合 六.事件监听 使用addEventListener()方法添加事件监听器 使用onX属性直接指定事件处理函数 使用removeEventListener()方法移除事件监听器 一.JavaScript基础…

Linux日志轮替

文章目录 1. 基本介绍2. 日志轮替文件命名3. logrotate 配置文件4. 把自己的日志加入日志轮替5. 日志轮替机制原理6. 查看内存日志 1. 基本介绍 日志轮替就是把旧的日志文件移动并改名&#xff0c;同时建立新的空日志文件&#xff0c;当旧日志文件超出保存的范围之后&#xff…

Git基本指令

从远程拉代码 git clone gitgitlab-internal.wedobest.com.cn:dengyanhui/gittest.git添加所有文件到待上传列表 git add .提交 git commit -m message推送 git push获取现在的状态 git status更新本地代码 git pullgit拉取某一分支代码 git clone -b develop XXX本地删除…

开源博客项目Blog .NET Core源码学习(9:Autofac使用浅析)

开源博客项目Blog使用Autofac注册并管理组件和服务&#xff0c;Autofac是面向.net 的开源IOC容器&#xff0c;支持通过接口、实例、程序集等方式注册组件和服务&#xff0c;同时支持属性注入、方法注入等注入方式。本文学习并记录Blog项目中Autofac的使用方式。   整个Blog解…

视频推拉流EasyDSS视频直播点播平台授权出现激活码无效并报错400是什么原因?

视频推拉流EasyDSS视频直播点播平台集视频直播、点播、转码、管理、录像、检索、时移回看等功能于一体&#xff0c;可提供音视频采集、视频推拉流、播放H.265编码视频、存储、分发等视频能力服务&#xff0c;在应用场景上&#xff0c;平台可以运用在互联网教育、在线课堂、游戏…

CSS学习(三)

目录&#xff1a; 1. CSS引入方式 1.1 三种样式表 1.2 内部样式表&#xff08;嵌入式引入&#xff09; 1.3 行内样式表&#xff08;内联样式表&#xff09; 1.4 外部样式表 1.5 总结 1. CSS引入方式 1.1 三种样式表 1.2 内部样式表&#xff08;嵌入式引入&#xff09; …

7.(数据结构)堆

7.1 相关概念 堆&#xff08;Heap&#xff09;在计算机科学中是一种特殊的数据结构&#xff0c;它通常被实现为一个可以看作完全二叉树的数组对象。以下是一些关于堆的基本概念&#xff1a; 数据结构&#xff1a; 堆是一个优先队列的抽象数据类型实现&#xff0c;通过完全二叉树…

unity ui界面优化

优化一个比较复杂的界面&#xff0c;里面有多个rt和组件。 在初次打开这个界面的时候会发生1s多的卡顿&#xff0c;还是非常严重的。 分析 通过profiler分析 1.打开界面时卡顿。 分析&#xff1a;除了update和dotween相关逻辑&#xff0c;主要在于打开时的lua function调用…

svn客户端下载、安装、使用

下载、使用 打开360软件管家&#xff0c;选怎宝库&#xff0c;搜索svn&#xff0c;点击安装 可以修改安装路径 使用 在桌面右键弹出菜单&#xff0c;点击 输入地址&#xff0c;点击ok 输入用户名、密码 &#xff0c;等待检出完成

【web】nginx+php环境搭建-关键点(简版)

一、nginx和php常用命令 命令功能Nginxphp-fpm启动systemctl start nginxsystemctl start php-fpm停止systemctl stop nginxsystemctl stop php-fpm重启systemctl restart nginxsystemctl restart php-fpm查看启动状态systemctl status nginxsystemctl status php-fpm开机自启…

3ds Max视频怎么渲染 3ds Max云渲染操作

在3ds Max软件中制作视频动画本质上是逐帧生成画面&#xff0c;并将这些连续帧串联起来创造出动态连贯的视觉效果。常见的视频帧率包括25 FPS(每秒帧数)、60 FPS、以及120 FPS等&#xff0c;帧率的提升可以使视频动画更加流畅。在实质上&#xff0c;视频渲染就是动画渲染&#…

uniapp-提现功能(demo)

页面布局 提现页面 有一个输入框 一个提现按钮 一段提现全部的文字 首先用v-model 和data内的数据双向绑定 输入框逻辑分析 输入框的逻辑 为了符合日常输出 所以要对输入框加一些条件限制 因为是提现 所以对输入的字符做筛选,只允许出现小数点和数字 这里用正则实现的 小数点…

Linux--自定义shell

shell shell就是操作系统提供给用户与操作系统进行交互的命令行界面。它可以理解为一个用户与操作系统之间的接口&#xff0c;用户可以通过输入命令来执行各种操作&#xff0c;如文件管理、进程控制、软件安装等。Shell还可以通过脚本编程实现自动化任务。 常见的Unix系统中使…

BERT学习笔记

论文&#xff1a;《BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding》&#xff0c;2019 代码&#xff1a;[tensorflow]&#xff0c;[pytorch] 来源&#xff1a;李沐精度BERT 0、摘要 与之前模型的区别&#xff1a; GPT考虑的是一个单向…

RabbitMQ 部署方式选择

部署模式 RabbitMQ支持多种部署模式&#xff0c;可以根据应用的需求和规模选择适合的模式。以下是一些常见的RabbitMQ部署模式&#xff1a; 单节点模式&#xff1a; 最简单的部署方式&#xff0c;所有的RabbitMQ组件&#xff08;消息存储、交换机、队列等&#xff09;都运行在…

【Java程序设计】【C00278】基于Springboot的数码论坛管理系统(有论文)

基于Springboot的数码论坛管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的数码论坛系统 本系统分为系统功能模块、管理员功能模块以及用户功能模块。 系统功能模块&#xff1a;在系统首页可以查看首页、…

Linux Android USB gadget(从设备驱动)

Linux Android USB gadget 一:Linux usb gadget 与 Android Composite Gadget二:原生方式和Android方式如何配置函数调用逻辑内核配置原生驱动android驱动三:mass_storage配置虚拟化U盘四:遍历usb设备五:adb usb判断usb设备为adb获取adb配置信息adb设备序列号发送与接收《Linux…