APIを使って土地の公示価格を調べるプログラムを作る

2013年6月12日(水)
薬師寺 国安

次に、ソリューションエクスプローラー内のMainWindow.xamlを展開して表示される、MainWindow.xaml.vbをダブルクリックしてリスト2のコードを記述します。

ロジックコードを記述する

リスト2 (MainWindow.xaml.vb)

Option Strict On

最新のHTTPアプリケーション用のプログラミングインターフェイスを提供するクラスの含まれる、System.Net.Http名前空間をインポートします。

Imports System.Net.Http

コンテテキストメニューおよびメッセージダイアログのサポートを提供するクラスの含まれる、Windows.UI.Popups名前空間をインポートします。

Imports Windows.UI.Popups

Bing Mapsに関するクラスの含まれるBing.Maps名前空間をインポートします。

Imports Bing.Maps

コアシステムの機能とその UI についてのランタイム情報にアクセスするアプリケーションを提供するクラスの含まれる、Windows.UI名前空間をインポートします。
PushPinの色を指定する場合等に、この名前空間に含まれるクラスを使用します。

Imports Windows.UI
Public NotInheritable Class MainPage
  Inherits Page
  Dim _image As String

[OK]ボタンがタップされた時の処理

Bing Maps内を一度クリアしておきます。変数myUriに
String.Format("http://db1.jyutaku.co.jp/njr/JFW/Api/?apli=chika&v=1&addr={0}&syubetsu=0&dist=1000&limit=10", Uri.EscapeDataString(searchTextBox.Text))
と指定してRESTの文字列を格納しておきます。
引数addrにエスケープした住所入力ボックス内の値を指定します。
syubetsuには0を指定して、「地価公示(標準地)」とします。
distには検索範囲距離をメートル単位で指定します。このサンプルでは1000メートル(1km)としています。
これで返される結果XMLは図14のようになります。赤い線の引かれた要素の値を取得します。

図14:結果XML(クリックで拡大)

HttpClientクラスの新しいインスタンスmyHttpClientオブジェクトを作成します。
HttpClientクラスは、URI で識別されるリソースに HTTP 要求を送信し、そのリソースから HTTP 応答を受信するためのクラスです。
HttpClientクラスのGetStringAsyncメソッドで、指定したURIにGET送信し、非同期操作で応答本体を文字列として受け取り、変数resultに格納します。
XElement.Parseメソッドでresult変数の内容を文字列として読み込みます。

Descendantsメソッドで全ての子孫要素である要素を取得するクエリを定義します。
Countプロパティで要素の個数を取得し、個数が0より大きい場合は、Descendantsメソッドで全ての子孫要素である要素内を変数resultで反復処理しながら以下の処理を行います。

変数myAddressに要素の値を格納し、変数myYearに要素の値を格納します。変数myPriceに要素の値を格納し、変数myLatitudeに要素の値を、変数myLongitudeに要素の値を格納します。
変数noの値を1ずつ加算します。この値はPushPinの表面に表示される数値です。

MapのCenterプロパティにDouble型に変換したmyLatitude(要素の値を格納)とmyLongitude(要素の値を格納)の値を指定します。

新しいPushPinクラスのインスタンスmyPinオブジェクトを作成します。
背景色にCrimsonを指定し、Textプロパティにピンの表面に表示される変数noの値を文字列に変換して指定します。

新しいStackPanelのインスタンスmyStackPanelオブジェクトを作成します。
Marginプロパティに5を指定して余白を設けます。背景色にはPinkを指定します。
myStackPanelオブジェクトを非表示としておきます。

新しいTextBlockのインスタンスmyTextBlockオブジェクトを作成します。

文字色にNavyを、文字サイズに24、パディングに5を指定し、Textプロパティに「更新年度:」という文字列とmyYear変数の値に「年」を連結して指定します。

新しいTextBlockのインスタンスmyPriceTextBlockオブジェクトを作成します。

