2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

国際宇宙ステーション捕捉システム

Last updated at Posted at 2025-08-30
  • 娘にWebAPI(JSON)の取扱法を教えるのに使用したWebAPI
  • 上部にISSの位置情報等を表示。
  • 下部に世界地図をWeb表示させてどの辺を飛行しているか分かるようにした。
    (地図中央にISSがあるのでこの場合はカナダ辺り)
  • タスクバーに東京~ISS間の距離を表示。何時でも距離が確認可能。

1.起動中画面

NDMC_SSTMP.JPG

2.詳細データ表示部

08/30 06:41:25(JST) 東京に接近した様子(福島県沖の太平洋上)
250830-06-43-57.jpg

3.データ取得法

message	"success"
timestamp	1756462393
iss_position	
   longitude	"-160.4546"
   latitude	    "-15.2078"
  • timestampはUNIXTIME。1970年1月1日午前0時0分0秒を起点。これをJSTに変換して表示。
  • longitude等は経緯度です。10進法なので下記の計算により変換してます。
    上記の場合、双方マイナスなので南緯、西経になります。

ConvertToDMS()
ex 35.4321(Decimal Degrees)の表記から度分秒に変換
度 = 35
分 = 0.4321 x 60 = 25.926 -> 25
秒 = 0.926 x 60 = 55.56 -> 55
結果= 35度25分55秒

緯度、経度は以下のような符号
正 = 北緯 負 = 南緯
正 = 東経 負 = 西経

  • 取得した経緯度を地図サイトのURLに埋め込んでISSの中心位置を表示させました。
"https://www.bing.com/maps?cp="+latitude.ToString()+"~"+ longitude.ToString()+"&lvl=3"
  • 地図の中心にISSがあります。分かり辛いのでISSのアイコンを書き込もうとしたがかなり面倒。

  • そもそもMicrosoft.Web.WebView2はHwndHostで描画しているので色々制限がある。

  • 代替案としてWeb画面をキャプチャしてそのキャプチャ画像にISSアイコンを書き込んで表示させる。

  • または世界地図を画像として表示させその上にISSアイコンを書き込む。
    (経緯度からどこにプロットするか算出が面倒そうではあるが最善の方法。ただフリーに使えて転載できる地図が見当たらず止めた)

  • 距離計算法 Haversineの公式

4.WPF SourceCode (.NET)

//////////////////////////////////////////////////////////////
// InternationalSpaceStation RealTimeLocationViewer Testtype
// (c)inf102 S.H. & H.H 2025.
// WPF+.NET & Microsoft.Web.WebView2(NuGet)
//////////////////////////////////////////////////////////////

using System.Net;
using System.Text;
using System.Windows;

namespace ISS_LOCA{
    public partial class MainWindow : Window    {

        const int WAIT=15000; // 更新間隔(mmSec);

        public MainWindow() {
            InitializeComponent();
            L(" InternationalSpaceStation RealTimeLocationViewer. Testtype (c)inf102 S.H. & H.H. all rights reserved 2025.");
            _=Get_ISS_LOCATION();
        }
        
        // ROOT
        public class Root_object {
            public Iss_position iss_position { get; set; }
            public string message { get; set; }
            public long timestamp { get; set; }
        }

        public class Iss_position {
            public string latitude  { get; set; }
            public string longitude { get; set; }
        }
                
        public void L(string s) {
            L1.Items.Add(s);
        }
        
