使用(h3.js)繪制六角網格碼

今天來記錄一篇關于h3.js插件庫的使用,他可以很高效的計算出地球上某個經緯度坐標六邊形頂點。

前段時間領導突然給我個售前功能,要求是使用h3.js插件在地球上繪制出六邊形網格碼,本來以為挺棘手的,結果看完文檔后發現也挺簡單的,話不多說,開干...

h3.js

學前熱身

首先看幾張示意圖:

1. 基礎的六角網格

2. 可根據地球縮放層級的不同而渲染不同大小的六邊形

3. 右擊網格碼,可以變換底色

4. 可以根據隨機給六角網格添加顏色區分

?實現思路
準備

首先給項目安裝相關依賴

npm install h3-js

或者

pnpm install h3-js

?當然如果我們不是vue等框架項目,也無所謂,只需要引入h3.js的js文件即可。

<script src="https://unpkg.com/h3-js"></script>

?實現

useHexagonTrellisCode?是一個基于 Cesium 和 H3 庫的六邊形網格碼可視化工具,用于在地圖上生成和顯示 H3 六邊形網格系統。

其中我們實現時需要用到幾個h3.js自帶的api,大家想了解的可以去官網看看。

polygonToCells, cellToLatLng, latLngToCell, cellToBoundary, getHexagonEdgeLengthAvg, UNITS

?我將本次編輯的代碼整合到一個類中,下面是使用方法:

初始化
import * as Cesium from 'cesium';
import { useHexagonTrellisCode } from './useHexagonTrellisCode';// 創建Cesium Viewer
const viewer = new Cesium.Viewer('cesiumContainer');// 初始化配置,參數下面有簡介
let option = {level: 6,                  // 網格層級 (3-6)polygonArea: [             // 初始繪制區域,注意這里是緯度在前,經度在后[緯度1, 經度1],[緯度2, 經度2],[緯度3, 經度3]],isSort: true,              // 是否對六邊形進行排序(可選)Mark_color: ["#00ffff85"]   // 標記顏色(可選)
}// 初始化六邊形網格碼工具
const hexagonTool = new useHexagonTrellisCode(viewer, option);// 是否顯示標簽(可選)
hexagonTool.showLabel();// 渲染網格
hexagonTool.render();
參數配置(option)
參數類型默認值說明
levelnumber6H3網格層級 (3-6)
isPolygonFullDrawbooleanfalse是否根據視口大小繪制圖形(還在實驗中)
isSortbooleanfalse是否對六邊形進行排序
Mark_colorstring[]["#00ffff85", "#a605ff85", "#ffce0585", "#05ff1d85"]標記顏色數組
polygonAreanumber[][][]定義繪制六邊形網格碼的區域
?主要方法

1、顯示標簽

showLabel()

2、渲染網格

render()

3、高亮選中的六邊形

/*** longitude: 經度* latitude: 緯度* option: 可選配置,如 { selectColor: "red" }*/
select_high_lightObject(longitude, latitude, option)

4、設置網格層級

setLevel(level)

5、設置繪制區域

setPolygonArea(position)

6、銷毀實例

destory()
使用示例

1、基本使用

const useHexagonTrellis = new useHexagonTrellisCode(viewer, {level: 5,polygonArea: [[39.9, 116.3],[39.9, 116.5],[40.1, 116.5],[40.1, 116.3]]
}).showLabel().render();

2、交互示例

// 點擊地圖高亮六邊形
viewer.screenSpaceEventHandler.setInputAction(function(movement) {const pickedObject = viewer.scene.pick(movement.endPosition);if (pickedObject && pickedObject.id) {const cartographic = Cesium.Cartographic.fromCartesian(pickedObject.id);const longitude = Cesium.Math.toDegrees(cartographic.longitude);const latitude = Cesium.Math.toDegrees(cartographic.latitude);useHexagonTrellis.select_high_lightObject(longitude, latitude, {selectColor: "#ff0000"});}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

3、動態調整層級

viewer.camera.changed.addEventListener(() => {const height = viewer.camera.positionCartographic.height;if (viewer.scene.mode === Cesium.SceneMode.SCENE3D) {let level = Math.floor(Math.log2(2.0e7 / height));useHexagonTrellis.setLevel(level);}
})
主要代碼
import * as Cesium from 'cesium'
import { polygonToCells, cellToLatLng, latLngToCell, cellToBoundary, getHexagonEdgeLengthAvg, UNITS } from "h3-js";
export class useHexagonTrellisCode {viewer = null;hexgonIds = [];/*** 所有六邊形圖元*/PrimitiveMain = null;/*** 選中時所顯示的圖元*/selectPrimitive = null;/*** 編碼標簽的集合*/labelsCollection = null;/*** 標識圓的所有圖元集合*/_circles = [];config = {level : 6,      // 當前層級isPolygonFullDraw: false,   // 是否根據視口大小繪制圖形isSort: false,      // 是否排序Mark_color: ["#00ffff85", "#a605ff85", "#ffce0585", "#05ff1d85"],    // 是否在六邊形上添加透明圖元polygonArea: [],    // 定義繪制六邊形網格碼的區域}/*** useHexagonTrellisCode 生成六邊形網格碼* @param {*} viewer * @param {*} option * @returns */constructor (viewer, option) {this.viewer = viewer;this.config = {...this.config,...option};return false;}/*** 開啟標簽顯示* @returns */
/*** longitude: 經度* latitude: 緯度* option: 可選配置,如 { selectColor: "red" }*/showLabel() {this.labelsCollection && this.viewer.scene.primitives.remove(this.labelsCollection);this.labelsCollection = new Cesium.LabelCollection();this.viewer.scene.primitives.add(this.labelsCollection);return this;}/*** 渲染* @returns */render() {if (this.config.polygonArea.length == 0) {return false;}this.clearOldPrimitive();const hexagons = polygonToCells(this.config.polygonArea, this.config.level);this.hexgonIds = hexagons;let _hexagons_center = hexagons;// 添加排序if (this.config.isSort) {let _hexagons = hexagons.map(hexId => {const center = cellToLatLng(hexId);return {hexId, lon:center[1], lat: center[0]}})_hexagons_center = _hexagons.sort((a, b) => {if (a.lat !== a.lat) return b.lat - a.lat;return a.lon - b.lon;}).map(t => t.hexId)}this.PrimitiveMain = this.createPrimitive_line();let instances = [];let drawNum = 0;_hexagons_center.forEach((hexId) => {instances.push(this.createHexagonInstance_line(hexId))if (this.config.Mark_color.length > 0 && drawNum++ < this.config.Mark_color.length) {this.drawCircles(hexId, this.config.Mark_color[drawNum]);}if (this.labelsCollection) this.addLabel(hexId);})this.PrimitiveMain.geometryInstances = instances;return this.viewer.scene.primitives.add(this.PrimitiveMain);}/*** 根據視口繪制六邊形* 實驗中...*/drawPolygonByViewFull() {// 判斷選中區域是否在視口內let isPolygonFull = this.isPolygonFullyInViewport(this.config.polygonArea);if (isPolygonFull == 0) {console.log("111")return false;}if (isPolygonFull == 2) {console.log("222")return this.render();}console.log("333")const viewRectangle = this.viewer.camera.computeViewRectangle();let position = [[Cesium.Math.toDegrees(viewRectangle.west),Cesium.Math.toDegrees(viewRectangle.south)],[Cesium.Math.toDegrees(viewRectangle.east),Cesium.Math.toDegrees(viewRectangle.south)],[Cesium.Math.toDegrees(viewRectangle.east),Cesium.Math.toDegrees(viewRectangle.north)],[Cesium.Math.toDegrees(viewRectangle.west),Cesium.Math.toDegrees(viewRectangle.north)]]this.removeLabelCollection();const _hexagons = polygonToCells(position, this.config.level);let instances = [];this.hexgonIds.forEach(hexId => {if (_hexagons.includes(hexId)) {instances.push(this.createHexagonInstance_line(hexId))if (this.labelsCollection) this.addLabel(hexId);}})this.PrimitiveMain.geometryInstances = instances;return true;}/*** 添加label標簽* @param {*} hexId * .padEnd(this.config.labelLenght || 5, '0')*/addLabel(hexId){let lonlat = cellToLatLng(hexId);this.labelsCollection.add({position : Cesium.Cartesian3.fromDegrees(lonlat[1], lonlat[0]),text : hexId.replace(/[^\d]/g,''),font : `${this.config.labelSize || 16}px sans-serif`,horizontalOrigin : Cesium.HorizontalOrigin.CENTER,verticalOrigin : Cesium.VerticalOrigin.BOTTOM,})}/*** 通過經緯度添加選中效果* @param {*} longitude * @param {*} latitude * @param {*} option * @returns */select_high_lightObject(longitude, latitude, option) {if(!longitude || !latitude || this.config.level == -1) {return false;}let _code = latLngToCell(latitude, longitude,this.config.level);if (this.hexgonIds.includes(_code)) {// 刪除之前高亮圖元this.viewer.scene.primitives.remove(this.selectPrimitive); this.selectPrimitive = this.createPrimitive_polygon();this.selectPrimitive.geometryInstances = [ this.createHexagonInstance_polygon(_code, option.selectColor || "red") ];this.viewer.scene.primitives.add(this.selectPrimitive);return true;}else {return false;}}/*** 繪制圓* @param {*} hexId */drawCircles(hexId, color) {// 繪制填充多邊形let polygon = this.createPrimitive_polygon();let geomtry = this.createHexagonInstance_polygon(hexId, color || "red");polygon.geometryInstances = geomtry;this._circles.push(polygon);this.viewer.scene.primitives.add(polygon);// 繪制圓let _circle = this.createPrimitive_circle();let instance = [];let distance = parseInt(getHexagonEdgeLengthAvg(this.config.level, UNITS.m)) * (Math.random() * (0.9 - 0.2) + 0.2);let colors = ["#098", "#af2","#f2a","#b2a"];for (let i=0; i<4; i++){let radius = distance - (distance * (i / 5));// 使用疊加法繪制原型輪廓線for (let j=0; j< 30; j++){instance.push(this.createHexagonInstance_circle(hexId, radius - j,colors[i]))}}_circle.geometryInstances = instance;this._circles.push(_circle);this.viewer.scene.primitives.add(_circle);}/*** 刪除選中后添加的高亮圖元*/remove_select_primitive() {this.selectPrimitive && this.viewer.scene.primitives.remove(this.selectPrimitive);}/*** 添加線類型Primitive* @returns */createPrimitive_line() {return new Cesium.Primitive({geometryInstances: [],appearance: new Cesium.PolylineColorAppearance({translucent: false,renderState: {depthTest: { enabled: false }, // 關閉深度測試blending: Cesium.BlendingState.ALPHA_BLEND,depthMask: false,    // 關鍵:禁止寫入深度緩沖區}}),asynchronous: false});}/*** 添加圓類型Primitive* @returns */createPrimitive_circle() {return new Cesium.Primitive({geometryInstances: [],appearance: new Cesium.PerInstanceColorAppearance({translucent: false,closed: false,flat: true,renderState: {depthTest: { enabled: false }, // 關閉深度測試blending: Cesium.BlendingState.ALPHA_BLEND,depthMask: false    // 關鍵:禁止寫入深度緩沖區}}),asynchronous: false});}/*** 添加多邊形類型Primitive* @returns */createPrimitive_polygon() {return new Cesium.Primitive({geometryInstances: [],appearance: new Cesium.PerInstanceColorAppearance({translucent: false,closed: false,renderState: {depthTest: { enabled: false }, // 關閉深度測試blending: Cesium.BlendingState.ALPHA_BLEND,depthMask: false,    // 關鍵:禁止寫入深度緩沖區}}),asynchronous: false});}/*** 添加圓類型GeometryInstance* @param {*} hexId * @param {*} radius * @param {*} color * @returns */createHexagonInstance_circle(hexId, radius = 5, color = "blue") {const coordinates = cellToLatLng(hexId, true); // 獲取六邊形邊界const center = Cesium.Cartographic.fromDegrees(coordinates[1], coordinates[0]);const _center = Cesium.Cartesian3.fromRadians(center.longitude,center.latitude, 0);return new Cesium.GeometryInstance({geometry: new Cesium.CircleOutlineGeometry({center: _center,radius: isNaN(radius) ? 5 : radius}),attributes: {color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.fromCssColorString(color))},id: hexId // 保存H3 ID以便交互});}/*** 添加線類型GeometryInstance* @returns */createHexagonInstance_line = (hexId, color = "#008df1a3") => {const coordinates = cellToBoundary(hexId, true); // 獲取六邊形邊界const positions = coordinates.map(coord => Cesium.Cartesian3.fromDegrees(coord[0], coord[1]));return new Cesium.GeometryInstance({geometry: new Cesium.PolylineGeometry({positions: positions,width : 2.0}),attributes: {color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.fromCssColorString(color))},id: hexId // 保存H3 ID以便交互});}/*** 添加多邊形類型GeometryInstance* @returns */createHexagonInstance_polygon(hexId, color = "#008df1a3") {const coordinates = cellToBoundary(hexId, true); // 獲取六邊形邊界const positions = coordinates.map(coord => Cesium.Cartesian3.fromDegrees(coord[0], coord[1], 200));return new Cesium.GeometryInstance({geometry: new Cesium.PolygonGeometry({polygonHierarchy: new Cesium.PolygonHierarchy(positions),height: 20 // 可選高度}),attributes: {color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.fromCssColorString(color))},id: hexId // 保存H3 ID以便交互});}/*** 判斷當前選中的區域是否在全視口內* @param {*} positions * @returns *      0: 全不在視口中,不需要渲染*      1: 所選區域部分在視口內*      2: 所選區域全部在視口內*/isPolygonFullyInViewport(positions) {const viewRectangle = this.viewer.camera.computeViewRectangle();if (!viewRectangle || !positions || positions.length < 3) return 0;const _positions = positions.map(t => new Cesium.Cartographic(t[1],t[0]));let polygonRectangle  = this.createValidRectangle(_positions);console.log(viewRectangle, polygonRectangle);// 所選區域全部在視口內if (_positions.every(t => Cesium.Rectangle.contains(viewRectangle, polygonRectangle))) {return 2;}// 所選區域全部不在視口內if (!_positions.some(t => Cesium.Rectangle.contains(viewRectangle, polygonRectangle))) {return 0;} else {// 所選區域部分在視口內return 1;}}// 輔助方法:創建有效的RectanglecreateValidRectangle(cartographics) {// 1. 計算邊界const west = Math.min(...cartographics.map(c => c.longitude));const south = Math.min(...cartographics.map(c => c.latitude));const east = Math.max(...cartographics.map(c => c.longitude));const north = Math.max(...cartographics.map(c => c.latitude));// 2. 驗證范圍if (west >= east || south >= north) {console.warn("無效的坐標范圍:", {west, south, east, north});return null;}// 3. 返回有效的Rectanglereturn Cesium.Rectangle.fromDegrees(west, south, east, north);}/*** 重置層級* @param {*} level 限制 最大是6 最小是3*/setLevel(level) {let _level= Math.max(Math.min(level, 6), 3);if (Object.is(this.config.level, _level)) return false;this.config.level = _level;return this.config.isPolygonFullDraw ? this.drawPolygonByViewFull() : this.render();;}/*** 重新選擇生成網格碼的區域* @param {*} position */setPolygonArea(position) {this.config.polygonArea = position;this.config.isPolygonFullDraw ? this.drawPolygonByViewFull() : this.render();}/*** 刪除標簽*/removeLabelCollection() {this.labelsCollection && this.labelsCollection.removeAll();}/*** 刪除可視化圖元*/clearOldPrimitive() {this.remove_select_primitive();this.PrimitiveMain && this.viewer.scene.primitives.remove(this.PrimitiveMain);this._circles.forEach(item => this.viewer.scene.primitives.remove(item));this.removeLabelCollection();}/*** 銷毀示例*/destory() {this.clearOldPrimitive();}
}

如何我們不是vue等框架項目,不容易用import和export方法來導出、引入的話,我們可以script標簽方式引入,然后在所有api前添加h3.就行了(如:h3.cellToLatLng(xxx)即可)。最后將export去掉,底部添加window.useHexagonTrellisCode = useHexagonTrellisCode;代碼就可以了。

最后想法

如果哪位同賽道的同事發現問題或者有更好的建議可以私信我,一起努力哦,

最后!!!

啥也不想說了,睡覺...

明天還要出差呢,牛馬的每一天(_ _)( - . - )(~O~)……( - . - )

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

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

相關文章

GO 1.25

Go 1.25 發布說明&#xff08;草案&#xff09; Go 1.25 尚未發布。 本文檔是正在編寫中的發布說明。Go 1.25 預計于 2025 年 8 月發布。 語言變更 Go 1.25 中沒有影響 Go 程序的語法變更。然而&#xff0c;在語言規范中&#xff0c;“核心類型”&#xff08;core types&…

解析Android SETUP_DATA_CALL 鏈路信息字段

Android 對象返回的log信息經常都不是標準的JSON字符串,排查字段不直觀,比如下面的日志: 06-13 15:56:36.204 8076 8407 D RILJ : [1655]> SETUP_DATA_CALL,reason=NORMAL,accessNetworkType=EUTRAN,dataProfile=[DataProfile=[ApnSetting] IMS, 2318, 310260, ims,…

跨語言RPC:使用Java客戶端調用Go服務端的HTTP-RPC服務

在構建分布式系統時&#xff0c;實現不同編程語言之間的無縫通信是一個常見的需求。本文將詳細介紹如何使用Go語言創建一個HTTP-RPC服務&#xff0c;并通過Java客戶端進行遠程調用。我們將探索整個過程&#xff0c;包括服務端的實現、客戶端的編寫以及測試驗證。 一、背景介紹…

CVPR2024遷移學習《Unified Language-driven Zero-shot Domain Adaptation》

摘要 本文提出了一個名為 Unified Language-driven Zero-shot Domain Adaptation&#xff08;ULDA&#xff09;的新任務設置&#xff0c;旨在使單一模型能夠適應多種目標領域&#xff0c;而無需明確的領域標識&#xff08;domain-ID&#xff09;知識。現有語言驅動的零樣本領域…

AI安全風險監測平臺:全周期防護體系構建

AI安全風險監測平臺通過構建全生命周期防護體系&#xff0c;實現對人工智能系統研發、部署、運行、迭代各階段的安全風險動態監測。該平臺融合算法審計、行為分析、合規驗證等核心能力&#xff0c;建立覆蓋模型安全、數據安全、應用安全的立體防御網絡&#xff0c;為智能系統提…

數據集-目標檢測系列- 杯子 數據集 bottle >> DataBall

數據集-目標檢測系列- 杯子 數據集 bottle &#xff1e;&#xff1e; DataBall 貴在堅持&#xff01; * 相關項目 1&#xff09;數據集可視化項目&#xff1a;gitcode: https://gitcode.com/DataBall/DataBall-detections-100s/overview 2&#xff09;數據集訓練、推理相關…

視頻點播web端AI智能大綱(自動生成視頻內容大綱)的代碼與演示

通過AI技術將視頻課程自動生成結構化大綱和摘要&#xff0c;支持PPT教學視頻、企業內訓等場景應用。核心功能包括&#xff1a;自動匹配視頻知識點生成文本大綱、快速內容定位、降低課程制作成本。系統采用模塊化架構&#xff0c;包含Vue2.7前端組件、JS邏輯庫和演示項目&#x…

Linux: errno: EINPROGRESS-115

在connect接口的使用說明里&#xff0c;有這個錯誤&#xff1a;EINPROGRESS。 The socket is nonblocking and the connection cannot be completed immediately. It is possible to select(2) or poll(2) for completion by selecting the socket for writing. After select(2…

Node.js特訓專欄-基礎篇:3. Node.js內置模塊的使用

&#x1f525; 歡迎來到 Node.js 實戰專欄&#xff01;在這里&#xff0c;每一行代碼都是解鎖高性能應用的鑰匙&#xff0c;讓我們一起開啟 Node.js 的奇妙開發之旅&#xff01; Node.js 特訓專欄主頁 Node.js內置模塊&#xff1a;強大功能的基石 在Node.js的世界里&#xff…

基于MATLAB實現的Capon、MUSIC、ESPRIT和PM算法進行DOA

使用Capon、MUSIC、ESPRIT和PM多種算法進行doa估計&#xff0c;通過譜峰搜索函數估計到達角&#xff0c;并使用蒙特卡洛方法估計各算法的RMSE。&#xff08;可能計算時間較長&#xff0c;如需節省時間可以減小蒙特卡洛次數&#xff09; PM.m , 574 RMSE.m , 274 TLS_ESPRIT.m …

某網站極驗4滑塊驗證碼逆向分析

文章目錄 1. 寫在前面2. 接口分析3. w逆向分析4. JSON參數分析5. 距離識別6. RSA純算還原7. AES純算還原【??作者主頁】:吳秋霖 【??作者介紹】:擅長爬蟲與JS加密逆向分析!Python領域優質創作者、CSDN博客專家、阿里云博客專家、華為云享專家。一路走來長期堅守并致力于…

深入理解 C++ inline:三大語法特性 + 七大高頻考點全解析

一、什么是內聯函數 編譯器嘗試將 inline 函數的代碼直接插入調用處&#xff08;類似宏展開&#xff09;&#xff0c;避免函數調用的壓棧、跳轉、返回等額外開銷。適用于短小頻繁調用的函數&#xff1a;如簡單的 getter/setter、數學運算等。inline 只是 建議&#xff0c;編譯…

Flink 與 Hive 深度集成

引言 在大數據生態中&#xff0c;Flink 的流批一體化處理能力與 Hive 的數據存儲分析優勢結合&#xff0c;通過 Flink Connector for Hive 實現無縫對接&#xff0c;能顯著提升數據處理效率。本文將系統解析 Flink 與 Hive 集成的核心操作&#xff0c;涵蓋配置、讀寫、優化全流…

Axios面試常見問題詳解

axios面試常問題目及其詳解 以下是前端面試中關于 Axios 的常見問題及詳細解答&#xff0c;涵蓋核心原理、實戰場景和進階優化&#xff0c;幫助你在面試中清晰展示技術深度。 1. Axios 是什么&#xff1f;它與原生 Fetch API 有何區別&#xff1f; 回答要點&#xff1a; Axi…

14.2 《3小時從零搭建企業級LLaMA3語言助手:GitHub配置+私有化模型集成全實戰》

3小時從零搭建企業級LLaMA3語言助手&#xff1a;GitHub配置私有化模型集成全實戰 關鍵詞&#xff1a;GitHub 倉庫配置, 項目初始化, 目錄結構設計, 私有化模型集成, 開發環境標準化 Fork 并配置 GitHub 項目倉庫 本節將手把手完成 LanguageMentor 項目的倉庫克隆、環境配置和…

生物制藥自動化升級:Modbus TCP與Ethernet/IP協議轉換實踐

為優化生物制藥生產流程&#xff0c;我司計劃將現有的Allen-Bradley PLC控制系統與新型生物反應器進行集成。由于兩者采用不同的通信協議&#xff08;AB PLC使用Modbus TCP&#xff0c;而生物反應器支持Ethernet/IP&#xff09;&#xff0c;直接通信存在障礙。為此通過穩聯技術…

商業云手機核心優缺點分析

商業云手機核心優缺點分析&#xff0c;綜合技術性能、成本效率及場景適配性等多維度對比&#xff1a; 核心優勢? 成本革命? 硬件零投入?&#xff1a;免除實體手機采購&#xff08;旗艦機均價6000元&#xff09;&#xff0c;企業百臺規模可省60萬 CAPEX。 彈性計費?&…

Windows 遠程桌面添加 SSL 證書指南

Windows 遠程桌面添加 SSL 證書指南 &#x1f9fe; 準備工作&#x1f510; 第一步&#xff1a;使用 Certbot 申請 SSL 證書&#x1f4e6; 第二步&#xff1a;生成 PFX 格式證書文件&#x1f4c1; 第三步&#xff1a;導入證書到 Windows 證書管理器&#x1f512; 第四步&#xf…

項目實訓技術實現——核心關鍵:基于二叉分割的布局生成算法

核心關鍵&#xff1a;基于二叉分割的布局生成算法 上一篇針對llava這種為每個元素分別預測每個元素的框的方法進行了分析&#xff0c;已經證實這條路難以行得通。因此&#xff0c;我們考慮直接按照板塊劃分整個背景布局&#xff0c;然后在板塊內&#xff0c;進一步劃分出我們需…

uniapp 配置devserver代理

在uniapp項目中配置devserver代理&#xff0c;需要先檢查用的vue版本。 vue3不能在manifest.json配置代理。 1.先檢查項目用的vue版本 找到manifest.json文件查看vue的版本。 2.vue2在manifest.json內配置 "h5" : { "devServer": { …