Created
April 30, 2015 17:32
-
-
Save 667bdrm/33989e7fe9d751dd3968 to your computer and use it in GitHub Desktop.
car-online.ru vehicle tracking service data to gpx converter / openstreetmap uploader
This file contains hidden or 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 | |
# | |
# caronline.pl | |
# | |
# car-online.ru data to gpx converter / openstreetmap uploader | |
# | |
# (c) 2009, https://gist.github.com/667bdrm | |
# | |
use Getopt::Long; | |
use Pod::Usage; | |
use HTTP::Request::Common; | |
use LWP::UserAgent; | |
use XML::LibXML; | |
my $cfgFile = ""; | |
my $cfgUser = ""; | |
my $cfgPass = ""; | |
my $cfgHost = ""; | |
my $cfgPort = ""; | |
my $cfgTplName = ""; | |
my $cfgGPXfile = ""; | |
my $cfgXslFile = ""; | |
my $cfgOutputFile = ""; | |
my $coAPIUrl = "http://export.car-online.ru"; | |
my $coAPIPattern = 189; | |
my $coAPIKey = ""; | |
my $osmAPIUrl = "http://www.openstreetmap.org"; | |
my $osmAPILogin = ""; | |
my $osmAPIPass = ""; | |
my $updateOSM = 0; | |
my $dataSource = "gpx"; | |
my $gpxFile = 'test.gpx'; | |
my $man = 0; | |
my $help = 0; | |
my $result = GetOptions ( | |
"help|h" => \$help, | |
"outputfile|of|o=s" => \$gpxFile, | |
"apikey|a=s" => \$coAPIKey, | |
"copattern|p=s" => \$coAPIPattern, | |
"courl=s" => \$coAPIUrl, | |
"osmurl=s" => \$osmAPIUrl, | |
"updateosm" => \$updateOSM, | |
"osmuser|ou=s" => \$osmAPILogin, | |
"osmpass|op=s" => \$osmAPIPass, | |
"datasource|ds=s" => \$dataSource, | |
"costartdate=s" => \$coStartDate, | |
"coenddate=s" => \$coEndDate, | |
); | |
pod2usage(1) if ($help); | |
if ($updateOSM and !($osmAPILogin and $osmAPIPass)) { | |
print STDERR "You must set OpenStreetMap.org login and password!\n"; | |
exit(0); | |
} | |
$ua = LWP::UserAgent->new; | |
$ua->agent('Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; YPC 3.0.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)'); | |
$ua->env_proxy; | |
if ($coStartDate) { | |
$coStartDate =~ /(\d+)\.(\d+)\.(\d{4})(\s+(\d{1-2}):(\d{1-2})(:(\d{1-2}))?)?/; | |
$hour = 0; | |
$hour = $5 if ($5); | |
$min = 0; | |
$min = $6 if ($6); | |
$sec = 0; | |
$sec = $8 if ($8); | |
$coStartDate = sprintf("%02d%02d%04d_%02d%02d%02d", $1, $2, $3, $hour, $min, $sec); | |
print STDERR "Start Date: $coStartDate\n"; | |
} | |
if ($coEndDate) { | |
$coEndDate =~ /(\d+)\.(\d+)\.(\d{4})(\s+(\d{1-2}):(\d{1-2})(:(\d{1-2}))?)?/; | |
$hour = 23; | |
$hour = $5 if ($5); | |
$min = 59; | |
$min = $6 if ($6); | |
$sec = 59; | |
$sec = $8 if ($8); | |
$coEndDate = sprintf("%02d%02d%04d_%02d%02d%02d", $1, $2, $3, $hour, $min, $sec); | |
print STDERR "End Date: $coEndDate\n"; | |
} | |
my $lastDate = ''; | |
$gpxUrl = $coAPIUrl . "/do?data=gpsPoints&skey=$coAPIKey&content=xml"; | |
if ($coAPIPattern) { | |
$gpxUrl .= "&pattern=$coAPIPattern"; | |
} | |
if ($coStartDate) { | |
$gpxUrl .= "&begin=$coStartDate"; | |
} | |
if ($coEndDate) { | |
$gpxUrl .= "&end=$coEndDate"; | |
} | |
print STDERR "Dumping car-online data...\n"; | |
my $response = $ua->get($gpxUrl); | |
if ($response->code==200) { | |
#my $doc = $parser->parsefile($gpxUrl); | |
my $doc = XML::LibXML->load_xml(string => $response->content); | |
my @points = $doc->getElementsByTagName('gps'); | |
my $totalPoints = $#points + 1; | |
print STDERR "Points: " . sprintf("%d", $totalPoints) . "\n"; | |
if ($totalPoints > 0) { | |
my $gpx = XML::LibXML::Document->new(); | |
print STDERR "Creating gpx-doc...\n"; | |
my $gpxDoc = $gpx->createElement('gpx'); | |
$gpxDoc->setAttribute('version', '1.0'); | |
$gpxDoc->setAttribute('creator', 'caronline.pl'); | |
$gpxDoc->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); | |
$gpxDoc->setAttribute('xmlns', 'http://www.topografix.com/GPX/1/0'); | |
$gpxDoc->setAttribute('xsi:schemaLocation', 'http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd'); | |
my $track = $gpx->createElement('trk'); | |
open(OUT, ">$gpxFile"); | |
my $trkseg = $gpx->createElement('trkseg'); | |
my $ptCount = 0; | |
foreach my $gps (@points) { | |
my $trackPoint = $gpx->createElement('trkpt'); | |
$trackPoint->setAttribute('lat', $gps->getAttribute('lat')); | |
$trackPoint->setAttribute('lon', $gps->getAttribute('lon')); | |
my $speed = $gpx->createElement('speed'); | |
$speed->appendChild($gpx->createTextNode($gps->getAttribute('speed'))); | |
$trackPoint->appendChild($speed); | |
my $hdop = $gpx->createElement('hdop'); | |
$hdop->appendChild($gpx->createTextNode($gps->getAttribute('hdop'))); | |
$trackPoint->appendChild($hdop); | |
my $course = $gpx->createElement('course'); | |
$course->appendChild($gpx->createTextNode($gps->getAttribute('course'))); | |
$trackPoint->appendChild($course); | |
my $coDateTime = $gps->getAttribute('date'); | |
$coDateTime =~ /(\d{2})(\d{2})(\d{4})_(\d{2})(\d{2})(\d{2})/; | |
my ($day,$mon,$year,$hour,$min,$sec) = ($1,$2,$3,$4,$5,$6); | |
my $datetime = "$year-$mon-$day"."T$hour:$min:$sec+03:00"; | |
$lastDate = $datetime; | |
my $time = $gpx->createElement('time'); | |
$time->appendChild($gpx->createTextNode($datetime)); | |
$trackPoint->appendChild($time); | |
# Adding raw NMEA string for reference | |
my $nmea = $gps->getAttribute('nmea'); | |
if ($nmea) { | |
my $gpxExt = $gpx->createElement('extensions'); | |
my $nmeaExt = $gpx->createElement('nmea'); | |
$nmeaExt->appendChild($gpx->createTextNode($nmea)); | |
$gpxExt->appendChild($nmeaExt); | |
$trackPoint->appendChild($gpxExt); | |
} | |
$trkseg->appendChild($trackPoint); | |
$ptCount++; | |
} | |
$track->appendChild($trkseg); | |
my $name = $gpx->createElement('name'); | |
$name->appendChild($gpx->createTextNode("Track $lastDate")); | |
$track->appendChild($name); | |
$gpxDoc->appendChild($track); | |
my $gpxData = $gpxDoc->toString(); | |
print STDERR "Writing gpx-file...\n"; | |
print OUT $gpxData; | |
close(OUT); | |
if ($updateOSM and $ptCount > 0) { | |
$ua = LWP::UserAgent->new; | |
$ua->credentials('www.openstreetmap.org:80','Web Password',$osmAPILogin, $osmAPIPass); | |
print STDERR "Uploading to OSM...\n"; | |
$response=$ua->request(POST 'http://www.openstreetmap.org/api/0.6/gpx/create', | |
Content_Type => 'form-data', | |
Content => [ | |
file =>[$gpxFile], | |
description=> "Track $lastDate", | |
tags => "", | |
visibility =>"private" ] | |
); | |
if ($response->code==200) { | |
print STDERR "GPX uploaded\n"; | |
} else { | |
print STDERR "GPX upload failed!\n"; | |
} | |
} | |
} | |
} else { | |
print "Error getting track data: $!\n"; | |
exit(0); | |
} | |
1; | |
__END__ | |
=head1 NAME | |
./caronline.pl - utility for working with caronline data | |
=head1 SYNOPSIS | |
./caronline.pl [options] [<gpx file>] | |
=head1 OPTIONS | |
=over 8 | |
=item B<-help> | |
Print a brief help message and exits. | |
=item B<-of> | |
Path to output file filename. | |
=item B<-apikey> | |
car-online.ru API key, providede by car-online.ru | |
=item B<-copattern> | |
car-online.ru pattern, used for getting more detalized gpx data | |
=item B<-courl> | |
car-online.ru API url, default http://export.car-online.ru | |
=item B<-osmurl> | |
openstreetmap.org upload url, default http://www.openstreetmap.org | |
=item B<-updateosm> | |
Upload track to www.openstreetmap.org | |
=item B<-osmuser> | |
openstreetmap.org user login | |
=item B<-osmpass> | |
openstreetmap.org user password | |
=item B<-datasource> | |
Data source: gpx = gpxfile, caronline = caronline.ru | |
=item B<-costartdate> | |
car-online.ru track start date and time | |
=item B<-coenddate> | |
car-online.ru track end date and time | |
=back | |
=head1 DESCRIPTION | |
B<This program> will upload track to openstreetmap.org. | |
=cut |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment