Gis數據的A*算法規劃航線

1.1 用到的技術棧
  • geotools?
  • JTS
  • Jgrapht
1.2 實現思路
          // 定義柵格網格參數private static final double CELL_SIZE_DEGREES = 0.005;private static int gridWidth = 0;//格子高度 index + 1private static int gridHeight = 0;//格子寬度// 1. 讀取GeoJSON文件File geoJsonFile = new File("C:/aaa/src/main/resources/" + "map.geojson");SimpleFeatureCollection features = readGeoJson(geoJsonFile);// 2. 獲取邊界范圍Envelope envelope = getEnvelope(features);// 3. 創建柵格網格GridCell[][] grid = createGrid(envelope);// 4. 將GeoJSON要素柵格化rasterizeFeatures(features, grid, envelope);// 5. 構建圖結構SimpleWeightedGraph<GridCell, DefaultWeightedEdge> graph = buildGraph(grid);// 6. 定義起點和終點  new GridCell[gridHeight][gridWidth];GridCell start = grid[2][2]; // 左下角GridCell end = grid[gridHeight -1][gridWidth - 1]; // 右上角// 7. 運行A*算法AStarShortestPath<GridCell, DefaultWeightedEdge> aStar = new AStarShortestPath<>(graph, new ManhattanDistance());GraphPath<GridCell, DefaultWeightedEdge> path = aStar.getPath(start, end);// 8. 輸出結果if (path != null) {System.out.println("找到路徑,長度: " + path.getLength());for (GridCell cell : path.getVertexList()) {System.out.println("[" + cell.centerX + ", " + cell.centerY + "],");}} else {System.out.println("未找到路徑");}}
  • 讀取GeoJSON文件
    // 讀取GeoJSON文件private static SimpleFeatureCollection readGeoJson(File file) throws IOException {FeatureJSON fjson = new FeatureJSON();try (FileInputStream in = new FileInputStream(file)) {return (SimpleFeatureCollection) fjson.readFeatureCollection(in);}}
  • ?利用圖形邊界創建柵格網格
