純Java環(huán)境下實(shí)現(xiàn)將在線地圖路網(wǎng)數(shù)據(jù)轉(zhuǎn)為GeoJSON與WKT
前言
隨著GIS(地理信息系統(tǒng))技術(shù)在智慧城市、路徑規(guī)劃、交通調(diào)度等領(lǐng)域的深度滲透,在線地圖路網(wǎng)數(shù)據(jù)的高效獲取與格式適配已成為后端開(kāi)發(fā)的核心需求之一。百度、高德等主流在線地圖開(kāi)放平臺(tái),通過(guò)RESTful API等方式提供了豐富的路網(wǎng)數(shù)據(jù),但返回的原生數(shù)據(jù)格式多為平臺(tái)自定義JSON,難以直接適配PostGIS空間數(shù)據(jù)庫(kù)存儲(chǔ)、QGIS可視化分析等主流GIS工具的使用需求。GeoJSON作為輕量級(jí)地理空間數(shù)據(jù)交換標(biāo)準(zhǔn),憑借簡(jiǎn)潔的結(jié)構(gòu)和良好的跨平臺(tái)兼容性,成為前端可視化與數(shù)據(jù)傳輸?shù)氖走x格式;而WKT(Well-Known Text)作為OGC規(guī)范定義的空間數(shù)據(jù)文本表示方式,在空間查詢、數(shù)據(jù)庫(kù)存儲(chǔ)中具備不可替代的優(yōu)勢(shì),二者的格式轉(zhuǎn)換是打通在線地圖數(shù)據(jù)與GIS生態(tài)的關(guān)鍵環(huán)節(jié)。

當(dāng)前雖存在各類格式轉(zhuǎn)換工具,但多依賴第三方GIS組件或混合開(kāi)發(fā)環(huán)境,存在耦合度高、可移植性差、難以嵌入Java后端服務(wù)等問(wèn)題。純Java環(huán)境下的轉(zhuǎn)換方案雖有零散實(shí)踐,但缺乏完整的技術(shù)鏈路支撐——從主流在線地圖API的路網(wǎng)數(shù)據(jù)抓取、清洗,到標(biāo)準(zhǔn)化的GeoJSON與WKT雙向轉(zhuǎn)換,再到轉(zhuǎn)換成果的可視化驗(yàn)證,尚未形成一套可復(fù)用、高可靠的實(shí)現(xiàn)方案。同時(shí),百度與高德地圖的路網(wǎng)數(shù)據(jù)結(jié)構(gòu)存在差異,如何統(tǒng)一解析不同平臺(tái)的返回?cái)?shù)據(jù)、規(guī)避坐標(biāo)偏移問(wèn)題,以及基于JTS等工具包實(shí)現(xiàn)高效轉(zhuǎn)換,成為開(kāi)發(fā)者面臨的核心痛點(diǎn)。
基于此,本文聚焦純Java開(kāi)發(fā)環(huán)境,搭建從在線地圖路網(wǎng)數(shù)據(jù)獲取到格式轉(zhuǎn)換、成果展示的全流程實(shí)現(xiàn)方案。全文將按照“數(shù)據(jù)獲取-轉(zhuǎn)換實(shí)現(xiàn)-成果驗(yàn)證-總結(jié)展望”的邏輯展開(kāi),先介紹百度、高德地圖路網(wǎng)查詢API的調(diào)用方式與數(shù)據(jù)解析技巧,再詳細(xì)闡述Java環(huán)境下的技術(shù)路線設(shè)計(jì),以及基于JTS工具包與JSON解析庫(kù)實(shí)現(xiàn)路網(wǎng)數(shù)據(jù)至WKT、GeoJSON格式的轉(zhuǎn)換細(xì)節(jié),隨后通過(guò)QGIS工具完成轉(zhuǎn)換成果的可視化展示與底圖疊加驗(yàn)證,最終總結(jié)方案的優(yōu)勢(shì)與可優(yōu)化方向,為Java開(kāi)發(fā)者提供一套高效、可復(fù)用的在線地圖路網(wǎng)數(shù)據(jù)格式轉(zhuǎn)換實(shí)踐參考,助力打通在線地圖與GIS生態(tài)的數(shù)據(jù)壁壘。
一、在線地圖道路查詢
本節(jié)將簡(jiǎn)單介紹如何使用百度地圖和高德地圖這兩個(gè)在線地圖平臺(tái)來(lái)進(jìn)行道路名稱的檢索。通過(guò)介紹具體檢索和路線信息的獲取,讓大家了解如何手工獲取這些數(shù)據(jù)。
1. 百度路網(wǎng)查詢
我們可以在百度地圖的首頁(yè)的搜索框中實(shí)現(xiàn)對(duì)道路名稱的檢索,如下圖:

