LoginSignup
20
21

More than 5 years have passed since last update.

日本語対応の世界都市名データベースを作成する

Last updated at Posted at 2014-09-09

世界の都市名(カタカナ)から、その都市名(英語)と国名を返すプログラムが必要になったので、都市名データベースを用意します。
英語表記のデータベースは有償含めいくつかありましたが、日本語表記のものはあまりないのかなという印象です。

元になるデータをダウンロード

リンク先の「日本世界地名データ」をダウンロードします。
今回はこの中の「世界都市フォルダ」を使いますが、日本国内の市町村名などのファイルも含まれています。

※ ライセンスが明記されていないので注意が必要です

文字コードをUTF8に変換(どっちでもいいです)

先ほどダウンロードしたcsvファイルの文字コードを、nkfを使ってSJISからUTF8に変換します。

$ brew install nkf
$ cd flapna12
$ cd 世界都市フォルダ
$ nkf -Sw --overwrite **/*.csv

nkfをbrewでインストールして、さきほどダウンロードしたフォルダに移動、フォルダ内csvファイルをUTF8に一括変換。

csvファイルを編集

このcsvファイルには、ロンドンがイギリスとカナダ両方に含まれています
今回は日本語の都市名から一意に国名を返したいので、Canada.csvからロンドンをコメントアウトします。

#ロンドン,London,42.59,-81.14,都市,4,

多次元ハッシュに格納し保存

国ごとに、

  • 国名(英語)
  • 国名(日本語)
  • 都市名(英語)
  • 都市名(日本語)

を多次元ハッシュとして格納し、cities.rbにハッシュを、cities.jsにjsonを保存するRubyコードを書きました。

convert.rb
require 'find'
require 'csv'
require "json"

d = Hash::new

Find.find('./') {|f|
  if /.*?\.csv/ =~ f

    CSV.foreach(f) do |city|
      if $. == 1
        next
      elsif $. == 2
        city[0] =~ /<TITLE>(.*?)\((.*?)\)<\/TITLE>/
        $country_ja = $1
        $country_en = $2

        d[$country_en] = Hash::new
        d[$country_en][:ja] = $country_ja
        d[$country_en][:city] = Hash::new
      else
        d[$country_en][:city][city[1]] = city[0]
      end
    end

  end
}

d.each_key do |key|
  puts "#{d[key][:ja]}(#{d[key][:city].length})"
end

File.write("cities.rb", d)
File.write("cities.js", d.to_json)

現在のディレクトリが世界都市フォルダであることを確認し、実行します。

ruby convert.rb

結果

cities.rb
{
  "Afghanistan" => {
    :ja=>"アフガニスタン",
    :city=>{
      "Kabul" => "カブール",
      "Qandahar" => "カンダハール",
      "Herat" => "ヘラート",
      "Qonduz" => "コンドゥーズ",
      "Baghlan" => "バグラーン"
    }
  },
  "Bahrain" => {
    :ja => "バーレーン",
    .
    .
    .

このような形式のハッシュができました。

国数:200
都市数:1778

また、国数・都市数共に十分実用的な数はあるのかなと思います。(日本は東京しかありませんけど)

他にもGoogle Map Apiから都市名を引っ張ってくるなんて方法もありかと思います。

20
21
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
21