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,一经查实,立即删除!

相关文章

关于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 服务…

使用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…

[数据集][目标检测]焊接处缺陷检测数据集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[]…

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

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

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

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

【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]) …

【显示方案IC-速显微】

最近偶然间接触到“速显微”的显示方案&#xff0c;个人体验了一把感觉还是挺顺手的&#xff0c;虽然手里没有板子没有上手测试一番。 这是他们的官网链接&#xff1a; https://www.thorsianway.com/product/chip 从官网可以看到有两颗个系列的IC已经量产&#xff1a;GC9005和G…

Docker部署pulsar独立集群消息队列服务器

1、下载Pulsar docker 镜像 docker pull apachepulsar/pulsar:latest 2、生成Pulsar容器&#xff0c;把容器的6650和8080端口映射到宿主机的6650和8080端口&#xff0c;standalone参数表示pulsar为独立集群模式&#xff0c;把容器中的conf目录映射到宿主机的/var/lib/docker/…

【QEMU中文文档】1.1 支持的构建平台

本文由 AI 翻译&#xff08;ChatGPT-4&#xff09;完成&#xff0c;并由作者进行人工校对。如有任何问题或建议&#xff0c;欢迎联系我。联系方式&#xff1a;jelin-shoutlook.com。 原文&#xff1a;Supported build platforms — QEMU documentation QEMU 旨在支持在多个主机…

基础—SQL—DCL(数据控制语言)小结

一、总结 在SQL分类中的DCL语句部分&#xff0c;主要讲到了两个部分的知识。 1、用户管理 用户管理&#xff0c;主要是管理哪些用户可以访问当前 mysql 数据库。 包括&#xff1a;创建用户、修改用户密码以及删除用户 2、权限控制 权限管理&#xff0c;主要是控制我们当前用户…

vue前端Echars

<template><div :class"className" :style"{height:height,width:width}" /> </template><script> import * as echarts from echarts require(echarts/theme/macarons) // echarts theme 柱状图 import resize from ./mixins/re…

禁用USB端口的办法,哪一种禁用USB端口的方法好

禁用USB端口的办法&#xff0c;哪一种禁用USB端口的方法好 禁用USB端口是保护公司数据安全的一种常见做法&#xff0c;旨在防止未经授权的数据传输和潜在的恶意软件传播。以下是几种常见的禁用USB端口方法及其效果评价。 1、硬件方法&#xff1a; BIOS设置&#xff1a;通过BIO…

混合动力电动汽车介绍(一)

电动汽车发展的技术背景主要包含环境问题和能源问题两大方面。环境问题的表现形式为空气污染&#xff0c;而能源问题的表现形式为现有能源供应体系对化石燃料的过分依赖。《新能源汽车产业发展规划&#xff08;2021-2035&#xff09;》中明确我国新能源汽车技术研发的“三纵”、…

软件架构设计属性之5:可维护性属性分析与应用

文章目录 引言一、可维护性定义和重要性1.1 定义1.2 重要性 二、可维护性关键要素2.1 模块化2.2 单一职责2.3 低耦合2.4 高内聚2.5 抽象和封装2.6 实践建议 三、设计原则3.1 开闭原则3.2 依赖倒置原则3.3 评估方法3.4 挑战与解决方案 四、实战应用总结 引言 在当今数字化飞速发…