基于Geotools的兩條道路相交并根據交點形成新路線實戰-以OSM數據為例

目錄

前言

一、需求場景及分解

1、需求場景

2、需求應用

二、需求實現

1、加載路網數據

2、獲取道路信息

3、相交點求解

4、生成新道路

5、結果可視化

三、總結


前言

????????在當今數字化迅速發展的時代,地理空間數據的處理與分析已成為眾多領域不可或缺的關鍵技術。從城市規劃到智能交通,從環境監測到物流配送,精準且高效的地理數據操作直接影響著決策的科學性和方案的可行性。OpenStreetMap(OSM)作為全球廣泛使用的開源地理數據平臺,蘊含著海量的道路、建筑、地形等信息,為各類地理空間應用奠定了堅實的數據基礎。然而,如何從這些紛繁復雜的 OSM 數據中提取有價值的信息,并進行深入的空間分析,是一個備受關注且極具挑戰性的課題。

????????道路網絡分析作為地理信息系統(GIS)中的核心內容之一,尤其是處理道路相交問題以及基于交點構建新路線的任務,既具有高度的實用性,又蘊含著復雜的空間幾何與拓撲關系。在實際場景中,例如交通流量優化、應急救援路徑規劃、公共交通線路設計等,都需要準確地識別道路相交點,并依據這些交點合理地重組路線,以滿足特定的需求和目標。Geotools 作為一款功能強大的開源 GIS 工具庫,為 Java 開發者提供了豐富的地理數據處理和空間分析能力。它不僅支持多種地理數據格式的讀取與寫入,還具備強大的幾何運算、空間查詢以及拓撲關系構建等功能,為解決復雜的地理空間問題提供了有力的工具。

????????本實戰項目旨在深入探索如何基于 Geotools,充分利用 OSM 數據的豐富性與開放性,實現兩條道路相交的精確檢測,并根據相交點構建出符合需求的新路線。這不僅是對 Geotools 在道路網絡分析方面功能的一次全面檢驗,更是為實際的地理空間應用提供了一種可操作的解決方案。通過該項目的實施,我們期望能夠提高地理數據處理的自動化水平,為相關領域的專業人士和開發者提供寶貴的經驗和參考,助力其在各自的實際項目中更好地運用地理空間技術,挖掘地理數據的巨大潛力,解決復雜的現實問題,提升工作效率和決策質量。

一、需求場景及分解

????????本節將從需求場景和應用兩個角度來介紹一下道路相交點的一些基本知識。作為業務知識讓大家對需求有一定的了解。在生活當中,我們可能對兩條道路進行相交求解后,還要求根據交點,求解按照交點連接而成的新路線,因此有必要深入的來講解一下這些基礎知識。

1、需求場景

????????在交通規劃與管理領域,道路相交求解和合成新路線具有至關重要的作用。隨著城市化進程的加速,城市交通網絡日益復雜,準確地求解道路相交點并構建合理的新路線,對于優化交通流量、緩解擁堵、提高道路通行效率等方面起著關鍵的支撐作用。從城市規劃的角度來看,新建的道路往往需要與現有的道路網絡相連接,這就涉及到確定道路之間的相交點,并基于這些交點合理規劃新路線,以確保交通的順暢銜接。例如,在城市新區的開發中,規劃部門需要根據土地利用規劃和交通需求預測,設計新的道路布局,并通過道路相交求解和路線合成技術,生成科學合理的道路網絡方案,保障居民的出行便利和城市的可持續發展。在智能交通系統中,實時的交通信息采集與處理對道路相交求解和新路線合成有著迫切的需求。通過在道路上安裝的傳感器和監控設備,能夠獲取車輛的位置、速度等信息,利用這些數據可以實時判斷車輛行駛路線與其它道路的相交情況,進而為車輛提供最優的行駛路線建議,實現交通誘導和路徑優化,減少交通事故的發生,提高道路資源的利用率。對于物流配送行業而言,高效的貨物運輸路線規劃離不開道路相交求解和新路線合成技術。物流企業的車輛需要在復雜的道路網絡中快速、準確地到達目的地,通過對道路相交點的精確計算和路線的智能合成,可以為物流車輛規劃出最短路徑、避開擁堵路段,從而降低運輸成本,提高配送效率,增強企業的競爭力。

