2017年3月16日木曜日

日本語カスタムPOI ファイルの 作成確認 [20171225更新]

Garminのハンディデバイスは、カーナビとは比べ物にならないぐらい低機能だ。 少しは便利に使うために、自分用のWaypointとかTrackを登録していくのだが、 点数制限とか、管理とか面倒なので、WaypointはPOI形式のファイルにまとめて管理するのが良いみたい。
私は、ここ(GARMIN カスタム POIの日本語化 )で公開して頂いてるPOIファイルを便利に使わせてもらっている。 登録ポイントを近い順に表示してくれるので、 チャリで出かけた時など、最寄りのコンビニリストが利用できる。
自分でこのように便利なPOIファイルを作成することは諦めているが、 自分で行ってみたい飯屋とかを登録、更新しておくと、この辺りに・・・とか いう場合に活躍してくれることもあるので、ある程度は出来るようにしている。
で、その方法の確認、覚書。i3 WMにしたもんで。

作業環境とか

  • PC:TP510(Debian x86_64 GNU/Linux、Stretch)
  • GPS:Garmin の eTrex30 と Colorado300。 いずれも英語版
  • ネット環境(Webブラウザで登録したい座標を調べる)
  • Viking(WayPointなどの管理)
    • Viking GPS data editor and analyzer download | SourceForge.net
    • 開発は継続されているようだが、ほとんど停滞かと思う。 時々期待と異なる動きをするし、カシミール3Dに比べると完成度はかなり低いと思うが、 Linuxで動くこと、地理院のオルソが使えるのは魅力。
    • ここにVikingのこととかまとめてみた。少し古いけど。
  • JaVaWa RTWtool(GPXからPOIへの変換ができる)
    • JaVaWa GPS-tools | Voorpagina
    • 病気されたようで、ご自愛くださいませ。
    • 残念だが、wine 32 での利用になる。
    • 利用は自己責任で。 ネットで日本語での情報が出てこないので、 なにか注意が必要かもしれない。数年使ってるけど、まだ怒られてない。 以前は日本語が通らなかったと記憶。 Colorado300は日本語ダメなので問題なかった。 今は、日本語を含むデータもいける。

POIの元になるデータの収集、整理

  • ブラウザ と Viking を起動しておく。
  • POIとして登録したい場所を、Google-map や Yahoo地図で検索する。
  • 登録したいポイントの右クリックから、 「この場所について」とか「この地点の情報を見る」で、 座標を表示させる。
  • この座標をコピーして、Vikingのトラックポイントに新規登録。
    • アイコンも設定できるが、 私はアイコンを気にしないので、良く分からない。
    • Vikingのファイル形式で、保存しておく。データは使いまわす。
    • データのエキスポートはレイヤー毎で可能なので、レイヤーで分類するとよい。
[201804] Google Map で、登録したい場所をクリックすると、座標を含めたurlになる。 ブラウザのプラグインを使えば、urlを特定の書式に変換してクリップボードに取り込むことが可能。 クリップボードに入ってしまえばローカルにハンドリングできるので、この方法を使うようにしてみた。 ここ

GPX形式から、POI形式へ

  • VikingからデータをGPXファイルでExportする。 
  • 左ペインの該当レイヤーを右クリックし、ExportLayer の、 Export as gpx か Export via GPSbabel を選ぶ。
  • GPXをそのまま使うなら、GPSbabelを通す方がよい。 RTWtool だけなら、GPSbabel 経由は不要。
  • JaVaWa RTWtool を起動して先のgpxファイルを開くと読み込まれたポイントデータが表示される。 CSVもいける。
  • ここで表記等の変更ができるので、必要に応じて作業する。
  • Export to: で Garmin POI file を選択し、メニューバーの Convert をクリック、 ファイル指定で保存。
  • 最後に View POI statistics? と聞かれるが、No。
  • あとは、デバイスをマウントして送り込む。左がeTrexで右が Colorado。
 
RTWtoolは他にも色々できそうだが、CSV以外、試してない。


 以上、i3 WM にしても無事使えてる。

