連載
» 2013年12月02日 18時00分 公開

手書きで入力した住所の位置をBing Maps SDKで地図上に表示するには2カ月で160本作った還暦開発者が送る10のアプリ開発ノウハウ(8)(3/5 ページ)

[薬師寺国安,PROJECT KySS]

Bing Mapの表示されるページの作成(BingMapsPage.xaml)

 次にBing Mapの表示されるページを作成する。

 VS 2013のメニューから、[プロジェクト(P)]→[新しい項目の追加(W)]と選択し、表示される「新しい項目の追加」画面で、左のWindows ストアを選択し、右の欄から「空白のページ」を選択する。「名前(N)」には「BingMapsPage.xaml」と指定し、[追加(A)]ボタンをクリックする。

 ツールボックスから、デザイン画面上にコントロールを配置する。書き出されるXAMLコードはリスト2のようになる。

<Page
    x:Class="FreeHandAddressMap.BingMapsPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:FreeHandAddressMap"
    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">
    <Viewbox>
        <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Width="1920" Height="1080">
        <bm:Map Credentials="Bing Maps Account Centerで取得したBing Maps Key" x:Name="myMap"/>■(2)
        <TextBox x:Name="addressTextBox" Margin="540,10,442,1015"  FontFamily="Meiryo UI" FontSize="36" FontWeight="Bold"/>■(3)
        </Grid>
    </Viewbox>
</Page>
リスト2 書き出されたXAMLコード(BingMapsPage.xaml)

 レイアウトしたのが、図13だ。

図13 コントロールを配置した

(1)

 Grid要素全体をViewbox要素で囲む。

(2)

 「bm」という名前空間を定義している。

(3)

 名前が「myMap」という、bm:Map要素を配置し、Credentialsプロパティに「Bing Maps Account Centerで取得したBing Maps Key」を指定する。Bing Maps Keyの取得方法は後述している。

(4)

 手書きで入力した住所を認識して表示する、名前が「addressTextBox」というTextBox要素を配置する。

メイン画面のロジックコードを記述する(MainWindow.xaml.vb)

 次に、[ソリューション・エクスプローラー内]の「MainWindow.xaml」を展開して表示される、「MainWindow.xaml.vb」のコードを記述する。

 ここではコードが長くなるため、今回のテーマと肝となる「画像の合成」「データの一覧表示」部分の解説にとどめている。名前空間の読み込み、メンバー変数の宣言も省略している。全てのコードを見る場合は、サンプルをダウンロードして「MainWindow.xaml.vb」ファイルを見ていただきたい。

要素内で、プレスアクションを起こし、ポインタデバイスが開始された時に発生するイベント(myCanvas_PointerPressedイベント処理)

    Private Sub myCanvas_PointerPressed(sender As Object, e As PointerRoutedEventArgs)
        Try
            Dim myPointer As PointerPoint = e.GetCurrentPoint(myCanvas)
            prevContactPoint = myPointer.Position
            Dim myPointerDevType As PointerDeviceType = e.Pointer.PointerDeviceType
            If myPointerDevType = PointerDeviceType.Pen Or myPointerDevType = PointerDeviceType.Mouse Or myPointerDevType = PointerDeviceType.Touch And myPointer.Properties.IsLeftButtonPressed = True Then
                myInkManager.ProcessPointerDown(myPointer)
                myPenID = myPointer.PointerId
                e.Handled = True
            End If
        Catch
            Exit Sub
        End Try
    End Sub

 単一のマウス、ペン/スタイラス、またはタッチに関連付けられた入力のポインタを提供するクラスである、PointerPoint型の変数myPointerを宣言し、GetCurrentPointメソッドで、Canvasの現在のポインタを取得する。PointerPointクラスのPositionプロパティで、ポインタ入力の位置のクライアント座標を取得し、メンバー変数prevContactPointに格納する。

 この記述によって、現在の、ポインタデバイスのPointerDeviceTypeを取得する。

 次は、ポインタデバイスのタイプがペンまたはマウス、またはタッチで、かつ入力がマウスの左ボタン押下、またはその他の入力メソッドの左ボタン押下からであった場合の処理だ。

 「文字認識」ボタンの使用を可能にする。InkManagerクラスのProcessPointerDownメソッドで、Canvasの、初期の接触位置と圧力、および傾きなどの接触点の位置や機能に関する情報を処理する。InkManagerクラスは、入力、操作、および1つ以上の(手書きの認識を含む)の処理を管理するプロパティとメソッドを提供するクラスだ。PointerIdで、入力ポインタの一意の識別子を取得して、メンバー変数myPenIDに格納しておく。

要素内で、ポインタが移動した時に発生するイベント(myCanvas_PointerMovedイベント処理)

 イベントデータを提供するPointerIdが、入力ポインタの一意の識別子と同じである場合の処理だ。

    Private Sub myCanvas_PointerMoved(sender As Object, e As PointerRoutedEventArgs)
        If e.Pointer.PointerId = myPenID Then
            recognizeButton.IsEnabled = True
            clearButton.IsEnabled = True
            Dim myPointer As PointerPoint = e.GetCurrentPoint(myCanvas)
            currentContactPoint = myPointer.Position
            x1 = prevContactPoint.X
            y1 = prevContactPoint.Y
            x2 = currentContactPoint.X
            y2 = currentContactPoint.Y
            Dim myLine As New Line
            With myLine
                .X1 = x1
                .Y1 = y1
                .X2 = x2
                .Y2 = y2
                .StrokeThickness = 5
                .Stroke = New SolidColorBrush(Colors.Red)
            End With
            prevContactPoint = currentContactPoint
            myCanvas.Children.Add(myLine)
            myInkManager.ProcessPointerUpdate(myPointer)
        End If
        e.Handled = True
    End Sub

 GetCurrentPointメソッドで、Canvasの現在のポインタを取得する。PointerPointクラスのPositionプロパティで、ポインタ入力位置のクライアント座標を取得し、メンバー変数currentContactPointに格納する。

 メンバー変数x1に、ポインタデバイスが開始された時のX座標を指定する。メンバー変数y1にポインタデバイスが開始された時のY座標を指定する。メンバー変数x2に、要素内で、ポインタが移動した時のX座標を指定する。メンバー変数y2に、要素内で、ポインタが移動した時のY座標を指定する。

 新しいLineのインスタンスmyLineオブジェクトを作成する。Lineの始点のx座標に変数x1の値を指定する。Line の始点のy座標に変数y1の値を指定する。Lineの終点のx座標に変数x2の値を指定する。Lineの終点のy座標に変数y2の値を指定する。Lineの太さを5に指定し、ラインの色を赤に指定する。

 要素内で、ポインタが移動した時の、Canvasの現在のポインタをメンバー変数prevContactPointに代入する。CanvasにAddメソッドでmyLineオブジェクトを追加する。InkManagerクラスのProcessPointerUpdateメソッドで、最後のイベントポインタから現在のポインタイベントまでの、圧力と傾きなどの、位置と状態プロパティを更新する。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。