文字色にNavyを、文字サイズに24、パディングに5を指定し、Textプロパティに「価格:」という文字列とmyPrice変数の値に「円」を連結して、三桁区切りで指定します。

新しいTextBlockのインスタンスmyDistTextBlockオブジェクトを作成します。

文字色にNavyを、文字サイズに24、パディングに5を指定し、Textプロパティに「検索地からの距離:」という文字列とmyDistance変数の値に「m」を連結して指定します。

myStackPanelオブジェクトにAddメソッドで、myTextBlock、myYearTextBlock、myPriceTextBlock、myDistTextBlockオブジェクトを追加します。

SetValueメソッドでZIndexの値に1ずつ加算される変数noの値を指定します。
これで、StackPanelが表示された時は、PushPinより前面に表示されます。

MapLayerクラスのSetPositionメソッドで、マップレイヤー内に要素の位置を設定します。この場合、myLatitudeとmyLongitudeの位置にmyPinオブジェクトをセットします。MapLayerクラスは、地図上の要素の位置を保持しているマップレイヤーを表すクラスです。
MapにAddメソッドでmyPinオブジェクトを追加します。

同様に、MapLayerクラスのSetPositionメソッドで、マップレイヤー内に要素の位置を設定します。この場合、myLatitudeとmyLongitudeの位置にmyStackPaneオブジェクトをセットします。MapLayerクラスは、地図上の要素の位置を保持しているマップレイヤーを表すクラスです。
MapにAddメソッドでmyStackPanelオブジェクトを追加します。

AddHandlerステートメントで、ピンがタップされた時のイベントハンドラを追加します。
myStackPanelを表示状態にします。

AddHandlerステートメントで、myStackPanelオブジェクトがタップされた時のイベントハンドラを追加します。
myStackPanelを非表示状態にします。