2、需求應用

????????在交通工程領域,道路相交求解和新路線合成技術被廣泛應用于交通設施的設計與優化。在設計立交橋、交通環島等交通設施時,準確地確定道路相交點的位置和角度,是確保交通設施合理布局和高效運行的基礎。通過合成優化后的路線,可以引導車輛順暢地通過交通設施,減少車輛的交織和沖突,提高道路的安全性和通行能力。在導航軟件的開發中,這一技術的應用更是不可或缺。導航軟件需要對大量的道路數據進行處理和分析,快速準確地求解道路相交點,并根據實時的交通狀況和用戶的出行需求,合成出最佳的行駛路線。例如,高德地圖、百度地圖等導航軟件,正是基于精確的道路相交求解和路線合成算法,為用戶提供了一個個準確、實時的導航服務,使用戶能夠方便快捷地到達目的地,同時也推動了移動互聯網應用的快速發展。在應急救援領域,道路相交求解和新路線合成技術發揮著至關重要的作用。在發生自然災害、交通事故等緊急情況時,救援人員需要迅速到達事故現場。通過對道路相交點的快速判斷和路線的合理合成,可以為救援車輛規劃出最短、最快的救援路線,爭取寶貴的救援時間,提高救援效率,保障人民生命財產安全。此外,在智能駕駛技術的研發中,道路相交求解和新路線合成也是關鍵的技術環節。智能駕駛車輛需要具備對復雜道路環境的感知和理解能力,能夠實時判斷與其它道路的相交情況,并根據交通規則和行駛條件,自主地合成出安全、合理的行駛路線,實現自動駕駛功能,這對于推動智能駕駛技術的商業化應用和未來交通運輸的智能化發展具有深遠的意義。

二、需求實現

????????了解了大致的需求之后,接下來我們就圍繞著這個需求使用Geotoools來進行實現。要想實現根據道路相交點的打斷再生成新路線的需求,需要進行以下的步驟,從路網數據到生成結果基本包含:加載路網、查找道路信息、相交點求解、根據交點生成新道路以及對新道路數據的結果進行可視化。通過這個過程,希望大家對整個技術實現過程有一個完整的理解和掌握。當然如果有興趣也可以跟著博文來進行重現,如有問題請及時在評論區留言。

????????實現需求的基本步驟和技術實現路徑如下:

在GeoTools中,基于SHP格式路網數據,求兩條道路的相交點,按以下步驟進行:

1. 讀取SHP文件,獲取道路的FeatureCollection。

2. 從FeatureCollection中提取出兩條道路(假設我們通過某個屬性或索引選定兩條道路)。

3. 將兩條道路的幾何對象(LineString)進行求交操作。

4. 由于兩條線相交可能得到多個交點(例如交叉路口),我們需要獲取所有的交點。

注意:兩條道路相交,我們期望得到點(Point)或者多點(MultiPoint)。但是,如果兩條道路有重疊部分,則可能會返回線(LineString)或多線(MultiLineString)。但通常我們只關心點相交。

使用GeoTools的幾何運算工具,可以使用`Intersection`函數,然后判斷返回的幾何類型。

步驟:

1. 讀取SHP文件。

2. 選擇兩條道路(這里假設我們通過屬性選擇,或者直接取兩個Feature)。

3. 獲取兩條道路的幾何對象(Geometry),這里應該是LineString(或MultiLineString,但通常道路是LineString)。

4. 使用`intersection`方法求交。

5. 檢查返回的幾何類型:

- 如果是Point,則直接得到交點。

- 如果是MultiPoint,則優先獲取第一個(簡化操作)。

- 如果是LineString或MultiLineString,則說明有重疊部分,但通常我們不考慮這種情況,或者根據需求處理。但是,注意:兩條線相交通常返回的是點,但如果沒有相交則返回空幾何(Empty Geometry)。另外,由于浮點精度問題,可能需要使用精度模型(PrecisionModel)來確保交點的準確性。

1、加載路網數據

????????要想實現對OSM路網數據點的求解,首先我們需要加載整個OSM的shp格式的數據。加載的路網數據的關鍵代碼如下:

