当前位置: 首页 > news >正文

【MBtiles数据索引和服务发布】GeoServer改造Springboot番外系列二

xyz地图服务访问示例:http://192.168.1.240:8081/gmserver/raster/xyz/firstWP:Imagery-raster/{z}/{x}/{y}.jpg

访问示例如下:

mbtiles目录结构

根据z,x,y获取对应mbtiles文件路径的工具方法

说明:重点是使用getMbtilesPath方法,通过xyz获取mbtiles文件路径。

getTilesFile方法是通过图层(因为我做的项目是mbtiles数据集绑定在图层上)获取对应的mbtiles文件。

package com.gs.springboot.gmserver.util;import com.gs.springboot.gmserver.core.CommonConstants;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.StoreInfo;import java.io.File;
import java.io.Serializable;
import java.util.Collection;
import java.util.Map;/*** @Desc mbtiles工具类*/
public class MbtilesUtil {/*** 根据zxy索引mbtiles文件所在目录** @param z        层级* @param x        行* @param y        列* @param rootPath mbtiles根目录* @return java.lang.String*/public static String getMbtilesPath(int z, int x, int y, String rootPath) {int p = 0;//文件级别的列号int q = 0;//文件级别的行号int m = 0;//文件夹级别的列号int n = 0;//文件夹级别的行号if (z <= 8) {p = 0;q = 0;m = 0;n = 0;} else if (z >= 9) {double fileTotal = Math.pow(2, 2 * (z - 8));//文件总数double tileTotal = 65536 * fileTotal;//瓦片总数double maxTileNum = Math.sqrt(tileTotal);//行和列坐标轴方向的瓦片个数,行列相等double segmentNum = Math.sqrt(fileTotal);//行和列分的段数,即行和列坐标轴方向的mbtiles文件个数double tileNumOfEachMbtiles = maxTileNum / segmentNum;//单个mbtiles的最大行列的瓦片数,行列瓦片数相等p = (int) (x / tileNumOfEachMbtiles);q = (int) (y / tileNumOfEachMbtiles);if (z == 9 || z == 10) {m = 0;n = 0;} else {double dirTotal = fileTotal / 16;//文件夹总数double segmentDirNum = Math.sqrt(dirTotal);//行和列坐标轴方向的最大文件夹个数,行列相等double tileNumOfEachDir = segmentNum / segmentDirNum;//每段文件夹内的mbtiles的个数m = (int) (p / tileNumOfEachDir);n = (int) (q / tileNumOfEachDir);}}String mbtiles_file = rootPath + "/" + z + "/" + m + "_" + n + "/" + z + "_" + p + "_" + q + ".mbtiles";return mbtiles_file;}/*** 通过图层信息索引瓦片对应文件* @param layerInfo 图层* @param tilecol 列x* @param tilerow 行y* @param z 层级z* @param format 后缀* @return java.io.File*/public static File getTilesFile(LayerInfo layerInfo, int tilecol, int tilerow, Integer z, String format) {StoreInfo store = layerInfo.getResource().getStore();String type = store.getType();File file = null;Map<String, Serializable> connectionParameters = store.getConnectionParameters();for (String key : connectionParameters.keySet()) {if (key.contains("filePath")) {Serializable value = connectionParameters.get(key);String rootPath = (String) value;String tilesPath = null;if (type.equals(CommonConstants.DataStoreType.TilesFolderRaster.getValue())|| type.equals(CommonConstants.DataStoreType.TilesFolderVector.getValue())|| type.equals(CommonConstants.DataStoreType.TilesFolderDEM_terrain.getValue())) {tilesPath = rootPath + "/" + z + "/" + tilecol + "/" + tilerow + "." + format;} else if (type.equals(CommonConstants.DataStoreType.TilesFolderDEM_png.getValue())) {tilesPath = rootPath + "/" + z + "/" + tilecol + "/" + tilerow + ".png";}else if (type.equals(CommonConstants.DataStoreType.MbtilesFolderRaster.getValue())|| type.equals(CommonConstants.DataStoreType.MbtilesFolderVector.getValue())|| type.equals(CommonConstants.DataStoreType.MbtilesFolderDEM.getValue())) {tilesPath = getMbtilesPath(z, tilecol, tilerow, rootPath);}file = new File(tilesPath);if (file.exists() && file.length() > 0) {break;}}}return file;}}

发布mbtiles地图服务的接口。

说明:此处由于是项目的完整功能,所以代码是通过图层名称获取mbtiles的文件,你也可以将layer直接换成mbtiles数据集的根目录,或者直接写死根目录。通过xyz就可以访问瓦片。

package com.gs.springboot.gmserver.tiles;import cn.hutool.core.io.file.FileNameUtil;
import com.gs.springboot.gmserver.core.CommonConstants;
import com.gs.springboot.gmserver.util.MbtilesUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.IOUtils;
import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.StoreInfo;
import org.imintel.mbtiles4j.MBTilesReadException;
import org.imintel.mbtiles4j.MBTilesReader;
import org.imintel.mbtiles4j.Tile;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.concurrent.CompletableFuture;@RestController
@Api(tags = "栅格瓦片服务发布接口")
public class RasterTilesController {@Autowiredprivate Catalog catalog;@GetMapping("/raster/xyz/{layer}/{z}/{x}/{y}.{format}")@ApiOperation(value = "发布栅格Mbtiles文件夹数据XYZ服务")@ApiImplicitParams({@ApiImplicitParam(name = "layer", value = "图层名称", dataType = "String", paramType = "path"),@ApiImplicitParam(name = "z", value = "z坐标", dataType = "int", paramType = "path"),@ApiImplicitParam(name = "x", value = "x坐标", dataType = "int", paramType = "path"),@ApiImplicitParam(name = "y", value = "y坐标", dataType = "int", paramType = "path"),@ApiImplicitParam(name = "format", value = "格式", dataType = "String", paramType = "path")})public void publishXYZ(@PathVariable("layer") String layer,@PathVariable("z") int z,@PathVariable("x") int x,@PathVariable("y") int y,@PathVariable("format") String format,HttpServletResponse response) {LayerInfo layerInfo = catalog.getLayerByName(layer);StoreInfo store = layerInfo.getResource().getStore();if (store.getConnectionParameters().get("scheme") != null) {String scheme = (String) store.getConnectionParameters().get("scheme");if (!CommonConstants.DataStoreScheme.XYZ.getValue().equals(scheme)) {y = (1 << z) - y - 1;//此处是将xyz转tms}}extracted(layerInfo, z, x, y, format, response);}private void extracted(LayerInfo layerInfo, int z, int x, int y, String format, HttpServletResponse response) {File file = MbtilesUtil.getTilesFile(layerInfo, x, y, z, format);String prefix = FileNameUtil.getSuffix(file);// 异步执行任务,返回一个 CompletableFutureCompletableFuture<Void> future = CompletableFuture.runAsync(() -> {InputStream data = null;if ("mbtiles".equals(prefix)) {MBTilesReader r = null;Tile tile;try {r = new MBTilesReader(file);tile = r.getTile(z, x, y);} catch (MBTilesReadException e) {throw new RuntimeException(e);}data = tile.getData();} try {if ("png".equals(format) || "jpg".equals(format)) {response.setContentType("image/" + format);} else {response.setStatus(400);return;}ServletOutputStream oStream = response.getOutputStream();IOUtils.copy(data, oStream);oStream.flush();oStream.close();} catch (IOException e) {throw new RuntimeException(e);}});// 等待 CompletableFuture 完成future.join();}}

相关文章:

【MBtiles数据索引和服务发布】GeoServer改造Springboot番外系列二

xyz地图服务访问示例&#xff1a;http://192.168.1.240:8081/gmserver/raster/xyz/firstWP:Imagery-raster/{z}/{x}/{y}.jpg 访问示例如下&#xff1a; mbtiles目录结构 根据z&#xff0c;x&#xff0c;y获取对应mbtiles文件路径的工具方法 说明&#xff1a;重点是使用getMb…...

Redis抓取数据到Logstash再推到Elasticsearch集群

一、安装Logstash 前面安装过Logstash了,不做解释直接跳过 参考:上一篇文章 二、配置Logstash 在logstash目录下,编辑我们之前的配置文件logstash.conf vim logstash.confinput、output字面意思,从redis去拿取数据,输出到Elasticsearch data_type:数据类型为list k…...

【代码随想录-链表】反转链表

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老导航 檀越剑指大厂系列:全面总结 jav…...

32GPIO输入LED闪烁蜂鸣器

一.GPIO简介 所有的GPIO都挂载到APB2上&#xff0c;每个GPIO有&#xff11;&#xff16;个引脚 内核可以通过APB&#xff12;对寄存器进行读写&#xff0c;寄存器都是32位的&#xff0c;但每个引脚端口只有&#xff11;&#xff16;位 驱动器用于增加信号的驱动能力 二.具体…...

Qt|QPushButton控件讲解

前提 按钮分为了四种状态&#xff1a;常态、聚焦、按下、禁用 前一段时间更新了MFC框架下CButton的自绘。因为MFC框架下的按钮限制性很高&#xff0c;所以只能由自绘实现各种风格&#xff0c;但是QT框架完美的解决了这个问题&#xff0c;我们只需要了解如何调用&#xff0c;就…...

再学webpack

1 优化 webpack 打包体积的思路 优化 webpack 打包体积的思路包括&#xff1a; 提取第三方库或通过引用外部文件的方式引入第三方库&#xff1a;将第三方库单独打包&#xff0c;并通过 CDN 引入&#xff0c;减少打包体积。使用代码压缩插件&#xff1a;例如 UglifyJsPlugin&a…...

systemd:service与target使用及相关命令

文章目录 一、 unit1.1 unit常用命令 二、 service系统服务2.1 unit service配置文件2.1.1 [Unit]区块2.1.2 [Service]区块2.1.3 [Install]区块2.1.4 示例介绍 2.2 service常用命令 三、target3.1 tartget有关命令 四、其他系统命令4.1 systemctl 相关系统管理命令4.2 journalc…...

FairGuard游戏加固入选《CCSIP 2023中国网络安全行业全景册(第六版)》

2024年1月24日&#xff0c; FreeBuf咨询正式发布《CCSIP 2023中国网络安全行业全景册(第六版)》。本次发布的全景图&#xff0c;共计展示20个一级分类、108个细分安全领域&#xff0c;旨在为广大企业提供网络安全产品选型参考&#xff0c;帮助企业了解中国网络安全技术与市场的…...

文心一言 VS ChatGPT :谁是更好的选择?

前言 目前各种大模型、人工智能相关内容覆盖了朋友圈已经各种媒体平台&#xff0c;对于Ai目前来看只能说各有千秋。GPT的算法迭代是最先进的&#xff0c;但是它毕竟属于国外产品&#xff0c;有着网络限制、注册限制、会员费高昂等弊端&#xff0c;难以让国内用户享受。文心一言…...

七街八巷×实在RPA丨财务凭证录入零出错,效率提升8倍

在如今的数字化时代&#xff0c;企业财务面临着海量且复杂的数据流程。特别是在凭证录入这一看似简单却又频繁的环节中&#xff0c;传统的手工操作已无法满足日益增长的业务需求。 中国轻食知名品牌七街八巷&#xff0c;通过部署实在智能集“自动化平台开箱即用解决方案咨询”…...

线性代数----------学习记录

线性代数发展历程 &#xff08;1&#xff09;线性方程组&#xff1a;例如二元一次方程组&#xff1b; &#xff08;2&#xff09;行列式&#xff1a;determinant,克莱默&#xff0c;莱布尼兹&#xff1b; &#xff08;3&#xff09;矩阵&#xff1a;方程个数与未知数的个数可…...

Ubuntu如何安装使用Nginx反向代理?

在Ubuntu上安装Nginx并配置使其生效是相对简单的过程。以下是一步一步的指南&#xff1a; 步骤 1&#xff1a;安装 Nginx 打开终端&#xff0c;并执行以下命令来安装 Nginx&#xff1a; sudo apt update sudo apt install nginx步骤 2&#xff1a;启动 Nginx 服务 安装完成…...

Linux系统——正则表达式

有一段时间本机访问量过高&#xff0c;如何查看日志提取出访问量前十的信息 1.使用提取命令&#xff08;cut、awk、sed&#xff09;提取出ip地址的那一列 2.使用sort按数字排序&#xff0c;将相同的地址整合到一起 3.使用uniq -c统计出数量 4.使用sort 数字 数字倒序排序 5.最…...

【文本到上下文 #9】NLP中的BERT和迁移学习

​ ​ 一、说明 ​BERT&#xff1a;适合所有人的架构概述&#xff1a;我们将分解 BERT 的核心组件&#xff0c;解释该模型如何改变机器理解人类语言的方式&#xff0c;以及为什么它比以前的模型有重大进步。    ​BERT的变体&#xff1a; 在BERT取得成功之后&#xff0c;已…...

github单文件下载——DownGit

记录一下一个好用的网站&#xff0c;支持github中某一特定文件夹下文件的下载 选择一个合适的梯子&#xff0c;访问Downgit网址 https://minhaskamal.github.io/DownGit/#/home 将所需网站连接粘贴到这里&#xff0c;点击download即可...

Java之Stream的应用与原理分析

前言 stream是怎么做到一次迭代中将所有流操作进行叠加&#xff1f;stream怎么做到只有在终止操作时进行元素遍历&#xff1f;那中间操作是做了些什么&#xff1f; Stream 与集合的区别 集合是内存中的数据结构抽象&#xff0c;描述了数据在内存中是如何存储的。流描述了对数据…...

Git 实战场景过程(工作总结篇)

目录 前言1. Git远程仓库建立分支&#xff0c;本地未显示1.1 问题所示1.2 知识补充 2. Git暂存内容切换分支2.1 问题所示2.2 知识补充 3. Git放弃修改数据3.1 问题所示3.2 知识补充 前言 主要总结工作中的疑惑点&#xff0c;如果你也有相应的场景&#xff0c;可以评论区见&…...

iperf3 打流工具的使用介绍

目录 1. iperf3简介 2. 详细命令参数 1. iperf3简介 iPerf3是用于主动测试IP网络上最大可用带宽的工具。它支持时序、缓冲区、协议&#xff08;TCP&#xff0c;UDP&#xff0c;SCTP与IPv4和IPv6&#xff09;有关的各种参数。对于每次测试&#xff0c;它都会详细的带宽报告&a…...

网络异常案例一_RST

本文以及后面几篇会整理输出下以前处理过的一些网络相关的异常 4G定向卡上网问题 问题现象&#xff0c;自研路由器&#xff0c;使用运营商定向的4G卡上网&#xff0c;访问服务器异常&#xff0c;相应的开发同学反馈被服务器拒绝了&#xff1b; 复现问题&#xff0c;同步在cli…...

提升工作效率,畅享便捷PDF编辑体验——Adobe Acrobat Pro DC 2023

作为全球领先的PDF编辑软件&#xff0c;Adobe Acrobat Pro DC 2023将为您带来前所未有的PDF编辑体验。无论您是个人用户还是企业用户&#xff0c;Adobe Acrobat Pro DC 2023将成为您提高工作效率、简化工作流程的得力助手。 一、全面编辑功能 Adobe Acrobat Pro DC 2023提供了…...

Python调用WebAssembly破解APP签名算法实战

1. 这不是“调用JS”&#xff0c;而是把WebAssembly当真实CPU来调试你有没有遇到过这样的情况&#xff1a;抓包看到某资讯APP的请求里&#xff0c;sign参数像雪花一样每秒变一个&#xff0c;长度固定32位&#xff0c;全是小写字母加数字&#xff1b;Fiddler里点开响应&#xff…...

Unity Find Reference2 2.5.2版本深度解析与正确接入指南

1. 这不是普通插件下载&#xff1a;Find Reference2 的真实价值与误用重灾区“Unity Find Reference2 2.5.2版本资源下载”——看到这个标题&#xff0c;很多Unity开发者第一反应是点开就找网盘链接、GitHub Release页面或某论坛的打包附件。我试过不下二十次&#xff1a;复制标…...

如何高效使用智能手机号码定位工具:开源解决方案全指南

如何高效使用智能手机号码定位工具&#xff1a;开源解决方案全指南 【免费下载链接】location-to-phone-number This a project to search a location of a specified phone number, and locate the map to the phone number location. 项目地址: https://gitcode.com/gh_mir…...

Gazebo Sim物理引擎对比:Bullet、ODE与DART性能优化指南

Gazebo Sim物理引擎对比&#xff1a;Bullet、ODE与DART性能优化指南 【免费下载链接】gz-sim Open source robotics simulator. The latest version of Gazebo. 项目地址: https://gitcode.com/gh_mirrors/gz/gz-sim Gazebo Sim作为开源机器人仿真的终极工具&#xff0c…...

Wand-Enhancer终极指南:免费解锁WeMod专业版的完整教程

Wand-Enhancer终极指南&#xff1a;免费解锁WeMod专业版的完整教程 【免费下载链接】Wand-Enhancer Advanced UX and interoperability extension for Wand (WeMod) app 项目地址: https://gitcode.com/gh_mirrors/we/Wand-Enhancer 还在为WeMod专业版的高昂订阅费用而烦…...

在Ubuntu 20.04上从源码编译Spconv 1.2.1:一份给点云感知开发者的避坑指南

在Ubuntu 20.04上从源码编译Spconv 1.2.1&#xff1a;一份给点云感知开发者的避坑指南 对于从事3D点云感知研究的开发者来说&#xff0c;Spconv库的安装往往是搭建开发环境时遇到的第一个"拦路虎"。这个专为稀疏卷积优化的库&#xff0c;虽然在性能上表现出色&#…...

碧蓝航线Alas自动化脚本:解放双手的终极游戏助手

碧蓝航线Alas自动化脚本&#xff1a;解放双手的终极游戏助手 【免费下载链接】AzurLaneAutoScript Azur Lane bot (CN/EN/JP/TW) 碧蓝航线脚本 | 无缝委托科研&#xff0c;全自动大世界 项目地址: https://gitcode.com/gh_mirrors/az/AzurLaneAutoScript 你是否厌倦了每…...

JMeter实战:从接口测试到性能基线的全链路压测指南

1. 这不是“点点点就能跑通”的测试&#xff0c;而是用JMeter撬动系统稳定性的杠杆很多人第一次打开JMeter&#xff0c;以为它就是个“高级版Postman”&#xff1a;填URL、选方法、点执行&#xff0c;看到Response里有JSON就松一口气——“接口通了&#xff0c;测试完了”。我带…...

3步解决洛雪音乐播放问题:六音音源修复完整指南

3步解决洛雪音乐播放问题&#xff1a;六音音源修复完整指南 【免费下载链接】New_lxmusic_source 六音音源修复版 项目地址: https://gitcode.com/gh_mirrors/ne/New_lxmusic_source 你是否遇到过洛雪音乐升级后无法播放歌曲的困扰&#xff1f;点击播放按钮只有加载动画…...

深度强化学习在自动驾驶赛车中的迁移优化实践

1. 项目概述&#xff1a;深度强化学习在自动驾驶赛车中的迁移优化在自动驾驶赛车领域&#xff0c;如何将仿真环境中训练的控制策略无缝迁移到真实车辆上一直是个棘手问题。传统方法通常面临两大挑战&#xff1a;仿真环境与真实物理世界之间的动力学差异&#xff08;即所谓的&qu…...