<※前ページからの続きです。>
[現在の情報保存]ボタンがクリックされた時の処理
現在の、何年何月何日何時何分何秒.xmlという文字列を作成し、変数myFileに格納しておきます。
ピクチャライブラリ内のEarthQuakeDataというサブフォルダにアクセスします。CreateAsyncFolderメソッドにCreationCollisionOption.OpenIfExistsを指定してフォルダを作成すると、既に同名のフォルダがある場合は、そのフォルダ名を返し、無い場合はフォルダを新規に作成してくれます。
CreateFileAsyncメソッドでサブフォルダ内に変数myFileが格納しているファイルを作成し、変数saveFileで参照しておきます。
FileIO.WriteTextAsyncメソッドで、指定したファイルにmyResponse(結果XMLが入っている)の内容を書き込みます。「保存しました。」のメッセージを表示し、dataShowButtonを使用可能にします。
これで、現在の地震の情報を記録したXMLファイルが保存されます。非同期処理で行われるため、メソッドの先頭にAsyncを追加します。
01 | Private Async Sub dataSaveButton_Click(sender As Object, e As RoutedEventArgs) Handles dataSaveButton.Click |
02 | Dim myFile As String = DateTime.Now.ToString("yyyy年MM月dd日HH時mm分ss秒") & ".xml" |
03 | Dim myStorageFolder As StorageFolder = Windows.Storage.KnownFoldersPicturesLibrary |
04 | Dim mySubFolder = Await myStorageFolder.CreateFolderAsync("EarthQuakeData", CreationCollisionOption.OpenIfExists) |
05 | Dim saveFile As StorageFile = Await mySubFolder.CreateFileAsync(myFile) |
06 | Await FileIO.WriteTextAsync(saveFile, myResponse) |
07 | Dim myMessage As New MessageDialog("保存しました") |
08 | Await myMessage.ShowAsync |
09 | dataShowButton.IsEnabled = True |
[過去のデータ一覧]ボタンをクリックした時の処理
Button表面の文字で条件分岐を行います。
Button表面の文字が「過去のデータ一覧」の場合の処理です。
非表示だったListBoxを表示します。ピクチャライブラリのEarthQuakeDataサブフォルダにアクセスします。
GetFileAsyncメソッドでEarhtQuakeDataサブフォルダ内のファイルを取得しコレクション変数DataFileに格納します。
文字列型の新しいリストであるmyFileオブジェクトを作成します。
ファイルを格納しているコレクション変数DataFile内のファイルを変数resultで取得しながら、反復処理を行います。
リストのオブジェクトmyFileにAddメソッドで、Path.GetFileNameWithoutExtension(result.Path)と指定して、取得したファイル名を、パスや拡張子を除いて追加していきます。
同じくリストであるメンバ変数myFile2にはパス付拡張子付のファイル名を追加していきます。
Button表面の文字が「現在のデータ表示」の場合は、ListBoxを非表示にし、Buttonの文字を「過去のデータ一覧」としてDataShowプロシージャを実行します。
非同期処理で行われるため、メソッドの先頭にAsyncを追加します。Asyncが追加されていると、その処理が非同期で行われることを意味します。
01 | Private Async Sub dataShowButton_Click(sender As Object, e As RoutedEventArgs) Handles dataShowButton.Click |
02 | Select Case dataShowButton.Content.ToString |
04 | ListBox1.Visibility = Xaml.Visibility.Visible |
05 | Dim myStorageFolder As StorageFolder = Windows.Storage.KnownFolders.PicturesLibrary |
06 | Dim mySubFolder = Await myStorageFolder.CreateFolderAsync("EarthQuakeData", CreationCollisionOption.OpenIfExists) |
07 | Dim DataFile As IReadOnlyList(Of StorageFile) = Await mySubFolder.GetFilesAsync() |
08 | Dim myFile As New List(Of String) |
10 | For Each result In DataFile |
11 | myFile.Add(System.IO.Path.GetFileNameWithoutExtension(result.Path)) |
12 | myFile2.Add(result.Path) |
14 | ListBox1.ItemsSource = myFile |
15 | dataShowButton.Content = "現在のデータ表示" |
17 | ListBox1.Visibility = Xaml.Visibility.Collapsed |
18 | dataShowButton.Content = "過去のデータ一覧" |
ListBoxから表示したい日付が選択された時の処理
Mapを一度初期化しておきます。この処理を怠ると円が重複して表示されますので、注意してください。
ピクチャライブラリのEarthQuakeDataサブフォルダにアクセスします。GetFileAsyncメソッドでEarthQuakeDataサブフォルダ内のファイルを取得し、コレクション変数readXmlFileに格納しておきます。
コレクション変数readXmlFileでListBoxから選択されたインデックスに該当するファイルを取得し、変数myTextに格納します。ドキュメントライブラリのEarthQuakeDataフォルダには図18のような形でXMLファイルが保存されています。
図18:ドキュメントライブラリのEarthQuakeDataサブフォルダに保存されているXMLファイル(クリックで拡大)
XElement.ParseメソッドでテキストとしてのXMLファイル(myText)を読み込みます。
地図の表示形式を「道路表示」とします。各変数をString.Emptyで初期化しておきます。
ListBoxから選択されたファイル名を、SubStringメソッドを使って、年、月、日の値を抽出します。/(スラッシュ)で連結して変数nenTukiHiに格納しておきます。
DescenDatnstメソッドで全ての子孫要素に対して、その値を変数resultに格納しながら、反復処理を行います。メンバ変数zIndexNo2の値を1ずつ加算します。
- 要素の各子要素の値を各変数に格納していきます。結果XMLの構造はリスト3を参照してください。
リスト3の結果XML内の、要素の子要素、、要素の子要素での子要素、要素の子要素での子要素、、要素の値を使用します。
MapのCenterプロパティにDouble型に変換したmyLatitude(要素の値を格納)とmyLongitude(要素の値を格納)の値で初期化された、新しいLocationを指定します。
新しい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が追加されていると、その処理が非同期で行われることを意味します。
01 | Private Async Sub ListBox1_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles ListBox1.SelectionChanged |
03 | myMap.Children.Clear() |
04 | Dim myStorageFolder As StorageFolder = Windows.Storage.KnownFoldersPicturesLibrary |
05 | Dim mySubFolder = Await myStorageFolder.CreateFolderAsync("EarthQuakeData", CreationCollisionOption.OpenIfExists) |
06 | Dim readXmlFile As IReadOnlyList(Of StorageFile) = Await mySubFolder.GetFilesAsync() |
07 | Dim myText As String = Await FileIO.ReadTextAsync(readXmlFile(ListBox1.SelectedIndex)) |
08 | Dim doc As XElement = XElement.Parse(myText) |
10 | myMap.MapType = MapType.Road |
12 | Dim detectionDate As String = String.Empty |
13 | Dim myLocation As String = String.Empty |
14 | Dim myLatitude As String = String.Empty |
15 | Dim myLongitude As String = String.Empty |
16 | Dim myMagnitude As String = String.Empty |
17 | Dim myIntensity As String = String.Empty |
19 | Dim myDateTimeStr = ListBox1.SelectedItem.ToString |
20 | Dim _year As String = myDateTimeStr.Substring(0, 4) |
21 | Dim _month As String = myDateTimeStr.Substring(5, 2) |
22 | Dim _day As String = myDateTimeStr.Substring(8, 2) |
23 | Dim nenTukiHi As String = _year & "/" & _month & "/" & _day |
25 | For Each result In From c In doc.Elements("item") Select c |
26 | zIndexNo2 = zIndexNo2 + 1 |
27 | myLocation = result.Element("epicenter_location_name").Value |
28 | detectionDate = result.Element("detection_date").Value |
29 | myLatitude = result.Element("epicenter_coor_lat").Value |
30 | myLongitude = result.Element("epicenter_coor_long").Value |
31 | myMagnitude = result.Element("magnitude").Value |
32 | myIntensity = result.Element("intensity").Value |
33 | myMap.Center = New Location(CDbl(myLatitude), CDbl(myLongitude)) |
35 | Dim myEllipse As New Ellipse |
38 | myEllipse.Stroke = New SolidColorBrush(Colors.Blue) |
40 | Dim myStackPanel As New StackPanel |
41 | myStackPanel.SetValue(Canvas.ZIndexProperty, zIndexNo2) |
42 | myStackPanel.Background = New SolidColorBrush(Colors.Gainsboro) |
43 | myStackPanel.Visibility = Xaml.Visibility.Collapsed |
45 | Dim myTextBlock As New TextBlock |
46 | myTextBlock.Padding = New Thickness(5) |
47 | myTextBlock.Text = "発生日時=" & detectionDate & vbCrLf & "震源地=" & myLocation & vbCrLf & "マグニチュード=" & myMagnitude & vbCrLf & "震度=" & myIntensity |
48 | myTextBlock.Foreground = New SolidColorBrush(Colors.Navy) |
49 | myTextBlock.FontSize = 20 |
50 | myStackPanel.Children.Add(myTextBlock) |
52 | MapLayer.SetPosition(myStackPanel, New Location(CDbl(myLatitude), CDbl(myLongitude))) |
53 | myMap.Children.Add(myStackPanel) |
55 | Dim _myDate As DateTime = Date.Now |
56 | If detectionDate.Contains(nenTukiHi) = True Then |
57 | myEllipse.Fill = New SolidColorBrush(Colors.Red) |
59 | myEllipse.Fill = New SolidColorBrush(Colors.Yellow) |
61 | MapLayer.SetPosition(myEllipse, New Location(CDbl(myLatitude), CDbl(myLongitude))) |
62 | myMap.Children.Add(myEllipse) |
63 | AddHandler myEllipse.Tapped, Sub() |
64 | myStackPanel.Visibility = Xaml.Visibility.Visible |
67 | AddHandler myStackPanel.Tapped, Sub() |
68 | myStackPanel.Visibility = Xaml.Visibility.Collapsed |
地図の拡大縮小、表示モードの変更等はBing Mapsで自動的に処理されるため、コードを書く必要はありません。
今回はここまでです。ありがとうございました。