// 1. 加載路網數據
File shpFile = new File("F:/vector_data/2024年OSM長沙路網/長沙路網OSM2024.shp");
ShapefileDataStore store = new ShapefileDataStore(shpFile.toURI().toURL());
store.setCharset(Charset.forName("GBK"));//設置中文字符編碼7      
SimpleFeatureSource featureSource = store.getFeatureSource();
SimpleFeatureCollection features = featureSource.getFeatures();

2、獲取道路信息

????????為了實現在很多的OSM路網信息中快速的找到對應的道路線對象,我們需要進行數據的查詢,這里將數據查詢封裝的方法給出源代碼(這里是根據道路的OSMID來確定,實際情況下可以根據其它已知的屬性來提取,都是可以的),供參考:

// 按屬性獲取道路幾何對象
private static Geometry getRoadGeometry(SimpleFeatureCollection features, String attribute, Object value) {try (SimpleFeatureIterator it = features.features()) {while (it.hasNext()) {SimpleFeature feature = it.next();if (value.equals(feature.getAttribute(attribute))) {return (Geometry) feature.getDefaultGeometry();}}}throw new IllegalArgumentException("未找到指定道路");
}

?????????在查找源道路的時候,我們使用道路的OSMID作為屬性查詢的條件,實際情況的查詢肯定比這種場景復雜,這里不考慮太復雜的情況。由于需求求解兩條路的相交點,因此我們需要找到兩條路的OSMID(如果有不會的,可以使用Qgis軟件使用屬性查看器來進行查找關鍵的點),查找屬性值如下:

// 2. 選擇兩條要連接的道路(實際應用中可能需要根據ID或其他屬性選擇)
Geometry road1 = getRoadGeometry(features, "osm_id", "538532552");
Geometry road2 = getRoadGeometry(features, "osm_id", "538532558");

3、相交點求解

????????找到兩條道路了之后,接下來就需要根據兩條道路來求解他們的交點,當然這里需要考慮有多條道路的情況,關于如何處理,大家可以看看之前的博客。這里使用一種粗暴的方法,直接只取第一個。核心處理方法如下:

// 查找兩條道路的相交點
private static Point findIntersectionPoint(Geometry road1, Geometry road2) {// 處理可能的拓撲錯誤double snapTolerance = 0.000001;Geometry [] snappedRoad1 = GeometrySnapper.snap(road1, road2, snapTolerance);// 計算交點 ,這里演示一個,有可能有多個Geometry intersection = snappedRoad1[0].intersection(road2);if (intersection instanceof Point) {return (Point) intersection;} else if (intersection instanceof MultiPoint && intersection.getNumGeometries() > 0) {return (Point) intersection.getGeometryN(0);}throw new IllegalStateException("道路未相交或相交點不是點類型");
}

????????可以看到,如果當前的返回點是多個的話,則默認返回相交的第一個點,關鍵代碼如下:

else if (intersection instanceof MultiPoint && intersection.getNumGeometries() > 0) {return (Point) intersection.getGeometryN(0);
}

????????傳入之前得到的道路信息,進行相交點求解,調用核心方法如下:

// 3. 找到兩條道路的相交點
Point intersection = findIntersectionPoint(road1, road2);

4、生成新道路

????????有了路線,也經過計算得到相交點之后,下面就可以根據交點和原始的道路來生成新道路。新道路的生成關鍵就是需要對道路進行切斷和拼接。最后就可以生成生成新的道路。關鍵的處理代碼如下:

 // 在相交點處連接兩條道路private static LineString connectRoadsAtIntersection(Geometry road1, Geometry road2, Point intersection) {// 創建索引線以便分割道路MultiLineString mline1 = (MultiLineString)road1;MultiLineString mline2 = (MultiLineString)road2;LengthIndexedLine indexedRoad1 = new LengthIndexedLine((LineString) mline1.getGeometryN(0));LengthIndexedLine indexedRoad2 = new LengthIndexedLine((LineString) mline2.getGeometryN(0));// 獲取相交點在兩條道路上的位置double position1 = indexedRoad1.project(intersection.getCoordinate());double position2 = indexedRoad2.project(intersection.getCoordinate());// 從道路1的起點到相交點Geometry road1Part = indexedRoad1.extractLine(0, position1);// 從相交點到道路2的終點Geometry road2Part = indexedRoad2.extractLine(position2, indexedRoad2.getEndIndex());// 合并兩個部分形成新道路Coordinate[] coords1 = road1Part.getCoordinates();Coordinate[] coords2 = road2Part.getCoordinates(); // 創建新坐標數組(跳過重復的相交點)Coordinate[] newCoords = new Coordinate[coords1.length + coords2.length - 1];System.arraycopy(coords1, 0, newCoords, 0, coords1.length);System.arraycopy(coords2, 1, newCoords, coords1.length, coords2.length - 1);// 確保連接點精確使用相交點坐標newCoords[coords1.length - 1] = intersection.getCoordinate(); return new GeometryFactory().createLineString(newCoords);
}