調(diào)用成功后,返回JSON格式數(shù)據(jù),包含單條道路的完整信息,坐標(biāo)數(shù)據(jù)采用百度墨卡托坐標(biāo)系(BD-09),需注意后續(xù)轉(zhuǎn)換時(shí)的坐標(biāo)適配。可以打開(kāi)調(diào)試面板來(lái)查看請(qǐng)求參數(shù),如下所示:

可以看出在載荷信息中,對(duì)請(qǐng)求的數(shù)據(jù)進(jìn)行了加密。這里暫時(shí)先不用管,接下來(lái)看看具體的道路信息。點(diǎn)擊左邊搜索結(jié)果中的道路名稱,前端發(fā)送接口,得到一下信息:

以上通過(guò)官網(wǎng)搜索可以獲取的道路信息。只是需要注意的是,這里返回的坐標(biāo)是百度的坐標(biāo),不是經(jīng)緯度的坐標(biāo),在實(shí)際進(jìn)行處理時(shí)需要進(jìn)行轉(zhuǎn)換。關(guān)于如何轉(zhuǎn)換,可以翻閱之前的博客進(jìn)行了解。
2. 高德路網(wǎng)查詢
同樣的,下面來(lái)看看高德是如何進(jìn)行操作的。

與百度地圖不同的是,高德的請(qǐng)求載荷沒(méi)有加密,可以看到很直觀的請(qǐng)求,請(qǐng)求數(shù)據(jù)如下:

來(lái)看看點(diǎn)擊詳情獲取什么數(shù)據(jù),

