Created
September 5, 2012 11:06
-
-
Save andrewharvey/3635081 to your computer and use it in GitHub Desktop.
gtfs2osm - simple perl scripts to convert GTFS data into .osm files.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl -w | |
# This script converts a GTFS stops.txt into an OSM file. | |
# | |
# To the extent possible under law, the person who associated CC0 | |
# with this work has waived all copyright and related or neighboring | |
# rights to this work. | |
# http://creativecommons.org/publicdomain/zero/1.0/ | |
use strict; | |
use Text::CSV; | |
use XML::Writer; | |
use Encode; | |
use Switch; | |
if (scalar @ARGV < 2) { | |
print "Usage: $0 stops.txt stops.osm\n"; | |
exit 1; | |
} | |
my $csvfile = $ARGV[0]; | |
my $csv = Text::CSV->new ( { binary => 1, empty_is_undef => 1 } ) | |
or die "Cannot use CSV: ".Text::CSV->error_diag (); | |
# stops.txt has a BOM marker which we need to properly handle otherwise our | |
# first key from the CSV header will have the BOM in as part of the first key! | |
use File::BOM(); | |
open my $csvfh, "< :utf8 :via(File::BOM)", $csvfile or die "$csvfile: $!"; | |
my $xmlout = new IO::File(">$ARGV[1]"); | |
my $xmlwriter = new XML::Writer(OUTPUT => $xmlout, NEWLINES => 'true'); | |
# remap the CSV keys using this hash. | |
# note that all keys not mentioned here will be dropped so if you want | |
# some left as is, map them to themselfs (i.e. same key and value in the hash) | |
my %key_map = ("stop_name" => "name"); | |
# add new tags to created objects from this hash | |
my %new_map = ( | |
'source' => 'TDX', | |
'attribution' => 'NSW Government (Transport for NSW)', | |
'license' => 'https://tdx.131500.com.au/terms-conditions.php' | |
); | |
$csv->column_names($csv->getline($csvfh)); | |
$xmlwriter->xmlDecl("UTF-8"); | |
#start the XML file | |
$xmlwriter->startTag("osm", "version" => "0.6"); | |
my $node_id = 0; | |
my $default_attr = 'visible="true" version="1"'; | |
sub tag($$) { | |
my ($key, $value) = @_; | |
$xmlwriter->emptyTag('tag', 'k' => encode('utf8', $key), 'v' => encode('utf8', $value)); | |
} | |
#read through the input CSV file | |
while ( my $row_hash = $csv->getline_hr( $csvfh ) ) { | |
my $x = $row_hash->{'stop_lon'}; | |
my $y = $row_hash->{'stop_lat'}; | |
if (defined $x && defined $y) { | |
$node_id--; | |
$xmlwriter->startTag('node', 'id' => $node_id, 'lat' => $y, 'lon' => $x, 'visible' => 'true', 'version' => '1'); | |
foreach my $key (keys %{ $row_hash } ) { | |
my $value = $row_hash->{$key}; | |
# if the value for this property is defined | |
if (defined $value) { | |
# if direct mapping was defined | |
if (exists $key_map{$key}) { | |
$key = $key_map{$key}; | |
tag($key, $value); | |
} else { | |
switch ($key) { | |
case "wheelchair_boarding" { | |
switch ($value) { | |
case "0" { # Unknown | |
} | |
case "1" { # Accessible | |
tag('wheelchair', 'yes'); | |
} | |
case "2" { # Inaccessible | |
tag('wheelchair', 'no'); | |
} | |
} | |
} | |
case "stop_id" { | |
if ($value =~ /^CR_/) { | |
tag('operator', 'Sydney Trains'); | |
tag('railway', 'platform'); | |
} elsif ($value =~ /^PST/) { | |
tag('railway', 'station'); | |
} else { | |
# FIXME this could be wrong sometimes but I don't | |
# see any better way... the data doesn't provide any | |
# definitive way to distinguish between a bus_stop | |
# and ferry terminal. | |
# | |
# For example, | |
# | |
# This is actually a bus_stop | |
# Barrenjoey Rd Opp Palm Beach Wharf | |
# | |
# This is actually a ferry terminal | |
# Wagstaffe Wharf | |
if (($row_hash->{'stop_name'} =~ /Wharf$/) && | |
($row_hash->{'stop_name'} !~ /(Near|Opp)/)) { | |
tag('amenity', 'ferry_terminal'); | |
} else { | |
tag('highway', 'bus_stop'); | |
} | |
} | |
} | |
case "stop_code" { | |
tag('ref:tsn', $value); | |
} | |
} | |
} | |
} | |
} | |
# add new tags | |
foreach my $new_key (keys %new_map) { | |
$xmlwriter->emptyTag('tag', 'k' => encode('utf8', $new_key), 'v' => encode('utf8', $new_map{$new_key})); | |
} | |
$xmlwriter->endTag('node'); | |
} | |
} | |
#finish the XML file and exit | |
$xmlwriter->endTag("osm"); | |
$xmlwriter->end(); | |
$xmlout->close(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment