2019年10月31日木曜日

GPS ロガー的なアプリを作ってみた

前回のエントリーで HCL Nomad で NotesGPS クラスが動いたことを書きましたが、今回はその続きで、GPSの位置情報を継続的に保存する仕組みを作ってみたお話です。

LotusScript には NotesTimer という私があまり使ったことの無いクラスが存在します。NotesTimer クラスを使うと、指定した間隔(秒単位)ごとにイベントを発生させることができます。

定期的に発生するイベントでGPSからの位置情報を保存すれば、GPSロガー的なものになりそうです。


まずは、フォームを1つ作成して以下のコードをフォームへ追加しました。

(Globals)の(Declarations)
Dim elapsedTimer As NotesTimer
Dim gps As NotesGPS
Dim position As NotesGPSPosition
Dim ss As NotesSession
%INCLUDE "lsconst.lss"

(Globals)の Initialize
Sub Initialize
 Set  ss = New NotesSession
End Sub

QyeryOpen
Sub Queryopen(Source As NotesUIDocument, Mode As Integer, Isnewdoc As Variant, Continue As Variant)
 On Error 4508 Goto ERROR4508
 
 Set gps = ss.CreateGPS
 gps.TimeoutSec = 9
 gps.HighAccuracy = False
 If Not gps.RequestAccess Then
  Messagebox "False",,"Request access"
  Exit Sub
 End If
 Set position = gps.GetCurrentPosition
 Call gpslog( "Start" )
 Exit Sub
 
ERROR4508:
 Messagebox "NotesGPS class のインスタンスを取得できません。" & Chr(10) & "Err: 4508"
 Continue = False
 Exit Sub
End Sub

PostOpen
Sub Postopen(Source As NotesUIDocument)
 Set elapsedTimer = New NotesTimer(60, "")
 On Event Alarm From elapsedTimer Call elapsedTimerHandler
End Sub

QueryClose
Sub Queryclose(Source As NotesUIDocument, Continue As Variant)
 elapsedTimer.Enabled = False
 Call gpslog( "End" )
End Sub

さらに次の2つのコードを追加しました。

Sub elapsedTimerHandler(Source As NotesTimer)
 Call gpslog( "" )
End Sub
Sub gpslog( msg As String )
 Dim ndt As NotesDateTime
 Dim doc As NotesDocument
 Dim coodinates As NotesGPSCoordinates
 
 position.Update
 Set ndt = position.TimeStamp
 Set coodinates = position.Coordinates
 
 Set doc = New NotesDocument( ss.CurrentDatabase )
 
 doc.Form = "Main"
 doc.Message = msg
 doc.gps.TimeoutSec = gps.TimeoutSec
 doc.gpsposition.TimeStamp = ndt.LSLocalTime
 
 doc.Latitude = coodinates.Latitude
 doc.Longitude = coodinates.Longitude
 doc.Altitude = coodinates.Altitude
 doc.Heading = coodinates.Heading
 doc.Speed = coodinates.Speed
 doc.Accuracy = coodinates.Accuracy
 doc.AltitudeAccuracy = coodinates.AltitudeAccuracy
 
 doc.Save True, False
 
 Set doc = Nothing
 Set ndt = Nothing
End Sub


このフォームを開くとき、NotesGPS のオブジェクトを作り、イベント発生の間隔を60秒にセットします。イベント発生ごとにコールするスクリプトを「elapsedTimerHandler」としました。

このフォームを閉じるとき、NotesTimer を非アクティブの状態にします。これでイベントが発生しなくなります。


さて NotesTimer のヘルプには次のような記述があります。
NotesTimer はエージェントではなく Lotus Notes UI オブジェクトで使用することを意図されています。
なんだか嫌な予感が...

HCL Nomad でこのフォームを前面に開いてる間は 約60秒おきに位置情報が保存されました。

