Bing Maps上に地震の震源地を表示するプログラムを作る
「構成マネージャ」の設定
この状態では、まだBing Maps SDKが使用できませんので、これを使用できるようにします。まず、VS2012のメニューから「ビルド(B)/構成マネージャ(O)」と選択します。「プラットフォーム」がAny CPUになっていますので、プルダウンメニューから、該当するプラットフォームを選択します。筆者の環境では×86を選択する必要がありました(図11)。
[閉じる]ボタンをクリックすると、ソリューションエクスプローラー内の「参照設定」にあった「Bing Maps for C#, C++, or Visual Basic (Beta)」と「Microsoft Visual C++ Runtime Package」の先頭の黄色いアイコンが消えています。これでBing Maps SDKの使用が可能になりました。
コントロールの配置
表示されるデザイン画面の
bm:Mapコントロールを配置すれば、Bing.Mapsの地図が表示されるはずです。もし地図が表示されない場合は、一度VS2012を再起動してください。
書き出されるXAMLコードをリスト1のように編集します。レイアウトは図13になります。
リスト1 書き出され編集されたXAMLコード(MainPage.xaml)
- (1) bmという名前空間を定義しています。
- (2)
- (3)
要素を配置し、背景色にDarkGreenを指定します。その子要素として、 要素を配置し、OrientationプロパティにHorizontalと指定します。この 要素の子要素として、名前がdataSaveButtonという
<Page x:Class="Win8_EarthQuakeJapan.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:Win8_EarthQuakeJapan" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:bm="using:Bing.Maps"■(1) mc:Ignorable="d"> <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <bm:Map Credentials="Bing Maps Account Center で取得したキー" x:Name="myMap"/>■(2) <AppBar Background="DarkGreen" Height="100" Margin="0,668,0,0">■(3) <StackPanel Orientation="Horizontal">■(3) <Button Width="152" x:Name="dataSaveButton" Foreground="Gold" Style="{StaticResource SaveAppBarButtonStyle}" />■(3) <Button Content="過去のデータ一覧" Height="50" Width="218" x:Name="dataShowButton" Background="Black" Margin="40,0,0,0" BorderBrush="Crimson" Foreground="Crimson"/>■(3) <ListBox Name="ListBox1" Margin="40,0,0,0" BorderBrush="Navy" Width="433"/>■(3) </StackPanel>■(3) </AppBar>■(3) </Grid> </Page>
Bing Maps Keyの取得方法
Bing Mapsを使用するには下記URLのBing Maps Account Centerに行って専用のライセンスキーを取得する必要があります。
→ Bing Maps Account Center
ライセンスキーの取得にはWindows Live IDが必要です。持っていない方はCreateからWindows Live IDを作成してSign Inしてください。お持ちの方はそのままSign Inしてください。筆者はIDを持っているため、ここではSign Inから入ります(図14)。
表示される画面の左にあるCreate or view keysをクリックします(図15)。
Create keyの画面が表示されますので、必要な項目を入力してSubmitしてください。筆者は既にキーを持っていますので、下記にキーが表示されています(図16)。Key typeはBasicとなっています。BasicでPublic websiteの場合は、「アプリケーションが制限なしに利用され、500,000 のトランザクションの任意の種類の 12 ヶ月の期間内を超えない、公開ウェブサイトです。」となっているようです。
ドキュメントライブラリへのアクセス許可の設定
今回のサンプルは、XMLファイルをドキュメントライブラリ内に作成して、読み込んだりしますので「ドキュメントライブラリ」へのアクセス許可が必要です。ソリューションエクスプローラー内にpackage.appxmanifestというファイルがありますので、このファイルをダブルクリックします。「機能」タブをクリックして、「画像ライブラリ」にチェックを付けます(図17)。
次に、ソリューションエクスプローラー内のMainWindow.xamlを展開して表示される、MainWindow.xaml.vbをダブルクリックしてリスト2のコードを記述します。
ロジックコードを記述する
リスト2 (MainWindow.xaml.vb)
Option Strict On
Bing Mapsに関するクラスの含まれるBing.Maps名前空間をインポートします。
Imports Bing.Maps
最新のHTTPアプリケーション用のプログラミングインターフェイスを提供するクラスの含まれる、System.Net.Http名前空間をインポートします。
Imports System.Net.Http
コアシステムの機能とその UI についてのランタイム情報にアクセスするアプリケーションを提供するクラスの含まれる、Windows.UI名前空間をインポートします。描く円の色を指定する場合等に、この名前空間に含まれるクラスを使用します。
Imports Windows.UI
図形に関するクラスの含まれる、Windows.UI.Xaml.Shapes名前空間をインポートします。
Imports Windows.UI.Xaml.Shapes
ファイル、フォルダ、およびアプリケーションの設定を管理するクラスの含まれる、Windows.Storage名前空間をインポートします。
Imports Windows.Storage Public NotInheritable Class MainPage Inherits Page Dim zIndexNo As Integer = 0 Dim zIndexNo2 As Integer = 0 Dim myResponse As String
文字列型の新しいリストであるmyFile2メンバ変数を宣言します。
Dim myFile2 As New List(Of String)
「なまず地震情報取得API」のUriで初期化された新しいUriのインスタンス、myUriメンバ変数を宣言します。返されるデータ形式はXML形式となります。
Dim myUri As Uri = New Uri("http://api.nmzu.jp/history.xml", UriKind.Absolute)
ページがアクティブになった時の処理
ピクチャライブラリ内にCreateFolderAsyncメソッドで、EarthQuakeDataというサブフォルダを作成します。その際、CreationCollisionOption.OpenIfExistsを指定すると、同名フォルダが存在ずる場合は、そのフォルダ名を返し、無い場合は新規に作成してくれます。
GetFilesAsyncメソッドでEarthQuakeDataサブフォルダ内のファイルを取得し、コレクション変数earthQuakeDataに格納します。
Countプロパティでファイルの個数を取得し、ファイルが無い場合は、dataShowButtonの使用を不可とし、それ以外は使用を可とします。
地図上の地震の震源地に●印を表示するDataShowプロシージャを実行します。
非同期処理で行われるため、メソッドの先頭にAsyncを追加します。
Protected Overrides Async Sub OnNavigatedTo(e As Navigation.NavigationEventArgs) Dim myStorageFolder As StorageFolder = Windows.Storage.KnownFolders.PicturesLibrary Dim mySubFolder = Await myStorageFolder.CreateFolderAsync("EarthQuakeData", CreationCollisionOption.OpenIfExists) Dim earthQuakeData = Await mySubFolder.GetFilesAsync If earthQuakeData.Count = 0 Then dataShowButton.IsEnabled = False Else dataSaveButton.IsEnabled = True End If DataShow() End Sub
地図上の地震の震源地に●印を表示する処理
HttpClientクラスの新しいインスタンスmyHttpClientオブジェクトを作成します。HttpClientクラスは、URI で識別されるリソースに HTTP 要求を送信し、そのリソースから HTTP 応答を受信するためのクラスです。
HttpClientクラスのGetStringAsyncメソッドで、指定したURIにGET送信し、非同期操作で応答本体を文字列として受け取ります。
地図の表示形式を「道路表示」にしておきます。各変数を宣言し、2013/01/01といった形式で、現在の日付を生成して変数myDateに格納しておきます。数値を、01、02といった形式で表示するには、Tostring(“00”)と指定します。
XElement.Parseメソッドで、文字列として読み込まれたXML(myResponse)を読み取ります。
読み込んだXMLから、DescenDantsメソッドで全ての子孫要素
リスト3 結果XMLの構造
<?xml version="1.0" encoding="UTF-8"?> <nmzu_api_responce> <api> <name>namazu disaster information API</name> <version>1</version> </api> <results> <jishin_info> <entry> <jishin_code>sSk6</jishin_code> <url>http://nmzu.jp/sSk6</url> <detection_date>2013/01/26 06:57</detection_date> <epicenter> <coordinate> <latitude>36.9</latitude> <longitude>139.4</longitude> </coordinate> <name>栃木県北部</name> </epicenter> <intensity_no>1</intensity_no> <magnitude>2.6</magnitude> <tweet_info> <account>@nmzu</account> <id>294928388777467904</id> </tweet_info> </entry> <entry> <jishin_code>XAdy</jishin_code> <url>http://nmzu.jp/XAdy</url> <detection_date>2013/01/26 04:41</detection_date> <epicenter> <coordinate> <latitude>42.3</latitude> <longitude>143</longitude> </coordinate> <name>日高地方東部</name> </epicenter> <intensity_no>1</intensity_no> <magnitude>3.6</magnitude> <tweet_info> <account>@nmzu</account> <id>294894162795442178</id> </tweet_info> </entry> ~<entry></entry>繰り返し~ </jishin_info> </results> </nmzu_api_responce>
上記結果XML内の、
MapのCenterプロパティにDouble型に変換したmyLatitude(
新しいEllipseのインスタンスmyEllipseオブジェクトを作成します。枠線の色をNavyに指定します。WidthとHeightは30とします。直径30pixelの円が描かれます。
新しいStackPanelのインスタンスmyStackpanelオブジェクトを作成します。SetValueメソッドのZIndexPropertyに1ずつ加算されるzIndexNoの値を指定します。StackPanelが円よりも前面に表示されます。myStackPanelオブジェクトの背景色にGainsBoroを指定します。初期状態ではmyStackPanelオブジェクトを非表示としておきます。
次に、TextBlockの新しいインスタンスmyTextBlockオブジェクトを作成します。パディングに5を指定し、Textプロパティに改行を含めた、「発生日時」、「震源地」、「マグニチュード」、「震度」を指定します。文字色はNavyで、文字サイズは20とします。myStackPanelオブジェクトにmyTextBlockオブジェクトを追加します。
MapLayerクラスのSetPositionメソッドで、マップレイヤー内に要素の位置を設定します。この場合、myLatitudeとmyLongitudeの位置にmyStackPaneオブジェクトをセットします。MapLayerクラスは、地図上の要素の位置を保持しているマップレイヤーを表すクラスです。MapにAddメソッドでmyStackPanelオブジェクトを追加します。
現在の日付より-1日した日付を作成し、変数_myDate2に格納しておきます。-1日した日付は、AddDays(-1).Day.ToString(“00”)で取得できます。日付で条件分岐を行います。
「発生日時が」変数_myDate2(現在の日付より1日前)であった場合は、円をOrangeで塗りつぶします。変数「発生日時が」変数myDate(現在の日付)であった場合は、円をRedで塗りつぶします。それ以外はYellowで塗りつぶします。
MapLayerクラスのSetPositionメソッドで、マップレイヤー内に要素の位置を設定します。この場合、myLatitudeとmyLongitudeの位置にmyEllipse(円)オブジェクトをセットします。MapにAddメソッドでmyEllipseオブジェクトを追加します。
円がタップされた時はmyStackPanelオブジェクトを表示します。「発生日時」、「震源地」、「マグニチュード」、「震度」の書かれたTextBlockが表示されます。
myStackPanelオブジェクトがタップされた時は、myStackPanelオブジェクトを非表示にします。「発生日時」、「震源地」、「マグニチュード」、「震度」の書かれたTextBlockも非表示になります。例外が発生した場合は、メッセージを表示して処理を抜けるErrorShowプロシージャを実行します。
Private Async Sub DataShow() Try Dim myHttpClient As New HttpClient myResponse = Await myHttpClient.GetStringAsync(myUri) 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 nowYear As Integer = Date.Now.Year Dim nowMonth As Integer = Date.Now.Month Dim nowDay As Integer = Date.Now.Day Dim myDate As String = CStr(nowYear.ToString & "/" & nowMonth.ToString("00") & "/" & nowDay.ToString("00")) Dim xmldoc As XElement = XElement.Parse(myContent) For Each result In From c In xmldoc.Elements("item") Select c zIndexNo + = 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, zIndexNo) 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 Dim _Year = _myDate.Year Dim _Month = _myDate.AddDays(0).Month.ToString("00") Dim _Day = _myDate.AddDays(-1).Day.ToString("00") Dim _myDate2 As String = _Year & "-" & _Month & "-" & _Day If detectionDate.Contains(_myDate2) = True Then myEllipse.Fill = New SolidColorBrush(Colors.Orange) ElseIf detectionDate.Contains(myDate) = 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 DataShow() End Try End Sub
Bing Maps上に地震の震源地を表示するWindowsアプリ
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- フリーハンドで書いた住所を認識してBing Map上に表示する
- Bing Maps上の好きな場所をマークして情報を表示するプログラムを作る
- APIを使って土地の公示価格を調べるプログラムを作る
- 場所と写真を記録するプログラムを作って思い出のシーンを保存しよう
- 写真と現在位置を入れた画像日記アプリを作る
- 現在位置の近くにある宿を検索するサンプルプログラム
- 自分の現在位置を取得して表示するサンプルプログラム
- 現在位置近くの病院を素早く検索するサンプルプログラム
- Yahoo!ローカルサーチAPIを使って地図上にランドマークを表示させるプログラムを作る
- 入力された住所の位置をBing Mapsに表示する