// 創建柵格網格private static GridCell[][] createGrid(Envelope envelope) {double minLon = envelope.getMinX() - CELL_SIZE_DEGREES * 1.5;double minLat = envelope.getMinY() - CELL_SIZE_DEGREES * 1.5;double maxLon = envelope.getMaxX() + CELL_SIZE_DEGREES * 1.5;double maxLat = envelope.getMaxY() + CELL_SIZE_DEGREES * 1.5;gridWidth = (int) Math.ceil((maxLon - minLon) / CELL_SIZE_DEGREES);gridHeight = (int) Math.ceil((maxLat - minLat) / CELL_SIZE_DEGREES);GridCell[][] grid = new GridCell[gridHeight][gridWidth];for (int y = 0; y < gridHeight; y++) {for (int x = 0; x < gridWidth; x++) {// 3. 計算當前單元格的左下角坐標 (minX, minY)// 3. 計算當前單元格的左下角坐標 (minX, minY)double currentCellMinX = minLon + x * CELL_SIZE_DEGREES;double currentCellMinY = minLat + y * CELL_SIZE_DEGREES;// 4. 計算當前單元格的右上角坐標 (maxX, maxY)double currentCellMaxX = currentCellMinX + CELL_SIZE_DEGREES;double currentCellMaxY = currentCellMinY + CELL_SIZE_DEGREES;// 5. 計算當前單元格的中心點坐標double centerX = currentCellMinX + CELL_SIZE_DEGREES / 2.0;double centerY = currentCellMinY + CELL_SIZE_DEGREES / 2.0;grid[y][x] = new GridCell(x, y,centerX,centerY);}}return grid;}// 網格單元類static class GridCell {final int x, y; // 網格坐標final double centerX, centerY; // 地理坐標boolean isObstacle = false;GridCell(int x, int y, double centerX, double centerY) {this.x = x;this.y = y;this.centerX = centerX;this.centerY = centerY;}@Overridepublic String toString() {return "Cell(" + x + "," + y + ")" + "lonlat(" + centerX + "," + centerY + ")" ;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;GridCell gridCell = (GridCell) o;return x == gridCell.x && y == gridCell.y;}@Overridepublic int hashCode() {return 31 * x + y;}}
  • ?柵格化要素
    // 柵格化要素private static void rasterizeFeatures(SimpleFeatureCollection features, GridCell[][] grid, Envelope envelope)throws FactoryException, TransformException {try (SimpleFeatureIterator it = features.features()) {while (it.hasNext()) {SimpleFeature feature = it.next();Geometry geom = (Geometry) feature.getDefaultGeometry();// 檢查每個網格單元是否與幾何圖形相交for (int y = 0; y < gridHeight; y++) {for (int x = 0; x < gridWidth; x++) {GridCell cell = grid[y][x];GeometryFactory geometryFactory = new GeometryFactory();// 定義矩形的邊界 (minX, minY) 到 (maxX, maxY)double minX = cell.centerX - CELL_SIZE_DEGREES / 2;double minY = cell.centerY - CELL_SIZE_DEGREES / 2;double maxX = cell.centerX + CELL_SIZE_DEGREES / 2;double maxY = cell.centerY + CELL_SIZE_DEGREES / 2;// 2. 定義矩形的頂點坐標 (按順時針或逆時針順序,最后一個點與第一個點相同)Coordinate[] coords = new Coordinate[] {new Coordinate(minX, minY), // 左下new Coordinate(maxX, minY), // 右下new Coordinate(maxX, maxY), // 右上new Coordinate(minX, maxY), // 左上new Coordinate(minX, minY)  // 回到左下,閉合環};// 3. (可選,如果你需要更復雜的序列,這里直接用Coordinate數組)// CoordinateSequence coordinateSequence = geometryFactory.getCoordinateSequenceFactory().create(coords);// 4. 創建 LinearRing (外部邊界)LinearRing shell = geometryFactory.createLinearRing(coords);// 5. 創建 Polygon (矩形)// 第二個參數是內孔的 LinearRing 數組,對于簡單矩形,通常是空的Polygon rectangle = geometryFactory.createPolygon(shell, null);//                        Point point = new GeometryFactory().createPoint(new Coordinate(cell.centerX, cell.centerY));if (geom.intersects(rectangle)) {cell.isObstacle = true;}}}}}}
  • 構建圖結構
    // 構建圖結構private static SimpleWeightedGraph<GridCell, DefaultWeightedEdge> buildGraph(GridCell[][] grid) {SimpleWeightedGraph<GridCell, DefaultWeightedEdge> graph =new SimpleWeightedGraph<>(DefaultWeightedEdge.class);// 添加所有頂點for (int y = 0; y < gridHeight; y++) {for (int x = 0; x < gridWidth; x++) {if (!grid[y][x].isObstacle) {graph.addVertex(grid[y][x]);}}}// 添加邊(8連通)for (int y = 0; y < gridHeight; y++) {for (int x = 0; x < gridWidth; x++) {if (grid[y][x].isObstacle) continue;// 檢查8個相鄰方向for (int dy = -1; dy <= 1; dy++) {for (int dx = -1; dx <= 1; dx++) {if (dx == 0 && dy == 0) continue; // 跳過自身int nx = x + dx;int ny = y + dy;if (nx >= 0 && nx < gridWidth && ny >= 0 && ny < gridHeight) {if (!grid[ny][nx].isObstacle && graph.containsVertex(grid[ny][nx])) {DefaultWeightedEdge edge = graph.addEdge(grid[y][x], grid[ny][nx]);if (edge != null) {// 對角線距離為√2,直線距離為1double weight = (dx != 0 && dy != 0) ? Math.sqrt(2) : 1.0;graph.setEdgeWeight(edge, weight);}}}}}}}return graph;}
  • 實現啟發函數
    public static class ManhattanDistance implements AStarAdmissibleHeuristic<GridCell> {@Overridepublic double getCostEstimate(GridCell source, GridCell target) {double dx = Math.abs(source.x - target.x);double dy = Math.abs(source.y - target.y);return dx + dy;//            double dx = source.centerX - target.centerX;
//            double dy = source.centerY - target.centerY;
//            return Math.sqrt(dx * dx + dy * dy);}}
  • 完美實現

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/93178.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/93178.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/93178.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Spring Boot 默認使用 CGLIB,但CGLIB 無法代理 final 類或 final 方法

那么當這兩件事沖突時&#xff0c;Spring Boot 是怎么“解決”的呢&#xff1f;答案是&#xff1a;它不解決&#xff0c;也無法解決。當這種情況發生時&#xff0c;你的應用程序會直接啟動失敗。這不是 Spring Boot 的疏忽&#xff0c;而是由 CGLIB 的底層原理和 Java 語言的規…

cuda編程筆記(10)--memory access 優化

全局內存訪問優化&#xff08;Coalesced Access&#xff09; 什么是 Coalesced Access&#xff1f; 定義&#xff1a;一個 warp&#xff08;32 個線程&#xff09;在同一指令中訪問全局內存時&#xff0c;如果這些訪問請求可以合并成盡可能少的內存事務&#xff08;通常是 32…

閑庭信步使用圖像驗證平臺加速FPGA的開發:第三十一課——車牌識別的FPGA實現(3)車牌字符分割預處理

&#xff08;本系列只需要modelsim即可完成數字圖像的處理&#xff0c;每個工程都搭建了全自動化的仿真環境&#xff0c;只需要雙擊top_tb.bat文件就可以完成整個的仿真&#xff0c;大大降低了初學者的門檻&#xff01;&#xff01;&#xff01;&#xff01;如需要該系列的工程…

電子電氣架構 --- 汽車軟件全生命周期

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 簡單,單純,喜歡獨處,獨來獨往,不易合同頻過著接地氣的生活,除了生存溫飽問題之外,沒有什么過多的欲望,表面看起來很高冷,內心熱情,如果你身…

力扣面試150(41/150)

7.25 56. 合并區間 以數組 intervals 表示若干個區間的集合&#xff0c;其中單個區間為 intervals[i] [starti, endi] 。請你合并所有重疊的區間&#xff0c;并返回 一個不重疊的區間數組&#xff0c;該數組需恰好覆蓋輸入中的所有區間 。 我的思路&#xff1a; 左端點升序…

【隧道篇 / IPsec】(7.6) ? 01. 利用向導快速建立IPsec安全隧道 (點對點) ? FortiGate 防火墻

【簡介】相信很多人已經習慣利用導向快速創建VPN了&#xff0c;而且已經有部分嘗鮮者已經用上了FortiOS 7.6&#xff0c;但是會發現FortiOS 7.6下的VPN向導改變了很多&#xff0c;一時無法下手&#xff0c;下面我們來看看最常見的點對點是如何配置的。環境介紹在配置IPsec VPN之…

PLLIP核

。1 號紅色框內的速度等級代表著設備的速度 等級&#xff0c;保存默認就好&#xff1b;2 號紅色框內設置輸入頻率&#xff1b;3 號紅色框選擇 PLL 的工作模式。我們 開發板用的晶振是 50MHz 的&#xff0c;故在 2 號紅色框內我們填寫 50MHz&#xff1b;我們在 3 號紅色框內選正…

1.1 Deep learning?pytorch ?深度學習訓練出來的模型通常有效但無法解釋合理性? 如何 解釋?

DL 是什么&#xff0c;你如何理解DL模型&#xff1f; DL 對于我而言&#xff0c;就是人類試圖想通過數學語言描述人類學習過程的一門技術&#xff0c;或者說學科。 因此 DL 模型 相當于 數學 的 一個 funciton &#xff0c;有輸入&#xff0c;通過function處理&#xff0c;得…

java實現在工具類中注入其他對象方式

方案1&#xff1a; Slf4j Component public class ChatdocApiClient {Value("${chatdoc.app-id}")private String appId;Value("${chatdoc.secret}")private String secret;Value("${chatdoc.domain}")private String domain;private final Rest…

electron中IPC 渲染進程與主進程通信方法解析

electron中ipcRenderer.invoke、ipcRenderer.on、ipcRenderer.send、ipcRenderer.sendSync作用與區別 IPC 渲染進程與主進程通信方法解析 ipcRenderer 的這幾個方法作用不完全相同&#xff0c;它們適用于不同的通信場景&#xff0c;核心區別在于通信方向、是否需要響應以及同步…

epoll_event 事件類型詳解

epoll_event 事件類型詳解 epoll_event 是 Linux epoll I/O 多路復用機制的核心結構體&#xff0c;其中的事件類型決定了 epoll 監控的行為和觸發條件。以下是各種事件類型的詳細解析&#xff1a; epoll_event 結構體 #include <sys/epoll.h>typedef union epoll_data {v…

設計自己的小傳輸協議 導論與概念

設計自己的小傳輸協議 導論與概念 1&#xff1a;聊一聊協議頭設計 ? 早在《TCP/IP詳解》中的第一句話中&#xff0c;我們就知道協議的含義是這樣的&#xff1a;協議是通信雙方共同遵守的一套規則&#xff0c;提供格式定義、語義解釋等&#xff0c;使不同設備或軟件能夠正確交…

iOS —— 天氣預報仿寫總結

在iOS中&#xff0c;最常見的網絡請求方式是NSURLSession&#xff0c;它是蘋果推薦的現代API&#xff0c;簡單安全且易于拓展。一次完整的網絡請求流程&#xff1a;構造 NSURL 對象創建 NSURLSessionDataTask發起請求&#xff08;resume&#xff09;在回調中解析數據回到主線程…

MySQL 8.4 Windows 版安裝記錄與步驟參考

導語&#xff1a; MySQL 作為廣泛使用的開源數據庫管理系統&#xff0c;是許多開發者和學習者的必備工具。最近有朋友詢問安裝過程&#xff0c;正好整理了 MySQL 8.4 在 Windows 系統下的安裝步驟和一些注意事項&#xff0c;分享給有需要的朋友做個參考。關于 MySQL&#xff1a…

七、搭建springCloudAlibaba2021.1版本分布式微服務-skywalking9.0鏈路追蹤

前言鏈路追蹤介紹 對于一個大型的幾十個&#xff0c;幾百個微服務構成的微服務架構系統&#xff0c;通常會遇到下面的一系列問題。 如何串聯整個調用鏈路&#xff0c;快速定位問題&#xff1f;如何澄清各個微服務之間的依賴關系&#xff1f;如何進行各個微服務接口的性能分析&a…

深入理解大語言模型生成參數:temperature、top\_k、top\_p 等全解析

在使用大語言模型&#xff08;如 GPT-4、LLaMA、ChatGLM 等&#xff09;進行文本生成任務時&#xff0c;很多開發者會面對各種“生成參數”&#xff0c;如 temperature、top_k、top_p、repetition_penalty 等。這些參數雖然看起來抽象&#xff0c;但掌握它們的意義和配置技巧&a…

vulhub Web Machine(N7)靶場攻略

下載地址&#xff1a; https://download.vulnhub.com/webmachine/Web-Machine-N7.ova 使用方法&#xff1a; 靶場下載好以后不用解壓&#xff0c;需要使用Oracle VirtualBox虛擬機打開&#xff0c;用VMware會報錯。安裝Oracle VirtualBox虛擬機時安裝地址不能隨便選擇&#…

【機器學習深度學習】模型微調:多久才算微調完成?——如何判斷微調收斂,何時終止訓練

目錄 前言 一、微調過程的目標&#xff1a;優化模型表現 二、微調需要多久&#xff1f; 微調時間無法確定 三、如何判斷微調何時收斂&#xff1f; 3.1 觀察Loss的下降趨勢 3.2 損失值趨于平穩&#xff0c;意味著收斂 如何識別收斂&#xff1f; 3.3 驗證Loss的波動&…

紅隊視角:實戰滲透測試中漏洞利用的進階技巧與防御

紅隊作為滲透測試的 “攻擊方”&#xff0c;其核心價值不僅在于發現漏洞&#xff0c;更在于挖掘漏洞的深度利用方式 —— 通過繞過防護措施、組合低危漏洞形成攻擊鏈&#xff0c;暴露企業真實安全風險。從紅隊視角解析漏洞利用的進階技巧&#xff0c;既能幫助防御方理解攻擊思路…

OpenHarmony BUILD.gn中執行腳本

在OpenHarmony編譯構建中筆者經常遇到這樣的場景——需要執行sh腳本完成某些操作。筆者將OpenHarmony BUILD.gn中執行腳本的方法分享如下&#xff1a; 前置知識點 1.能夠把自定義的子系統加入OpenHarmony源碼的編譯構建&#xff0c;請參考&#xff1a;https://ost.51cto.com/…