User:Tatata/ksj2osm-railway.pl

From OpenStreetMap Wiki
Jump to navigation Jump to search

This perl script convert KSJ2 railway data xml file to osm xml file directly. (ja)このperlスクリプトは国土数値情報(鉄道データ)のxmlファイルをosmのxmlファイルに直接変換します。

Preparation

(ja)準備

  • Installation of JOSM (a java program; needs J2SE SDK or JRE). (ja)JOSMの導入(javaプログラムなので実行にはJ2SE SDK或いはJREが必要。)
  • Installation of perl. You can download ActivePerl from ActiveState site (free of charge). (ja)perlの導入。ActiveStateのサイトからActivePerlをダウンロードできる(無料)。
  • Save the code below as a file with proper name. (e.g. ksj2osm-railway.pl) (ja)適切なファイル名を付けて下のソースコードを保存する。(例えばksj2osm-railway.plなど。)

How to convert the data

(ja)変換手順

  • Download KSJ2 railway data decompress from zip file to xml file. (ja)国土数値情報(鉄道データ)をダウンロードし、zipファイルを解凍してxmlファイルにする。
  • Put the xml file on the same directory of the script. (ja)xmlファイルをスクリプトと同じディレクトリに置く。
  • Open this perl script by editor program, edit the initial values of $target_opc and $target_lin to specify railway operator name and railway line name with UTF-8 characters (you can copy and paste from list), and then save the script. (ja)このperlスクリプトをエディタープログラムで開き、$target_opcと$target_linの初期値にUTF-8の文字による鉄道事業者名と鉄道路線名を書き込んでスクリプトを保存する(このリストからコピペ可)。
  • Open command prompt window and run the script on the directory where you put the script and xml file. Output files (ksj2osm-railway.osm, ksj2osm-railway.log) will be created on the same directory. (ja)コマンドプロンプトを開いて、スクリプトとxmlファイルを置いたディレクトリでスクリプトを実行する。出力ファイル (ksj2osm-railway.osm, ksj2osm-railway.log) は同じディレクトリに作成される。
  • Open ksj2osm-railway.osm by JOSM, check and edit the data (see notes below), and then upload to server. (ja)JOSMでksj2osm-railway.osmを開いてデータの確認や編集を行い(下の注意を参照)、それからサーバーにアップロードする。

Notes

(ja)注意

  • KSJ2 railway data doesn't have information about distinction between "rail" and "subway" and there are some subway lines that have RAC(RailwayClassCd)=16 (automated guideway transit) or RAC=21 (tram). The script doesn't cope with these problem automatically, so you have to check tags in the output file and change them to correct appropriate one before you upload to server. (ja)国土数値情報の鉄道データには地上の鉄道と地下鉄の区別するための情報がありません。また、幾つかの地下鉄路線にはRAC(RailwayClassCd)=16(案内軌上式鉄道)やRAC=21(軌道)として分類されています。このスクリプトはこれらの問題には自動的に対応できませんので、出力ファイル内のタグを確認し、サーバーへアップロードする前に適切なものに変更して下さい。
  • A single railway line information of KSJ2 data (e.g. Tōkaidoō Shinkansen) is divided into many sections and two or more nodes with the same coordinates (a set of latitude and longitude) are piled up on a connection point of adjoining sections. The script merge nodes with the same coordinates, but doesn't combine ways automatically, so it would be better to do it yourself manually. (ja)鉄道データに含まれる1つの路線の情報(例えば東海道新幹線)は多くの区間に分割されており、同じ座標(緯度経度の組合せ)を持った複数のnodeが隣接する区間の接続点で重なっています。このスクリプトは同じ座標を持った複数のnodeをマージしますが、wayの自動的な結合はできませんので、サーバーへアップロードする前に手作業で直した方が良いでしょう。


elapsed time comparison



D:\INSTPGM\OpenStreetMap\JPGIS\data>perl ksj2osm-railway.pl
***** KSJ2 Railway Data 2007 : Start Thu Mar 20 23:26:38 2008
***** Target : 九州旅客鉄道 / 鹿児島線
***** Process of infile : End Thu Mar 20 23:30:16 2008
Skip error data : id = eb02_3014, coordinate = 5101 130.810014, lat = 5101, long
 = 130.810014
Skip error data : id = eb02_3204, coordinate = 30.311243
Skip error data : id = eb02_3208, coordinate = 7
***** Railway Lines : 3478 nodes on 236 ways
***** Railway Lines : 95 nodes tagged as stastion
***** Done!: End Thu Mar 20 23:30:19 2008

D:\INSTPGM\OpenStreetMap\JPGIS\data>perl shp2osm-railway.pl
***** KSJ2 Railway Data 2007 : Start Thu Mar 20 23:31:08 2008
***** Target : 九州旅客鉄道 / 鹿児島線
***** Railway Stations (EB03) : 10315 shapes
***** Railway Stations (EB03) : 239 nodes on 95 ways processed
***** Railway Stations (EB03) : 95 nodes found as station
***** Railway Lines (EB02) : 22041 shapes
***** Railway Lines (EB02) : process Shape ID from 0 to 99999
***** Railway Lines (EB02) : 3481 nodes on 236 ways
***** Railway Lines (EB02) : 95 nodes tagged as stastion
***** Done!: End Thu Mar 20 23:31:50 2008

D:\INSTPGM\OpenStreetMap\JPGIS\data>

User:Tatata/shp2osm-railway.pl is better than this... ;-)

code

As of 2009-05-26.


#!/usr/bin/perl

use strict;
use warnings;
# use encoding "utf8"; 
use encoding "utf8", STDOUT => "shiftjis", STDERR => "shiftjis"; # for Windows
use Encode;
use open IO => "utf8";
use XML::Parser;

#####
#
# KSJ2 Railway Data
#
# National-Land Numerical Information (Railway) 2007, MLIT Japan
# 国土数値情報(鉄道データ)平成19年 国土交通省
#
# Files
#   Input
#     XML file : N02-07.xml
#   Output
#     Osm file : ksj2osm-railway.osm
#     Log file : ksj2osm-railway.log
#
#####

our $file_in = "N02-07";
our $file_name = "ksj2osm-railway";

our $target_opc = "神戸市"; # railway operator name (UTF-8) "九州旅客鉄道", "*", ""
our $target_lin = "西神延伸線"; # railway line name (UTF-8) "鹿児島線", "*", ""

our @workArray;
our %workHash;
our $workString;
our %lineHash;
our %stationHash;
our %int_code;
our %rac_code;
our $negative_id = 0;
our $node_ref;
our %nodes = ();
our $num_nodes;
our $num_stations;
our $num_ways;

sub main() {

  my $parser = new XML::Parser(ErrorContext => 3,
                               Handlers => {Init => \&handle_init,
                                            Start => \&handle_start,
                                            Char => \&handle_char,
                                            End => \&handle_end,
                                            Final => \&handle_final});

  $parser->parsefile("$file_in.xml");

}


sub handle_init() {

  open_log();
  %int_code = get_int_code();
  %rac_code = get_rac_code();

}


sub handle_start() {

  my ($expat, $element, %hash) = @_;
  if ($element eq "ksj:EB02" 
    || $element eq "ksj:LOC"
    || $element eq "ksj:RAS"
    || $element eq "ksj:EB03"
    || $element eq "jps:GM_Curve"
    || $element eq "GM_PointRef.point"
    || $element eq "jps:GM_Point") {get_id(@_);}
  $workString = "";                               # add 2009-05-26

}


sub handle_char () {

   my ($expat, $string) = @_;
#   $workString = $string;
   $workString .= $string;            # mod 2009-05-26

}


sub handle_end() {

  my ($expat, $element) = @_;
  if ($element eq "ksj:RAC"
    || $element eq "ksj:INT"
    || $element eq "ksj:LIN"
    || $element eq "ksj:OPC"
    || $element eq "ksj:STN"
    || $element eq "DirectPosition.coordinate") {get_element(@_);}
  elsif ($element eq "ksj:EB02") {add_line();}
  elsif ($element eq "ksj:EB03") {add_station();}
  elsif ($element eq "jps:GM_Curve") {add_point();}
  elsif ($element eq "jps:GM_Point") {replace_point();}

}


sub handle_final() {

  my $time = localtime(time);
  print LOG "***** Process of infile : End $time\n";
  print "***** Process of infile : End $time\n";

  print LOG "*****\n";
  foreach my $item(keys %lineHash) {
    print LOG "* 1st key: $item\n";
    foreach my $item2(keys %{$lineHash{$item}}) {
        print LOG "** 2nd key: $item2, value: $lineHash{$item}{$item2}\n";
    }

  }

  create_osm();

  close_log();

}


sub open_log() {

  my $time = localtime(time);
  open(LOG, ">$file_name.log");
  print LOG "***** KSJ2 Railway Data 2007 : Start $time\n";
  print "***** KSJ2 Railway Data 2007 : Start $time\n";
  print LOG "***** Target : $target_opc / $target_lin\n";
  print "***** Target : $target_opc / $target_lin\n";

}


sub close_log() {

  my $time = localtime(time);
  print LOG "***** Done!: End $time\n";
  close LOG;
  print "***** Done!: End $time\n";

}


sub get_int_code() {

  # "InstitutionTypeCd.xml"
  my %hash = (
    "1" => "新幹線",
    "2" => "JR在来線",
    "3" => "公営鉄道",
    "4" => "民営鉄道",
    "5" => "第三セクター"
  );

  return %hash;

}


sub get_rac_code() {

  # "RailwayClassCd.xml"
  my %hash = (
    "11" => "普通鉄道JR",
    "12" => "普通鉄道",
    "13" => "鋼索鉄道",
    "14" => "懸垂式鉄道",
    "15" => "跨座式鉄道",
    "16" => "案内軌上式鉄道",
    "17" => "無軌上式鉄道",
    "21" => "軌道",
    "22" => "懸垂式モノレール",
    "23" => "跨座式モノレール",
    "24" => "案内軌上式",
    "25" => "浮上式"
  );

  return %hash;

}


sub get_id() {

  my ($expat, $element, %hash) = @_;
  if ($element eq "ksj:LOC" ) {
    if (exists($hash{"idref"})) {
      $workHash{"LOC"} = $hash{"idref"};
    }
    else {
      print LOG "* id not found in element ksj:LOC.\n";
      print "* id not found in element ksj:LOC.\n";
      while (my ($key, $value) = each(%hash)) {
        print LOG "key: $key , value: $value \n";
        print "key: $key , value: $value \n";
      }
      die "id not found in element ksj:LOC.";
    }
  }
  elsif ($element eq "ksj:RAS" ) {
    if (exists($hash{"idref"})) {
      $workHash{"RAS"} = $hash{"idref"};
    }
    else {
      print LOG "* id not found in element ksj:RAS.\n";
      print "* id not found in element ksj:RAS.\n";
      while (my ($key, $value) = each(%hash)) {
        print LOG "key: $key , value: $value \n";
        print "key: $key , value: $value \n";
      }
      die "id not found in element ksj:RAS.";
    }
  }
  elsif ($element eq "GM_PointRef.point" ) {
    if (exists($hash{"idref"})) {
      if (exists($workHash{"points"})) {
        $workHash{"points"} .= ",";
      }
      $workHash{"points"} .= $hash{"idref"};
    }
    else {
      print LOG "* id not found in element GM_PointRef.point.\n";
      print "* id not found in element GM_PointRef.point.\n";
      while (my ($key, $value) = each(%hash)) {
        print LOG "key: $key , value: $value \n";
        print "key: $key , value: $value \n";
      }
      die "id not found in element GM_PointRef.point.";
    }
  }
  else {
    if (exists($hash{"id"})) {
      $workHash{"id"} = $hash{"id"};
    }
    else {
      print LOG "* id not found in element $element.\n";
      print "* id not found in element $element.\n";
      while (my ($key, $value) = each(%hash)) {
        print LOG "key: $key , value: $value \n";
        print "key: $key , value: $value \n";
      }
      die "id not found in element $element";
    }
  }
}


sub get_element() {

  my ($expat, $element) = @_;
  if ($element eq "ksj:RAC" ) {
    $workHash{"RAC"} = $workString;
    $workHash{"RAC_label"} = $rac_code{$workString};
  }
  elsif ($element eq "ksj:INT" ) {
    $workHash{"INT"} = $workString;
    $workHash{"INT_label"} = $int_code{$workString};
  }
  elsif ($element eq "ksj:LIN" ) {$workHash{"LIN"} = $workString;}
  elsif ($element eq "ksj:OPC" ) {$workHash{"OPC"} = $workString;}
  elsif ($element eq "ksj:STN" ) {$workHash{"STN"} = $workString;}
  elsif ($element eq "DirectPosition.coordinate" ) {
    if (exists($workHash{"points"})) {
      $workHash{"points"} .= ",";
    }
    $workHash{"points"} .= $workString;
  }
  $workString = "";                               # add 2009-05-26
}


sub add_line() {

  if ($target_opc eq $workHash{"OPC"} || $target_opc eq "*" || $target_opc eq "") {

    if ($target_lin eq $workHash{"LIN"} || $target_lin eq "*" || $target_lin eq "") {

      while (my ($key, $value) = each(%workHash)) {
        $lineHash{$workHash{"id"}}{$key} = $value;
      }
    }
  }
  %workHash = ();
}


sub add_station() {

  if ($target_opc eq $workHash{"OPC"} || $target_opc eq "*" || $target_opc eq "") {

    if ($target_lin eq $workHash{"LIN"} || $target_lin eq "*" || $target_lin eq "") {

      foreach my $item(keys %lineHash) {
        if (exists($lineHash{$item}{"RAS"})) {
          if ($lineHash{$item}{"RAS"} eq $workHash{"id"}) {
            $lineHash{$item}{"STN"} = $workHash{"STN"};
          }
        }
      }
    }
  }
  %workHash = ();
}


sub add_point() {

  foreach my $item(keys %lineHash) {
    if ($lineHash{$item}{"LOC"} eq $workHash{"id"}) {
      $lineHash{$item}{"points"} = $workHash{"points"};
    }
  }
  %workHash = ();
}


sub replace_point() {

  foreach my $item(keys %lineHash) {
      $lineHash{$item}{"points"} =~ s/$workHash{"id"}/$workHash{"points"}/g;
  }
  %workHash = ();
}


sub create_osm(){

  my $i = 0;

  open(OSM, ">$file_name.osm");
  print OSM "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
  print OSM "<osm version=\"0.5\" generator=\"KSJ2OSM\">\n";

  station_table();

  foreach my $item(keys %lineHash) {
    @workArray = split(/,/, $lineHash{$item}{"points"});
    foreach my $coordinate(@workArray) {
      $i = write_node($i, $item, $coordinate);
    }
    write_way($i, $item);
    $i = 0;
  }

  print OSM "</osm>";
  close OSM;
  printf LOG 
    "***** Railway Lines : %d nodes on %d ways\n"
    , $num_nodes, $num_ways;
  printf LOG 
    "***** Railway Lines : %d nodes tagged as stastion\n"
    , $num_stations;
  printf 
   "***** Railway Lines : %d nodes on %d ways\n"
   , $num_nodes, $num_ways;
  printf 
   "***** Railway Lines : %d nodes tagged as stastion\n"
   , $num_stations;

}


sub station_table() {

  foreach my $item(keys %lineHash) {
    if (exists($lineHash{$item}{"RAS"})) {
      @workArray = split(/,/, $lineHash{$item}{"points"});
      my $num_points = @workArray;
      my $i = 0;
      foreach my $coordinate(@workArray) {
        if ($i == int(($num_points - 1) / 2)) {
          $stationHash{$coordinate}{"RAS"} = $lineHash{$item}{"RAS"};
          $stationHash{$coordinate}{"STN"} = $lineHash{$item}{"STN"};
        }
        $i++;
      }
    }
  }

}


sub write_node() {

  my ($i, $item, $coordinate) = @_;
  my $node_id = 0;
  my $value_stn = "";
  my ($lat, $long) = split(/\s/, $coordinate);

  unless (defined($lat) && defined($long)) {
    print LOG "Skip error data : id = $item, coordinate = $coordinate\n";
    print "Skip error data : id = $item, coordinate = $coordinate\n";
    return;
  }
  if (($lat eq "") || ($long eq "")) {
    print LOG "Skip error data : id = $item, coordinate = $coordinate, lat = $lat, long = $long\n";
    print "Skip error data : id = $item, coordinate = $coordinate, lat = $lat, long = $long\n";
    return;
  }
  if (($lat > 90) || ($lat < -90) || ($long > 180) || ($long < -180)) {
    print LOG "Skip error data : id = $item, coordinate = $coordinate, lat = $lat, long = $long\n";
    print "Skip error data : id = $item, coordinate = $coordinate, lat = $lat, long = $long\n";
    return;
  }

  my $tags = "<tag k=\"created_by\" v=\"National-Land-Numerical-Information_MLIT_Japan\"/>";
  $tags .= "<tag k=\"source\" v=\"KSJ2\"/>";
  $tags .= "<tag k=\"source_ref\" v=\"http://nlftp.mlit.go.jp/ksj/jpgis/datalist/KsjTmplt-N02-v1_1.html\"/>";
  $tags .= "<tag k=\"note\" v=\"National-Land Numerical Information (Railway) 2007, MLIT Japan\"/>";
  $tags .= "<tag k=\"note:ja\" v=\"国土数値情報(鉄道データ)平成19年 国土交通省\"/>";
  $tags .= "<tag k=\"KSJ2:segment\" v=\"$lineHash{$item}{'id'}\"/>";
  $tags .= "<tag k=\"KSJ2:LOC\" v=\"$lineHash{$item}{'LOC'}\"/>";
  $tags .= "<tag k=\"KSJ2:coordinate\" v=\"$coordinate\"/>";
  $tags .= "<tag k=\"KSJ2:lat\" v=\"$lat\"/>";
  $tags .= "<tag k=\"KSJ2:long\" v=\"$long\"/>";
  $tags .= "<tag k=\"KSJ2:RAC\" v=\"$lineHash{$item}{'RAC'}\"/>";
  $tags .= "<tag k=\"KSJ2:RAC_label\" v=\"$lineHash{$item}{'RAC_label'}\"/>";
  $tags .= "<tag k=\"KSJ2:INT\" v=\"$lineHash{$item}{'INT'}\"/>";
  $tags .= "<tag k=\"KSJ2:INT_label\" v=\"$lineHash{$item}{'INT_label'}\"/>";
  $tags .= "<tag k=\"KSJ2:OPC\" v=\"$lineHash{$item}{'OPC'}\"/>";
  $tags .= "<tag k=\"KSJ2:LIN\" v=\"$lineHash{$item}{'LIN'}\"/>";

  if (exists($stationHash{$coordinate})) {
    $value_stn = $stationHash{$coordinate}{"STN"};
    unless (defined($value_stn)) {$value_stn = "?";}
    $tags .= "<tag k=\"KSJ2:RAS\" v=\"$stationHash{$coordinate}{'RAS'}\"/>";
    $tags .= "<tag k=\"KSJ2:STN\" v=\"$value_stn\"/>";
    $tags .= "<tag k=\"name\" v=\"$value_stn\"/>";
    $tags .= "<tag k=\"name:ja\" v=\"$value_stn\"/>";
    if ($lineHash{$item}{"RAC"} eq "17" || $lineHash{$item}{"RAC"} eq "21")
      {$tags .= "<tag k=\"railway\" v=\"tram_stop\"/>";}
    elsif  ($lineHash{$item}{"OPC"} eq "名古屋ガイドウェイバス")
      {$tags .= "<tag k=\"highway\" v=\"bus_stop\"/>";}
    else
      {$tags .= "<tag k=\"railway\" v=\"station\"/>";}
  }

  if (exists($nodes{"$lat $long"})) {
    $node_id = $nodes{"$lat $long"};
  }
  else {
    $negative_id--;
    $node_id = $negative_id;
    $nodes{"$lat $long"} = $node_id;
    my $node 
      = sprintf("<node id=\"%d\" visible=\"true\" lat=\"%s\" lon=\"%s\">$tags</node>"
      , $node_id, $lat, $long);
    print OSM "$node\n";
    $num_nodes++;
    unless ($value_stn eq "") {
      $num_stations++;
    }
  }

  $node_ref .= sprintf("<nd ref=\"%d\" />", $node_id);
  printf LOG "Node %d: %s, %s, %s\n", $node_id, $lat, $long, $value_stn;
  $i++;
  return $i;

}