gpsbabelで、Garmin Points of Interest (.gpi) (garmin_gpi)が使えるんですね。 昔は出来なかったように記憶してるんだが、知らなかった。 kmlやgpxからの変換は出来たが、デバイスでの確認は未了。 RTWtoolで作ったものとファイルサイズがかなり違う。心配だ。
  -->> やっぱり、だめだった。

[2017.05.15] 追加(近接アラームがなんとか使えた。不十分だけど)
JaVaWa RTWtool で変換する場合、一括で近接アラームの設定が可能になっている。 メニューのsettingから、Waypointsの項目でProximityの値をメートルで設定すれば、 convert時に全点追加される仕様のようだ。

ただ、そのままでは、etrex30英語版ではうまくいかなかった。 出力ファイルの修正が必要だった。 なので、JaVaWa RTWtoolで gpx を作成し直すことになる。
ちなみに、Vikingでこのような追記は出来ないみたい。

修正は、gpxファイルで、以下のような箇所を
<extensions>
<gpxx:WaypointExtension>
<gpxx:Proximity>200 </gpxx:Proximity>
</gpxx:WaypointExtension>
</extensions>
次のように変更すると、
<extensions>
<wptx1:WaypointExtension>
<wptx1:Proximity>200 </wptx1:Proximity>
</wptx1:WaypointExtension>
</extensions>
近接アラーム200m が使えるようになる。

不要な箇所を変更しないように注意して、 エディタとかで一括置換すればよい。

ちなみにpoi化するとこの変更は反映されない。当然か。
つまり、POIでは使えない。単純にgpxファイルに近接アラームを一括追加してくれるだけ。
でも、点数制限はあるものの、道案内用のwaypointに近接アラーム設定しておけば、 簡易ナビになる。はず。
次は階層化の確認かなあ

道の駅のデータを作製してみた

[210906] 地理院からxmlをダウンロードできるようになってた。 ここから。

(1) 道の駅のデータをテキストファイルに保存する。

元データはRS 道の駅一覧表 for GPSで、 画面に表示されるデータをコピペしてテキストファイルに保存する。

[20171128] データた追加されていたので、今度はコピペではなく、pythonでスクレイピングしてみた。ところどころ、データがダブったりしておかしい。難しい。次は、道の駅 公式ホームページから作ってみよう。

項目は、駅名、北緯(N)、東経(E)、P、備考、MAPCODE、路線名、住所 だ。 tabで区切られたテキストファイルになる。
rnamae.csv あいおい 43.32.35 143.59.04 105 ○ 866 463 154 R240 北海道網走郡津別町字相生 愛ランド湧別 44.07.42 143.43.23 208 ○ 404 476 383 R238 北海道紋別郡湧別町字志撫子6-2
(2) 必要な形式、項目のCSVに変換する。

  1) 緯度経度が度分秒の60進から十進数に変換
  2) 日本語フォントが使えない端末用に、日本語をアルファベット化
    以上をgawkで処理。

# BEGIN{ FS="\t"; OFS="\t" OFMT="%.11g" } { namae= $1 split($2,ary,".") lat=ary[1]+ary[2]/60.0+ary[3]/60./60. split($3,ary,".") lon=ary[1]+ary[2]/60.0+ary[3]/60./60. cmd = sprintf("echo %s | kakasi -iutf8 -Ja -Ha -Ka -Ea", $1); cmd | getline nn close(cmd) cmd = sprintf("echo %s | kakasi -iutf8 -w | kakasi -iutf8 -Ja -Ha -Ka -Ea", $8); cmd | getline aa close(cmd) rna = sprintf("%s_[%s]",nn,namae) print rna,lat,lon,aa }
出力結果は以下。手作業前。
rnamae2.csv aioi_[あいおい ] 43.543055556 143.98444444 hokkaidou abashiri gun tsubetsu machi ji aioi airandoyuubetsu_[愛ランド湧別 ] 44.128333333 143.72305556 hokkaidou monbetsu gun yuu betsu machi ji kokorozashi nadeshiko 6-2
3) 一部、括弧や横棒の文字化けや、いらんスペースがあるので、手作業で修正。
こいつを、JaVaWa RTWtool で poi 化すれば終了。


[20171225] 道の駅 公式ホームページにある、道の駅検索結果を県毎にpythonでスクレイプしてみた。例えば山形県の結果。名前と座標とidはいける。リンク先を追いかければ、住所や電話番号もとれるかも。とりあえず不要。Kakasiでローマ字名を作り、全角を半角に変換(mojimoji)するのを追加。これでさくっとcsvが作れる。kakasiはここを、mojimojiはここを参考にした(感謝)。
#!~/.pyenv/shims/python
"""Get Michi-no eki List from  web site."""
#

import sys

import regex
import requests
from bs4 import BeautifulSoup

import mojimoji
from pykakasi import kakasi

kakasi = kakasi()
kakasi.setMode("H", "a")  # default: Hiragana no conversion
kakasi.setMode("K", "a")  # default: Katakana no conversion
kakasi.setMode("J", "a")  # default: Japanese no conversion
kakasi.setMode("r", "Hepburn")  # default: use Hepburn Roman table
kakasi.setMode("C", True)  # add space default: no Separator
kakasi.setMode("c", False)  # capitalize default: no Capitalize

convk = kakasi.getConverter()

ss = regex.compile(r'{((?>[^{}]+|(?R))*)}')
target_url0 = 'https://www.michi-no-eki.jp/stations/search?prefecture_id='
#   1: Hokkaidou     2: Aomori     3: Iwate
#   4: Miyagi        5: Akita      6: Yamagata
#  46: Kagoshima    47: Okinawa

for jj in range(1, 48):
    tar_url = target_url0 + str(jj)
    r = requests.get(tar_url, verify=False)
    soup0 = BeautifulSoup(r.text, "lxml")
    scripts = soup0("script")

    mark_datas = []
    mark_datas = scripts[0].string.strip().split(";")

    for ii in range(1, len(mark_datas) - 1):
        s1 = ss.findall(mark_datas[ii])
        s2 = s1[0].split(",")
        s_id = int(s2[0].split(":")[1].strip())
        sh_name = s2[1].split(":")[1].strip()
        sr_name = mojimoji.zen_to_han(convk.do(sh_name))
        s_name = "{0:}_[{1:}]".format(sr_name.strip("'"), sh_name.strip("'"))
        s_lat = s2[2].split(":")[1].strip()
        s_lng = s2[3].split(":")[1].strip()
        s_pref = int(s2[4].split(":")[1].strip())
        print("{1:d}, {2:}, {3:}, {4:}, {0:d}".format(s_pref, s_id, s_name, s_lat, s_lng))
    #
sys.exit()

[20180406] 処理に時間がかかるので、wget でデータを一旦取得してから、parse するように変更。

#!~/.pyenv/shims/python
"""Get Michi-no eki List from  web site."""
#

# -*- coding: utf-8 -*-

import glob
import os
import subprocess
import sys
from datetime import datetime

from bs4 import BeautifulSoup

import logzero
from logzero import logger

from pykakasi import kakasi

from pytz import timezone

import regex

import mojimoji


def get_file_list(t_dir):
    """Get csv file names."""
    # 単純にファイルのリストを取得するだけ

    f_list = []
    f_list = sorted(glob.glob(t_dir))

    return f_list


def subcommand(arg_ss, err_jj):
    """Execute external command."""
    # print(" ** ", arg_ss)
    try:
        res = subprocess.run(arg_ss, stdout=subprocess.PIPE)
        sys.stdout.buffer.write(res.stdout)
    except ValueError:
        e_mes = "Error.{:d} ...".format(err_jj + 100)
        logger.info(e_mes)

    return None


def set_my_kakasi():
    """Set my kakasi function."""
    #
    m_kakasi = kakasi()
    m_kakasi.setMode("H", "a")  # default: Hiragana no conversion
    m_kakasi.setMode("K", "a")  # default: Katakana no conversion
    m_kakasi.setMode("J", "a")  # default: Japanese no conversion
    m_kakasi.setMode("r", "Hepburn")  # default: use Hepburn Roman table
    m_kakasi.setMode("C", True)  # add space default: no Separator
    m_kakasi.setMode("c", False)  # capitalize default: no Capitalize

    return m_kakasi.getConverter()


