国土数値情報ダウンロードサイトの観光資源データをrubyでjsonに変換

投稿日: 2025-09-09

国土交通省国土数値情報ダウンロードサイトの観光資源データ
https://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-P12-v2_2.html

平成26年の全国(P12-14_GML.zip)をダウンロードしました。
データフォーマットはシェープファイル形式になっているため、パースにはrgeo-shapefileを使いました。
https://github.com/rgeo/rgeo-shapefile

zipファイルダウンロード&解凍

wget "https://nlftp.mlit.go.jp/ksj/gml/data/P12/P12-14/P12-14_GML.zip"
unzip P12-10_GML.zip -d P12-10_GML

今回は緯度経度の座標のみを取得するため、中心点の情報が入っているP12aから始まるファイルのみをパースします。
各観光資源には属性として観光資源名、種別名称、所在地住所が文字列型で入っていますが
なぜか広島県のファイルのみ文字列部分がUTF-8になっていて、それ以外はShift_JISと混ざっていたため、どちらでもパース出来るようにしました。

require "rgeo/shapefile"
require "json"

Dir.glob("P12-14_GML/P12a*.shp") do |path|
  RGeo::Shapefile::Reader.open(path) do |file|
    file.each do |record|
      texts = [
        record.attributes["P12_002"], 
        record.attributes["P12_005"], 
        record.attributes["P12_006"], 
        record.attributes["P12_003"], 
        record.attributes["P12_004"]
      ]
      name, type, address, pref_code, admini = texts.map {|text|
        if text.inspect.include?("\\x")
          text.encode('UTF-8', 'Shift_JIS', :invalid => :replace, :undef => :replace, :replace => "?")
        else
          text
        end
      }

      geo = if record.geometry.is_a?(RGeo::Cartesian::MultiPointImpl)
        record.geometry.geometries.first
      else
        record.geometry
      end

      row = {
        id: record.attributes["P12_001"],
        longitude: geo.x, 
        latitude: geo.y, 
        name: name, 
        type: type, 
        address: address,
        pref_code: pref_code,
        admini: admini.gsub("、", ","),
        resource_category: record.attributes["P12_007"]
      }      
      puts JSON.dump(row)
    end
    file.rewind
    record = file.next
  end
end