        public async Task Get_ISS_LOCATION() {         
            string def="";
            string output="";

            using WebClient client = new();
            //client.Proxy = new WebProxy ("xxxxxxxx:8080");
            //client.Proxy.Credentials = new NetworkCredential("ID","PW");
         
            // 非同期受信イベントハンドラ登録
            client.DownloadDataCompleted += async (sender, e) => {
                byte[] data;
                try{
                   data = e.Result;
                }
                catch{ 
                  //  L("exception");
                    return;
                }

                string json=Encoding.UTF8.GetString(data);
                Root_object obj = System.Text.Json.JsonSerializer.Deserialize<Root_object>(json);

                //  def ="Message:"+obj.message;
                //  L(def);

                //   def ="UNIXTIME:"+obj.timestamp;
                //   L(def);

                // UNIXTIME2JST
                DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(obj.timestamp);
                DateTime JST = dateTimeOffset.ToOffset(TimeSpan.FromHours(9)).DateTime;
                output ="JST:" + JST.ToShortDateString() + " " + JST.Hour.ToString("00") + ":" + JST.Minute.ToString("00")+":"+ JST.Second.ToString("00");

                // 経緯度 10進法
                double t=double.Parse( obj.iss_position.latitude);
                string xx=t.ToString("000.0000");
                output+=" 緯度:"+xx;//(obj.iss_position.latitude);
                
                t=double.Parse( obj.iss_position.longitude);
                xx=t.ToString("000.0000");
                output+="度 経度:"+xx +"度";
               
                // 経緯度 DMS法
                double latitude  = Double.Parse(obj.iss_position.latitude);
                double longitude = Double.Parse(obj.iss_position.longitude);
                string latitudeDMS  = ConvertToDMS(latitude,  true);   // 緯度
                string longitudeDMS = ConvertToDMS(longitude, false);  // 経度
                output+=" "+latitudeDMS+" "+longitudeDMS;

                // 距離測定 宇宙ステーション~東京
                double TokyoLat = 35.6895;
                double TokyoLon = 139.6917;
                double IssLat = Double.Parse(obj.iss_position.latitude);
                double IssLon = Double.Parse(obj.iss_position.longitude);
                double distance = GeoUtils.CalculateDistance(TokyoLat, TokyoLon, IssLat, IssLon);
                output+=(" ISS~東京間 "+distance.ToString("00000")+"Km");

                // 出力
                L(" "+output);

                // タイトル距離
                Title = distance.ToString("00000")+"Km 宇宙ステーション~東京間距離";
                          
                // 地図表示 
                string url ="https://www.bing.com/maps?cp="+latitude.ToString()+"~"+ longitude.ToString()+"&lvl=3";
                //string url ="https://www.google.com/maps?q="+latitude.ToString()+","+ longitude.ToString()+"&z=20";

                await webView.EnsureCoreWebView2Async(null);
                webView.Source = new Uri(url);           
            };
                        
            Uri uri = new("http://api.open-notify.org/iss-now.json");
            // MAIN_LOOP
            while (true){
                client.DownloadDataAsync(uri);
                await Task.Delay(WAIT);
            }
        }

        public static string ConvertToDMS(double decimalDegrees, bool isLatitude) {
            string direction;

            if (isLatitude) direction = decimalDegrees >= 0 ? "北緯" : "南緯";
            else
                direction = decimalDegrees >= 0 ? "東経" : "西経";

            decimalDegrees = Math.Abs(decimalDegrees);

            int degrees = (int)decimalDegrees;
            double minutesDecimal = (decimalDegrees - degrees) * 60;
            int minutes = (int)minutesDecimal;
            double seconds = (minutesDecimal - minutes) * 60;

            return $"{direction+":"} {degrees.ToString("000")}{minutes.ToString("00")}{seconds.ToString("00")}秒";
        }

        // 東京から宇宙ステーションまでの距離算出
        public class GeoUtils{
            // 地球の半径Km
            const double EarthRadiusKm = 6371.0;

            public static double CalculateDistance(double lat1, double lon1,double lat2, double lon2){
                // ラジアンに変換
                double dLat = DegreesToRadians(lat2 - lat1);
                double dLon = DegreesToRadians(lon2 - lon1);
                double rLat1 = DegreesToRadians(lat1);
                double rLat2 = DegreesToRadians(lat2);

                // Haversineの公式
                double a = Math.Pow(Math.Sin(dLat / 2), 2) + Math.Cos(rLat1) * Math.Cos(rLat2) * Math.Pow(Math.Sin(dLon / 2), 2);
                double c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));

                return EarthRadiusKm * c;
            }

            private static double DegreesToRadians(double degrees){
                return degrees * Math.PI / 180.0;
            }
        }
    }
}

5.WPF XAML

<Window x:Class="ISS_LOCA.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ISS_LOCA" xmlns:wv2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
        mc:Ignorable="d"
        Title="MainWindow" Height="850" Width="1450">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="150"/>
            <RowDefinition Height="5"/>
            <RowDefinition Height="300*"/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <ListBox Grid.Column="0" Grid.Row="0" x:Name="L1" FontSize="18"  Background="Black" Foreground="White" />
        <GridSplitter Grid.Row="1" Height="2" HorizontalAlignment="Stretch" VerticalAlignment="Center"/>
        <wv2:WebView2 x:Name="webView" Grid.Column="0"  Grid.Row="2" />
    </Grid>
</Window>
  • たまに例外で止まる事あり。その場合はAPP再起動。更新間隔は10Sec以上推奨。(冒頭のconst値)
  • スマートフォンの何時ISSがみられるか表示するAPPを使用してISS見た事あり。予測通りの軌道。
  • 光点が移動するだけで形は分からないものの面白かったがもう一回見ようとは思わず。
  • 筑波の時のきぼうや、HTVが打ちあがったと思うと感無量。
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?