当前位置:   article > 正文

2024-08-15升级记录:Android开发-实现绘制卫星天顶图/卫星星空图/方位图/卫星星座

2024-08-15升级记录:Android开发-实现绘制卫星天顶图/卫星星空图/方位图/卫星星座

一、效果

Android中实现卫星天顶图/卫星星空图/方位图/卫星星座,

最后效果:

卫星天顶图:即是根据每一颗卫星的方位角和高度角将其画在以观测位置为中心的天顶图上。

天顶图其底图为由外向内的三个圆和四条直线。三个圆由外向内依次代表高度角0°、30°、60°,中心点代表90°;四条直线分别表示正北-正南、东北-西南、正东-正西、东南-西北的方位角方向。

二、卫星信息获取

通过GnssStatus.Callback接口的,GnssStatus的参数对象来获取,具体参见我的另一篇:

2024-08-06升级记录:Android开发接口-获取定位卫星相关信息-CSDN博客

三、自定义显示控件

1、绘制底图:

        圆、线、刻度、文字:

  1. //高度角三圆
  2. private void drawCircle(Canvas c, float radius) {
  3. c.drawCircle(radius, radius + Y_TRANSLATION, elevationToRadius(radius, 60.0f), mPaintGnss);
  4. c.drawCircle(radius, radius + Y_TRANSLATION, elevationToRadius(radius, 30.0f), mPaintGnss);
  5. c.drawCircle(radius, radius + Y_TRANSLATION, elevationToRadius(radius, 0.0f), mPaintGnss);
  6. }
  7. /***
  8. * 计算不同高度角的半径
  9. * @param s 最外圆的半径
  10. * @param elev 点的高度角
  11. * @return
  12. */
  13. private float elevationToRadius(float s, float elev) {
  14. return s * (1.0f - (elev / 90.0f));
  15. }
  16. //米叉线
  17. private void drawLine(Canvas c, int s, float radius) {
  18. c.drawLine(radius, Y_TRANSLATION, radius, s + Y_TRANSLATION, mPaintGnss);
  19. c.drawLine(0, radius + Y_TRANSLATION, s, radius + Y_TRANSLATION, mPaintGnss);
  20. final float cos45 = (float) Math.cos(Math.PI / 4);
  21. float d1 = radius * (1 - cos45);
  22. float d2 = radius * (1 + cos45);
  23. c.drawLine(d1, d1 + Y_TRANSLATION, d2, d2 + Y_TRANSLATION, mPaintGnss);
  24. c.drawLine(d2, d1 + Y_TRANSLATION, d1, d2 + Y_TRANSLATION, mPaintGnss);
  25. }
  26. //刻度和文字
  27. private void drawDegree(Canvas c, float radius) {
  28. int iText_Offset = -10;
  29. int iText_Offset_X = -15;
  30. for (int i = 0; i < 360; i += 15) {
  31. if (i == 45 || i == 135 || i == 225 || i == 315) {
  32. c.drawText(String.valueOf(i), radius+iText_Offset_X, iText_Offset + Y_TRANSLATION, mPaintText);
  33. } else if (i == 0) {
  34. c.drawText("N", radius+iText_Offset_X, iText_Offset + Y_TRANSLATION, mPaintText);
  35. } else if (i == 90) {
  36. // c.drawText("E", radius+iText_Offset_X, iText_Offset + Y_TRANSLATION, mPaintText);
  37. } else if (i == 180) {
  38. c.drawText("S", radius+iText_Offset_X, iText_Offset + Y_TRANSLATION, mPaintText);
  39. } else if (i == 270) {
  40. // c.drawText("W", radius+iText_Offset_X, iText_Offset + Y_TRANSLATION, mPaintText);
  41. } else {
  42. c.drawLine(radius, Y_TRANSLATION, radius, 20 + Y_TRANSLATION, mPaintGnss);
  43. }
  44. c.rotate(15, radius, radius + Y_TRANSLATION);
  45. }
  46. }

2、根据高度角和方位角绘制卫星图标和标识号

  1. //卫星图标
  2. private Bitmap getSatelliteBitmap(int constellationType) {
  3. Bitmap baseMap, newMap;
  4. int width, height;
  5. switch (constellationType) {
  6. case GnssStatus.CONSTELLATION_BEIDOU:
  7. baseMap = BitmapFactory.decodeResource(getResources(), R.drawable.flag_beidou);
  8. break;
  9. case GnssStatus.CONSTELLATION_GPS:
  10. baseMap = BitmapFactory.decodeResource(getResources(), R.drawable.flag_gps);
  11. break;
  12. case GnssStatus.CONSTELLATION_GALILEO:
  13. baseMap = BitmapFactory.decodeResource(getResources(), R.drawable.flag_galileo);
  14. break;
  15. case GnssStatus.CONSTELLATION_GLONASS:
  16. baseMap = BitmapFactory.decodeResource(getResources(), R.drawable.flag_glonass);
  17. break;
  18. case GnssStatus.CONSTELLATION_QZSS:
  19. baseMap = BitmapFactory.decodeResource(getResources(), R.drawable.flag_qzss);
  20. break;
  21. case GnssStatus.CONSTELLATION_SBAS:
  22. baseMap = BitmapFactory.decodeResource(getResources(), R.drawable.flag_sbas);
  23. break;
  24. case GnssStatus.CONSTELLATION_UNKNOWN:
  25. baseMap = BitmapFactory.decodeResource(getResources(), R.drawable.flag_ufo);
  26. break;
  27. case 7:
  28. baseMap = BitmapFactory.decodeResource(getResources(), R.drawable.flag_india);
  29. break;
  30. default:
  31. baseMap = BitmapFactory.decodeResource(getResources(), R.drawable.flag_other);
  32. }
  33. width = baseMap.getWidth();
  34. height = baseMap.getHeight();
  35. newMap = scaling(baseMap, (SAT_RADIUS * 2.0f) / width, (SAT_RADIUS * 2.0f) / height);
  36. return newMap;
  37. }
  38. //缩放卫星图标
  39. private static Bitmap scaling(Bitmap bitmap, float widthScale, float heightScale) {
  40. Matrix matrix = new Matrix();
  41. matrix.postScale(widthScale, heightScale); //长和宽放大缩小的比例
  42. return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
  43. }
  44. /***
  45. * 绘制卫星图标
  46. * @param c 画布
  47. * @param s 最外圆半径
  48. * @param elev 卫星高度角
  49. * @param azim 卫星方位角
  50. * @param snr
  51. * @param prn
  52. * @param constellationType 星座枚举类型
  53. */
  54. private void drawSatellite(Canvas c, float s, float elev, float azim, float snr, int prn, int constellationType) {
  55. double radius, angle;
  56. float x, y;
  57. Bitmap satMap;
  58. satMap = getSatelliteBitmap(constellationType);
  59. String satText;
  60. satText = getSatelliteText(prn, constellationType);
  61. radius = elevationToRadius(s / 2.0f, elev);
  62. angle = (float) Math.toRadians(azim);
  63. x = (float) ((s / 2.0f) + (radius * Math.sin(angle)));
  64. y = (float) ((s / 2.0f) - (radius * Math.cos(angle)));
  65. c.drawBitmap(satMap, x - SAT_RADIUS, y - SAT_RADIUS + Y_TRANSLATION, null);
  66. c.drawText(satText, x - SAT_RADIUS, y + SAT_RADIUS * 1.5f + Y_TRANSLATION, mPaintText);
  67. }
  68. private String getSatelliteText(int prn, int constellationType) {
  69. StringBuilder builder = new StringBuilder();
  70. switch (constellationType) {
  71. case GnssStatus.CONSTELLATION_BEIDOU:
  72. builder.append("C");
  73. break;
  74. case GnssStatus.CONSTELLATION_GPS:
  75. builder.append("G");
  76. break;
  77. case GnssStatus.CONSTELLATION_GALILEO:
  78. builder.append("E");
  79. break;
  80. case GnssStatus.CONSTELLATION_GLONASS:
  81. builder.append("R");
  82. break;
  83. case GnssStatus.CONSTELLATION_QZSS:
  84. builder.append("Q");
  85. break;
  86. case GnssStatus.CONSTELLATION_SBAS:
  87. builder.append("S");
  88. break;
  89. case 7:
  90. builder.append("I");
  91. break;
  92. case GnssStatus.CONSTELLATION_UNKNOWN:
  93. builder.append("u");
  94. break;
  95. default:
  96. builder.append("x");
  97. }
  98. builder.append(prn);
  99. return builder.toString();
  100. }

3、根据实时信号更新显示内容

  1. //实时更新卫星数据
  2. @RequiresApi(api = Build.VERSION_CODES.N)
  3. public void updateGnssStatus(GnssStatus status) {
  4. int length = status.getSatelliteCount();
  5. arrPrns = new int[length];
  6. arrElevations = new float[length];
  7. arrAzimuths = new float[length];
  8. arrConstellationTypes = new int[length];
  9. arrSnrs = new float[length];
  10. int mSvCount = 0;
  11. while (mSvCount < length) {
  12. arrPrns[mSvCount] = status.getSvid(mSvCount);
  13. arrElevations[mSvCount] = status.getElevationDegrees(mSvCount);
  14. arrAzimuths[mSvCount] = status.getAzimuthDegrees(mSvCount);
  15. arrConstellationTypes[mSvCount] = status.getConstellationType(mSvCount);
  16. arrSnrs[mSvCount] = status.getCn0DbHz(mSvCount);
  17. mSvCount++;
  18. }
  19. invalidate();
  20. }
  1. @Override
  2. protected void onDraw(Canvas canvas) {
  3. super.onDraw(canvas);
  4. int minScreenDimen = Math.min(getWidth(), getHeight());
  5. float radius = minScreenDimen / 2.0f;
  6. drawCircle(canvas, radius);
  7. drawLine(canvas, minScreenDimen, radius);
  8. drawDegree(canvas, radius);
  9. if(arrPrns !=null){
  10. if(arrPrns.length>0){
  11. for(int i = 0; i< arrPrns.length; i++){
  12. if(arrConstellationTypes[i]>0) {
  13. drawSatellite(canvas, minScreenDimen, arrElevations[i], arrAzimuths[i], arrSnrs[i], arrPrns[i], arrConstellationTypes[i]);
  14. }
  15. }
  16. }
  17. }
  18. }

四、获取卫星星座状态

参见:2024-08-09升级记录:各导航卫星系统星座状态和卫星发射记录-CSDN博客

参考链接:

Android GNSS 可视卫星星空图/卫星天顶图 原理及画法介绍-CSDN博客

安卓应用开发学习:获取导航卫星信息_android 获取卫星位置-CSDN博客

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号