def parse_data(mup_dat):
    """Parse url data."""
    #

    re_st = regex.compile(r'{((?>[^{}]+|(?R))*)}')
    conv_kaka = set_my_kakasi()

    d_lst = []

    for i in range(1, len(mup_dat) - 1):
        s_1 = re_st.findall(mup_dat[i])
        s_2 = s_1[0].split(",")
        s_id = int(s_2[0].split(":")[1].strip())
        sh_name = s_2[1].split(":")[1].strip()
        sr_name = mojimoji.zen_to_han(conv_kaka.do(sh_name))
        s_name = "{0:}_[{1:}]".format(sr_name.strip("'"), sh_name.strip("'"))
        s_lat = s_2[2].split(":")[1].strip()
        s_lng = s_2[3].split(":")[1].strip()
        s_pref = int(s_2[4].split(":")[1].strip())
        out_buf = "{1:d}, {2:}, {3:}, {4:}, {0:d}".format(s_pref, s_id, s_name, s_lat, s_lng)

        d_lst.append(out_buf)

    return d_lst


def write_line_data(f_name, list_line_data):
    """Write line data."""
    #

    with open(f_name, "wt") as f_out:
        for k in list_line_data:
            w_buf = k + '\n'
            # logger.info(w_buf)
            f_out.writelines(w_buf)

    return


def main():
    """Do main process."""
    #

    target_url0 = 'https://www.michi-no-eki.jp/stations/search?prefecture_id='

    for j in range(1, 48):
        tar_url = target_url0 + str(j)
        out_url = "./site_data/saved" + "{0:02d}".format(j) + ".html"
        # wget --no-check-certificate  -O savedfile.html

        arg_1 = ['--no-check-certificate']
        arg_2 = ['-O', out_url]
        arg_0 = ['wget'] + arg_1 + [tar_url] + arg_2
        if os.path.exists(out_url):
            logger.info("File is exist.")
        else:
            logger.info("Get urlsite date")
            subcommand(arg_0, 5)

    url_data_files = get_file_list("./site_data/*.html")

    out_datas = []
    for f_name in url_data_files:
        soup0 = BeautifulSoup(open(f_name), "lxml")
        scripts = soup0("script")

        mark_datas = []
        mark_datas = scripts[0].string.strip().split(";")

        out_dat = parse_data(mark_datas)
        out_datas.extend(out_dat)

    # logger.info(len(out_datas))
    now_time = "michieki_" \
               + datetime.now(timezone('UTC')).strftime("%Y%m%dT%H%MZ") \
               + ".csv"
    logger.info(now_time)
    write_line_data(now_time, out_datas)

    return


if __name__ == '__main__':
    #
    LOG_FORMAT = '%(color)s[%(module)s:%(lineno)d]%(end_color)s %(message)s'
    FORMATTER = logzero.LogFormatter(fmt=LOG_FORMAT)
    logzero.setup_default_logger(formatter=FORMATTER)

    main()

    sys.exit()

スポーツサイクルのショップリストを作るのは中断

サイクルスポーツ.jpのショップナビの店舗をpoiにしようかと、 pythonでscrapingしたショップリストからジオコーディングで座標を求めたcsvファイルを作成しようとしたが、 ジオコーディングで比較的正確な情報が得られるらしいgoogleを使うにはライセンスのハードルがあるみたい。 近畿とその周辺があたりで、コーディングしてくれなくなる。 1箇所あたり10アクセスのカウントになるらしい。お金を払うつもりはないし、 少しづつスクリプトを走らせるなら、手作業でも大差ないかもと思ったが、 ショップのWebサイトやblogをついつい読み始めてしまい、作業は一向に進まない。 あと、このリストで作業してよいか、というのにも気付いた。これまでの作業をプロットしてみると、 来年足を伸ばそうと思っている若狭周辺のデータがない。福井にも当然サイクルショップは有るわけで、 元データの性格なんだろう。外の地域でも同様かもしれないので、しばらく中断。
やっぱり、その都度ネット検索というのが本筋なんだろうな。

0 件のコメント:

コメントを投稿

麻のボディタオル

2018年の秋(まだ、自転車を封印してない)、 近江上布伝統産業会館 で、興味からボディタオルを購入した。 お、よかった。: 自然派パン工房 ふるさとの道 ほぼ毎日風呂で使ってきて、ついに寿命がきたようだ。 お店の方に、「糸が痩せて破れてくる」まで使える、と...