手搓柵格工具-山體陰影

一、概述

山體陰影工具通過為柵格中的每個像元確定照明度,來獲取表面的假定照明度。 通過設置假定光源的位置并計算每個像元相對于相鄰像元的照明度值來實現此目的。 它可以顯著增強用于分析或圖形顯示的表面的可視化效果,尤其是在使用透明度時。

默認情況下,陰影和光是與從 0 到 255(從黑色到白色遞增)的整數關聯的灰色陰影。

二、參數

1、太陽方位角

方向角指的是太陽的角度方向,是以北為基準方向在 0 到 360 度范圍內按順時針進行測量的。 90 度的方位角指向為東。 默認方位角為 315 度 (NW)。

2、太陽高度角

高度指的是照明源高出地平線的角度或坡度。 高度的單位為度,范圍為 0(位于地平線上)到 90(位于頭上)之間。 默認值為 45 度。

3、高程縮放因子

一個表面 z 單位中地面 x,y 單位的數量。

z 單位與輸入表面的 x,y 單位不同時,可使用 z 因子調整 z 單位的測量單位。 計算最終輸出表面時,將用 z 因子乘以輸入表面的 z 值。

如果 x,y 單位和 z 單位采用相同的測量單位,則 z 因子為 1。 這是默認設置。

如果 x,y 單位和 z 單位采用不同的測量單位,則必須將 z 因子設置為適當的因子,否則會得到錯誤的結果。 例如,如果 z 單位是英尺,而 x,y 單位是米,則應使用 z 因子 0.3048 將 z 單位從英尺轉換為米(1 英尺 = 0.3048 米)。

三、示例

下面的山體陰影示例的方位角為 315 度,高度角為 45 度,z因子為1.0。
喜馬拉雅山脈
原TIF為:
在這里插入圖片描述

四、gdal代碼實現

def calculateSlopeAndAspect(demData: Array[Float],width: Int,height: Int,demx: Double,   demy: Double, zFactor: Double): (Array[Float], Array[Float]) = {val slopeData = new Array[Float](width * height)val aspectData = new Array[Float](width * height)// 遍歷每個像素(跳過邊緣1像素,避免越界)for (y <- 0 until height - 1; x <- 0 until width - 1) {// 獲取3x3窗口的DEM值val z1 = demData((y - 1) * width + (x - 1))val z2 = demData((y - 1) * width + x)val z3 = demData((y - 1) * width + (x + 1))val z4 = demData(y * width + (x - 1))val z6 = demData(y * width + (x + 1))val z7 = demData((y + 1) * width + (x - 1))val z8 = demData((y + 1) * width + x)val z9 = demData((y + 1) * width + (x + 1))// x方向一階偏導數val dx = ((z3 + 2 * z6 + z9) - (z1 + 2 * z4 + z7)) / (8.0 * demx)// y方向一階偏導數val dy = ((z7 + 2 * z8 + z9) - (z1 + 2 * z2 + z3)) / (8.0 * demy)// 計算坡度// 公式:slope = arctan(zFactor * sqrt(dx2 + dy2))val slopeRad = atan(zFactor * sqrt(dx * dx + dy * dy))slopeData(y * width + x) = slopeRad.toFloat  // 弧度制坡度// 計算坡向var aspectRad = atan2(dy, -dx)  if (aspectRad < 0) {aspectRad += 2 * Pi  // 轉換為0~2π范圍}aspectData(y * width + x) = aspectRad.toFloat  // 弧度制坡向}(slopeData, aspectData)
}
def calculateHillShade(slopeData: Array[Float], aspectData: Array[Float], azimuth: Double, altitude: Double): Array[Float] = {//將角度值轉為弧度val azimuthRad = toRadians(azimuth)val altitudeRad = toRadians(altitude)val hillShadeData = new Array[Float](slopeData.length)for (i <- slopeData.indices) {val slope = slopeData(i)val aspect = aspectData(i)val hillShade = cos(altitudeRad) * cos(slope) + sin(altitudeRad) * sin(slope) * cos(azimuthRad - aspect)hillShadeData(i) = (255 * hillShade).toFloat}hillShadeData
}

五、geotrellis-raster代碼

