GG - GPX からGPIファイルを生成するツール

Last-modified: 2020-08-10 (月) 08:49:22
Today:?/Total:?

概要

GarminのGPS端末で使われるカスタムPOIの実装であるGPIファイルをGPX から生成するツールです。
CSVには対応する気はありません。だって面倒だから。

利用にあたっては全て自己責任となります。
海外向けGARMINデバイス(UTF8仕様)でカスタムPOIを日本語化したい人はどぞ。

DOWNLOAD

v3.0.0はPCを更新してVS2019を導入したのでビルドし直したものです。サードパーティのライブラリも更新していますが1.7.0から機能に変わりはありません。
v1.7.0はVS2017を導入したので試しにビルドし直したものです。サードパーティのライブラリも更新していますが1.6.0と変わりません。

動作要件

  • 3.0.0
    .NET framework 4.8 or .NETCore3.1

  • 1.7.0
    .NET framework 4.6.1 or lator

ライセンス

付属のlicense.txt参照。
要は修正BSDライセンスです。

利用しているソフトウェアとそのライセンス

機能

  • フォルダ又はGPXファイルの指定によるGPIファイルの生成。
  • 定義ファイルによるGPIファイルの生成。
  • 階層構造に対応(1階層のみ)。
  • GPXファイル/フォルダと同一名称のBMPファイルが存在すれば、それをイメージとして使用。
  • 同一カテゴリ内で複数のイメージを使用可能(定義ファイルからの生成時のみ)
  • 出力する文字コードは.NET frameworkが対応するコードページであれば何でも対応しているはず・・・
    既定値は65001(utf-8)
    ※ cp932とutf-8で動作確認してます。
    端末側が対応しているかどうかは知らん。

  • jpeg,mp3,TourGuideの格納に対応。

POI Loaderとの対比

  • GPXファイル名に数値(1-199)があっても近接/速度は有効としません。こんな糞仕様実装したくない。
  • CSVファイルには対応しません。使いたければ他のツールでGPXに変換して下さい。
  • 近接距離はm、進入速度はkm/hのみ対応。マイル?標準に従え田舎者が。
  • 近接距離と進入速度の丸め方は異なる・・・多分。
  • 512個以上のWAYPOINTがあると内部で分割するのですが、分割の仕方は異なります。多分・・・
    というか、POI Loaderの仕組みがわからん。
    バイナリレベルで比較しても一致しなかったりする部分があるので異なっているはず。

  • 512個以上の同一地点のWAYPOINTがある場合はエラーになります。POI Loaderはプログラムが異常終了しますw
    同一地点か否かは概算距離で1cm未満(小数部7桁まで有効)としてます。まぁdoubleでの比較処理だし厳密ではないです。

  • 文字列長は2byteで保存されるので、文字列の最大は65535byteになります。
    UTF-8だと日本語はだいたい3byteなので約21845文字になります。
    それを超えたらエラーにしています。
    POI Loaderで65535byteを超える文字列を入れると文字列長が循環しやがりますw
    結果、文字列はちゃんと入らない癖にエラーにもなりません。

  • 一つのwaypointにjpeg,mp3,TourGuideが複数ある場合、それぞれ最初に見つけたもののみを格納します。
    POI Loader は全て格納します。しかしGPIの定義を見る限り複数格納されても使用されないような?特にmp3。
    また、mp3は格納先がwaypointとは異なる領域なので、内容が同じであれば重複して格納しないようにしています。
    ※ jpegはwaypoint毎に格納するので重複排除は出来ません。
    POI Loaderは重複して格納しています。

  • cmtが空文字列でdescも空文字列として存在する場合、POI Loaderはdescのみdescとして出力しますが、ggは何も出力しません。

問題点

GPIの仕様が不明なまま実装してます。
よって、正常に実装されている保証はなく、不正なGPIが生成されるかもしれません。
不正なGPIをGARMIN端末にいれると起動しなくなることがあります。
※ 端末が起動時にGPIを読もうとして失敗するため。
その場合は問題のGPIを消せば起動するようになります。

使用方法

コマンドラインでの実行になります。

usage: gg [OPTIONS] GPXファイル/フォルダ/定義ファイル [出力先ファイル名]
[OPTIONS]
	  -?, -h, --help             ヘルプ
	  -c, --codepage=VALUE       変換後のCODEPAGE. 既定値は65001(UTF-8)
	  -p, --proximity=VALUE      近接距離(m)
	  -s, --speed=VALUE          侵入速度. 1-199(km/h)
	  -Q                         QUIETモード
	  -v, --verbose              Verbose
	      --generate-hjson-from   ファイル/フォルダから定義ファイルを生成します
	      --test-hjson            定義ファイルを検証します

以下、使用例

  • 単一のGPXファイルからgpi(utf-8)を生成する場合
    poi.gpxが存在するとして以下を実行。
    >gg poi.gpx
    poi.gpiが生成されます。カテゴリは「poi」です。
  • 単一のGPXファイルからgpi(cp932)を生成する場合
    poi.gpxが存在するとして以下を実行。
    >gg -c 932 poi.gpx
    poi.gpiが生成されます。カテゴリは「poi」です。
  • 複数のGPXファイルからgpi(utf-8)を生成する場合
    poi/
       poi1.gpx
       poi2.gpx
    が存在するとして以下を実行。
    >gg poi
    poi.gpiが生成されます。カテゴリは「poi1」,「poi2」です。
  • 複数のGPXファイルから階層構造のgpi(utf-8)を生成する場合
    poi/
       root/
           poi1.gpx
           poi2.gpx
    が存在するとして以下を実行。
    >gg poi
    poi.gpiが生成されます。カテゴリは第一階層が「root」、第二階層が「poi1」,「poi2」です。
  • 単一のGPXファイルから近接警報を伴うgpi(utf-8)を生成する場合
    poi.gpxが存在するとして以下を実行。
    >gg -p 500 -s 100 poi.gpx
    poi.gpiが生成されます。カテゴリは「poi」です。
    500m圏内に100km/hで接近すると警報となります。
  • 複数のGPXファイルとイメージからgpi(utf-8)を生成する場合(其の壱)
    poi/
        poi1.gpx
        poi1.bmp
        poi2.gpx
    が存在するとして以下を実行。
    >gg poi
    poi.gpiが生成されます。カテゴリは「poi1」,「poi2」です。
    カテゴリ「poi1」のWAYPOINTにはイメージが付きます。
    カテゴリ「poi2」のWAYPOINTにはイメージが付きません
  • 複数のGPXファイルとイメージからgpi(utf-8)を生成する場合(其の弐)
    poi/
       root.bmp
       root/
           poi1.gpx
           poi2.gpx
    が存在するとして以下を実行。
    >gg poi
    poi.gpiが生成されます。カテゴリは第一階層が「root」、第二階層が「poi1」,「poi2」です。
    カテゴリ「poi1」「poi2」のWAYPOINTにはpoi.bmpのイメージが付きます。
  • 定義ファイルからgpi(utf-8)を生成する場合
    poi/
        poi1.gpx
        poi1.bmp
        poi2.gpx
        poi3.gpx
        poi4.gpx
    が存在するとして以下を実行。
    >type xx.hjson
    [
      {
        name: カテゴリ1
        categories:[{
            name: カテゴリ11
            src: poi/poi1.gpx
          },{
            name: カテゴリ12
            src: poi/poi2.gpx
          },
        ]
      },{
        name: カテゴリ2
        src:[
          {src: poi/poi3.gpx}
          {src: poi/poi4.gpx}
        ]
      }
    ]
    >gg xx.hjson
    xx.gpiが生成されます。gpi名はリスト定義のファイル名(拡張子無し)になります。
    カテゴリは以下の階層で出力されます。
    + カテゴリ1
      - カテゴリ11
      - カテゴリ12
    - カテゴリ2
    カテゴリ11の内容はpoi1.gpx、カテゴリ12の内容はpoi2.gpx、カテゴリ2の内容はpoi3.gpx及びpoi4.gpxになります。
    イメージの指定がありませんが、フォルダ指定時と同様にGPXファイル名と同じイメージが使用されます。
    よって、カテゴリ11に含まれるpoi1.gpxはpoi1.bmのイメージが付きます。他のWaypointには付きません。
  • ファイル/フォルダから定義ファイルを生成する場合
    poi/
        poi1.gpx
        poi2.gpx
    が存在するとして以下を実行。
    >gg --generate-hjson-from poi
    poi.hjsonが生成されます。
  • 定義ファイルを検証する場合
    poi.hjsonが存在するとして以下を実行。
    >gg --test-hjson poi.hjson
    カテゴリ毎に使用するイメージ及びgpxファイルの一覧が表示されます。
    ファイルが存在する場合は碧色の〇を、存在しない場合は赤色の×で状態を表示します。
    又、問題がある場合時点でテストを続行するか否かを確認してきます。
    ※ QUIETモードでは確認されません。%ERRORLEVEL%で判断してください。というか、そのためのモードだしね。