同樣注意,這里的數(shù)據(jù)雖然是經(jīng)緯度的形式,但是是增加了偏移的,如需轉(zhuǎn)換,可以搜索相關(guān)資源。
二、Java實(shí)現(xiàn)路網(wǎng)轉(zhuǎn)換
本節(jié)將介紹如何純Java實(shí)現(xiàn)將路網(wǎng)數(shù)據(jù)轉(zhuǎn)換成GeoJSON和WKT數(shù)據(jù)。為方便講解,這里使用的數(shù)據(jù)是高德的數(shù)據(jù),百度的數(shù)據(jù)也是可以轉(zhuǎn)換的,需要處理后就可以,這里暫時(shí)不做講解。
1. 技術(shù)路線
本文采用純Java環(huán)境實(shí)現(xiàn)路網(wǎng)數(shù)據(jù)格式轉(zhuǎn)換。整體技術(shù)路線分為4個(gè)步驟:第一步,通過(guò)調(diào)用高德路網(wǎng)頁(yè)面,獲取原生JSON數(shù)據(jù);第二步,通過(guò)解析JSON,提取道路名稱、坐標(biāo)串等信息,轉(zhuǎn)換為標(biāo)準(zhǔn)化Java實(shí)體類,并完成GCJ-02坐標(biāo)系到WGS84坐標(biāo)系的轉(zhuǎn)換(可選);第三步,將標(biāo)準(zhǔn)化實(shí)體類轉(zhuǎn)換為WKT格式;第四步,將實(shí)體類轉(zhuǎn)換為GeoJSON格式,完成整個(gè)轉(zhuǎn)換流程。該技術(shù)路線無(wú)需依賴任何第三方GIS軟件或混合開(kāi)發(fā)環(huán)境,可直接嵌入Java后端服務(wù),具備高可移植性、低耦合度的優(yōu)勢(shì)。
首先需要封裝一個(gè)Point點(diǎn)對(duì)象,用于接收每個(gè)坐標(biāo)點(diǎn)信息,關(guān)鍵代碼如下:
public static class Point {
public double longitude;
public double latitude;
public Point(double longitude, double latitude) {
this.longitude = longitude;
this.latitude = latitude;
}
@Override
public String toString() {
return String.format("Point(%.6f, %.6f)", longitude, latitude);
}
}然后將通過(guò)解析返回的JSON中的道路信息,獲取道路信息坐標(biāo)點(diǎn),并將其轉(zhuǎn)換為L(zhǎng)ist集合,核心代碼如下:
/**
* 將高德路線shape字符串轉(zhuǎn)換為Point列表
* @param shapeStr 高德路線shape字符串(分號(hào)分隔的經(jīng)緯度對(duì))
* @return Point列表
*/
public static List<Point> parseShapeToPoints(String shapeStr) {
List<Point> points = new ArrayList<>();
// 按分號(hào)分割獲取所有坐標(biāo)對(duì)
String[] coordPairs = shapeStr.split(";");
for (String coordPair : coordPairs) {
// 處理可能的分隔符(可能是豎線或分號(hào))
if (coordPair.contains("|")) {
String[] subPairs = coordPair.split("\\|");
for (String subPair : subPairs) {
Point point = parseSingleCoordinate(subPair);
if (point != null) {
points.add(point);
}
}
} else {
Point point = parseSingleCoordinate(coordPair);
if (point != null) {
points.add(point);
}
}
}
return points;
}在轉(zhuǎn)換的時(shí)候,需要解析單個(gè)坐標(biāo)字符串,并且轉(zhuǎn)換成Point對(duì)象,代碼如下:
/**
* 解析單個(gè)坐標(biāo)對(duì)字符串
*/
private static Point parseSingleCoordinate(String coordPair) {
if (coordPair == null || coordPair.trim().isEmpty()) {
return null;
}
String[] lonLat = coordPair.split(",");
if (lonLat.length == 2) {
try {
double longitude = Double.parseDouble(lonLat[0].trim());
double latitude = Double.parseDouble(lonLat[1].trim());
return new Point(longitude, latitude);
} catch (NumberFormatException e) {
System.err.println("解析坐標(biāo)失敗: " + coordPair);
}
}
return null;
}2. 轉(zhuǎn)為WKT
WKT格式用于表示空間幾何對(duì)象,路網(wǎng)數(shù)據(jù)多為線串(LineString)或多線串(MultiLineString),其中單條道路對(duì)應(yīng)LineString,多條關(guān)聯(lián)道路對(duì)應(yīng)MultiLineString。將道路解析成WKT的關(guān)鍵代碼如下:
/**
* 將Point列表轉(zhuǎn)換為WKT格式的LineString
*/
public static String toWKTLineString(List<Point> points) {
if (points == null || points.isEmpty()) {
return null;
}
StringBuilder sb = new StringBuilder("LINESTRING (");
for (int i = 0; i < points.size(); i++) {
Point p = points.get(i);
sb.append(String.format("%.6f %.6f", p.longitude, p.latitude));
if (i < points.size() - 1) {
sb.append(", ");
}
}
sb.append(")");
return sb.toString();
}3. 轉(zhuǎn)為GeoJSON
GeoJSON格式采用JSON結(jié)構(gòu)表示地理空間數(shù)據(jù),核心包含“type”(幾何類型)、“coordinates”(坐標(biāo)數(shù)組)、“properties”(屬性信息,如道路名稱、類型)等字段。轉(zhuǎn)換過(guò)程中,需注意GeoJSON的坐標(biāo)順序與JTS默認(rèn)順序一致,同時(shí)確保屬性字段的完整性,便于后續(xù)QGIS可視化時(shí)展示道路信息。轉(zhuǎn)換GeoJSON的代碼如下:
/**
* 將Point列表轉(zhuǎn)換為GeoJSON格式的LineString
*/
public static String toGeoJSONLineString(List<Point> points) {
if (points == null || points.isEmpty()) {
return null;
}
StringBuilder sb = new StringBuilder();
sb.append("{\n");
sb.append(" \"type\": \"Feature\",\n");
sb.append(" \"geometry\": {\n");
sb.append(" \"type\": \"LineString\",\n");
sb.append(" \"coordinates\": [\n");
for (int i = 0; i < points.size(); i++) {
Point p = points.get(i);
sb.append(String.format(" [%.6f, %.6f]", p.longitude, p.latitude));
if (i < points.size() - 1) {
sb.append(",");
}
sb.append("\n");
}
sb.append(" ]\n");
sb.append(" },\n");
sb.append(" \"properties\": {}\n");
sb.append("}");
return sb.toString();
}最后調(diào)用生成轉(zhuǎn)換數(shù)據(jù)的代碼如下,(請(qǐng)注意,如果使用以下代碼,請(qǐng)注意補(bǔ)全數(shù)據(jù)才可以):
public static void main(String[] args) {
// 您的數(shù)據(jù)
String shapeData = "113.177455,28.116717;..."; // 完整數(shù)據(jù)
// 解析為點(diǎn)列表
List<Point> points = parseShapeToPoints(shapeData);
System.out.println("解析完成,共 " + points.size() + " 個(gè)點(diǎn)");
// 輸出前5個(gè)點(diǎn)作為示例
System.out.println("\n前5個(gè)點(diǎn):");
for (int i = 0; i < Math.min(5, points.size()); i++) {
System.out.println(points.get(i));
}
// 轉(zhuǎn)換為WKT格式
String wkt = toWKTLineString(points);
System.out.println("\nWKT格式:");
System.out.println(wkt.substring(0, Math.min(100, wkt.length())) + "...");
// 轉(zhuǎn)換為GeoJSON格式
String geojson = toGeoJSONLineString(points);
System.out.println("\nGeoJSON格式:");
System.out.println(geojson);
System.out.println("--------------------------------------------------");
System.out.println(geojson.substring(0, Math.min(200, geojson.length())) + "...");
}運(yùn)行以上代碼后可以看到控制有如下輸出:

可以直接將以上的結(jié)果新建一個(gè)GeoJSON的文件,將具體的數(shù)據(jù)復(fù)制進(jìn)去保存即可。
三、成果展示
本節(jié)將使用QGIS來(lái)對(duì)生成的數(shù)據(jù)進(jìn)行展示,包括疊加影像底圖的方式。為了展示貼合的結(jié)果,影像底圖使用高德影像數(shù)據(jù)。
1. QGIS展示
QGIS是開(kāi)源免費(fèi)的GIS可視化工具,支持WKT、GeoJSON等多種空間數(shù)據(jù)格式的導(dǎo)入與展示,可直觀驗(yàn)證轉(zhuǎn)換成果的準(zhǔn)確性。展示步驟如下:第一步,導(dǎo)入數(shù)據(jù):打開(kāi)QGIS,通過(guò)“添加矢量圖層”功能,選擇“文件”類型,分別導(dǎo)入轉(zhuǎn)換后的WKT文件(.wkt)和GeoJSON文件(.geojson);第二步,配置樣式:導(dǎo)入后,QGIS會(huì)自動(dòng)識(shí)別幾何類型(LineString),可通過(guò)“屬性-樣式”功能,設(shè)置道路的顏色、線寬,區(qū)分不同類型的道路(如高速用紅色粗線,國(guó)道用藍(lán)色中線);第三步,驗(yàn)證準(zhǔn)確性:放大地圖,查看道路的走向、連接關(guān)系是否與在線地圖一致,核對(duì)道路名稱等屬性信息是否完整,確認(rèn)轉(zhuǎn)換無(wú)偏差。

2. 疊加底圖
為進(jìn)一步驗(yàn)證路網(wǎng)數(shù)據(jù)的準(zhǔn)確性,可在QGIS中疊加高德在線影像底圖,對(duì)比轉(zhuǎn)換后的路網(wǎng)與底圖路網(wǎng)的匹配度。操作步驟如下:第一步,使用xyz圖層添加高德影像,加載至QGIS畫(huà)布;第二步,疊加路網(wǎng):將轉(zhuǎn)換后的WKT/GeoJSON路網(wǎng)圖層,疊加到底圖上方;第三步,驗(yàn)證匹配度:查看路網(wǎng)是否與底圖道路完全重合,坐標(biāo)是否無(wú)偏移,確保轉(zhuǎn)換后的路網(wǎng)數(shù)據(jù)可直接用于實(shí)際GIS應(yīng)用。