def calculateHillshade(dem: Tile,cellSize: CellSize,solarAzimuth: Double,solarAltitude: Double,zFactor: Double): Tile = {val (cols, rows) = (dem.cols, dem.rows)val hillshade = ArrayTile.empty(DoubleConstantNoDataCellType, cols, rows)// 太陽參數轉換為弧度val azimuthRad = toRadians(solarAzimuth)val altitudeRad = toRadians(solarAltitude)val zenithRad = toRadians(90 - solarAltitude)def getZ(col: Int, row: Int): Double = {if (col < 0 || col >= cols || row < 0 || row >= rows) Double.NaNelse {val v = dem.getDouble(col, row)if (isNoData(v)) Double.NaN else v}}// 遍歷每個像素for (row <- 0 until rows; col <- 0 until cols) {val (z1, z2, z3) = (getZ(col-1, row-1), getZ(col, row-1), getZ(col+1, row-1))val (z4, z5, z6) = (getZ(col-1, row),   getZ(col, row),   getZ(col+1, row))val (z7, z8, z9) = (getZ(col-1, row+1), getZ(col, row+1), getZ(col+1, row+1))if (!e.isNaN && isData(e)) {// 計算x、y方向導數val dzdx = ((z3 + 2*z6 + z9) - (z1 + 2*z4 + z7)) / (8 * cellSize.width)val dzdy = ((z7 + 2*z8 + z9) - (z1 + 2*z2 + z3)) / (8 * cellSize.height)// 計算坡度(弧度)val slopeRad = atan(zFactor * math.sqrt(dzdx*dzdx + dzdy*dzdy))// 計算坡向(度)val aspectDeg = {if (dzdx == 0 && dzdy == 0) 0.0else {var aspect = math.toDegrees(atan2(dzdy, -dzdx))if (aspect < 0) aspect + 360 else aspect}}// 計算山體陰影val cosSlope = cos(slopeRad)val sinSlope = sin(slopeRad)val cosZenith = cos(zenithRad)val sinZenith = sin(zenithRad)val deltaAzimuth = azimuthRad - toRadians(aspectDeg)val cosDelta = cos(deltaAzimuth)val shade = math.max(0.0, cosZenith * cosSlope + sinZenith * sinSlope * cosDelta)hillshade.setDouble(col, row, (shade * 255.0))} else {hillshade.setDouble(col, row, Double.NaN)}}hillshade
}

六、3x3網格示例

在這里插入圖片描述

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

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

相關文章

Censtos docker安裝方法

#設置防火墻 systemctl stop firewalld.service setenforce 0 #安裝依賴包 yum install -y yum-utils device-mapper-persistent-data lvm2 #yum-utils&#xff1a;提供了 yum-config-manager 工具。 #device mapper&#xff1a; 是Linux內核中支持邏輯卷管理的通用設備映射機制…

單片機51 day46

單片機 一&#xff1a;基礎概念 一&#xff1a;單片機最小系統 單片機&#xff1a;電源時鐘&#xff08;晶振&#xff09;復位 //實現的最小組件 電源&#xff1a;5V直流 時鐘(晶振)&#xff1a;決定系統運行的速率 一般12M&#xff08;不超過50M&#xff09;&#xff0c…

【無標題】解鎖未來無線網絡的無限可能——Mesh自組網設備

在科技迅猛發展的今天&#xff0c;無線網絡已經成為了現代生活不可或缺的一部分。無論是在家庭中娛樂觀看視頻、在線游戲&#xff0c;還是在企業中進行辦公、遠程協作&#xff0c;網絡的穩定性和覆蓋范圍都直接影響著我們的使用體驗。傳統的Wi-Fi網絡在面臨多設備同時連接或大面…

Libevent(5)之使用教程(4)工具

Libevent(5)之使用教程(4)工具函數 Author: Once Day Date: 2025年8月3日 一位熱衷于Linux學習和開發的菜鳥&#xff0c;試圖譜寫一場冒險之旅&#xff0c;也許終點只是一場白日夢… 漫漫長路&#xff0c;有人對你微笑過嘛… 本文檔翻譯于&#xff1a;Fast portable non-blo…

Linux指令(3):

1. cal指令&#xff1a;我們的cal指令有日歷的意思看上面&#xff0c;我們輸入一個cal指令&#xff0c;可以查看當前月的日歷&#xff0c;我們給cal指令后面加上 - 3&#xff0c;他就會顯示這個月為中間的三個月的日歷&#xff0c;但是-4 不行&#xff0c;-5 也不行。只能 - 3。…

MLS平滑濾波

1.前言 最近在學習&#xff0c;因此查閱相關資料&#xff0c;該怎么表述感覺有些困難 2.代碼 2.1代碼1 使用全局坐標系 參考&#xff1a;python點云移動最小二乘法(Moving Least Squares)平滑_移動最小二乘法python-CSDN博客 def Moving_Least_Squares_Smoothing_v1_expla…

華為2288H V5服務器閃紅燈 無法開機案例

廣東某客戶1臺華為2288H V5服務器&#xff0c;由于單位外圍電力維修導致服務器有過一次異常斷電。結果來電之后發現服務器無法開機&#xff0c;開機面板上有個紅色心跳指示燈&#xff0c; 工程師到客戶現場后通過192.168.2.100登陸到2288H V5服務器的BMC管理口&#xff0c;打算…

SRIO入門之官方例程仿真驗證

仿真SRIO事務時序仿真之前先完成下面兩步操作&#xff1a;1.Vivado軟件版本2020.1&#xff0c;創建好工程及SRIO的IP核2.右鍵綜合化的IP核&#xff0c;然后選擇打開IP示例工程直接運行仿真分別將request和response兩個模塊添加到仿真窗口進行查看運行1000us左右就可以看到信號動…

CMake進階: 使用FetchContent方法基于gTest的C++單元測試

目錄 1.前言 2.FetchContent詳解 2.1.FetchContent簡介 2.2.FetchContent_Declare 2.2.1.簡介 2.2.2.關鍵特性 2.2.3.常見示例 2.3.FetchContent_MakeAvailable 2.3.1.簡介 2.3.2.核心功能與工作流程 2.3.3.示例用法 2.3.4.關鍵特性 2.3.5.常見問題與解決方案 3.…