フォームを開いて記録している間、HCL Nomad 上には、3つのタブ(ホーム、GPS Logger ビュー、フォーム)がありましたが、GPS Logger ビューのタブをタップしてフォームのタブが他のタブのうしろにある状態でも、位置情報は記録され続けました。※下図はフォームのタブが前面に表示されてます

しかしながら、画面の操作をしばらくやめて画面が暗転した状態では、位置情報が記録されませんでした。また HCL Nomad から別のアプリに切り替えている間も位置情報は記録されませんでした。

それから、 iPhone などのスマホでは他のアプリからの通知が表示されることがありますが、通知が表示されている間は位置情報は記録されていないような印象です。

位置情報が記録されなかった場合も、フォームを開いている間はタイマーが有効のようで、指定した間隔どおりにはなりませんでしたが遅れて記録され続けました。

こんなことがあったので、フォームを開いた後は、画面が暗くならないように画面をサワサワと触り続けたり、通知が表示されればすぐさま画面の外へスワイプするといったつまらない操作を継続的に行っていました。

そんなこんなで散歩ついでに取得した位置情報から KML ファイルを作り、Google Map へ読み込んでみると、次のように表示できました。→KMLファイルの作り方


GPS ロガーとしては、なかなか使いづらいものが出来上がりました。

2019年10月29日火曜日

Nomad で GPS を使う

つい数日前に Notes/Domino V11 Beta 2 がダウンロード可能になりました。

このベータ版で、私が楽しみにしていた機能のひとつがようやく実装されたのです!

実は V11 Beta 1 の Domino Designer でも LotusScript に新たに追加された3つのクラス、
NotesGPS
NotesGPSPosition
NotesGPSCoodinates
が見えてはいるのですが、NotesSession クラスに CreateGPS メソッドが実装されていないために実質使えなかったのです...

V11 Beta 2 の Domino Designer では、これらが動くことを確認しました。

次のコードがこれらのクラスの動作を確認できたものです。

Dim ss As New NotesSession
Dim gps As NotesGPS
Dim gpscoodinates As NotesGPSCoordinates
Dim gpsposition As NotesGPSPosition
Dim ndt As NotesDateTime
Dim msg$

Set gps = ss.CreateGPS
gps.TimeoutSec = 9
gps.HighAccuracy = False
If Not gps.RequestAccess Then
 MessageBox "False",,"Request access"
 Exit sub
End If

Set gpsposition = gps.GetCurrentPosition
Set ndt = gpsposition.TimeStamp
Set gpscoodinates = gpsposition.Coordinates

msg = _
"タイムスタンプ: " & ndt.LSLocalTime & Chr(10) &_
"緯度(Latitude): " & gpscoodinates.Latitude & Chr(10) &_
"経度(Longitude): " & gpscoodinates.Longitude & Chr(10) &_
"高度(Altitude): " & gpscoodinates.Altitude & Chr(10) &_
"緯度経度の誤差(Accuracy): " & gpscoodinates.Accuracy & Chr(10) &_
"高度の誤差(AltitudeAccuracy): " & gpscoodinates.AltitudeAccuracy & Chr(10) &_
"方角(Heading): " & gpscoodinates.Heading & Chr(10) &_
"速度(Speed): " & gpscoodinates.Speed

MessageBox msg

このコードを私の iPad 上の HCL Nomad 1.0.5 (TestFlight版)で実行すると、次のように表示されました。


ここで取得した緯度と経度の値で現在地がわかります。(自宅なので隠しましたが..)

GPS レシーバの無い端末(=私のパソコン)で実行すると、CreateGPS メソッドでコード 4508 Method is not available となりました。


さて、私がこの GPS の使い道として考えているのは、現在地に最も近い現場の情報を自動で入力/表示することです。

現在地に関係している情報とは、国、地域、住所、現場の名称の他、顧客名、プロジェクト名やこれらのコードなど意外に多いように思います。

また、iPad を持ちながら、HCL Nomad の入力画面をソフトウェアキーボードでタイプすることはかなりしんどい作業になります。リストから選択するにしても、リストが1000件にもなれば小さい画面の中で縦スクロールして見つけ出すことさえ困難なように思います。

