イベントデータを提供するPointerIdが、入力ポインタの一意の識別子と同じである場合の処理だ。
Private Sub myCanvas_PointerReleased(sender As Object, e As PointerRoutedEventArgs) If e.Pointer.PointerId = myPenID Then Dim myPointer As PointerPoint = e.GetCurrentPoint(myCanvas) myInkManager.ProcessPointerUp(myPointer) End If myPenID = 0 e.Handled = True End Sub
GetCurrentPointメソッドで、Canvas内の現在のポインタを取得する。
InkManagerクラスのProcessPointerUpメソッドで、ポインタの位置と圧力の傾きを処理する。このメソッドは ProcessPointerUpdateメソッドを呼び出した後で呼び出す必要がある。
このアプリの肝となる部分だ。手書きで入力した文字の認識を行う。
Private Async Sub recognizeButton_Click(sender As Object, e As RoutedEventArgs) Handles recognizeButton.Click backButton.IsEnabled = True clearButton.IsEnabled = False myFrame.Visibility = Xaml.Visibility.Visible Dim myStroke = myInkManager.GetStrokes For i As Integer = 0 To myStroke.Count - 1 myStroke(i).Selected = True Next ‘ このアプリの肝。「Microsoft 日本語手書き認識エンジン」をデフォルトとする。 Dim myRecName = "Microsoft 日本語手書き認識エンジン" Dim myRecognizer = myInkManager.GetRecognizers For i As Integer = 0 To myRecognizer.Count - 1 If myRecName = myRecognizer(i).Name Then myInkManager.SetDefaultRecognizer(myRecognizer(i)) End If Next Dim result As IReadOnlyList(Of InkRecognitionResult) = Await myInkManager.RecognizeAsync(InkRecognitionTarget.All) myInkManager.UpdateRecognitionResults(result) Dim myAlternate = String.Empty For Each myResult In result Dim myText = myResult.GetTextCandidates myAlternate = myAlternate & " " & myText(0) TextBox1.Text = myAlternate Next Dim myUri As String = String.Format("http://www.geocoding.jp/api/?v=1.1&q={0}", Uri.EscapeDataString(TextBox1.Text)) Dim myHttpClient As New HttpClient Dim myResponse = myHttpClient.GetStringAsync(New Uri(myUri, UriKind.Absolute)) Dim myContent = myResponse.Result Dim xmldoc As XElement = XElement.Parse(myContent) myMapPosition.myLatitude = xmldoc.Descendants("coordinate").Elements("lat").Value myMapPosition.myLogitude = xmldoc.Descendants("coordinate").Elements("lng").Value myMapPosition.myAddress = TextBox1.Text myFrame.Navigate(GetType(BingMapsPage), myMapPosition) myFrame.SetValue(Canvas.ZIndexProperty, 10) backButton.Visibility = Xaml.Visibility.Visible End Sub
まず、非同期処理で行われるので、メソッドの先頭にAsyncを追加する。
InkManagerのGetStrokesメソッドで、InkManagerの位置を管理するコレクション内の全てのInkStrokeオブジェクトを取得し、変数myStrokeに格納する。InkStrokeのコレクションの数だけ繰り返し処理を行う。すべてのInkStrokeを選択状態にする。
文字列変数myRecNameを「Microsoft 日本語手書き認識エンジン」で初期化しておく。
英語の認識エンジンを使用する場合は「Microsoft English (US) Handwriting Recognizer」と指定する。
InkManagerのGetRecognizersメソッドで、手書き認識エンジンのコレクションを取得する。
取得したコレクションの数だけ反復処理を行う。変数myRecNameの値が、手書き認識エンジンのコレクションのNameと一致する場合は、その手書き認識エンジンを、SetDefaultRecognizerメソッドで規定値として設定する。「Microsoft 日本語手書き認識エンジン」が規定値に設定される。
RecognizeAsyncメソッドで、1つまたは複数のInkStrokeオブジェクトに対して手書き認識を実行し、コレクション変数resultで参照しておく。InkRecognitionTarget.Allで、ストロークコレクション内のすべてのストロークを認識エンジンに渡す。UpdateRecognitionResultsメソッドにコレクション変数resultを渡し、潜在的なテキストのコレクションが、手書きの認識からマッチするよう更新する。
認識された手書きの結果テキストのコレクション内を反復処理しながら、以下の処理を行う。
InkRecognitionResult.GetTextCandidatesメソッドで、手書き認識と一致する可能性のある候補として識別された文字列のコレクションを取得して、変数myTextに格納する。認識された文字列を非表示としているTextBox1に表示する。
変数myUriにGeocodingのWeb APIを使用して、以下のように指定する。
String.Format("http://www.geocoding.jp/api/?v=1.1&q={0}", Uri.EscapeDataString(TextBox1.Text))
「q」には、非表示となっているTextBox1内に表示されている、認識された文字列を渡す。
このWeb APIは住所から緯度、経度を取得できるWeb APIだ。詳細については下記のURLを参照してほしい。
HttpClientクラスの新しいインスタンスmyHttpClientオブジェクトを作成する。HttpClientクラスは、URIで識別されるリソースにHTTP要求を送信し、そのリソースからHTTP応答を受信するためのクラスだ。
HttpClientクラスのGetStringAsyncメソッドで、指定したURIにGET送信し、非同期操作で応答本体を文字列として受け取り、変数myResponseに格納する。返された結果XMLをResultプロパティで受け取り、変数myContentに格納しておく。XElement.Parseメソッドで、文字列として読み込まれたXML(myContent)を読み取る。
MapPosition構造体のmyLatitudeにcoordinate要素の子要素latの値(緯度)を指定する。myLogitudeにlng要素の値(経度)を指定する。myAddressに非表示となっているTextBoxの値を指定する(認識された住所)。
FrameのNavigateメソッドで、構造体オブジェクトであるmyMapPositionを引数に、BingMapsPageに遷移する。Frameを前面に出し、backButtonを表示する。
文字認識には「Microsoft 日本語手書き認識エンジン」を使用しているため、日本語版OS上でしか動作しない。Windowsストアに申請する際は、「日本語版OSでの確認を希望」と明確に書いておく必要がある。
Copyright © ITmedia, Inc. All Rights Reserved.