データが存在しない場合は、警告メッセージを表示して、処理を抜けます。

  Private Async Sub OkButton_Click(sender As Object, e As RoutedEventArgs) Handles OkButton.Click
    If searchTextBox.Text<>String.Empty Then
      myMap.Children.Clear()
      Dim no As Integer = 0
      Dim myUri = String.Format("http://db1.jyutaku.co.jp/njr/JFW/Api/?apli=chika&v=1&addr={0}&syubetsu=0&dist=1000&limit=10", Uri.EscapeDataString(searchTextBox.Text))
      Dim myHttpClient As New HttpClient
      Dim resut = Await myHttpClient.GetStringAsync(myUri)
      Dim xmldoc As XElement = XElement.Parse(resut)
      Dim myQuery = From c In xmldoc.Descendants("item") Select c
      Dim resultCount = myQuery.Count
 
      If myQuery.Count> 0 Then
        For Each result In From c In xmldoc.Descendants("item") Select c
          Dim myAddress = result.Attribute("addr").Value
          Dim myYear = result.Attribute("year").Value
          Dim myPrice = result.Attribute("price_10").Value
          Dim myDistance = result.Attribute("dist").Value
          Dim myLatitude = result.Attribute("lat").Value
          Dim myLongitude = result.Attribute("lng").Value
          no += 1
          myMap.Center = New Location(CDbl(myLatitude), CDbl(myLongitude))
          Dim myPin As New Pushpin
          myPin.Background = New SolidColorBrush(Colors.Crimson)
          myPin.Text = no.ToString
          Dim myStackPanel As New StackPanel
          myStackPanel.Margin = New Thickness(5)
          myStackPanel.Background = New SolidColorBrush(Colors.Pink)
          myStackPanel.Visibility = Xaml.Visibility.Collapsed
          Dim myTextBlock As New TextBlock
          myTextBlock.Foreground = New SolidColorBrush(Colors.Navy)
          myTextBlock.FontSize = 24
          myTextBlock.Padding = New Thickness(5)
 
          myTextBlock.Text = "住所:" &myAddress
 
          Dim myYearTextBlock As New TextBlock
          myYearTextBlock.Foreground = New SolidColorBrush(Colors.Navy)
          myYearTextBlock.FontSize = 24
          myYearTextBlock.Padding = New Thickness(5)
          myYearTextBlock.Text = "更新年度:" &myYear& "年"
 
          Dim myPriceTextBlock As New TextBlock
          myPriceTextBlock.Foreground = New SolidColorBrush(Colors.Navy)
          myPriceTextBlock.FontSize = 24
          myPriceTextBlock.Padding = New Thickness(5)
  
          myPriceTextBlock.Text = "価格:" &String.Format("{0:#,0}", CInt(myPrice)) & "円"
 
          Dim myDistTextBlock As New TextBlock
          myDistTextBlock.Foreground = New SolidColorBrush(Colors.Navy)
          myDistTextBlock.FontSize = 24
          myDistTextBlock.Padding = New Thickness(5)
          myDistTextBlock.Text = "検索地からの距離:" &myDistance& "m"

          myStackPanel.Children.Add(myTextBlock)
          myStackPanel.Children.Add(myYearTextBlock)
          myStackPanel.Children.Add(myPriceTextBlock)
          myStackPanel.Children.Add(myDistTextBlock)
          myStackPanel.SetValue(Canvas.ZIndexProperty, no)
          MapLayer.SetPosition(myPin, New Location(CDbl(myLatitude), CDbl(myLongitude)))
          myMap.Children.Add(myPin)

          MapLayer.SetPosition(myStackPanel, New Location(CDbl(myLatitude), CDbl(myLongitude)))
          myMap.Children.Add(myStackPanel)

          AddHandlermyPin.Tapped, Sub()
                                     myStackPanel.Visibility = Xaml.Visibility.Visible
                                End Sub

          AddHandlermyStackPanel.Tapped, Sub()
                                          myStackPanel.Visibility = Xaml.Visibility.Collapsed
              
                                      End Sub
        Next
      Else
        Dim myMessage As New MessageDialog("該当データがありません。入力しなおしてください。")
  
        Await myMessage.ShowAsync
        myMap.ZoomLevel = 1
      End If
    Else
      Exit Sub
    End If
  End Sub
End Class

地図の拡大縮小、表示モードの変更等はBing Mapsで自動的に処理されるため、コードを書く必要はありません。

今回はここまでです。ありがとうございました。

筆者からのお知らせ

筆者はWindowsストアでアプリを公開しています。チャームの検索からWindowsストアを選択して、検索欄に、kuniyasuまたはYakushijiKuniyasuと入力すると、公開されているアプリの一覧が表示されます。上記はどちらも私のアカウントですので、興味のある方は是非ダウンロードして使ってみてください。

  • 土地の公示価格を調べるプログラム

薬師寺国安事務所

薬師寺国安事務所代表。Visual Basic プログラミングと、マイクロソフト系の技術をテーマとした、書籍や記事の執筆を行う。
1950年生まれ。事務系のサラリーマンだった40歳から趣味でプログラミングを始め、1996年より独学でActiveXに取り組む。1997年に薬師寺聖とコラボレーション・ユニット PROJECT KySS を結成。2003年よりフリーになり、PROJECT KySS の活動に本格的に参加、.NETやRIAに関する書籍や記事を多数執筆する傍ら、受託案件のプログラミングも手掛ける。Windows Phoneアプリ開発を経て、現在はWindows ストア アプリを多数公開中

Microsoft MVP for Development Platforms - Client App Dev (Oct 2003-Sep 2012)。Microsoft MVP for Development Platforms - Windows Phone Development(Oct 2012-Sep 2013)。Microsoft MVP for Development Platforms - Client Development(Oct 2013-Sep 2014)。Microsoft MVP for Development Platforms-Windows Platform Development (Oct 2014-Sep 2015)。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています