【資料名稱】:mapinfo中繪制基站扇形的算法討論和工具共享(原創(chuàng))
【資料作者】:YZL
【資料日期】:2009.01
【資料語言】:中文
【資料格式】:其它
【資料目錄和簡介】:
mapinfo中繪制基站扇形的算法討論和工具共享. 討論5種算法并將我以前弄的一個工具貢獻給大家試試
----------------------討論和說明-----------------------------
很多同仁在論壇中談?wù)撘沧约壕幊套隽艘恍┗旧葏^(qū)(扇形、直線)圖形繪制工具,包括很多規(guī)劃軟件都有一個問題
就是生成的扇形圖形在mapinfo等gis系統(tǒng)中有一定失真。當(dāng)然由網(wǎng)友說這點失真可能不算啥了,如果是這樣你就不必看下面的方法了。
下面以MAGPINFO為例來說明,MAPINFO采用的WGS-84橢球體坐標(biāo)系,而我們?nèi)粘R话懔?xí)慣于在笛卡爾坐標(biāo)系中處理,這也是處理容易失真原因
我總結(jié)了一下,很多人在編制mapinfo下生成扇形圖形的時候有如下做法:
方法1:(極端做法):直接將直角坐標(biāo)用于計算,如:x=r*cos(theta) ,y=r*sin(theta)這種做法完全將一個地球球體表面當(dāng)成平面來處理,這種做法失真最大(當(dāng)然如果地表面積足夠小的時候誤差也不是很明顯)。這種做法論壇里很多excel2ge/excel2mapinfo都是這種方法。我個人認(rèn)為此方法不可取。
方法2:采用直角坐標(biāo)到經(jīng)緯度的近似轉(zhuǎn)換關(guān)系計算,這種算法采用經(jīng)緯度和直角坐標(biāo)之間 的簡單關(guān)系【/ (69.093 * 1609) 】。如網(wǎng)上的“[vb+Mapx]實現(xiàn)扇區(qū)三葉草圖形" ,大家可以搜索學(xué)習(xí)一下。這種算法個人感覺也不夠精確。
方法3:采用大地主題解算算法來實現(xiàn)。這種算法需要很多專業(yè)知識背景(我就是猛學(xué)了一段時間的測量專業(yè)的教材才理解的)。大地主題解算有很多算法,我采用了白賽爾算法實現(xiàn),具體算法我已經(jīng)放到了上帝之眼上,大家有興趣可以自行看看:
http://bbs.godeyes.cn/showtopic-248479.aspx。其實我的"googleearth基站扇區(qū)繪制工具(YZL)"就是按照這個算法弄的。
方法4:(mapinfo中,我采用mapbasic編程),將經(jīng)緯度轉(zhuǎn)換成直角坐標(biāo)系,然后再在直接坐標(biāo)系下(SETE COORDSYS nonearth語句)畫線和畫圓弧,然后再切換到經(jīng)緯度坐標(biāo)系下。這個方案比較簡單,但是從earth坐標(biāo)系到nonearth坐標(biāo)系的轉(zhuǎn)化,暫時沒有找到好的方法,而且誤差也很大。我認(rèn)為不可。
方法5:(mapinfo中,我采用mapbasic編程),想了另外一種方法:充分利用MAPINFO自身功能,完全拋開直角坐標(biāo)到經(jīng)緯度的轉(zhuǎn)換,實現(xiàn)起來很方便而且效果很好。
下面簡單介紹一下方法5:
主要思路:采用類似于我們高中幾何中常用到的輔助線的方法,直接再經(jīng)緯度坐標(biāo)系下處理。
mapinfo下繪制圓弧采用的命令是Create Arc。但mapinfo中Create Arc語句沒有基于兩個端點和圓心來繪制的方式。而是采用了四個點的坐標(biāo)方式(這又涉及到了坐標(biāo)轉(zhuǎn)換的問題了)。慶幸的是我們可以通過采用輔助圓的方式取得需要繪制圓弧的四個點的坐標(biāo):
1、使用CREATECIRCLE語句創(chuàng)建圓,然后再用ObjectGeography求出圓的外接矩形的左下角和右上角的坐標(biāo)(左下角(minx miny) 右上角(maxx maxy)。
2、根據(jù)這兩個點(minx miny) (maxx maxy) 和中心點以及起始角和終止角來繪制弧形。
3、將弧形轉(zhuǎn)換成pline取出弧形的兩個端點。
4、將兩個端點和中心相連
5、圖元合并就可以得出扇形
這種做法缺點也有:由于mapinfo的處理精度問題,所以半徑小于10m或者 大于500km均還是有一定誤差,但是這已經(jīng)不影響使用了。
主要算法如下:
'主要問題是mapinfo中Create Arc語句沒有基于兩個端點和圓心來繪制的方式。而是采用了四個點的坐標(biāo)方式。
'采用輔助圓的方式取得需要繪制圓弧的四個點的坐標(biāo)
'通過這四個點繪制弧形,然后取得該弧形的兩個端點坐標(biāo)
'通過端點坐標(biāo)和圓心繪制直線
'最后合并直線和圓弧就得到了標(biāo)準(zhǔn)的扇形,效果不錯
function mycreateregion(經(jīng)度,緯度,方向角,半功率角,半徑 as float) as object
dim x,y,r,x1,y1,x2,y2,start_angle,end_angle as float
dim arc_obj,line1_obj ,line2_obj,obj1,obj2,circle_objas object
dim endpointstring,endxstring,endystring as string
dim minx,miny,maxx,maxy as float'''''''園的左下角和右上角坐標(biāo)
X=經(jīng)度
Y=緯度
r=半徑
start_angle=方向角-半功率角/2
end_angle=半功率角/2+方向角
circle_obj=CreateCircle(x,y,r)''這里繪制輔助圓,
minx=ObjectGeography(circle_obj,obj_geo_minx)
miny=ObjectGeography(circle_obj,obj_geo_miny)
maxx=ObjectGeography(circle_obj,obj_geo_maxx)
maxy=ObjectGeography(circle_obj,obj_geo_maxy) '''這四行取得繪制圓弧的關(guān)鍵點坐標(biāo),
if (方向角<>-270) and (半功率角<>360)then' 此處的方向角是經(jīng)過處理后的方向角
Create Arc into Variable arc_obj
(minx,miny) (maxx,maxy)
start_angleend_angle
dim xx1,yy1,xx2,yy2 as float
xx1=getArcBEGX(arc_obj)
yy1=getArcBEGY(arc_obj)
xx2= getArcENDX(arc_obj)
yy2= getArcENDY(arc_obj)'這里是取得圓弧的端點坐標(biāo)
Create Line into Variable line1_obj
(x,y) (xx1,yy1)
Create Line into Variable line2_obj
(x,y) (xx2,yy2)'這里是繪制兩條直線
obj1 = ConvertToRegion(Combine(arc_obj,Combine(line1_obj,line2_obj))) '合并
else
obj1=circle_obj''''''''''''''''''''''全向站的處理,直接畫圓
end if
mycreateregion=obj1 '返回扇形。
end function
''''求圓弧端點的程序''''''''''''''''''
function getArcBEGX(byval obj as object) as float
ifobjectinfo(obj,OBJ_INFO_TYPE )=1 then
dim d as object
d=ConvertToPline( obj )
getArcBEGX =ObjectNodeX( d ,1 ,1)
else
getArcBEGX=0
end if
end function
function getArcBEGY(byval obj as object) as float
ifobjectinfo(obj,OBJ_INFO_TYPE )=1 then
dim d as object
d=ConvertToPline( obj )
getArcBEGY =ObjectNodeY( d ,1 ,1)
else
getArcBEGY=0
end if
end function
function getArcENDX(byval obj as object) as float
ifobjectinfo(obj,OBJ_INFO_TYPE )=1 then
dim d as object
d=ConvertToPline( obj )
getArcENDX =ObjectNodeX( d ,1 , objectinfo(d,OBJ_INFO_NPNTS))
else
getArcENDX=0
end if
end function
function getArcENDY(byval obj as object) as float
ifobjectinfo(obj,OBJ_INFO_TYPE )=1 then
dim d as object
d=ConvertToPline( obj )
getArcENDY =ObjectNodeY( d ,1 ,objectinfo(d,OBJ_INFO_NPNTS))
else
getArcENDY=0
end if
end function
我基于方法5做了一個簡單的mapinfo基站扇區(qū)圖形生成工具,大家試試看。大家使用超級用戶密碼登錄就可以了,密碼為:leizi_y。這個工具實現(xiàn)了點、線、面圖形的自定義等等功能,但沒有做excel/TXT導(dǎo)入mapinfo這樣基本的功能(我認(rèn)為這個mapinfo自身已經(jīng)能夠足夠處理了)。
歡迎大家討論
leizi_y@126.com,qq:31933208
[
本帖最后由 leizi_y 于 2009-5-6 19:37 編輯 ]