sub write_way() {

  my ($i, $item) = @_;
  my $tmp_lin;
  $negative_id--;

  my $tags = "<tag k=\"created_by\" v=\"National-Land-Numerical-Information_MLIT_Japan\"/>";
  $tags .= "<tag k=\"source\" v=\"KSJ2\"/>";
  $tags .= "<tag k=\"source_ref\" v=\"http://nlftp.mlit.go.jp/ksj/jpgis/datalist/KsjTmplt-N02-v1_1.html\"/>";
  $tags .= "<tag k=\"note\" v=\"National-Land Numerical Information (Railway) 2007, MLIT Japan\"/>";
  $tags .= "<tag k=\"note:ja\" v=\"国土数値情報(鉄道データ)平成19年 国土交通省\"/>";
#  $tags .= "<tag k=\"KSJ2:segment\" v=\"$lineHash{$item}{'id'}\"/>";
#  $tags .= "<tag k=\"KSJ2:LOC\" v=\"$lineHash{$item}{'LOC'}\"/>";
#  $tags .= "<tag k=\"KSJ2:points\" v=\"$lineHash{$item}{'points'}\"/>";
  $tags .= "<tag k=\"KSJ2:RAC\" v=\"$lineHash{$item}{'RAC'}\"/>";
  $tags .= "<tag k=\"KSJ2:RAC_label\" v=\"$lineHash{$item}{'RAC_label'}\"/>";
  $tags .= "<tag k=\"KSJ2:INT\" v=\"$lineHash{$item}{'INT'}\"/>";
  $tags .= "<tag k=\"KSJ2:INT_label\" v=\"$lineHash{$item}{'INT_label'}\"/>";
  $tags .= "<tag k=\"KSJ2:OPC\" v=\"$lineHash{$item}{'OPC'}\"/>";
  $tags .= "<tag k=\"KSJ2:LIN\" v=\"$lineHash{$item}{'LIN'}\"/>";

#  if (exists($lineHash{$item}{"STN"})) {
#    $tags .= "<tag k=\"KSJ2:RAS\" v=\"$lineHash{$item}{'RAS'}\"/>";
#    $tags .= "<tag k=\"KSJ2:STN\" v=\"$lineHash{$item}{'STN'}\"/>";
#  }

  if ($lineHash{$item}{"INT"} eq "1") {
    $tmp_lin = "$lineHash{$item}{'LIN'}";
  }
  elsif ($lineHash{$item}{"INT"} eq "2") {
    $tmp_lin = "JR$lineHash{$item}{'LIN'}";
  }
  elsif ($lineHash{$item}{"INT"} eq "3") {
    $tmp_lin = $lineHash{$item}{"OPC"};
    $tmp_lin .= "営";
    $tmp_lin .= $lineHash{$item}{"LIN"};
    if ($lineHash{$item}{"OPC"} eq "東京都") {
      if ($lineHash{$item}{"LIN"} eq "1号線浅草線") {$tmp_lin = "都営浅草線";}
      if ($lineHash{$item}{"LIN"} eq "6号線三田線") {$tmp_lin = "都営三田線";}
      if ($lineHash{$item}{"LIN"} eq "10号線新宿線") {$tmp_lin = "都営新宿線";}
      if ($lineHash{$item}{"LIN"} eq "12号線大江戸線") {$tmp_lin = "都営大江戸線";}
    }
    if ($lineHash{$item}{"OPC"} eq "福岡市" && $lineHash{$item}{"LIN"} eq "1号線(空港線)") 
      {$tmp_lin = "福岡市地下鉄空港線 (Fukuoka City Subway K?k? Line)";}
    if ($lineHash{$item}{"OPC"} eq "福岡市" && $lineHash{$item}{"LIN"} eq "2号線(箱崎線)") 
      {$tmp_lin = "福岡市地下鉄箱崎線 (Fukuoka City Subway Hakozaki Line)";}
    if ($lineHash{$item}{"OPC"} eq "福岡市" && $lineHash{$item}{"LIN"} eq "3号線(七隈線)") 
      {$tmp_lin = "福岡市地下鉄七隈線 (Fukuoka City Subway Nanakuma Line)";}
    if ($lineHash{$item}{"OPC"} eq "大阪市") {		# add Osaka-Subway
      if ($lineHash{$item}{"LIN"} eq "1号線(御堂筋線)") {$tmp_lin = "大阪市営地下鉄御堂筋線";}
      if ($lineHash{$item}{"LIN"} eq "2号線(谷町線)") {$tmp_lin = "大阪市営地下鉄谷町線";}
      if ($lineHash{$item}{"LIN"} eq "3号線(四つ橋線)") {$tmp_lin = "大阪市営地下鉄四つ橋線";}
      if ($lineHash{$item}{"LIN"} eq "4号線(中央線)") {$tmp_lin = "大阪市営地下鉄中央線";}
      if ($lineHash{$item}{"LIN"} eq "5号線(千日前線)") {$tmp_lin = "大阪市営地下鉄千日前線";}
      if ($lineHash{$item}{"LIN"} eq "6号線(堺筋線)") {$tmp_lin = "大阪市営地下鉄堺筋線";}
      if ($lineHash{$item}{"LIN"} eq "7号線(長堀鶴見緑地線)") {$tmp_lin = "大阪市営地下鉄長堀鶴見緑地線";}
      if ($lineHash{$item}{"LIN"} eq "8号線(今里筋線)") {$tmp_lin = "大阪市営地下鉄今里筋線";}
    }
    if ($lineHash{$item}{"OPC"} eq "神戸市") {		# add Kobe-Subway
      if ($lineHash{$item}{"LIN"} eq "山手線") {$tmp_lin = "神戸市営地下鉄西神・山手線";}
      if ($lineHash{$item}{"LIN"} eq "海岸線") {$tmp_lin = "神戸市営地下鉄海岸線";}
      if ($lineHash{$item}{"LIN"} eq "西神延伸線") {$tmp_lin = "神戸市営地下鉄西神・山手線";}
      if ($lineHash{$item}{"LIN"} eq "西神線") {$tmp_lin = "神戸市営地下鉄西神・山手線";}
    }
  }
  elsif ($lineHash{$item}{"INT"} eq "4" || $lineHash{$item}{"INT"} eq "5") {
    $tmp_lin = $lineHash{$item}{"OPC"};
    $tmp_lin .= "線";
    if ($lineHash{$item}{"LIN"} eq $tmp_lin) {
      $tmp_lin = "$lineHash{$item}{'OPC'}";
    }
    else {
      $tmp_lin = "$lineHash{$item}{'OPC'}$lineHash{$item}{'LIN'}";
    }
    if ($lineHash{$item}{"OPC"} eq "名古屋ガイドウェイバス") 
      {$tmp_lin = "ゆとりーとライン・名古屋ガイドウェイバス志段味線 (Yutorito Line, Guideway Bus Shidami Line)";}
    if ($lineHash{$item}{"OPC"} eq "沖縄都市モノレール") 
      {$tmp_lin = "ゆいレール・沖縄都市モノレール (Yui rail, Okinawa City Monorail Line)";}
    if ($lineHash{$item}{"OPC"} eq "いすみ鉄道") 
      {$tmp_lin = "いすみ鉄道";}
    if ($lineHash{$item}{"OPC"} eq "北総鉄道") 
      {$tmp_lin = "北総鉄道";}
    if ($lineHash{$item}{"OPC"} eq "千葉都市モノレール" && $lineHash{$item}{"LIN"} eq "1号線") 
      {$tmp_lin = "タウンライナー・千葉都市モノレール1号線 (Townliner, Chiba Urban Monorail Line 1)";}
    if ($lineHash{$item}{"OPC"} eq "千葉都市モノレール" && $lineHash{$item}{"LIN"} eq "2号線") 
      {$tmp_lin = "タウンライナー・千葉都市モノレール2号線 (Townliner, Chiba Urban Monorail Line 2)";}
    if ($lineHash{$item}{"OPC"} eq "東葉高速鉄道") 
      {$tmp_lin = "東葉高速鉄道";}
    if ($lineHash{$item}{"OPC"} eq "東京地下鉄") {
      if ($lineHash{$item}{"LIN"} eq "2号線日比谷線") {$tmp_lin = "東京メトロ日比谷線";}
      if ($lineHash{$item}{"LIN"} eq "3号線銀座線") {$tmp_lin = "東京メトロ銀座線";}
      if ($lineHash{$item}{"LIN"} eq "4号線丸ノ内線" 
        || $lineHash{$item}{"LIN"} eq "4号線丸ノ内線分岐線") {$tmp_lin = "東京メトロ丸ノ内線";}
      if ($lineHash{$item}{"LIN"} eq "5号線東西線") {$tmp_lin = "東京メトロ東西線";}
      if ($lineHash{$item}{"LIN"} eq "7号線南北線") {$tmp_lin = "東京メトロ南北線";}
      if ($lineHash{$item}{"LIN"} eq "8号線有楽町線") {$tmp_lin = "東京メトロ有楽町線";}
      if ($lineHash{$item}{"LIN"} eq "9号線千代田線") {$tmp_lin = "東京メトロ千代田線";}
      if ($lineHash{$item}{"LIN"} eq "11号線半蔵門線") {$tmp_lin = "東京メトロ半蔵門線";}
    }
    if ($lineHash{$item}{"OPC"} eq "東武鉄道" && $lineHash{$item}{"LIN"} eq "野田線") 
      {$tmp_lin = "東武野田線";}
    if ($lineHash{$item}{"OPC"} eq "総武流山電鉄") 
      {$tmp_lin = "総武流山電鉄";}
    if ($lineHash{$item}{"OPC"} eq "肥薩おれんじ鉄道") 
      {$tmp_lin = "肥薩おれんじ鉄道";}
    if ($lineHash{$item}{"OPC"} eq "舞浜リゾートライン") 
      {$tmp_lin = "ディズニーリゾートライン";}
    if ($lineHash{$item}{"OPC"} eq "首都圏新都市鉄道" && $lineHash{$item}{"LIN"} eq "常磐新線") 
      {$tmp_lin = "つくばエクスプレス";}
  }
  else  {
    printf "Railway Class Code Error (INT): ID=%d INT=%s"
      , $negative_id, $lineHash{$item}{"INT"};
    printf LOG 
      "Railway Class Code Error (INT): ID=%d RAC=%s INT=%s OPC=%s LIN=%s \n"
      , $negative_id, $lineHash{$item}{"RAC"}, $lineHash{$item}{"INT"}
      , $lineHash{$item}{"OPC"}, $lineHash{$item}{"LIN"};
    $tmp_lin = "$lineHash{$item}{'OPC'}$lineHash{$item}{'LIN'}";
  }

  $tags .= "<tag k=\"name\" v=\"$tmp_lin\"/>";
  $tags .= "<tag k=\"name:ja\" v=\"$tmp_lin\"/>";
  $tags .= "<tag k=\"operator\" v=\"$lineHash{$item}{'OPC'}\"/>";
  $tags .= "<tag k=\"operator:ja\" v=\"$lineHash{$item}{'OPC'}\"/>";

  if ($lineHash{$item}{"RAC"} eq "11" || $lineHash{$item}{"RAC"} eq "12"
  || $lineHash{$item}{"RAC"} eq "13") {
    if (($lineHash{$item}{"OPC"} eq "東京地下鉄")
      || ($lineHash{$item}{"OPC"} eq "東京都"
        && ($lineHash{$item}{"LIN"} eq "1号線浅草線" 
        || $lineHash{$item}{"LIN"} eq "6号線三田線"
        || $lineHash{$item}{"LIN"} eq "10号線新宿線" 
        || $lineHash{$item}{"LIN"} eq "12号線大江戸線"))
      || ($lineHash{$item}{"OPC"} eq "福岡市")
      || ($lineHash{$item}{"OPC"} eq "大阪市")		# add Osaka-Subway
      || ($lineHash{$item}{"OPC"} eq "神戸市"))		# add Kobe-Subway
      {$tags .= "<tag k=\"railway\" v=\"subway\"/>";}
    else {$tags .= "<tag k=\"railway\" v=\"rail\"/>";}
  }
  elsif ($lineHash{$item}{"RAC"} eq "14" || $lineHash{$item}{"RAC"} eq "15"
  || $lineHash{$item}{"RAC"} eq "22" || $lineHash{$item}{"RAC"} eq "23")
    {$tags .= "<tag k=\"railway\" v=\"monorail\"/>";}
  elsif ($lineHash{$item}{"RAC"} eq "16" || $lineHash{$item}{"RAC"} eq "25")
    {$tags .= "<tag k=\"railway\" v=\"light_rail\"/>";}
  elsif ($lineHash{$item}{"RAC"} eq "17" || $lineHash{$item}{"RAC"} eq "21")
    {if(($lineHash{$item}{"OPC"} eq "大阪市"))			# add Osaka-Subway
      {$tags .= "<tag k=\"railway\" v=\"subway\"/>";}
    else  {$tags .= "<tag k=\"railway\" v=\"tram\"/>";}}
  elsif ($lineHash{$item}{"RAC"} eq "24") {
    if ($lineHash{$item}{"OPC"} eq "名古屋ガイドウェイバス") 
      {$tags .= "<tag k=\"highway\" v=\"bus_guideway\"/>";}
    else  {$tags .= "<tag k=\"railway\" v=\"light_rail\"/>";}
  }
  else  {
    printf "Railway Class Code Error (RAC): ID=%d RAC=%s"
      , $negative_id, $lineHash{$item}{"RAC"};
    printf LOG 
      "Railway Class Code Error (RAC): ID=%d RAC=%s INT=%s OPC=%s LIN=%s \n"
      , $negative_id, $lineHash{$item}{"RAC"}, $lineHash{$item}{"INT"}
      , $lineHash{$item}{"OPC"}, $lineHash{$item}{"LIN"};
    $tags .= "<tag k=\"railway\" v=\"rail\"/>";
  }

  my $way 
    = sprintf("<way id=\"%d\" action=\"modify\" visible=\"true\">$node_ref$tags</way>"
    , $negative_id);
  print OSM "$way\n";
  $num_ways++;
  printf LOG 
    "Way %d: %d nodes RAC=%s INT=%s OPC=%s LIN=%s \n"
      , $negative_id, $i, $lineHash{$item}{"RAC"}
      , $lineHash{$item}{"INT"}, $lineHash{$item}{"OPC"}
      , $lineHash{$item}{"LIN"};
  $node_ref = "";
}


# run this script.

main();


# end of script