2014.08.02
ขั้นตอนการหาอัตราการเปลี่ยนแปลงความสูงของแบบจำลอง
GTOPO30
ผมต้องการหาอัตราการเปลี่ยนแปลงความสูง
(Gradient)ของแบบจำลอง GTOPO30 ในทิศทางแกน X (Zonal)และ Y (Meridional)
ซึ่งให้สอดคล้องกับข้อมูลลม
เพื่อจะนำไปประมวลผลในขั้นต่อไป ขั้นตอนหลักๆคือ เฉลี่ย DEM หาGradientทั้งสองแกนในแต่ละค่าจุดภาพ
ส่งออกผลเป็นไบนารี่เพื่อแสดงใน Grads มาเริ่มกันเลย ยาวหน่อยครับ แถมเรื่องการคำนวนระยะทางบนพื้นผิวโลกให้ด้วยโดยสูตร Haversine ในฟังค์ชั่นนะครับ เด็กที่ชอบเรื่องแผนที่ทราบไว้ก็จะเยี่ยมเลย
1.
ดาวโหลดไฟล์แบบจำลองความสูงDEM GTOPO30 จาก https://lta.cr.usgs.gov/get_data
ทำการswap data ก่อน เช่น dd if=gt30e100n40.dem of=
DEM_tile_E100N40.dat conv=swab
2.
ใช้ฟอร์แทรนเฉลี่ย DEM จากนั้นหาGradientทั้งสองแกนในแต่ละค่าจุดภาพ และเก็บเป็นไบนารี่ตามข้างล่าง (ยาวมาก
แบบลูกทุ่งเลย) อย่าลืมเปลี่ยนขนาดของ Moving window ที่จะใช้เฉลี่ย DEM ด้วย
หากใช้เยอะจะเสียเวลามาก เช่นใช้ 10 pixel จะใช้เวลาประมาณ 5 นาทีแต่ละเครื่องไม่เท่ากัน
แล้วแต่สมรรถนะ
program
cal_dem_gradient
!---------------------------------------------------------------------------------------------------------
! 2014.08.01 NATTAPON MAHAVIK
! Smooth DEM,
Find Gradient in zonal and Meridional, write to binanry
! Please change
grd=10.0 as you like
! Haversine
codes :: http://rosettacode.org/wiki/Haversine_formula#Fortran
! Haversine
formula :: http://www.ig.utexas.edu/outreach/googleearth/latlong.html
!----------------------------------------------------------------------------------------------------------
implicit none
!-Variables for
DEM
character*150 :: infile_path
integer,parameter
:: row=6000,col=4800
integer,parameter
:: sizeofreal=4 !-record size
integer,parameter
:: sizeofint=2 !-record size
integer*2,dimension(col,row)
:: deml,demr !-dem left and
right tiles
real*4,dimension(col,row)
:: demn !-
restructure dem
integer ::
i,j,k,m,n
real,dimension(col,row)
:: demz,demm !- gradient
of DEM in zonal and meridional
real,parameter
:: min_elv=-1.0E+8 !- limit of
minimum elevation
real,parameter
:: max_elv= 1.0E+8 !- limit of
maximum elevation
real,parameter
:: na=-9999
real,parameter
:: res=0.008333333333333 !- DEM resolution in degree
real :: lat1,lon1 !- geographic
coordinate of considering pixel
real :: lat2,lon2 !- geographic
coordinate of neighboring pixel
real,parameter
:: ul_lon=100.0 !- geographic
coordinate of ul tile
real,parameter
:: ul_lat=40.0 !- geographic
coordinate of ul tile
integer,parameter
:: rgd=1 !- grid space [m]
real ::
grdz,grdm
!- gradient in zonal and meridional
real ::
delv
!- different of elevation in gradient
!-Variables for
smooth DEM
integer ::
si,ei,sj,ej
real,parameter :: grd=10.0 !-prefered
radius of grid from considering pixel[pixel] change!!!
real,dimension(col,row)
:: demsm !-smooth
dem output
real :: tdem
!-declare
variable
real ::
dist !-distance in meters
real ::
slope
!-atan(rise/run) in %
!-Function
calculating distance on sphere
real ::
haversine
!-Function name for calculating distance on sphere
infile_path='/home/mnattapon/RAID3storage4/research_icp/analysis_phb/beamblock_ans/dem_preparation/dem_raw_gtopo30/'
open(unit=10,file=trim(infile_path)//'E100N40.DEM2',form='unformatted',access='direct',recl=col*row*sizeofint)
print*,trim(infile_path)//'E100N40.DEM2'
read(10,rec=1)demr
close(10)
print*,'reading...'
do i=1,col
do j=1,row
m=col-i+1 !-col inverse
n=row-j+1 !-row inverse
demn(i,n)=demr(i,j)*1.0
enddo
enddo
print*,'smooth
DEM...'
do i=1,col
do j=1,row
!-start and end pixel of
defined radius
si=i-grd; ei=i+grd
sj=j-grd; ej=j+grd
!print*,i,j,si,ei,sj,ej
!-unwanted area
if ((i<=grd) .or. ((col-i)<=grd))
then
demsm(i,j)=na
cycle
endif
!-unwanted area
if ((j<=grd) .or. ((row-j)<=grd))
then
demsm(i,j)=na
cycle
endif
!-loop for average dem
tdem=0.0;k=0
do m=si,ei
do n=sj,ej
!-check outlier in dem
if
((demn(m,n)>max_elv).or.(demn(m,n)
cycle
endif
tdem=tdem+demn(m,n)
k=k+1
enddo
enddo
demsm(i,j)=tdem/k !-divided by total
number of pixel
!print*,'----------------------------------------------------------'
enddo
enddo
print*,'calculating
gradient of DEM ...'
do i=1,col
do j=1,row
!-unwanted area
if ((i<=rgd) .or. ((col-i)<=rgd))
then
demm(i,j)=na;demz(i,j)=na
cycle
endif
!-unwanted area
if ((j<=rgd) .or. ((row-j)<=rgd))
then
demm(i,j)=na;demz(i,j)=na
cycle
endif
!-calculate zonal gradient
lat1=ul_lat-(j*res)
lon1=ul_lon+((i+1)*res)
lat2=ul_lat-(j*res)
lon2=ul_lon+((i-1)*res)
dist=haversine(lat1,lon1,lat2,lon2) !-call function
delv=demsm(i+1,j)-demsm(i-1,j)
grdz=delv/dist
!-calculate meridional
gradient
lat1=ul_lat-(j+1*res)
lon1=ul_lon+(i*res)
lat2=ul_lat-(j-1*res)
lon2=ul_lon+(i*res)
dist=haversine(lat1,lon1,lat2,lon2) !-call function
delv=demsm(i,j+1)-demsm(i,j-1)
grdm=delv/dist
!-assign gradient to zonal
and meridional
demm(i,j)=grdm
demz(i,j)=grdz
enddo
enddo
!-write binary
file of zonal and meridional gradient for display in grads
open(unit=20,file='DEM_gradient_tile_E100N40_SM10.dat',form='unformatted',access='direct',recl=row*col*sizeofreal)
write(20,rec=1)demz
write(20,rec=2)demm
close(20)
print*,'done...'
endprogram
cal_dem_gradient
Real function haversine(dlat1,dlon1,dlat2,dlon2)
implicit none
real,intent(in) :: dlat1,dlon1,dlat2,dlon2 !- lat lon in degree converted to radian
real :: haversine !- distance will be return by this var
[m]
real :: lat1,lat2
real :: a,c
real, parameter :: pi = 4*atan(1.0) !- exploit intrinsic atan to generate pi
real,parameter :: rd=pi/180.0 !- radian conversion degree
to radian
real :: dlat,dlon !- difference in lat and lon in radian
real,parameter :: re=6372.8*1000.0 !- earth radius in m
dlat=(dlat2-dlat1)*rd
dlon=(dlon2-dlon1)*rd
lat1=dlat1*rd
lat2=dlat2*rd
!-Haversine formula
a=(sin(dlat/2))**2+cos(lat1)*cos(lat2)*(sin(dlon/2)**2)
c=2*atan2(sqrt(a),sqrt(1-a))
haversine=re*c
end function
haversine
3.
สร้าง Control file
ชื่อ “ctl_cal_dem_smooth_gradient_SM10.ctl”
dset
^DEM_gradient_tile_E100N40_SM10.dat
title
Gradient calculated from GTOPO30 map 0.008333333333333 deg
undef -9999.0
XDEF
4800 LINEAR 100
0.00833333333333
YDEF
6000 LINEAR -10
0.00833333333333
zdef 1 levels
0 1
tdef 1 linear
22Z24aug2010 1hr
vars 2
grdz 0 99 zonal gradient [unitless]
grdm 0 99 meridional gradient [unitless]
endvars
4.
เปิด GRADS แล้วลอง plot ภาพดูจะได้ดังภาพตัวอย่างข้างล่าง
เป็นการเปรียบเทียบอัตราการเปลี่ยนแปลงความสูงแต่ละระดับ Moving window จะเห็นว่าที่ไต้หวันเมื่อใช้
10 pixel
จะเห็นการเปลี่ยนแปลงความสูงชัดเจนคือสีแดงมีการลาดขึ้นส่วนสีน้ำเงินมีการลาดลงของภูมิประเทศในแนวแกน
X หรือ Zonal
direction
แถมให้นิดนึง ผมเปลี่ยนค่าสีตามโค้ดข้างล่างนะครับ ลองทำเล่นๆกันดู++
Open ctl_cal_dem_smooth_gradient_SM10.ctl
d demz
set rgb 16 0
0 255
set rgb 17 55
55 255
set rgb 18 110
110 255
set rgb 19 165
165 255
set rgb 20 220
220 255
set rgb 21 255
220 220
set rgb 22 255
165 165
set rgb 23 255
110 110
set rgb 24 255
55 55
set rgb 25 255
0 0
set gxout shaded
set
clevs -0.05 -0.04 -0.03 -0.02 -0.01 0.01 0.02 0.03 0.04 0.05
set
ccols 16 17 18 19 20 1 21 22 23 24 25
cbarn
ไม่มีความคิดเห็น:
แสดงความคิดเห็น