這學期的設計課涉及到了高速公路,鐵路等一系列交通基礎設施。我的設計範圍內既有架起的高速,又有下陷的高速,鐵路也在不同的標高上,外加自然的地形起伏,整個基地的高度變化十分豐富。所以需要很高精度(精確到米級的)的地形數據來進行一系列建模和分析。
先是嘗試在「地理空間數據云」這個網站尋找。這個網站提供GDEMEDM 30M的解析度的數字高程數據,按照經緯度條帶號來檢索。這個數據對於我而言有兩大短處:(1)數據精度不夠。在詳細設計中2m的高差已經很了不得了,這個數據的精度完全達不到這個要求(2)按照經緯度條帶號下載的數據範圍極大。在如此巨大的範圍中極難準確定位自己的基地。
聯想到谷歌地圖的移動端有地形的顯示
所以想到谷歌地圖可能提供了比較詳細的高程數據。
上網一搜,果不其然,谷歌地圖提供了Google Maps Elevation API,可以非常方便地獲取指定範圍內的地形數據。
下面簡單說一下怎麼做。
第一步你需要一個gmail,也就是谷歌的帳號(這一步就會難倒國內大部分人==)
第二步:登陸https://console.cloud.google.com/appengine,利用自己的帳號去創建appid,每個谷歌帳號可以創建多個appid,有了這些appid之後,你可以為每個id申請不同的api密鑰。或者直接登陸:https://developers.google.com/maps/documentation/elevation/intro?hl=zh-cn
點擊「獲取密鑰」
每個密鑰每天2500次免費請求,每次請求最多512個位置。每個人擁有的密鑰上限不確定(多年前我為了用gogent翻牆,申請了12個appid,所以應該可以有12個密鑰)。
第三步:向谷歌發送請求,谷歌返回高程值。
引用一個谷歌官方開發文檔的說明:
下例請求以 JSON 格式返回科羅拉多州「裡高城」丹佛的海拔高度:https://maps.googleapis.com/maps/api/elevation/json/locations=39.7391536,-104.9847034&key=YOUR_API_KEY
這個api要求的參數不多,簡單點來說就你你給他一個標準的經緯度,他就以json的格式給你返回高程。
不會寫代碼?沒關係,網上早就有大神幫我們寫好了!大家複製—粘貼—運行即可:)
import googlemaps
import numpy as np
def request_elevation(xmin, xmax, xinc, ymin, ymax, yinc, maxnum=512):
xlist = np.arange(xmin, xmax, xinc)
ylist = np.arange(ymin, ymax, yinc)
points = [(y, x) for y in ylist for x in xlist]
requestnum = int(np.floor(len(points) / maxnum) + 1)
npoints = np.array_split(points, requestnum)
if requestnum > 2500:
print("Error: Request number exceed! Change grid or region.")
return [gmaps.elevation(locations=loc.tolist()) for loc in npoints]
# 設置要下載高程數據的經度範圍、緯度範圍以及網格間隔
xmin, xmax, xinc = 7.720972, 7.740003, 0.0001
ymin, ymax, yinc = 48.579339, 48.591174, 0.0001
gmaps = googlemaps.Client(key='AIzaSyC37qhvBNXp4Y3u-hBrITP-kooJx_Unidc')
# Generate all locations
elevations = request_elevation(xmin, xmax, xinc, ymin, ymax, yinc)
# output data with format `longitude latitude elevation resolution`
with open("Elevations.dat", "w") as f:
for loclist in elevations:
for subloc in loclist:
outputstr = "{:.5f} {:.5f} {:.5f} {:.5f}\n".format(
subloc['location']['lng'],
subloc['location']['lat'],
subloc['elevation'],
subloc['resolution'])
f.writelines(outputstr)
以上代碼來自「GMT中文社區」,作者SeisPider。
在我看來,這個代碼的機智之處在於他在一次請求裡塞了512個位置。這樣充分利用2500次請求的話,就有128萬個位置。這麼多位置可以構成一個相當可觀的面積。
需要注意的是,谷歌地圖接受的是經緯度坐標,而我們做設計的有的時候更需精確的距離。比如這個地方我需要每隔5米選一個點來測量高程,這個時候就會涉及到一個經緯度和米之間的換算,簡單來說:經緯度偏差0.00001度相當於偏差1米(代碼裡的函數裡有參數,可以修改)
運行上述代碼成功的話會產生一個.dat的文件,獲得的數據如圖:
第一列經度,第二列緯度,第三列獲得的高程,第四列點與點之間的距離。我們看一下第三列的數據精度,我只能說:鵝妹子嚶!!!
將上述數據導入GIS可視化
(紅色代表高的地方,綠色代表低的地方,藍色的線是高架,灰色的線是鐵路)
低於地面的高速公路和高於地面的高速公路和自然的坡地的地形變化,一目了然!
有了這些精度的數據,我就能對這些場地做更加複雜的豎向設計,而不是把他當成一個平地來設計了。
收集基地的數據只是設計過程中必要的一小步,真正難的地方還是我們如何設想這個場地的未來以及如何真正地做一個設計:)
最後說一個題外話:)
去年暑假有邢臺市有一場大洪水,非常可怕,很多村民在睡夢之中被奪去了生命。這個事情發生後,關於洪水的起因竟然爭執不下。
網上各路大神各種分析,說是上遊水庫洩洪,有人說是附近某條河的鍋;當時我就想找那個地區的地形數據做個洪水的淹沒分析,結果國內提供的數據精度真的差的根本不能分析。我想如果國內能沒有這堵牆或者提高一些數據質量,受益的可不僅僅是我們設計領域的人哦。。。
(文中提到代碼的出處:http://gmt-china.org/blog/google-maps-elevation-api/,關於一些技術細節,這個帖子說得更充分,想要更加深入地了解,建議去看谷歌說明文檔)
版權聲明
本文版權歸本人所有,轉載請聯繫本人!!!