画出卫星在天体中的位置,如下图
activity_satellite.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.0"
android:orientation="horizontal" >
<!-- 卫星图 -->
<LinearLayout
android:id="@+id/bg"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1.0"
android:orientation="vertical"
>
<FrameLayout
android:id="@+id/LinearLayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.0"
android:layout_margin="5dp"
/>
<!-- 卫星选择 -->
<RadioGroup
android:id="@+id/satellite_rg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="20dp"
android:gravity="center"
>
<RadioButton
android:id="@+id/satellite_gps_rb"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:text="GPS"
android:textColor="@drawable/selector_satellite_select"
android:textSize="20sp"
android:button="@null"
android:gravity="center"
android:checked="true"
/>
<RadioButton
android:id="@+id/satellite_bd_rb"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:text="BD"
android:textColor="@drawable/selector_satellite_select"
android:textSize="20sp"
android:button="@null"
android:gravity="center"
/>
<RadioButton
android:id="@+id/satellite_glo_rb"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:text="GLO"
android:textColor="@drawable/selector_satellite_select"
android:textSize="20sp"
android:button="@null"
android:gravity="center"
/>
</RadioGroup>
</LinearLayout>
<!-- 信息 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1.0"
android:orientation="vertical"
android:layout_marginLeft="5dp"
>
<!-- 经度 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.0"
android:gravity="center"
android:orientation="horizontal"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="经度:"
/>
<TextView
android:id="@+id/longitude_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="N 0.0"
/>
</LinearLayout>
<!-- 纬度 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.0"
android:gravity="center"
android:orientation="horizontal"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="纬度:"
/>
<TextView
android:id="@+id/latitude_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="E 0.0"
/>
</LinearLayout>
<!-- 海拔 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.0"
android:gravity="center"
android:orientation="horizontal"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="海拔:"
/>
<TextView
android:id="@+id/height_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
<!-- 卫星 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.0"
android:gravity="center"
android:orientation="horizontal"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="卫星:"
/>
<TextView
android:id="@+id/satelliteCount_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="0"
/>
</LinearLayout>
<!-- 卫星状态 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.0"
android:gravity="center"
android:orientation="horizontal"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="状态:"
/>
<TextView
android:id="@+id/satelliteStatus_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
<!-- PDOP -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.0"
android:gravity="center"
android:orientation="horizontal"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="DOP:"
/>
<TextView
android:id="@+id/satellitePDOP_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
<!-- 时间 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.0"
android:gravity="center"
android:orientation="horizontal"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="时间:"
/>
<TextView
android:id="@+id/time_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
<!-- 日期 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.0"
android:gravity="center"
android:orientation="horizontal"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="日期:"
/>
<TextView
android:id="@+id/date_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
<!-- 精度 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.0"
android:gravity="center"
android:orientation="horizontal"
android:visibility="gone"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="精度:"
/>
<TextView
android:id="@+id/accuracy_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
<!-- bestposa精度 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.0"
android:gravity="center"
android:orientation="horizontal"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="精度:"
/>
<TextView
android:id="@+id/bestPosa_accuracy_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#ff0000"
/>
</LinearLayout>
画地球圆圈
package com.yongnuo.mcms.utils;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.view.View;
public class DrawEarth extends View {
private float mSatelliteX;
private float mSateLliteY;
public DrawEarth(Context context,float x,float y) {
super(context);
this.mSatelliteX = x;
this.mSateLliteY = y;
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint p = new Paint();
p.setAntiAlias(true);
p.setStyle(Style.STROKE);
p.setColor(Color.BLACK);
p.setTextSize(25);
canvas.drawCircle(mSatelliteX, mSateLliteY, mSatelliteX*1/3, p);
canvas.drawCircle(mSatelliteX, mSateLliteY, mSatelliteX*2/3, p);
canvas.drawCircle(mSatelliteX, mSateLliteY, mSatelliteX, p);
canvas.drawLine(0, mSateLliteY, mSatelliteX*2, mSateLliteY, p);//X
canvas.drawLine(mSatelliteX, 0, mSatelliteX, mSateLliteY*2, p);//Y
p.setStyle(Style.FILL);
canvas.drawText("北", mSatelliteX-15, 0+25, p);
canvas.drawText("南", mSatelliteX-15, mSateLliteY*2, p);
canvas.drawText("西", 0, mSateLliteY+10, p);
canvas.drawText("东", mSatelliteX*2-25, mSateLliteY+10, p);
}
}
画卫星,以及在天体中的显示算法
import java.util.ArrayList;
import com.yongnuo.mcms.R;
import com.yongnuo.p2.Parse.Satellite;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.view.View;
/**
* 画卫星
* @version v2.3
* @author SunTao
* @date 2016年5月18日 下午4:17:27
*/
public class DrawSatellite extends View {
private int mSatelliteX;
private int mSateLliteY;
private Context mContext;
private ArrayList<Satellite> mSatelliteList;
private Bitmap mSatelliteBitmap;
private Paint p;
public DrawSatellite(Context context,int x,int y,ArrayList<Satellite> list) {
super(context);
mContext = context;
this.mSatelliteX = x;
this.mSateLliteY = y;
this.mSatelliteList = list;
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
p = new Paint();
p.setAntiAlias(true);
p.setStyle(Style.FILL);
p.setColor(Color.RED);
p.setTextSize(20);
drawCircle(canvas,p);
}
private void drawCircle(Canvas canvas,Paint p){
mSatelliteBitmap = BitmapFactory.decodeResource(mContext.getResources(),R.mipmap.ic_satellite_blue);
for(Satellite s : mSatelliteList){
drawSatellite(canvas, s, mSatelliteX, mSateLliteY, mSatelliteX);
}
}
/**
* 在背景罗盘上绘制卫星
* @param canvas
* @param satellite
* @param cx 中心圆点的X座标
* @param cy 中心圆点的Y座标
* @param r 罗盘背景的半径
*/
private void drawSatellite(Canvas canvas,Satellite satellite, int cx, int cy, int r) {
/**
* GPS卫星导航仪通常选用仰角大于5º,小于85º。 因为当卫星仰角大于85º时,L1波段的电离层折射误差较大,故规定仰角大于85º时,
* 定位无效,不进行数据更新。而卫星仰角越小,则对流层折射误差越大,故一般选用仰角大于5º的卫星来定位。
*/
//得到仰角
float elevation = Float.valueOf(satellite.getElevationAngle());
//通过仰角,计算出这个卫星应该绘制到离圆心多远的位置,这里用的是角度的比值
double r2 = r * ((90.0f - elevation) / 90.0f);
/*得到方位角(与正北向也就是Y轴顺时针方向的夹角,注意我们通常几何上的角度
* 是与X轴正向的逆时针方向的夹角),在计算X,Y座标的三角函数时,要做转换
*/
double azimuth = Float.valueOf(satellite.getAzimuth());
/*
* 转换成XY座标系中的夹角,方位角是与正北向也就是Y轴顺时针方向的夹角,
* 注意我们通常几何上的角度是与X轴正向的逆时针方向的夹角),
* 在计算X,Y座标的三角函数时,要做转换
*/
double radian = degreeToRadian(360-azimuth + 90);
double x = cx + Math.cos(radian) * r2;
double y = cy + Math.sin(radian) * r2;
//得到卫星图标的半径
int sr = mSatelliteBitmap.getWidth() / 2;
//以x,y为中心绘制卫星图标
canvas.drawBitmap(mSatelliteBitmap, (float) (x - sr), (float) (y - sr),p);
//在卫星图标的位置上绘出文字(卫星编号及信号强度)
int snr=(int)satellite.getNum();
// int signLevel=snrToSignalLevel(snr); //暂时不用
// String info = String.format("#%s_%s", satellite.getNum(), snr);
String info = String.valueOf(satellite.getNum());
canvas.drawText(info, (float) (x)-15, (float) (y)+5, p);
}
/**
* 将角度转换为弧度,以用于三角函数的运算
*
* @param degree
* @return
*/
private double degreeToRadian(double degree) {
return (degree * Math.PI) / 180.0d;
}
}
卫星信息实体类
public class Satellite {
private int num;
private String elevationAngle;
private String azimuth;
private int snr = 0;
private String satelliteType;
public Satellite() {
}
public int getNum() {
return this.num;
}
public void setNum(int num) {
this.num = num;
}
public String getElevationAngle() {
return this.elevationAngle;
}
public void setElevationAngle(String elevationAngle) {
this.elevationAngle = elevationAngle;
}
public String getAzimuth() {
return this.azimuth;
}
public void setAzimuth(String azimuth) {
this.azimuth = azimuth;
}
public int getSnr() {
return this.snr;
}
public void setSnr(int snr) {
this.snr = snr;
}
public String getSatelliteType() {
return this.satelliteType;
}
public void setSatelliteType(String satelliteType) {
this.satelliteType = satelliteType;
}
}
在Activity中的使用
1、画出球体
//初始化
mWidth = ScreenUtils.getScreenWidth(this) / 2 - 35;
DrawEarth earthView = new DrawEarth(this, mWidth / 2, mWidth / 2);
earthView.invalidate();
mView.addView(earthView);
//添加卫星数据
mView.removeView(satelliteView);
satelliteView = new com.yongnuo.mcms.utils.DrawSatellite(this, w / 2, w / 2, list);
satelliteView.invalidate();
mView.addView(satelliteView);