GIS Java 生成四至图

目录

前言

操作步骤:

1,求出多边形的四至点

2,下载地图

3,绘制多边形


前言

对于地图上的一个多边形地块,其四至图就是能够覆盖这个多边形的最小矩形,也就是求出这个多边形的最东点,最西点,最南点,最北点,即四至点,其中最西点和最北点构成左上角,最南点和最东点构成右下点,只要知道了左上角和右下角,就知道这个最小覆盖矩形了。

前端生成四至图是比较简单的,后端如何生成四至图呢?后端生成四至图得到的是一个图片,图片的底图是天地图,在这个底图之上就是多边形。多边形的坐标长这样:"[[31.21729,121.583274],[31.217096,121.58378],[31.216985,121.583457],[31.21729,121.583274]]",它是4326的坐标系,第一个坐标和最后一个坐标是同一个,首尾相连,下图就是它的四至图。

操作步骤:

1,求出多边形的四至点

        即多边形的最东点,最西点,最南点,最北点,然后我们就知道四至图的左上点和右下点这两个点的地理坐标,根据这两个点求出它们各自在天地图的瓦片位置 (x,y) 。

/*** 计算瓦片行列号* @param latitude  纬度* @param longitude 经度* @param zoom      缩放级别* @return 瓦片行列号数组,格式为 [col, row]*/
public static int[] calculateTileXY(double latitude, double longitude, int zoom) {double n = Math.pow(2, zoom);double mercX = (longitude + 180) / 360;double mercY = (1 - Math.log(Math.tan(Math.toRadians(latitude)) + 1 / Math.cos(Math.toRadians(latitude))) / Math.PI) / 2;int tileX = (int) Math.floor(mercX * n);int tileY = (int) Math.floor(mercY * n);return new int[]{tileX, tileY};
}

2,下载地图

        下载从左上点到右下点的所有小瓦片图片,并把这些小瓦片地图图片合并为一张完整的大地图图片,这些小瓦片地图的名称依次命名为 1.png,2.png....。下载次序是从左上角开始从左到右,从上到下依次生成图片。记得下载的时候需要有天地图的秘钥 tk 。