亞馬遜廣告投放:如何減少無效曝光提高ROI

“為什么廣告花費高但轉化率低&#xff1f;”“如何判斷關鍵詞是否值得繼續投放&#xff1f;”“曝光量暴漲但訂單沒增加怎么辦&#xff1f;”“ACOS居高不下該如何優化&#xff1f;”“手動廣告和自動廣告的預算怎么分配&#xff1f;”如果你也在為這些問題頭疼&#xff0c;說…

Ethereum:擁抱開源,OpenZeppelin 未來的兩大基石 Relayers 與 Monitor

不知道大家是否注意到&#xff0c;OpenZeppelin 正在經歷一次重大的戰略轉型。他們決定在 2026 年 7 月 1 日正式關閉其廣受好評的 SaaS 平臺——Defender&#xff0c;并將重心全面轉向開源工具的建設。 這一舉動在社區引發了廣泛的討論&#xff0c;也標志著 OpenZeppelin 希望…

HFSS許可監控與分析

在電磁仿真領域&#xff0c;HFSS&#xff08;High Frequency Structure Simulator&#xff09;因其卓越的性能和廣泛的應用而受到用戶的青睞。然而&#xff0c;隨著企業和研究機構對HFSS使用需求的不斷增長&#xff0c;如何有效監控和分析HFSS許可證的使用情況&#xff0c;以確…

【前端:Html】--1.3.基礎語法

目錄 1.Html--文件路徑 2.Html--頭部元素 2.1.head元素 2.2.title元素 2.3.style元素 2.4.link元素 2.5.meta元素 2.6.script元素 2.7.base 3.Html--布局技巧 3.1.CSS Float 浮動布局 3.2.CSS Flexbox 布局 3.3.CSS Grid 網格布局 3.Html--響應式web設計 3.1.設…

Java 中 Nd4j 中的 INDArray 經過 reshape 之后數據丟失(rank = 0)

問題&#xff1a; 數據經過&#xff1a; INDArray inputArray Nd4j.create(input); // 將整個輸入數組轉換為 INDArray INDArray accs inputArray.get(NDArrayIndex.interval(0, imuNum * 3)).reshape(imuNum, 3, 1); // 加速度部分 INDArray oris inputArray.get(NDArrayIn…

正點原子阿波羅STM32F429IGT6移植zephyr rtos(四)---在獨立的應用工程里使用MPU6050

硬件平臺&#xff1a;正點原子阿波羅STM32F429IGT6 zephyr版本&#xff1a;Zephyr version 4.2.0 開發環境&#xff1a;wsl ubuntu 24.4 前景提要&#xff1a; 正點原子阿波羅STM32F429IGT6移植zephyr rtos&#xff08;三&#xff09;---創建一個獨立的應用工程-CSDN博客 一.修…

SAP_MMFI模塊-質保金標準解決方案詳解

一、業務背景 在許多企業的采購業務中,尤其是設備采購、工程項目或關鍵物料供應,通常會與供應商約定一筆質保金(或稱保留金)。這筆款項在貨物交付驗收后并不會立即支付,而是會被扣留一段時間(如一年),作為供應商產品質量的保證。 核心業務痛點: 在沒有系統化管理的…

Stanford CS336 assignment1 | Byte-Pair Encoding (BPE) Tokenizer

BPE一、 BPETrain1、 unicode standard and unicode encoding2、 子詞分詞(subword tokenization)3、 BPE的訓練a、 Vocabulary initializationb、 Pre-tokenizationc、 Compute BPE merges4、 train_BPE更多實現上的細節二、 BPETokenizerinit函數from_filesencodedecodeencod…

RockAI 的破壁之戰:Yan 架構如何啃下“端側煉丹”硬骨頭?

過去兩年&#xff0c;AI 模型的發展敘事幾乎被兩大陣營主導&#xff1a;無所不能的云端模型與充滿想象的端側模型。行業曾描繪一個誘人藍圖&#xff1a;隨著輕量化模型能力的提升&#xff0c;AI 終將擺脫云端束縛&#xff0c;在每個人的設備上實現永不離線的貼身智能。然而&…

交叉驗證:原理、作用與在機器學習流程中的位置

交叉驗證&#xff08;Cross-Validation&#xff09;是機器學習中評估模型性能、選擇最優參數和防止過擬合的核心技術。它在整個機器學習流程中扮演著關鍵角色。一、為什么需要交叉驗證&#xff1f;1. 解決訓練/測試劃分的局限性??問題??&#xff1a;隨機單次劃分訓練集/測試…

js怎么判斷一個未申明的變量?

在 JavaScript 中&#xff0c;判斷一個變量是否未聲明&#xff08;未定義&#xff09;需要特別注意&#xff0c;因為直接訪問未聲明的變量會拋出 ReferenceError 錯誤。 最安全的方式是使用 typeof 操作符&#xff0c;因為它對未聲明的變量操作時不會報錯&#xff0c;而是返回 …