定義ファイルの詳細

HJSON形式です。文字コードはutf-8でなければなりません。
https://hjson.org/

※ 既存のファイル/フォルダ構造から定義ファイルを生成して編集することが出来ます。
次のように引数に--generate-hjson-fromを使用するとGPIファイルでなく定義ファイルを出力します。

gg.exe --generate-hjson-from ファイル/フォルダ [出力先ファイル名]

  • 1ファイル/フォルダを1カテゴリとして出力する場合
    {
      name:カテゴリ名
      src:	GPXファイル/フォルダ
      img:	イメージファイル名(カテゴリ)
    }
    フォルダを指定しても階層形式にはなりません。
    この定義ではフォルダ内の全GPXファイルを一つのカテゴリとして出力します。
    imgは省略出来ます。省略された場合、GPXファイル/フォルダと同じ名称のbmpがあればイメージとして使用します。
  • 複数ファイル/フォルダを1カテゴリとして出力する場合
    {
      name: カテゴリ名
      src:	[{
        src: GPXファイル/フォルダ
        img: イメージファイル名(GPXファイル/フォルダ)
      }...]
      img:	イメージファイル名(カテゴリ)
    }
    複数のGPXファイルを一つのカテゴリとして出力します。
    imgは省略出来ます。gpxに対するimgを指定しないならば、
    src: [
      GPXファイル/フォルダ1,
      GPXファイル/フォルダ2,
    ]
    と、{}でオブジェクトにせずに、パスの文字列だけでもよいです。
  • 階層構造のカテゴリとして出力する場合
    {
      name: カテゴリ名
      categories: [
        {
          name: サブカテゴリ名
          src:[{
            src:	GPXファイル/フォルダ
    	 img:	イメージファイル名(GPXファイル/フォルダ)
          }...]
          img: イメージファイル名(サブカテゴリ)
        }...]
      img:	イメージファイル名(カテゴリ)
    }
    srcの代わりにcategoriesを定義します。
    もしsrcとcategoriesの両方がある場合はsrcは無視しますので注意して下さい。
  • カテゴリを複数出力する場合
    [
      {name: カテゴリ名...}
       ...
    ]
    今までのカテゴリの定義を[]で囲います。
  • コメント
    // /* */ でコメントが書けます。

WAYPOINTに適用されるイメージの優先順位は以下になります。

優先度: 高 > 低
イメージファイル名(GPXファイル)
>イメージファイル名(フォルダ)
>イメージファイル名(サブカテゴリ)
>イメージファイル名(カテゴリ)
>ファイル名と同じbmp
>フォルダ名と同じbmp

定義からGPIを生成する場合、GPXやフォルダを分ければ、同一カテゴリに属するWAYPOINTでも異なるイメージを使用できます。
但し端末側が対応しているかどうかは不明です。
※ Oregon700(Software Version 2.80)では表示可能でした。
GPIの仕様から判断すると、カテゴリの階層構造に対応している端末であれば表示可能だと思います。

定義ファイルからGPIを生成する場合、記述した順にGPIファイルへ格納します。
端末で表示する際には、格納順に表示しているようです。
※ Oregon700(Software Version 2.80)では格納順に表示しているようです。

結果として、表示順を制御したければ、定義ファイルの記述順を変更すればよいことになります。
しかしカテゴリの表示順の扱いに関するGPIの仕様はわかりません。(2016-12現在調べた限り)
「格納順に表示する」というのは恐らく偶々であってGPIの仕様ではないと推測しています。
ですので、現時点で期待通りに並べられたとしても、今後も並べられるとは限らないかもしれません。

FAQ

Q. 動きません。
A. アキラメロン

   _工_
  /×× \
  / ××× ニヘ
 |×・∀・× ニ|
 ヽ ××× _ニ/
  \××_ニ/

謝辞

こんな怪しいソフトの動作検証に付き合ってくれた 2ch 登山板 GPS情報交換スレッド@総合 の皆さまに。