そんな時、例えば「現場マスター」へ緯度経度の値を追加しておくことで、現在地から最も近い現場の情報を候補として表示できるようになりそうです。
たったこれだけでも使い勝手がよくなるのではないでしょうか。


これを実現するには、マスター上の緯度経度と現在地の緯度経度から「最も近い」場所を調べる必要があると考え、距離を求めるコードを書いてみました(以下)。戻り値の単位はメートルです
(lat は緯度、lng は経度、lat1 と lng1 が一方の地点、lat2 と lng2 が他方)

Function distance( lat1 As Double, lng1 As Double, lat2 As Double, lng2 As Double ) As Double
 Dim radLat1 As Double, radLng1 As Double
 Dim radLat2 As Double, radLng2 As Double
 Dim aveLat As Double, aveLng As Double
 Dim c As Double
 Const r = 6378137.0 '赤道半径
 
 '円弧の長さを扱うため、角度(緯度経度)をラジアンへ変換
 c = 180 / Pi
 radLat1 = lat1 / c
 radLng1 = lng1 / c
 radLat2 = lat2 / c
 radLng2 = lng2 / c
 
 aveLat = ( radLat1 - radLat2 ) / 2
 aveLng = ( radLng1 - radLng2 ) / 2
 
 distance = r * 2 * Asin( Sqr( Sin( aveLat ) ^ 2 + Cos( radLat1 ) * Cos( radLat2 ) * Sin( aveLng ) ^ 2 ) )
End Function

例えば、マスターに登録した緯度と経度の値を列に表示するビューを用意しておけば、最も近い情報を入力の候補として表示する、といった感じのものは簡単に作れそうです。

2019年10月17日木曜日

Nomad でも OCR

昨日の会社帰りは、約2カ月ぶりに開催された「のの会」に参加しました。


今回、私が担当したのは「iPad で OCR を試した事」のお話です。

既にこのブログでも何度も登場している NotesHTTPRequest や NotesJSONNavigator等の V10 で追加された機能が iPad でも動くことを、実機のデモを通してご紹介しました。

私が所有する iPad の OS は iPadOS にしています。昨日は ThinkPad Bluetooth ワイヤレス・トラックポイント・キーボード を使って、トラックポイントのマウス操作で HCL Nomad とそのアプリがグリグリ動く様子をご覧いただきました。

iPad でデモする時は、設定から「アクセシビリティ - タッチ - AssistiveTouch」をオンにすると、マウスカーソル的なマークがわかりやすく表示されるのがいいですね。

お話した内容をスライドにしていますので、共有いたしました。何かの参考になれば幸いです。





2019年10月11日金曜日

iPhone? iPad? @Platform の拡張について

先日 TestFlight で公開されました HCL Nomad 1.0.5 では iPhone でも使用できるということで、早速ダウンロード。

このバージョンは @Platform 関数が拡張され、iPhone と iPad を区別することができる、と説明されています。

これを試してみました。

まずは、ビューのアクションボタンに次の式を設定しました。

@Prompt([Ok];"Formula";@Platform([Specific]))

これを実行してみると、iPad と iPhone のどちらも "iOS" とだけ表示されます。

「これはバグではないか?」と思い、フィードバックしたところ、すぐさまメールで返事がありました。

回答によれば、@Platform([Specific]) の戻り値は次のようなテキストリストだというのです。

PrimaryOSNamefor example, iOS
PrimaryOSVersionNamefor example, 12.4
iOS Model Typeeither iPad or iPhone
Apple Hardware Identifierfor example, iPad8.4

さらに次の式を iPhone で実行すれば "Platform is iPhone" と表示されると。

@If(@Platform([Specific])="iPhone";@Prompt([Ok]; "Formula"; "Platform is iPhone");@Prompt([Ok]; "Formula"; "Platform is NOT iPhone")) 


