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

GeoJSON 转换工具类

1.maven依赖

    <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.4.4</version></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>net.postgis</groupId><artifactId>postgis-jdbc-jtsparser</artifactId><version>2.5.1</version></dependency><!-- JTS 几何库 --><dependency><groupId>org.locationtech.jts</groupId><artifactId>jts-core</artifactId><version>1.20.0</version></dependency></<dependencies>

2.转换类

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.io.WKBReader;
import org.locationtech.jts.io.WKTReader;
import org.locationtech.jts.io.geojson.GeoJsonReader;
import org.locationtech.jts.io.geojson.GeoJsonWriter;/*** GeoJSON 转换工具类* 用于 GeoJSON 与 JTS Geometry 之间的转换* */
public class GeoJsonUtil {private static final GeoJsonReader geoJsonReader = new GeoJsonReader();private static final GeoJsonWriter geoJsonWriter = new GeoJsonWriter();private static final ObjectMapper objectMapper = new ObjectMapper();/*** GeoJSON 字符串转 Geometry* @param geoJson GeoJSON 字符串,例如:{"type":"Point","coordinates":[113.93,22.58]}* @return JTS Geometry 对象*/public static Geometry geoJsonToGeometry(String geoJson) {if (geoJson == null || geoJson.trim().isEmpty()) {return null;}try {return geoJsonReader.read(geoJson);} catch (Exception e) {throw new RuntimeException("Failed to parse GeoJSON: " + geoJson, e);}}/*** Geometry 转 GeoJSON 字符串* @param geometry JTS Geometry 对象* @return GeoJSON 字符串*/public static String geometryToGeoJson(Geometry geometry) {if (geometry == null) {return null;}try {return geoJsonWriter.write(geometry);} catch (Exception e) {throw new RuntimeException("Failed to write GeoJSON", e);}}/*** 验证是否是有效的 GeoJSON* @param geoJson GeoJSON 字符串* @return true-有效,false-无效*/public static boolean isValidGeoJson(String geoJson) {if (geoJson == null || geoJson.trim().isEmpty()) {return false;}try {JsonNode node = objectMapper.readTree(geoJson);return node.has("type") && node.has("coordinates");} catch (Exception e) {return false;}}/*** 数据库 Geometry 字段转 GeoJSON* 支持 WKT 和 EWKB(十六进制字符串)两种格式* * @param dbGeometry 数据库返回的 geometry 字段值(WKT 或 EWKB 十六进制字符串)* @return GeoJSON 字符串,如果转换失败返回 null*/public static String dbGeometryToGeoJson(String dbGeometry) {if (dbGeometry == null || dbGeometry.trim().isEmpty()) {return null;}try {String geomStr = dbGeometry.trim();Geometry geometry;// 判断是 WKB(十六进制)还是 WKT 格式if (geomStr.matches("^[0-9A-Fa-f]+$")) {// EWKB 格式(十六进制字符串)- PostgreSQL PostGIS 默认返回格式WKBReader wkbReader = new WKBReader();byte[] wkbBytes = WKBReader.hexToBytes(geomStr);geometry = wkbReader.read(wkbBytes);} else {// WKT 格式(文本格式)WKTReader wktReader = new WKTReader();geometry = wktReader.read(geomStr);}return geometryToGeoJson(geometry);} catch (Exception e) {throw new RuntimeException("Failed to convert database geometry to GeoJSON: " + e.getMessage(), e);}}public static void main(String[] args) {// 标准 GeoJSON - 一个简单的矩形PolygonString geoJson = "{\"type\":\"Polygon\",\"coordinates\":[[[116.0,23.0],[116.1,23.0],[116.1,23.1],[116.0,23.1],[116.0,23.0]]]}";String dbGeometry = "0103000020E610000001000000050000000000000000005E40CDCCCCCCCC1C3F0000000000005E400000000000005E40CDCCCCCCCC1C3F00000000000062400000000000005E40CDCCCCCCCC1C3F00000000000062400000000000005E40CDCCCCCCCC1C3F0000000000005E40";System.out.println("【GeoJSON -> Geometry】" + geoJsonToGeometry(geoJson));System.out.println("【GeoJSON -> Geometry -> GeoJSON】" + geometryToGeoJson(geoJsonToGeometry(geoJson)));System.out.println("【数据库Geometry -> GeoJSON】" + dbGeometryToGeoJson(dbGeometry));}
}

3.效果图

image

http://www.jsqmd.com/news/955714/

相关文章:

  • MonkeyCode的团队协作能力:为什么Cursor和Codex都没有?
  • 2026江苏单招长期班应用白皮书系统集训路径深度剖析
  • 慢动作生成失效全归因,从光流抖动到物理一致性崩塌——Sora 2底层时序引擎拆解
  • 超高频RFID读写实战:从硬件连接到EPC Gen2协议指令全解析
  • Transformers.js离线提取并分类网页内容:可行性与性能评测
  • 客户至上:诚誉财税用口碑铸就南沙财税服务第一品牌 - 资讯快报
  • 35岁,大专、计算机专业,折腾了8年!失业一年后,翻身上岸1.3w
  • 2026年百达翡丽中国大陆授权维修服务网络优化公告(最新电话及地址) - 资讯纵览
  • 抖音批量下载神器:3分钟掌握无水印视频批量保存技巧
  • MuleSoft企业级AI编排:LLM与集成平台的深度协同
  • 国产化替代实战指南:从理性评估到系统验证的工程实践
  • 渝中区手工牛油火锅专业测评|老鹰茶降燥正宗老火锅推荐 - 资讯纵览
  • 2025_NIPS_Efficient RL with Impaired Observability: Learning to Act with Delayed and Missing Stat...
  • 装修拆除改造工程与厂矿企业搬迁拆除服务商深度评析:专业实力与区域标杆的全面洞察 - 深度智识库
  • 降本增效管理咨询口碑机构推荐:2026年家居建材企业利润保卫指南 - 远大方略管理咨询
  • League Akari:英雄联盟玩家的本地化智能助手如何提升游戏体验?
  • Mermaid在线编辑器终极指南:用代码快速创建专业图表
  • 2026年楚雄短视频账号策划与企业AI营销完整指南 - 精选优质企业推荐官
  • 高速CAN与低速CAN总线特性、工程选型与实战开发全解析|全网独家复现底层驱动与故障容错逻辑、优化车载总线实时性与抗干扰能力、助力车载电控系统稳定通信与故障自愈有效涨点
  • 2026 重庆钻石回收推荐,合扬专业门店鉴定功底扎实 - 奢侈品交易观察员
  • Matlab实现的BP神经网络车牌字符识别系统:含预处理、训练与实测图像
  • 终极指南:如何用TomatoBar打造macOS最高效的番茄工作法体验 [特殊字符]
  • MATLAB一键运行的雷达+相机外参联合标定工具包(含实测截图与优化函数)
  • 内置天线选购指南:如何挑选优质的手机内置天线厂家 - 资讯速览
  • 2026年楚雄新媒体运营与本地获客完整方案 - 精选优质企业推荐官
  • 资深工程师私藏电子开发资源导航:从MCU到FPGA的实战工具箱
  • 书匠策AI官网www.shujiangce.com|我把期刊论文写作的“难度等级“从地狱调成了简单模式
  • 本地租房网站哪个好用?同城租房优选平台盘点 - 讲清楚了
  • Nacos 2.x 源码深度解析 (二):通信协议迭代 —— HTTP长轮询到gRPC演进
  • 沃尔玛礼品卡回收防坑指南:避雷这几种低价回收套路 - 京顺回收