700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Polar(极坐标)投影--主要用于天气雷达图

Polar(极坐标)投影--主要用于天气雷达图

时间:2023-10-18 23:59:08

相关推荐

Polar(极坐标)投影--主要用于天气雷达图


Polar.java
001/*

002

003Polar投影(扫描方式,自正北方向顺时针)

004

005PACKAGE:mon.projection

006FILENAME:Polar.java

007LANGUAGE:Java2v1.4

008ORIGINAL:无

009DESCRIPTION:极坐标投影(主要用于雷达图像处理)

010RELATED:mon.projection.Lambert(兰勃特投影)

011EDITOR:UltraEdit-32v12.20a(Windows)NEdit(Linux)

012CREATE:-05-0620:08:23

013UPDATE:-07-18修改为抽象类Coordinate的扩展类

014AUTHOR:刘泽军(BJ0773@)

015广西气象减灾研究所

016GuangxiInstitudeofMeteorologyandDisaster-reducingResearch(GIMDR)

017

018Compile:javacCoordinate.javaPolar.java

019

020HowtousePolarclass:

021

022Polarpolar=newPolar(109.24,24.35,512,384,1.0,0.0);//构造函数

023...

024

025*/

026

027/**

028*

029*扫描平面

030*/

031*/

032*/

033*/

034*/

035*/仰角

036*--------------------0度平面

037*

038*如图所示:

039*扫描平面=>0度平面,需要乘以cos(仰角)

040*0度平面=>扫描平面,需要除以cos(仰角)

041*

042*注意,日常显示的雷达图是扫描平面上的图。本类所说的屏幕指扫描平面。

043*

044*/

045

046/**

047*雷达扫描示意图

048*

049*3590

050*|radius

051*|/

052*|/

053*|angle/

054*|/

055*|^/

056*|/

057*|/

058*|/

059*270-----------------中心-----------------90

060*|

061*|

062*|

063*|

064*|

065*|

066*|

067*|

068*|

069*180

070*/

071

072packagemon.projection;

073

074importjava.awt.*;

075importjava.awt.geom.*;

076importjava.lang.Math.*;

077