よくヘルプを読んでみるとバグでもなんでもなく「文字列リストが返されます」と書いてありました... orz


気をとりなおして、先のボタンの式を次のように書き換えてみました。

@Prompt([Ok];"Formula";@Implode(@Platform([Specific]);@NewLine))

そして表示されたプロンプトがこちらです。
iPhone
iPad
Windows 10
最後の Windows 10 はおまけですが、テキストリストの3番目にある iOS Model Type で iPhone か iPad を識別できることがわかりました。(2020/10/3追記を参照)

おかげで私の所有する端末が古い機種ということがバレバレです(笑)

V11 では GPS にも対応するとのことですし、まだまだ Nomad 対応アプリの開発を楽しめそうです。

2020/10/3追記
その後、機種変更したし iOS や HCL Nomad のバージョンもずいぶん上がったので試してみたところ、テキストリストの3番目の値は「phone」や「tablet」などと表示されるようになり、4番目も数字だけの表記にかわっていました(下図)。
iPhone
iPhone

iPad
iPad


2019年10月7日月曜日

NDS2019 トラブルチケットアプリの部分的裏話

NDS2019 は5都市を巡り、どの会場も盛況で幕を閉じました。

今年5回目の開催となる NDS ですが、私は今回が初参加でした。

その NDS へ参加することが決まったころ...

日本の IBM Champion でアプリを作り NDS2019 の参加者へのお土産にしよう!

とか

どうせなら iPad でも使えるアプリにしよう

さらには

ついでに CollabSphere の Beauty Contest に応募しよう!

といった話が持ち上がり、各地の NDS 最後のビアバッシュ中に、ケートリック田付様よりご説明いただいた「トラブルチケット」を作ることになりました。



アプリの概要はスライドをご覧ください。

このアプリで私が主に関わったのは Slack への投稿部分です。

開発は Domino Designer のバージョン 10.0.1 FP2 で行っていました。
IBM Domino Mobile Apps(以下 DMA)は 1.0.3 です。

当初の構想では、文書に添付された写真を文書のタイトルとともに Slack へ表示しようと考えていました。ところが、LotusScript では配列の制限があり、ちょっとしたサイズのバイナリデータを送ることができないことと、Base64 エンコードしたデータを Slack 側がサポートしていないことの2点で、写真の送信をあきらめました。Google Drive 等 Slack 以外のクラウドストレージへ送信し、そのURLを Slack で使用するといった代替案もあったのですが、複雑にしたくなかったのです。

さらに悩ましかったのは、投稿の内容が英数字だけなら Notes クライアントも iPad の DMA もうまくいくのに、ダブルバイト文字が入ると iPad では文字化けする問題が発生したことでした。

iPad の DMA から投稿自体はできるものの、Slack に表示される全角文字が "BAD+82" のような文字列になって表示されてしまう現象に遭遇したのです。

エンコードを変えてみたりなんとかできないかと工夫しようと試みましたが、どうにもうまくいきません。

万策尽きて完全にあきらめていたところ、NDS 東京会場の開催前日になり DMA 1.0.4 (このバージョンから名称が HCL Nomad へと変わりました)が TestFlight でダウンロード可能となりました。

なんとこの文字化け、1.0.4 で見事に解消していたのです!

日本語の文字化けは DMA のバグが原因であり 1.0.4 で Fix されていたのでした。

そのような訳で、NDS会場のデモでは iPad 上の HCL Nomad からの投稿後直後に、画面上部からピロンと Slack 通知が日本語で表示されたのでした。めでたしめでたし。


なお、今回作成しましたアプリは設計を公開した状態で、XPAGES.JP のWebサイトからダウンロードできるようになるようですりました。

改行を含む文字列を Slack へ投稿したり、notes:// で始まるリンクを送るコツなど、NDSのビアバッシュでほろ酔いの状態では到底話せないネタを、私の稚拙で汚いコードが語ってくれると思います。

公開されましたらこのページを更新してリンクを掲載したいと思います。
こちらからダウンロード可能です。