世界の測量

Sibling of "Relevant, Timely, and Accurate, " but much lighter and shorter ※自らの所属する組織の見解を示すものでない

数値地図(国土基本情報)の Shapefile データの接合&文字コード変換

数値地図(国土基本情報)の提供が2012年7月30日に開始された。とりあえず「江差」を購入してデータのハンドリングをしてみている。TileMill で Fast & Beautiful Map に加工できるようにすることが当面の目的である。

江差は延伸図であることもあり、TileMill は UTF-8Shapefile しか受け取らないこともあり、GeoRuby を使って一括コンバータを作成したので共有する(CC0)。

基盤地図情報 Shapefile と異なり、属性名称には日本語を使用していないようであるので、その部分の処理を省略してある。

Rakefile 形式にしてあるので、作業は rake コマンド一発で行えるような設計である。

#Rakefile cc0
require 'find'
require 'rubygems'
require 'geo_ruby'
require 'iconv'
include GeoRuby::Shp4r

task :default do
  c = Iconv.new('UTF-8', 'CP932')
  %w{AdmArea AdmBdry Anno BldA BldL BldSbl Cntr Cstline ElevPt GCP LUSbl Monument PwrPlnt PwrTrnsmL RailCL RailTrCL RdCL RdCompt RdEdg RTwr RvrCL SpcfArea StrctSbl TpgphArea TpghLine TpghSbl TrfSbl TrfStrct VegeClassL VLine WA WL WRltLine WStrL CSPt NNFLine NNFPt NRPt PFPt}.each {|theme|
    print "converting #{theme}..."
    dst_path = "dst/#{theme}.shp"
    sh "rm dst/#{theme}.*" if File.exist?(dst_path)
    dst = nil
    Dir.glob('../??????') {|dir|
      Find.find(dir) {|src_path|
        next unless /#{theme}/.match src_path
        next unless /shp$/.match src_path
        ShpFile.open(src_path) {|src|
          unless dst
            dst_fields = []
            src.fields.each {|field|
              dst_fields <<
                Dbf::Field.new(field.name, field.type, 
                               (field.type == 'C' ? 2 : 1) * field.length,
                               field.decimal)
            }
            dst = ShpFile.create(dst_path, src.shp_type, dst_fields)
          end
          dst.transaction {|tr|
            src.each {|r|
              d = {}
              r.data.each {|k, v|
                d[k] = (v.class == String) ? c.iconv(v) : v
              }
              tr.add(ShpRecord.new(r.geometry, d))
            }
          }
        }
      }
    }
    dst.close
    print "complete.\n"
  }                        
end