078publicclassPolarextendsCoordinate{

079

080//私有成员

081privatedoubleperKilometer=1.0;//比例尺:一公里对应的像素点数(扫描平面)

082privatedoubleelevation=0.0;//仰角

083privatedoublecosineElevation=1.0;//仰角的余弦值

084privatedoublekmPerDegreeX=1.0;//1经度对应的距离(公里),不同纬度数值不同

085privatedoublekmPerDegreeY=1.0;//1纬度对应的距离(公里),不同纬度数值不同

086

087/**

088*功能:计算球面上两点间的距离(单位:公里),原在edu.gimdr.Atmos.Meteorology类中写有,为避免import过多的类,故重写一份

089*参数:

090*lon1,lat1-第1点的位置(经纬度)

091*lon2,lat2-第2点的位置(经纬度)

092*返回值:

093*球面距离

094*/

095publicstaticdoubledistanceOfSphere(doublelon1,doublelat1,doublelon2,doublelat2){

096/*公式:

097A(x,y)B(a,b)

098AB点的球面距离=R*{arccos[cos(b)*cos(y)*cos(a-x)+sin(b)*sin(y)]},byGoogle

099*/

100

101doublerlon1=Math.toRadians(lon1);

102doublerlat1=Math.toRadians(lat1);

103doublerlon2=Math.toRadians(lon2);

104doublerlat2=Math.toRadians(lat2);

105

106return(Coordinate.RADIUS*(Math.acos(Math.cos(rlat2)*Math.cos(rlat1)*Math.cos(rlon2-rlon1)+Math.sin(rlat2)*Math.sin(rlat1))));

107}

108

109/**

110*功能:

111*重置参数

112*参数:

113*lon,lat-中心经纬度,

114*px,py-中心经纬度对应的屏幕坐标

115*sc-缩放系数

116*agl-仰角

117*返回值:

118*无

119*/

120publicvoidreset(doublelon,doublelat,intpx,intpy,doublesc,doubleagl){

121type=Coordinate.POLAR;

122center=newPoint2D.Double(

123lon<0.0?0.0:lon>360.0?360.0:lon,

124lat<-90.0?-90.0:lat>90.0?90.0:lat

125);

126place=newPoint(px,py);

127elevation=Math.toRadians(Math.IEEEremainder(Math.abs(agl),90.0));//在0-90度之间,但不能为90度

128cosineElevation=Math.cos(elevation);//仰角的余弦值

129scale=sc==0.0?1.0:Math.abs(sc);//缩放系数

130scaleOriginal=scale;

131offset=newPoint(0,0);

132

133perKilometer=1.0;//标准比例尺

134//中心经纬度或仰角发生改变,必须重新计算经向和纬向的1度对应的球面距离

135kmPerDegreeX=distanceOfSphere(center.x,center.y,center.x+1.0,center.y)/cosineElevation;

136kmPerDegreeY=distanceOfSphere(center.x,center.y,center.x,center.y+1.0)/cosineElevation;

137}

138

139/**

140*功能:构造函数

141*参数:

142*lon-中心对应的经度坐标

143*lat-中心对应的纬度坐标

144*x-中心对应的屏幕位置x

145*y-中心对应的屏幕位置y

146*sc-缩放系数

147*返回值:

148*无

149*/

150publicPolar(doublelon,doublelat,intx,inty,doublesc){

151reset(lon,lat,x,y,sc,0.0);

152}

153

154/**

155*功能:构造函数

156*参数:

157*lon-中心对应的经度坐标

158*lat-中心对应的纬度坐标

159*x-中心对应的屏幕位置x

160*y-中心对应的屏幕位置y

161*sc-缩放系数

162*agl=仰角

163*返回值:

164*无

165*/

166publicPolar(doublelon,doublelat,intx,inty,doublesc,doubleagl){

167reset(lon,lat,x,y,sc,agl);

168}

169

170/**

171*功能:获得仰角

172*参数:

173*无

174*返回值:

175*仰角的度数

176*/

177publicdoublegetElevation(){

178return(Math.toDegrees(elevation));

179}

180

181/**

182*功能:获得经纬度对应的屏幕像素坐标,与雷达仰角有关,主要用于体扫数据显示、底图叠加等。

183*参数:

184*lon-经度

185*lat-纬度

186*返回值:

187*对应的屏幕坐标

188*/

189publicPointgetPosition(doublelon,doublelat){

190doubledisX=distanceOfSphere(lon,center.y,center.x,center.y)/cosineElevation;

191doubledisY=distanceOfSphere(center.x,lat,center.x,center.y)/cosineElevation;

192doublex=(lon>center.x?1:-1)*(disX*perKilometer*scale)+place.x+0.5;

193doubley=-(lat>center.y?1:-1)*(disY*perKilometer*scale)+place.y+0.5;

194return(newPoint((int)x,(int)y));

195}

196

197/**

198*功能:获得极坐标对应的屏幕像素坐标,与雷达仰角无关,主要用于体扫数据显示、底图叠加等。

199*参数:

200*radius-极半径

201*angle-角度(以正北方向顺时针)

202*返回值:

203*对应的屏幕坐标

204*/

205

206publicPointgetXY(doubleradius,doubleangle){

207intx=(int)(0.5+radius*Math.sin(Math.toRadians(angle)));

208inty=(int)(0.5+radius*Math.cos(Math.toRadians(angle)));

209return(newPoint(place.x+x,place.y-y));

210}

211

212/**

213*功能:获得屏幕像素点位置的极坐标半径,由于是输入参数是扫描平面上的值,故与雷达仰角无关。

214*参数:

215*x-水平坐标

216*y-垂直坐标

217*返回值:

218*与极坐标中心的距离,即极半径

219*/

220publicdoublegetRadius(intx,inty){

221return(Math.sqrt(1.0*(x-place.x)*(x-place.x)+1.0*(y-place.y)*(y-place.y)));

222}

223

224/**

225*功能:获得经纬度位置的极坐标半径,与雷达仰角有关。

226*参数:

227*lon-经度坐标

228*lat-纬度坐标

229*返回值:

230*与极坐标中心的距离(象素点),即极半径

231*/

232publicdoublegetRadius(doublelon,doublelat){

233Pointpos=getPosition(lon,lat);//此函数已经考虑了仰角的影响

234return(getRadius(pos.x,pos.y));

235}

236

237/**

238*功能:获得屏幕像素点位置的极坐标角度(扫描平面与0度平面均相同),与雷达仰角无关。

239*参数:

240*x-水平坐标

241*y-垂直坐标

242*返回值:

243*角度值,自正北方向顺时针

244*/

245publicdoublegetAngle(intx,inty){

246doubleagl=0.0;

247if(x==place.x&&y==place.y){//重合

248agl=0.0;

249}

250elseif(x==place.x){

251agl=y>place.y?180.0:360.0;

252}

253elseif(y==place.y){

254agl=x>place.x?90.0:270.0;

255}

256else{

257agl=Math.toDegrees(Math.atan(1.0*Math.abs(x-place.x)/Math.abs(y-place.y)));

258agl=

259x>place.x&&y<place.y?agl://直角坐标的第一象限

260x<place.x&&y<place.y?180.0-agl://直角坐标的第二象限

261x<place.x&&y>place.y?180.0+agl://直角坐标的第三象限

262x>place.x&&y>place.y?360.0-agl://直角坐标的第四象限

263agl;

264}

265System.out.println(agl);

266return(agl);

267}

268

269/**

270*功能:获得经纬度位置的极坐标角度(扫描平面与0度平面均相同),与雷达仰角无关。

271*参数:

272*lon-水平坐标

273*lat-垂直坐标

274*返回值:

275*角度值,自正北方向顺时针

276*/

277publicdoublegetAngle(doublelon,doublelat){

278/*

279//若通过获得屏幕坐标来计算角度,精度比较差,特别是在极坐标中心附近

280Pointp=getPosition(lon,lat);

281return(getAngle(p.x,p.y);

282*/

283doubleagl=0.0;

284if(lon==center.x&&lat==center.y){//重合

285agl=0.0;

286}

287elseif(lon==center.x){

288agl=lat>center.y?360.0:180.0;

289}

290elseif(lat==center.y){

291agl=lon>center.x?90.0:270.0;

292}

293else{

294//注:由于经向和纬向的球面距离不等(华南,经向>纬向),故点(1,1)与中心点(0,0)的极角不等45度,而应是略大于45度

295agl=Math.toDegrees(Math.atan((Math.abs(lon-center.x)*kmPerDegreeX)/(Math.abs(lat-center.y)*kmPerDegreeY)));

296agl=

297lon>center.x&&lat>center.y?agl://第一象限

298lon<center.x&&lat>center.y?180.0-agl://第二象限

299lon<center.x&&lat<center.y?180.0+agl://第三象限

300lon>center.x&&lat<center.y?360.0-agl://第四象限

301agl;

302}

303return(agl);

304}

305

306/**

307*功能:

308*获得屏幕坐标对应的经纬度

309*参数:

310*x-屏幕水平坐标

311*y-屏幕垂直坐标

312*返回值:

313*对应的经纬度

314*/

315publicPoint2D.DoublegetCoordinate(intx,inty){

316doublelat=Math.toDegrees(Math.toRadians(center.y)+(place.y-y)*cosineElevation/perKilometer/scale/Polar.RADIUS);

317doubledisX0=distanceOfSphere(center.x,lat,center.x+1.0,lat);//0度平面上1经度的球面距离

318doubledisX=disX0/cosineElevation;//扫描平面上1经度的距离

319doubleperDegreeX=disX*perKilometer*scale;//扫描平面上1经度的对应的像素点数

320doublelon=center.x+(x-place.x)/perDegreeX;

321return(newPoint2D.Double(lon,lat));

322}

323

324/**

325*功能:

326*画经线、纬线

327*参数:

328*g-图形设备

329*f-字体

330*c-画线颜色

331*inc_lon-经线间隔//未使用

332*inc_lat-纬线间隔//未使用

333*返回值:

334*无

335*/

336publicvoiddrawGridLine(Graphics2Dg,Fontf,Colorc,intinc_lon,intinc_lat){

337ColorsaveColor=g.getColor();

338FontsaveFont=g.getFont();

339

340//以下两行改进线条的锯齿

341//RenderingHintsrenderHints=newRenderingHints(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

342//g.setRenderingHints(renderHints);

343

344//g.setColor(Color.black);//背景色

345//g.fillRect(c.x-(int)(z*240),c.y-(int)(z*240),(int)(z*240*2),(int)(z*240*2));

346

347g.setColor(c);//雷达图形区域的边框颜色

348g.drawRect((int)(0.5+place.x-scale*240),(int)(0.5+place.y-scale*240),(int)(0.5+scale*240*2),(int)(0.5+scale*240*2));

349

350//画极径

351Pointpos1,pos2;

352for(doublei=0.0;i<180.0;i=i+30.0){

353pos1=getXY(scale*240.0,0.0+i);

354pos2=getXY(scale*240.0,180.0+i);

355g.drawLine(pos1.x,pos1.y,pos2.x,pos2.y);

356}

357

358//画极圈

359for(inti=50;i<=200;i=i+50){//每50公里画一个圈

360g.drawArc((int)(0.5+place.x-scale*i),(int)(0.5+place.y-scale*i),(int)(0.5+scale*i*2),(int)(0.5+scale*i*2),0,360);

361}

362g.drawArc((int)(0.5+place.x-scale*240),(int)(0.5+place.y-scale*240),(int)(0.5+scale*240*2),(int)(0.5+scale*240*2),0,360);//外圈240公里

363

364g.setFont(saveFont);

365g.setColor(saveColor);

366}

367}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。