int k = 1;
// 从左上角开始从左到右,从上到下依次生成图片,图片序号依次递增
for (int j = leftUp[1]; j <= rightDown[1]; j++) {for (int i = leftUp[0]; i <= rightDown[0]; i++) {System.out.println("/" + j + "/" + i);HttpOkUtil.downloadImg("http://t0.tianditu.gov.cn/img_w/wmts?SERVICE=WMTS&REQUEST=GetTile" +"&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX=" + zoom +"&TILEROW=" + j + "&TILECOL=" + i + "&tk=xx", pathParent + k + ".png");k++;}
}

 下载得到的小瓦片大概长这样

 

 融合地图代码:

    /*** 合并瓦片图片** @param tiles           包含所有瓦片及其行列信息的列表* @param outputImagePath 输出合并后地图的文件路径* @throws IOException 如果图像文件读取失败或写入失败*/public static void mergeTiles(List<BufferedImage> tiles, String outputImagePath, int widthCnt, int heightCnt) throws IOException {// 假设所有瓦片都是正方形,获取瓦片的宽度和高度int tileWidth = tiles.get(0).getWidth();int tileHeight = tiles.get(0).getHeight();// 计算合并后图像的尺寸int width = tileWidth * widthCnt;// (int) Math.ceil(Math.sqrt(tiles.size())) * tileWidth;int height = tileHeight * heightCnt;// (int) Math.ceil(Math.sqrt(tiles.size())) * tileHeight;// width; //// 假设合并后的地图是正方形// 创建一个新的图像,用于合并后的地图BufferedImage mergedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);// 使用Graphics2D来绘制图像Graphics2D g2d = mergedImage.createGraphics();// 绘制瓦片到新图像上int x = 0;int y = 0;for (BufferedImage tile : tiles) {g2d.drawImage(tile, x, y, null);x += tileWidth;if (x >= width) {x = 0;y += tileHeight;}}// 释放Graphics2D资源g2d.dispose();// 将合并后的图像写入文件ImageIO.write(mergedImage, "PNG", new File(outputImagePath));}

3,绘制多边形

        在这张融合好的大地图图片上绘制多边形和四至矩形图,因为大地图图片和小瓦片是 png 格式,没有地图坐标,所有要把 path 中的点相对于其在瓦片中的位置按比例进行计算。因为每个小瓦片都是 256*256 的像素格式,所以大地图就是 (256*width,256*height) ,以大地图的左上点为相对起始点开始绘画,可以精确到像素级。

// boundingBox 就是四至图,有左上,右下两个点,也就是西北点,东南点,即west,east,north,south这四个属性
for (GeoPoint point : list) {int[] pointXy = FourBoundariesGraphUtil.calculateTileXY(point.getY(), point.getX(), zoom);FourBoundariesGraphUtil.BoundingBox tmp = FourBoundariesGraphUtil.tile2boundingBox(pointXy[0], pointXy[1], zoom);res.add((pointXy[0] - originX) * 256 + (int) ((point.getX() - tmp.west) / (tmp.east - tmp.west) * 256));res.add((pointXy[1] - originY) * 256 + (int) ((tmp.north - point.getY()) / (tmp.north - tmp.south) * 256));
}public static class BoundingBox {double north;double south;double east;double west;public double[] get_tianditu_info() {return new double[]{west, north, east, south};}}public static BoundingBox tile2boundingBox(final int x, final int y, final int zoom) {BoundingBox bb = new BoundingBox();bb.north = tile2lat(y, zoom);bb.south = tile2lat(y + 1, zoom);bb.west = tile2lon(x, zoom);bb.east = tile2lon(x + 1, zoom);return bb;}public static double tile2lon(int x, int z) {return x / Math.pow(2.0, z) * 360.0 - 180;}public static double tile2lat(int y, int z) {double n = Math.PI - (2.0 * Math.PI * y) / Math.pow(2.0, z);return Math.toDegrees(Math.atan(Math.sinh(n)));}
/*** 计算瓦片行列号* @param latitude  纬度* @param longitude 经度* @param zoom      缩放级别* @return 瓦片行列号数组,格式为 [col, row]*/
public static int[] calculateTileXY(double latitude, double longitude, int zoom) {double n = Math.pow(2, zoom);double mercX = (longitude + 180) / 360;double mercY = (1 - Math.log(Math.tan(Math.toRadians(latitude)) + 1 / Math.cos(Math.toRadians(latitude))) / Math.PI) / 2;int tileX = (int) Math.floor(mercX * n);int tileY = (int) Math.floor(mercY * n);return new int[]{tileX, tileY};
}

把得到的坐标点绘制到图片,这个需要使用 Java Image 的 api,百度一下就知道了。如果需要在大地图图片里写其他的信息但发现大地图图片生成得有些小了,那就在下载瓦片的地方减小左上角或增大右下角的位置,多留一点空间,如果有其他的要求,也可以对生成好的地图图片进行裁剪。下载的地图可以是任意级别经度,只要天地图支持,默认是18级最大精度。

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

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

相关文章

Java方法存档。组件容器

setIcon(new ImageIcon("banana.jpg")); javax.swing.ImageIcon.ImageIcon&#xff08;字符串文件名&#xff09; ConstructorProperties&#xff08;value{“描述”}&#xff09; 从指定的文件创建 ImageIcon。将使用 MediaTracker 预加载图像以监控图像的加载状…

关于GPT-4o的使用感受和评价

如何评价GPT-4o? 简介&#xff1a; 最近&#xff0c;GPT-4o横空出世。GPT-4o的发布无疑是人工智能领域的一次重大飞跃&#xff0c;它不仅仅是一个技术产品的迭代&#xff0c;更是人机交互理念的一次革新。作为OpenAI倾力打造的最新旗舰模型&#xff0c;GPT-4o在前代产品的基础…

Vue.js2+Cesium1.103.0 十六、多模型轨迹运动

Vue.js2Cesium1.103.0 十六、多模型轨迹运动 Demo <template><div id"cesium-container" style"width: 100%; height: 100%;"><ul class"ul"><li v-for"(item, index) of deviceInfo" :key"index" cl…

制作ChatPDF之前端Vue搭建(二)

前端界面 接上篇: 制作ChatPDF之Elasticsearch8.13.4搭建&#xff08;一&#xff09; 为了实现一个基于 Vue.js 的前端应用&#xff0c;用户可以上传 PDF 文件&#xff0c;输入查询&#xff0c;并在输出框中显示查询结果&#xff0c;你需要以下步骤&#xff1a; 初始化 Vue …

AIGC商业案例实操课,发觉其创造和商业的无限可能,Ai技术在行业应用新的商机

课程下载&#xff1a;https://download.csdn.net/download/m0_66047725/89307523 更多资源下载&#xff1a;关注我。 课程内容 1 AI为什么火 。写在课程前面的寄语 。AIGC标志性事件:太空歌剧院 。AI人工智能为什么这么火 &#xff0c;AI人工智能发展历程 。聊天AI会取…

【U-Boot 源码深度解析】001 - Ubuntu 24.04 虚拟机 及 基础环境搭建

【U-Boot 源码深度解析】001 - Ubuntu 24.04 虚拟机 及 基础环境搭建 一、VMware 、Ubuntu 安装包下载二、解决VMware NET 模式&#xff0c;虚拟机无法上网问题三、配置 Ubuntu 24.04 开发环境3.1 配置清华源 sources3.2 配置 Telnetd 服务3.3 配置 SSH 服务2.4 配置 samba 服务…

React框架的快速入门

React框架的快速入门可以按照以下步骤进行&#xff0c;同时结合参考文章中的相关数字和信息&#xff0c;我将为你提供一个清晰的入门指南&#xff1a; 一、了解React React是一个流行的JavaScript库&#xff0c;专注于构建用户界面。它的主要特点包括&#xff1a; 组件化架构…

什么是gRPC?

gRPC&#xff08;gRPC Remote Procedure Call&#xff09;是一个高性能、开源、通用的远程过程调用&#xff08;RPC&#xff09;框架&#xff0c;最初由 Google 开发。gRPC 使用 HTTP/2 作为传输协议&#xff0c;并采用 Protocol Buffers&#xff08;protobuf&#xff09;作为接…

使用autodl服务器进行模型训练

1.注册并且选择一个服务器租用 2.点击jupyter lab进入服务器内部 3.把yolov5-master这个的压缩文件上传到jupyter的文件列表中 4.打开终端 (1)查看目录 ls (2)解压yolov5-master(1) unzip "yolov5-master (1).zip" 可以看到解压成功&#xff01; (3)进入yolov5-m…

【Ubuntu上安装mvn】

Installing Maven on Linux/Ubuntu 在 Linux 系统中安装 Maven。 Step 1: Download the Maven Binaries 下载解压 $ wget <https://mirrors.estointernet.in/apache/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz> $ tar -xvf apache-maven-3.6.3-bin…

ARM-V9 RME(Realm Management Extension)系统架构之系统安全能力的系统隔离属性

安全之安全(security)博客目录导读 目录 一、系统隔离属性 1、系统配置完整性 1.1、时间隔离 2、关键错误的报告 一、系统隔离属性 1、系统配置完整性 MSD必须确保任何可能危及其安全保证的系统寄存器的正确性和完整性。例如&#xff0c;MSD必须确认内存控制器配置是一致…

[数据集][目标检测]焊接处缺陷检测数据集VOC+YOLO格式3400张8类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;3400 标注数量(xml文件个数)&#xff1a;3400 标注数量(txt文件个数)&#xff1a;3400 标注…

基于Chan-Vese算法的图像边缘提取matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ............................................................ % 迭代更新水平集函数 err[]…

PLC编程与IT编程的区别:深入探索两者之间的奥秘

PLC编程与IT编程的区别&#xff1a;深入探索两者之间的奥秘 在科技日新月异的今天&#xff0c;编程已成为各个领域中不可或缺的技能。然而&#xff0c;在众多的编程领域中&#xff0c;PLC编程和IT编程因其各自独特的特点和应用领域而备受关注。那么&#xff0c;PLC编程和IT编程…

【Linux】GNU编译器基础

文章目录 GCCMakefile、make GCC 常见的GNU编译器是GCC其包含gcc以及g等&#xff0c;适用于C/C中&#xff0c;在Windows系统中通常使用IDE进行程序的编写和编译、链接等操作&#xff0c;但在Linux系统中通常使用GNU编译器来进行&#xff0c;对于C/C等高级语言需要进行预编译、编…

亚马逊对IP的要求是什么?

IP的全称为Internet Protocol&#xff0c;是TCP/IP体系中的网际层协议&#xff0c;IP只为主机提供一种无连接、不可靠的、尽力而为的数据包传输服务。IP规定网络上所有的设备都必须有一个独一无二的IP地址&#xff0c;就好比是邮件上都必须注明收件人地址&#xff0c;邮递员才能…

函数递归输出1~100的数字及递归的栈溢出问题

什么是递归&#xff1f; 递归就是函数⾃⼰调⽤⾃⼰递归中的递就是递推的意思&#xff0c;归就是回归的意思如果递归就像循环一样&#xff0c;打一个大的复杂问题转化一个小的问题&#xff0c;但是要与原问题相似&#xff0c;分解成规模较⼩的⼦问题来求解&#xff1b;直到⼦问…

Spark SQL数据源 - 基本操作

Spark SQL 提供了丰富的API来与各种数据源进行交互&#xff0c;包括Parquet、JSON、CSV、JDBC等。以下是一些使用Spark SQL与数据源进行基本操作的基本步骤和示例代码。 1. 初始化SparkSession 首先&#xff0c;你需要初始化一个SparkSession对象&#xff0c;这是Spark SQL的…

【scau大数据技术与原理2】综合性实验Spark集群的安装和使用——安装启动spark shell篇

实验内容简介&#xff1a; Spark是一个分布式计算框架&#xff0c;常用于大数据处理。本次实验中&#xff0c;首先设计一个包含主节点和从节点的Spark集群架构&#xff0c;并在CentOS的Linux环境下进行搭建。通过下载并解压Spark安装包&#xff0c;配置环境变量和集群参数&…

【Python Cookbook】S1E09 对切片命名

目录 问题解决方案讨论 问题 代码的可阅读性非常重要&#xff0c;如何增强切片中的可阅读性&#xff1f;本文将提供一种方案。 解决方案 假设有一些代码用来从字符串的固定位置取出具体的数据&#xff1a; record "...100...513.25..." cost int(record[3:6]) …