2024/05/29

クラス化に挑戦: #7)Google マップ - Place API の結果をクラス化 ②

Google マップ の Place API の検索結果をクラス化してみる企画の 2 回目です。いよいよ具体的なコーディングに入ります。


位置クラス

Google マップ の 検索結果や GPS など地図上の位置情報を使用するには緯度と経度を使用します。まずはこれを管理する位置クラス Location を作成します。クラス初期化時に緯度と経度を与え、それをメンバ変数で保持し、プロパティから参照できるとても単純なクラスです。

サンプルコードは次の通りです。

Public Class Location
   Private zdLatitude As Double '緯度
   Private zdLongitude As Double '経度

   Public Sub New(ByVal vdLatitude As Double, ByVal vdLongitude As Double)
      zdLatitude = vdLatitude
      zdLongitude = vdLongitude
   End Sub

   Public Property Get Latitude As Double
      Latitude = zdLatitude
   End Property

   Public Property Get Longitude As Double
      Longitude = zdLongitude
   End Property
End Class

この程度であれば、クラス化する必要性はないかも知れません。サンプルの提示という側面もありますが、緯度・経度の入力チェックなど今後の拡張を考えて、クラスを採用しています。


場所クラス

続いてが本題である検索結果の 1 件分を表すクラスです。検索結果の JSON より場所の情報を取得してプロパティとして参照できる単純な仕様とします。

作成するプロパティは、とりあえず 3 つです。

PlaceID Google Place データベースで一意に表す ID
PlaceName 場所の名称
Location 場所の座標

まずは、クラスの大枠を作成します。クラスを定義し、メンバ変数とプロパティを作成します。

Public Class Place
   Private zsPlaceID As String
   Private zsName As String
   Private zoLocation As Location

   Public Property Get PlaceID As String
      PlaceID = zsPlaceID
   End Property

   Public Property Get PlaceName As String
      PlaceName = zsName
   End Property

   Public Property Get Location As Location
      Set Location = zoLocation
   End Property
End Class


場所クラスの初期化

続いてコンストラクタを作成します。

Place API の検索結果 result は配列となっていました。その 1 要素分を表す JSON が New メソッドの引数となる前提で作成します。JSON から取得した値はそれぞれのメンバ変数に格納しています。

   Sub New(vjePlace As NotesJSONElement)
      Dim jobjPlace As NotesJSONObject
      Dim jobj As NotesJSONObject
      Dim je1 As NotesJSONElement
      Dim je2 As NotesJSONElement

      Set jobjPlace = vjePlace.Value

      'プレースID
      Set je1 = xGetElementByName_Obj(jobjPlace, "place_id")
      If Not(je1 Is Nothing) Then
         zsPlaceID = je1.Value
      Else
         zsPlaceID = ""
      End If

      '場所の名称
      Set je1 = xGetElementByName_Obj(jobjPlace, "name")
      If Not(je1 Is Nothing) Then
         zsName = Trim(je1.Value)
      Else
         zsName = ""
      End If

      '場所の座標
      Set je1 = xGetElementByName_Obj(jobjPlace, "geometry")
      If Not(je1 Is Nothing) Then
         Set jobj = je1.Value
         Set je2 = xGetElementByName_Obj(jobj, "location")
         Set zoLocation = xGetLocation(je2)
      End If
   End Sub


この処理では 2 つのサブ関数を利用しています。

1 つ目が xGetElementByName_Obj 関数です。JSON 内のエレメントを名称で検索機能なのですが、NotesJSONObject の GetElementByName メソッドは検索にヒットしない場合エラーを返します。メインルーチンでエラー処理を書くと煩雑になるで関数化しています。エラーの場合は Nothing を返す仕様ということですね。

Function xGetElementByName_Obj(vjobj As NotesJSONObject, _
                                                       ByVal vsName As String) As NotesJSONElement
   Dim je As NotesJSONElement

   On Error GoTo ErrProc
   Set je = vjobj.GetElementByName(vsName)

ExitProc:
   Set xGetElementByName_Obj = je
   Exit Function

ErrProc:
   Resume ExitProc
End Function


2 つ目のサブ関数は今回作成した Location のインスタンスを返す関数です。

JSON を確認すると座標を表す項目がいくつもあります。今回は location で指定されている座標を使用していますが、汎用的に使用できるよう関数化しています。

関数は次の通りです。

Private Function xGetLocation(vjeLocation As NotesJSONElement) As Location
   Dim jobj As NotesJSONObject
   Dim jeLat As NotesJSONElement
   Dim jeLng As NotesJSONElement
   Dim dLat As Double
   Dim dLng As Double

   If Not(vjeLocation Is Nothing) Then
      Set jobj = vjeLocation.Value
      Set jeLat = xGetElementByName_Obj(jobj, "lat")
      dLat = CDbl(jeLat.Value)
      Set jeLng = xGetElementByName_Obj(jobj, "lng")
      dLng = CDbl(jeLng.Value)

      Set xGetLocation = New Location(dLat, dLng)
   End If
End Function

※ 2024.7.24 バグ修正

上記プログラムにバグがありました(赤字)。上記プログラムは修正済み。 
 修正箇所は下記の通り。

誤) 

      dLng = CDbl(jeLat.Value)

 正)

      dLng = CDbl(jeLng.Value) 

 

ちなみに、この関数を利用している New メソッドでは以下のようになっていました。

location のエレメントを取得してこの関数に渡しているので、location の位置情報を保持させているということですね。

   Sub New(vjePlace As NotesJSONElement)
         ・・・
      '場所の座標
      Set je1 = xGetElementByName_Obj(jobjPlace, "geometry")
      If Not(je1 Is Nothing) Then
         Set jobj = je1.Value
         Set je2 = xGetElementByName_Obj(jobj, "location")
         Set zoLocation = xGetLocation(je2)

      End If
   End Sub


ライブラリの状態

ここまでの作業が完了するとライブラリの状態は以下のようになっています。今回作成した部分は赤枠の部分となります。

次回はこのクラスを実際に使用してみましょう。

前回 クラス化に挑戦 次回


0 件のコメント:

コメントを投稿