Bing Maps上に地震の震源地を表示するプログラムを作る
<※前ページからの続きです。>
[現在の情報保存]ボタンがクリックされた時の処理
現在の、何年何月何日何時何分何秒.xmlという文字列を作成し、変数myFileに格納しておきます。
ピクチャライブラリ内のEarthQuakeDataというサブフォルダにアクセスします。CreateAsyncFolderメソッドにCreationCollisionOption.OpenIfExistsを指定してフォルダを作成すると、既に同名のフォルダがある場合は、そのフォルダ名を返し、無い場合はフォルダを新規に作成してくれます。
CreateFileAsyncメソッドでサブフォルダ内に変数myFileが格納しているファイルを作成し、変数saveFileで参照しておきます。
FileIO.WriteTextAsyncメソッドで、指定したファイルにmyResponse(結果XMLが入っている)の内容を書き込みます。「保存しました。」のメッセージを表示し、dataShowButtonを使用可能にします。
これで、現在の地震の情報を記録したXMLファイルが保存されます。非同期処理で行われるため、メソッドの先頭にAsyncを追加します。
Private Async Sub dataSaveButton_Click(sender As Object, e As RoutedEventArgs) Handles dataSaveButton.Click Dim myFile As String = DateTime.Now.ToString("yyyy年MM月dd日HH時mm分ss秒") & ".xml" Dim myStorageFolder As StorageFolder = Windows.Storage.KnownFoldersPicturesLibrary Dim mySubFolder = Await myStorageFolder.CreateFolderAsync("EarthQuakeData", CreationCollisionOption.OpenIfExists) Dim saveFile As StorageFile = Await mySubFolder.CreateFileAsync(myFile) Await FileIO.WriteTextAsync(saveFile, myResponse) Dim myMessage As New MessageDialog("保存しました") Await myMessage.ShowAsync dataShowButton.IsEnabled = True End Sub
[過去のデータ一覧]ボタンをクリックした時の処理
Button表面の文字で条件分岐を行います。
Button表面の文字が「過去のデータ一覧」の場合の処理です。
非表示だったListBoxを表示します。ピクチャライブラリのEarthQuakeDataサブフォルダにアクセスします。
GetFileAsyncメソッドでEarhtQuakeDataサブフォルダ内のファイルを取得しコレクション変数DataFileに格納します。
文字列型の新しいリストであるmyFileオブジェクトを作成します。
ファイルを格納しているコレクション変数DataFile内のファイルを変数resultで取得しながら、反復処理を行います。
リストのオブジェクトmyFileにAddメソッドで、Path.GetFileNameWithoutExtension(result.Path)と指定して、取得したファイル名を、パスや拡張子を除いて追加していきます。
同じくリストであるメンバ変数myFile2にはパス付拡張子付のファイル名を追加していきます。
Button表面の文字が「現在のデータ表示」の場合は、ListBoxを非表示にし、Buttonの文字を「過去のデータ一覧」としてDataShowプロシージャを実行します。
非同期処理で行われるため、メソッドの先頭にAsyncを追加します。Asyncが追加されていると、その処理が非同期で行われることを意味します。
Private Async Sub dataShowButton_Click(sender As Object, e As RoutedEventArgs) Handles dataShowButton.Click Select Case dataShowButton.Content.ToString Case "過去のデータ一覧" ListBox1.Visibility = Xaml.Visibility.Visible Dim myStorageFolder As StorageFolder = Windows.Storage.KnownFolders.PicturesLibrary Dim mySubFolder = Await myStorageFolder.CreateFolderAsync("EarthQuakeData", CreationCollisionOption.OpenIfExists) Dim DataFile As IReadOnlyList(Of StorageFile) = Await mySubFolder.GetFilesAsync() Dim myFile As New List(Of String) For Each result In DataFile myFile.Add(System.IO.Path.GetFileNameWithoutExtension(result.Path)) myFile2.Add(result.Path) Next ListBox1.ItemsSource = myFile dataShowButton.Content = "現在のデータ表示" Case "現在のデータ表示" ListBox1.Visibility = Xaml.Visibility.Collapsed dataShowButton.Content = "過去のデータ一覧" DataShow() End Select End Sub
ListBoxから表示したい日付が選択された時の処理
Mapを一度初期化しておきます。この処理を怠ると円が重複して表示されますので、注意してください。
ピクチャライブラリのEarthQuakeDataサブフォルダにアクセスします。GetFileAsyncメソッドでEarthQuakeDataサブフォルダ内のファイルを取得し、コレクション変数readXmlFileに格納しておきます。
コレクション変数readXmlFileでListBoxから選択されたインデックスに該当するファイルを取得し、変数myTextに格納します。ドキュメントライブラリのEarthQuakeDataフォルダには図18のような形でXMLファイルが保存されています。
XElement.ParseメソッドでテキストとしてのXMLファイル(myText)を読み込みます。
地図の表示形式を「道路表示」とします。各変数をString.Emptyで初期化しておきます。
ListBoxから選択されたファイル名を、SubStringメソッドを使って、年、月、日の値を抽出します。/(スラッシュ)で連結して変数nenTukiHiに格納しておきます。
DescenDatnstメソッドで全ての子孫要素
リスト3の結果XML内の、
MapのCenterプロパティにDouble型に変換したmyLatitude(
新しいEllipseのインスタンスmyEllipseオブジェクトを作成します。枠線の色をNavyに指定します。WidthとHeightは20とします。直径20pixelの円が描かれます。
新しいStackPanelのインスタンスmyStackpanelオブジェクトを作成します。SetValueメソッドのZindexPropertyに1ずつ加算されるzIndexNo2の値を指定します。StackPanelが円よりも前面に表示されます。myStackPanelオブジェクトの背景色にGainsBoroを指定します。初期状態ではmyStackPanelオブジェクトを非表示としておきます。
次に、TextBlockの新しいインスタンスmyTextBlockオブジェクトを作成します。パディングに5を指定し、Textプロパティに改行を含めた、「発生日時」、「震源地」、「マグニチュード」、「震度」を指定します。文字色はNavyで、文字サイズは20とします。
myStackPanelオブジェクトにmyTextBlockオブジェクトを追加します。
MapLayerクラスのSetPositionメソッドで、マップレイヤー内に要素の位置を設定します。この場合、myLatitudeとmyLongitudeの位置にmyStackPaneオブジェクトをセットします。MapLayerクラスは、地図上の要素の位置を保持しているマップレイヤーを表すクラスです。
MapにAddメソッドでmyStackPanelオブジェクトを追加します。
「発生日時が」の中に変数nenTukiHI(現在の日付)が含まれていた場合は、円をRedで塗りつぶします。それ以外はYellowで塗りつぶします。
MapLayerクラスのSetPositionメソッドで、マップレイヤー内に要素の位置を設定します。この場合、myLatitudeとmyLongitudeの位置にmyEllipse(円)オブジェクトをセットします。
MapにAddメソッドでmyEllipseオブジェクトを追加します。
円がタップされた時はmyStackPanelオブジェクトを表示します。「発生日時」、「震源地」、「マグニチュード」、「震度」の書かれたTextBlockが表示されます。
myStackPanelオブジェクトがタップされた時は、myStackPanelオブジェクトを非表示にします。「発生日時」、「震源地」、「マグニチュード」、「震度」の書かれたTextBlockも非表示になります。
非同期処理で行われるため、メソッドの先頭にAsyncを追加します。Asyncが追加されていると、その処理が非同期で行われることを意味します。
Private Async Sub ListBox1_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles ListBox1.SelectionChanged Try myMap.Children.Clear() Dim myStorageFolder As StorageFolder = Windows.Storage.KnownFoldersPicturesLibrary Dim mySubFolder = Await myStorageFolder.CreateFolderAsync("EarthQuakeData", CreationCollisionOption.OpenIfExists) Dim readXmlFile As IReadOnlyList(Of StorageFile) = Await mySubFolder.GetFilesAsync() Dim myText As String = Await FileIO.ReadTextAsync(readXmlFile(ListBox1.SelectedIndex)) Dim doc As XElement = XElement.Parse(myText) myMap.MapType = MapType.Road Dim detectionDate As String = String.Empty Dim myLocation As String = String.Empty Dim myLatitude As String = String.Empty Dim myLongitude As String = String.Empty Dim myMagnitude As String = String.Empty Dim myIntensity As String = String.Empty Dim myDateTimeStr = ListBox1.SelectedItem.ToString Dim _year As String = myDateTimeStr.Substring(0, 4) Dim _month As String = myDateTimeStr.Substring(5, 2) Dim _day As String = myDateTimeStr.Substring(8, 2) Dim nenTukiHi As String = _year & "/" & _month & "/" & _day For Each result In From c In doc.Elements("item") Select c zIndexNo2 = zIndexNo2 + 1 myLocation = result.Element("epicenter_location_name").Value detectionDate = result.Element("detection_date").Value myLatitude = result.Element("epicenter_coor_lat").Value myLongitude = result.Element("epicenter_coor_long").Value myMagnitude = result.Element("magnitude").Value myIntensity = result.Element("intensity").Value myMap.Center = New Location(CDbl(myLatitude), CDbl(myLongitude)) Dim myEllipse As New Ellipse myEllipse.Width = 20 myEllipse.Height = 20 myEllipse.Stroke = New SolidColorBrush(Colors.Blue) Dim myStackPanel As New StackPanel myStackPanel.SetValue(Canvas.ZIndexProperty, zIndexNo2) myStackPanel.Background = New SolidColorBrush(Colors.Gainsboro) myStackPanel.Visibility = Xaml.Visibility.Collapsed Dim myTextBlock As New TextBlock myTextBlock.Padding = New Thickness(5) myTextBlock.Text = "発生日時=" & detectionDate & vbCrLf & "震源地=" & myLocation & vbCrLf & "マグニチュード=" & myMagnitude & vbCrLf & "震度=" & myIntensity myTextBlock.Foreground = New SolidColorBrush(Colors.Navy) myTextBlock.FontSize = 20 myStackPanel.Children.Add(myTextBlock) MapLayer.SetPosition(myStackPanel, New Location(CDbl(myLatitude), CDbl(myLongitude))) myMap.Children.Add(myStackPanel) Dim _myDate As DateTime = Date.Now If detectionDate.Contains(nenTukiHi) = True Then myEllipse.Fill = New SolidColorBrush(Colors.Red) Else myEllipse.Fill = New SolidColorBrush(Colors.Yellow) End If MapLayer.SetPosition(myEllipse, New Location(CDbl(myLatitude), CDbl(myLongitude))) myMap.Children.Add(myEllipse) AddHandler myEllipse.Tapped, Sub() myStackPanel.Visibility = Xaml.Visibility.Visible End Sub AddHandler myStackPanel.Tapped, Sub() myStackPanel.Visibility = Xaml.Visibility.Collapsed End Sub Next Catch Exit Sub End Try End Sub End Class
地図の拡大縮小、表示モードの変更等はBing Mapsで自動的に処理されるため、コードを書く必要はありません。
今回はここまでです。ありがとうございました。
Bing Maps上に地震の震源地を表示するWindowsアプリ
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- フリーハンドで書いた住所を認識してBing Map上に表示する
- Bing Maps上の好きな場所をマークして情報を表示するプログラムを作る
- APIを使って土地の公示価格を調べるプログラムを作る
- 場所と写真を記録するプログラムを作って思い出のシーンを保存しよう
- 写真と現在位置を入れた画像日記アプリを作る
- 現在位置の近くにある宿を検索するサンプルプログラム
- 自分の現在位置を取得して表示するサンプルプログラム
- 現在位置近くの病院を素早く検索するサンプルプログラム
- Yahoo!ローカルサーチAPIを使って地図上にランドマークを表示させるプログラムを作る
- 入力された住所の位置をBing Mapsに表示する