garminに航空レーザ測量成果(ベクタ)を搭載

力技でgarminに航空レーザで取得した等高線を搭載します。 世間に公開するレベルではないですが、お役に立てれば。

手順

  1. 等高線dxfをshpに変換
  2. shpをQGISにてkmlに変換
  3. kmlをrubyにてosmに変換
  4. osmsisでosmを正規化
  5. splitterでosmを分割
  6. mkgmapでimgに変換

手順1、2ともにQGISで実施します。

注意すべきこととして、EPSGは4326にしておくことです。

3が最も力技です。 kmlをosmに以下のファイルで変換します。

以下を実行すると、何を変換するか聞かれますが、 等高線を選択してください。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# -*- coding: utf-8 -*-

=begin

kmlをosmに変換するプログラム。ただし、ポイントと等高線のみ。
使い方
ruby kml2osm.rb 変換したいkmlファイル名

=end

#! ruby -Ku
require "kconv"

class Placemark
  def initialize(lon, lat, name)
    @lon = lon
    @lat = lat
    @name = name
  end
  
  attr_accessor :lon, :lat, :name
  
  #ポイントのタグをつける
  def tagPoint(datasort)
    #林班のとき
    if datasort == "6"
      return ("\t<tag k=\"place\" v=\"city\" \/>\n\t<tag k=\"name_ext\" v=\"rinpanName\" \/>\n\t<tag k=\"name\" v=\"#{@name}\" \/>\n")
    #小班のとき
    elsif datasort == "7"
        return ("\t<tag k=\"place\" v=\"town\" \/>\n\t<tag k=\"name_ext\" v=\"syouhanName\" \/>\n\t<tag k=\"name\" v=\"#{@name}\" \/>\n")
    #山名のとき
    elsif datasort == "8"
      return ("\t<tag k=\"place\" v=\"summit\" \/>\n\t<tag k=\"name_ext\" v=\"summit\" \/>\n\t<tag k=\"name\" v=\"#{@name}\" \/>\n")
    end
  end
  
  #ラインのタグをつける
  def tagWay(datasort)
    #小班界のとき
    if datasort == "2"
      return ("<tag k=\"name\" v=\"#{@name}\" \/>\n<tag k=\"boundary\" v=\"administrative\" \/>\n<tag k=\"admin_level\" v=\"2\" \/>\n\t<tag k=\"name_ext\" v=\"syouhanLine\" \/>\n<\/way>")
      #林班界
    elsif datasort == "1"
      return ("<tag k=\"name\" v=\"#{@name}\" \/>\n<tag k=\"highway\" v=\"primary_link\" \/>\n\t<tag k=\"name_ext\" v=\"rinpanLine\" \/>\n<\/way>")
      #林道
    elsif datasort == "3"
      return ("<tag k=\"highway\" v=\"secondary\" \/>\n\t<tag k=\"name_ext\" v=\"rindou\" \/>\n<\/way>")
      #作業道
    elsif datasort == "4"
      return ("<tag k=\"highway\" v=\"track\" \/>\n\t<tag k=\"name_ext\" v=\"sagyoudou\" \/>\n<\/way>")
      #等高線
    elsif datasort == "5"
      if @name.to_i % 10 == 0   #計曲線の場合
        return ("<tag k=\"ele\" v=\"#{@name}\" \/>\n<tag k=\"contour\" v=\"elevation\" \/>\n<tag k=\"contour_ext\" v=\"Contour_major\" \/>\n<\/way>")
      else  #主曲線の場合
        return ("<tag k=\"ele\" v=\"#{@name}\" \/>\n<tag k=\"contour\" v=\"elevation\" \/>\n<tag k=\"contour_ext\" v=\"Contour_minor\" \/>\n<\/way>")
      end
    end
  end
end

way = String.new
id_number = 0
filename = ARGV[0]

#--ファイルオープン
data = open(filename, "r:UTF-8"){|io| io.read}
data.chomp!
w_filename = filename.sub(".kml","") + ".osm"
w_file = open(w_filename, "w:UTF-8")

#--Shift-JISの場合のみ、UTF-8に変換
str = Kconv.guess(data).to_s

if str =~/JIS/
	data = data.toutf8
end

#ラインの種類を聞く
print(Kconv.tosjis("データの種類は何ですか?\n林班界は1、小班界は2、林道は3、作業道は4、等高線は5、林班名は6、小班名は7、山の名前は8を半角で入力して下さい。\n"))
datasort= STDIN.gets.chomp!

#--- ヘッダーを入れる

w_file.puts('<?xml version="1.0"?>')
w_file.puts('<osm xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="0.6" generator="kml2osm" upload="false">')

#--- Placemarkの取り出し ---
placemark = data.scan(/<Placemark>.+?<\/Placemark>/m)

#--- nodeとwayの作成 ---
placemark.each{|value|
  #緯度経度と名前の抽出
  place = Placemark.new(value.scan(/(\d\d\d\.\d+),\d\d\.\d+/), value.scan(/\d\d\d\.\d+,(\d\d\.\d+)/), value.scan(/<SimpleData name=\"ele\">(.+?)<\/SimpleData>/m).join)
  
  #--- ポイントの場合 ---
  if datasort.to_i >= 6
    w_file.puts("<node id=\"#{99999999 - id_number}\" timestamp=\"#{Time.now.strftime("%Y-%m-%dT%H:%M:%SZ")}\" user=\"kml2osm\" uid=\"1\" visible=\"true\" lat=\"#{place.lat.join}\" lon=\"#{place.lon.join}\" version=\"1\" changeset=\"1\">")
    
    #タグをつける
    w_file.puts(place.tagPoint(datasort), '</node>')
    
    id_number += 1
    
  #--- ラインの場合---
  elsif datasort.to_i <= 5
    #nodeの追加
    for i in 0..place.lon.length-1
      w_file.puts("<node id=\"#{99999999 - id_number}\" timestamp=\"#{Time.now.strftime("%Y-%m-%dT%H:%M:%SZ")}\" user=\"kml2osm\" uid=\"1\" visible=\"true\" lat=\"#{place.lat[i].join}\" lon=\"#{place.lon[i].join}\" version=\"1\" changeset=\"1\" \/>")
      
      id_number += 1
      
    end
    
    #wayの追加
    way.concat("<way id=\"#{99999999 - id_number + 1}\" timestamp=\"#{Time.now.strftime("%Y-%m-%dT%H:%M:%SZ")}\" user=\"kml2osm\" uid=\"1\" visible=\"true\" version=\"1\" changeset=\"1\">\n")
    
    for k in 0..place.lon.length-1
      way.concat("<nd ref=\"#{99999999 - id_number + 1 + k}\" \/>\n")
    end
    
    #タグをつける
    way.concat(place.tagWay(datasort))
    
  end
}

w_file.puts(way)
w_file.puts('</osm>')

w_file.close

print(w_filename, Kconv.tosjis("を作成しました。"))

手順4として、これで作成したファイルをosmsisで正規化します

このとき、JREではなく、JDKをインストールしておく必要があります

1
osmosis --read-xml file="data.osm" --sort type="TypeThenId" --write-xml file="data-sorted.osm"

あとはsplitterとmkgmapでimgに変換すればOKです。

Licensed under CC BY-NC-SA 4.0
Hugo で構築されています。
テーマ StackJimmy によって設計されています。