????????調用代碼如下:

// 4. 在相交點處連接兩條道路
LineString newRoad = connectRoadsAtIntersection(road1, road2, intersection);

5、結果可視化

????????已知原始的路網數據,然后也根據道路信息求解出相交點和連接新交點的道路。那么接下來就是把生成的結果進行可視化。想要實現OSM路網數據和新道路的展示效果,這里采用原生自帶的Swing方式即可。在對結果進行可視化之前,還需要創建道路的臨時樣式才能展示。首先第一步是創建一個內存圖層layer,關鍵代碼如下:

// 創建內存圖層
private static Layer createMemoryLayer(Geometry geometry, String name, Color color, float width) {SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder();typeBuilder.setName("GeometryFeature");typeBuilder.add("geometry", geometry.getClass());SimpleFeatureType featureType = typeBuilder.buildFeatureType();SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(featureType);DefaultFeatureCollection featureCollection = new DefaultFeatureCollection();featureBuilder.add(geometry);SimpleFeature feature = featureBuilder.buildFeature(null);featureCollection.add(feature); Style style = SLD.createLineStyle(color, width);if (geometry instanceof Point) {style = SLD.createPointStyle("Circle", color, color, 1.0f, width);}return new FeatureLayer(featureCollection, style);
}

????????然后對前面的道路、相交點和新連接數據進行可視化,核心方法如下:

// 可視化結果
private static void visualizeResults(SimpleFeatureSource roads, Geometry road1, Geometry road2,Point intersection, LineString newRoad) {// 創建地圖內容MapContent map = new MapContent();map.setTitle("道路連接結果");// 添加原始路網SLD的方式Style roadStyle = null;try {roadStyle = createStyleFromSld("D:/road_intersection.sld");} catch (Exception e) {}map.addLayer(new FeatureLayer(roads, roadStyle));// 添加第一條道路(藍色)Layer layer1 = createMemoryLayer(road1, "道路1", Color.BLUE, 3.0f);map.addLayer(layer1);// 添加第二條道路(綠色)Layer layer2 = createMemoryLayer(road2, "道路2", Color.GREEN, 3.0f);map.addLayer(layer2);// 添加相交點(紅色)Layer intersectionLayer = createMemoryLayer(intersection, "相交點", Color.RED, 8.0f);map.addLayer(intersectionLayer);// 添加新道路(紫色粗線)Layer newRoadLayer = createMemoryLayer(newRoad, "新道路", new Color(128, 0, 128), 4.0f);map.addLayer(newRoadLayer);// 顯示地圖JMapFrame.showMap(map);}

????????調用渲染展示的代碼如下,在最后調用了store的disponse方法進行資源的釋放:

// 5. 可視化結果
visualizeResults(featureSource, road1, road2, intersection, newRoad); 
store.dispose();

?????????經過以上的步驟,就可以運行程序,成功運行后可以看到以下界面,默認的界面如下:

????????為了展示得更直觀,我們來持續放大地圖,可以比較清晰的看到相交點和新的連線信息,放大后的窗口效果如下:

????????經過以上步驟,基本達到我們的預期和需求。?

三、總結

????????以上就是本文的主要內容,本實戰項目旨在深入探索如何基于 Geotools,充分利用 OSM 數據的豐富性與開放性,實現兩條道路相交的精確檢測,并根據相交點構建出符合需求的新路線。這不僅是對 Geotools 在道路網絡分析方面功能的一次全面檢驗,更是為實際的地理空間應用提供了一種可操作的解決方案。通過該項目的實施,我們期望能夠提高地理數據處理的自動化水平,為相關領域的專業人士和開發者提供寶貴的經驗和參考,助力其在各自的實際項目中更好地運用地理空間技術,挖掘地理數據的巨大潛力,解決復雜的現實問題,提升工作效率和決策質量。行文倉促,定有不足之處,歡迎各位朋友在評論區批評指正,不勝感激。

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

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

相關文章

goland有基礎速通(需要其它編程語言基礎)

tip: 無論是變量、方法還是struct的訪問權限控制都是通過命名控制的,命名的首字母是大寫就相當于java中的public,小寫的話就是private,(private只有本包可以訪問) 1 go的變量聲明 普通變量 特點: 變量類…

量化面試綠皮書:19. 相關系數

文中內容僅限技術學習與代碼實踐參考,市場存在不確定性,技術分析需謹慎驗證,不構成任何投資建議。 19. 相關系數 假設有三個隨機變量x、y和z。 x與y之間的相關系數為0.8,x與z之間的相關系數也是0.8。 Q: 那么y與z之間的最大相關…

新生活的開啟:從 Trae AI 離開后的三個月

很久沒有寫文章了,想借著入職新公司一個月的機會,和大家嘮嘮嗑。 離職 今年2月份我從字節離職了,結束了四年的經歷,當時離開的核心原因是覺得加班時間太長了,平均每天都要工作15,16個小時,周末…

LLM部署之vllm vs deepspeed

部署大語言模型(如 Qwen/LLaMA 等)時,vLLM 與 DeepSpeed 是當前主流的兩種高性能推理引擎。它們各自專注于不同方向,部署流程也有明顯區別。 vLLM 提供極致吞吐、低延遲的推理服務,適用于在線部署;DeepSpeed 更側重訓練與推理混合優化,支持模型并行,適用于推理 + 微調/…

Git(二):基本操作

文章目錄 Git(二):基本操作添加文件修改文件版本回退撤銷修改情況一:工作區的代碼還沒有 add情況?:已經 add 但沒有 commit情況三:已經 add 并且也 commit 刪除文件 Git(二):基本操作 添加文件 首先我們先來學習一個…

nginx + ffmpeg 實現 rtsp視頻實時播放和歷史播放

nginx和ffmpeg 的安裝請參考我的另一篇文章 Nginxrtmpffmpeg搭建視頻轉碼服務_nginx-rtmp-module-master-CSDN博客 目錄 1、整體方案設計如圖 2、nginx下目錄創建和配置文件創建 3、創建視頻流生成腳本 4、修改nginx配置 5、管理界面 (video.html) 6、ffmpeg后臺啟動 …

全國產!瑞芯微 RK3576 ARM 八核 2.2GHz 工業核心板—硬件說明書

前 言 本文為創龍科技 SOM-TL3576 工業核心板硬件說明書,主要提供 SOM-TL3576 工業 核心板的產品功能特點、技術參數、引腳定義等內容,以及為用戶提供相關電路設計指導。 為便于閱讀,下表對文檔出現的部分術語進行解釋;對于廣泛認同釋義的術語,在此不做注釋。 硬件參考…

web3 瀏覽器注入 (如 MetaMask)

以下是關于 瀏覽器注入方式(如 MetaMask) 的完整詳解,包括原理、使用方法、安全注意事項及常見問題解決方案: 1. 核心原理 當用戶安裝 MetaMask 等以太坊錢包擴展時,錢包會向瀏覽器的 window 對象注入一個全局變量 window.ethereum,這個對象遵循 EIP-1193 標準,提供與區…

解密提示詞工程師:AI 時代的新興職業

大家好!在人工智能飛速發展的當下,有一個新興職業正悄然崛起——提示詞工程師。他們雖不如數據科學家般廣為人知,卻在 AI 應用領域發揮著獨特且關鍵的作用。 何為提示詞工程師? 提示詞工程師專注于設計和優化與 AI 模型進行交互的提示詞&…

linux 下 jenkins 構建 uniapp node-sass 報錯

背景: jenkins 中構建 uniapp 應用 配置: 1. 將windows HbuilderX 插件目錄下的 uniapp-cli 文件夾復制到 服務器 /var/jenkins_home/uniapp-cli 2. jenkins 構建步驟增加 執行 shell ,內容如下 echo ">> 構建中..."# 打包前端 export LANGen_US.UTF-8…

QT常見問題(1)

QT常見問題(1) 1.問題描述 Qt在編譯器中直接運行沒有任何問題,但是進入exe生成目錄直接雙擊運行就報錯:文件無法定位程序輸入點_zn10qarraydata10deallocateepsyy于動態鏈接庫。 2.問題原因 這個錯誤通常是由于程序運行時找不…

『大模型筆記』第2篇:并發請求中的 Prefill 與 Decode:優化大語言模型性能

『大模型筆記』并發請求中的 Prefill 與 Decode:優化大語言模型性能 文章目錄 一. Token 生成的兩個階段:Prefill 和 Decode1.1. 指標分析1.2. 資源利用率分析二. 并發處理機制2.1. 靜態批處理 vs 持續批處理(Static Batching vs. Continuous Batching)2.2. Prefill 優先策略…

JVM(7)——詳解標記-整理算法

核心思想 標記-整理算法同樣分為兩個主要階段,但第二個階段有所不同: 標記階段: 與標記-清除算法完全一致。遍歷所有可達對象(從 GC Roots 開始),標記它們為“存活”。 整理階段: 不再簡單地清…

進程虛擬地址空間

1. 程序地址空間回顧 我們在學習語言層面時,會了解到這樣的空間布局圖,我們先對他進行分區了解: 如果以靜態static修飾的變量就會當成已初始化全局變量來看待,存放在已初始化數據區和未初始化數據區之前。 如果不用static修飾test…

C語言學習day17-----位運算

目錄 1.位運算 1.1基礎知識 1.1.1定義 1.1.2用途 1.1.3軟件控制硬件 1.2運算符 1.2.1與 & 1.2.2或 | 1.2.3非 ~ 1.2.4異或 ^ 1.2.5左移 << 1.2.6右移 >> 1.2.7代碼實現 1.2.8置0 1.2.9置1 1.2.10不借助第三方變量&#xff0c;實現兩個數的交換…

【linux】簡單的shell腳本練習

簡單易學 解釋性語言&#xff0c;不需要編譯即可執行 對于一個合格的系統管理員來說&#xff0c;學習和掌握Shell編程是非常重要的&#xff0c;通過shell程序&#xff0c;可以在很大程度上簡化日常的維護工作&#xff0c;使得管理員從簡單的重復勞動中解脫出來 用戶輸入任意兩…

機構運動分析系統開發(Python實現)

機構運動分析系統開發(Python實現) 一、引言 機構運動分析是機械工程的核心內容,涉及位置、速度和加速度分析。本系統基于Python開發,實現了平面連桿機構的完整運動學分析,包含數學建模、數值計算和可視化功能。 二、系統架構設計 #mermaid-svg-bT8TPKQ98UU9ERet {font…

工程師生活:清除電熱水壺(鍋)水垢方法

清除電熱水壺&#xff08;鍋&#xff09;水垢方法 水垢是水加熱時自然形成的鈣質沉淀物&#xff0c;常粘附在水壺內壁及發熱盤上。它不僅影響水的品質&#xff0c;還會縮短水壺的使用壽命&#xff0c;因此需要定期清除。建議根據各地水質不同&#xff0c;每年除垢 2 至 4 次。…

[分布式并行策略] 數據并行 DP/DDP/FSDP/ZeRO

上篇文章【[論文品鑒] DeepSeek V3 最新論文 之 DeepEP】 介紹了分布式并行策略中的EP&#xff0c;簡單的提到了其他幾種并行策略&#xff0c;但礙于精力和篇幅限制決定將內容分幾期&#xff0c;本期首先介紹DP&#xff0c;但并不是因為DP簡單&#xff0c;相反DP的水也很深&…

LeeCode144二叉樹的前序遍歷

項目場景&#xff1a; 給你二叉樹的根節點 root &#xff0c;返回它節點值的 前序 遍歷。 示例 1&#xff1a; 輸入&#xff1a;root [1,null,2,3] 輸出&#xff1a;[1,2,3] 解釋&#xff1a; 示例 2&#xff1a; 輸入&#xff1a;root [1,2,3,4,5,null,8,null,null,6,7…