疊加底圖驗(yàn)證后,可確認(rèn)本文實(shí)現(xiàn)的轉(zhuǎn)換方案能夠準(zhǔn)確還原在線地圖路網(wǎng)信息,滿足實(shí)際應(yīng)用需求。
四、總結(jié)
本文圍繞純Java環(huán)境下在線地圖路網(wǎng)數(shù)據(jù)至GeoJSON與WKT的格式轉(zhuǎn)換,完成了從數(shù)據(jù)獲取、轉(zhuǎn)換實(shí)現(xiàn)到成果展示的全流程實(shí)踐,核心總結(jié)如下:
本文實(shí)現(xiàn)了高德地圖路網(wǎng)數(shù)據(jù)的獲取與解析;搭建了純Java環(huán)境下的轉(zhuǎn)換框架,無(wú)需依賴第三方GIS組件,實(shí)現(xiàn)了路網(wǎng)數(shù)據(jù)至WKT、GeoJSON格式的高效轉(zhuǎn)換,具備高可移植性、低耦合度的優(yōu)勢(shì),可直接嵌入Java后端服務(wù);通過(guò)QGIS可視化與底圖疊加驗(yàn)證,確認(rèn)轉(zhuǎn)換成果準(zhǔn)確可靠,能夠完美適配PostGIS存儲(chǔ)、前端可視化等主流GIS應(yīng)用場(chǎng)景。同時(shí),本文方案仍存在可優(yōu)化方向:一是可增加多線程并發(fā)獲取路網(wǎng)數(shù)據(jù)的功能,提升大規(guī)模區(qū)域路網(wǎng)數(shù)據(jù)的獲取效率;二是可優(yōu)化坐標(biāo)系轉(zhuǎn)換算法,進(jìn)一步提升坐標(biāo)精度;三是可擴(kuò)展支持更多在線地圖平臺(tái)(如騰訊地圖)的路網(wǎng)數(shù)據(jù)轉(zhuǎn)換。后續(xù)將針對(duì)這些方向進(jìn)行優(yōu)化,打造更完善、更高效的純Java路網(wǎng)數(shù)據(jù)格式轉(zhuǎn)換方案,為GIS相關(guān)Java開(kāi)發(fā)提供更全面的技術(shù)支撐。
本文路網(wǎng)獲取使用手動(dòng)獲取的模式,如需在線服務(wù),建議聯(lián)系高德或百度的官方平臺(tái)。
以上就是純Java環(huán)境下實(shí)現(xiàn)將在線地圖路網(wǎng)數(shù)據(jù)轉(zhuǎn)為GeoJSON與WKT的詳細(xì)內(nèi)容,更多關(guān)于Java路網(wǎng)數(shù)據(jù)轉(zhuǎn)GeoJSON與WKT的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
一小時(shí)迅速入門Mybatis之bind與多數(shù)據(jù)源支持 Java API
這篇文章主要介紹了一小時(shí)迅速入門Mybatis之bind與多數(shù)據(jù)源支持 Java API,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-09-09
mybatis映射文件操作存儲(chǔ)過(guò)程的實(shí)現(xiàn)
本文主要介紹了mybatis映射文件操作存儲(chǔ)過(guò)程的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03
springboot通過(guò)jar包啟動(dòng)中文日志亂碼問(wèn)題及解決
這篇文章主要介紹了springboot通過(guò)jar包啟動(dòng)中文日志亂碼問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06
MyBatis?XML?里<![CDATA[?]]>的使用示例詳解
<![CDATA[ ]]>是 MyBatis中處理SQL語(yǔ)句與XML語(yǔ)法沖突的安全屏障,本文給大家介紹MyBatis XML里<![CDATA[?]]>的使用,感興趣的朋友跟隨小編一起看看吧2026-02-02
JAVA內(nèi)存空間相關(guān)知識(shí)匯總
這篇文章主要介紹了JAVA內(nèi)存空間相關(guān)知識(shí),文中介紹的非常詳細(xì),代碼幫助大家更好的參考和學(xué)習(xí),感興趣的朋友可以了解下2020-06-06

