#!/usr/bin/perl -w

use strict;
use warnings;

use OSM::osm;

my $wayId ; 
my $wayUser ; my @wayIds; my @wayNodes ; my @wayTags ;
my $nodeId ; 
my $nodeUser ; my $nodeLat ; my $nodeLon ; my @nodeTags ;
my $aRef1 ; my $aRef2 ;
my $wayCount = 0 ;

my $file;
my $tag1;
my %wayNodesHash;
my %wayTagsHash;
my %Nodes;
my @neededNodes;

my $osmPath="$ENV{HOME}/osm/data";
my $fileName="mecklenburg-vorpommern.osm";

my @highwayTypes=("motorway", "trunk", "primary", "secondary", "tertiary");

openOsmFile(join("/", $osmPath, $fileName));

print STDERR "skipping nodes ...";
skipNodes();
print STDERR " done\n";


print STDERR "building ways hash ...";
($wayId, $wayUser, $aRef1, $aRef2) = getWay () ;
if ($wayId != -1) {
    @wayNodes = @$aRef1 ;
    @wayTags = @$aRef2 ;
}
while ($wayId != -1) {	
    if (scalar (@wayNodes) >= 3) {
	my $found = 0 ;
	foreach $tag1 (@wayTags) {
	    {
		foreach my $val(@highwayTypes) {
		    $found = 1 if (grep /highway:$val/, $tag1) ;
		}
	    }
	    if ($found) {
		$wayCount++;
		push @wayIds, $wayId;  
		@{$wayNodesHash{$wayId}} = @wayNodes ;
		@{$wayTagsHash{$wayId}} = @wayTags ;
		push @neededNodes, @wayNodes ;
	    }
	}
    }
    # next way
    ($wayId, $wayUser, $aRef1, $aRef2) = getWay () ;
    if ($wayId != -1) {
	@wayNodes = @$aRef1 ;
	@wayTags = @$aRef2 ;
    }
}
print STDERR " done\n";

closeOsmFile();

###  Jetzt ist @NeededNodes mit den IDs der Nodes bevölkert,
###  an denen wir interessiert sind. Jetzt müsste ein Hash
###  mit den Koordinaten dieser Nodes generiert werden.

openOsmFile(join("/", $osmPath, $fileName));

print STDERR "building nodes hash ...";
my ($gId, $gLon, $gLat, $gU, $gTags) = getNode() ;
while ($gId != -1) {	
    foreach my $nN(@neededNodes) {
	if ($gId == $nN) {
	    @{ $Nodes{$nN} } = ($gLon, $gLat, $gU, $gTags);
	    last;
	}
    }
    ($gId, $gLon, $gLat, $gU, $gTags) = getNode() ;
}
print STDERR " done\n";

closeOsmFile();

###  Schließlich werden alle gespeicherten Ways durchgegangen
###  und folgende Daten rausgeschrieben:
###  wayID   highway   name   nodeID   lat   lon   cosangle   distances

print STDERR "exporting ...";
print(join "\t", "wayId", "highway", "name", 
      "nodeId", "lat", "lon", "angle", "lengths");
for my $wayId(@wayIds) {
    my $highway = '';
    my $ref = '';
    my $name = '';
    for my $wayTag(@{ $wayTagsHash{$wayId} }) {
	if (grep(/^highway/, $wayTag)) {
	    $highway = $wayTag;
	    $highway =~ s/^highway://;
	} elsif (grep(/^name/, $wayTag)) {
	    $name = $wayTag;
	    $name =~ s/^name://;
	} elsif (grep(/^ref/, $wayTag)) {
	    $ref = $wayTag;
	    $ref =~ s/^ref://;
    }
    }
    if ($name) {
	if ($ref) {
	    $name = "$name ($ref)";
	}
    }
    else {
	if ($ref) {
	    $name = $ref;
	} else {
	    $name = "UNNAMED";	
	}
    }
    my $nodeId_1 = -1;
    my $nodeId_2 = -1;
    foreach $nodeId(@{ $wayNodesHash{$wayId} }) {
	if ($nodeId_2 > -1) {
	    my ($x1, $y1) = @{ $Nodes{$nodeId_2} }[0..1];
	    my ($x2, $y2) = @{ $Nodes{$nodeId_1} }[0..1];
	    my ($x3, $y3) = @{ $Nodes{$nodeId} }[0..1];
	    my $cosangle = cosangle($x1, $y1, $x2, $y2, $x3, $y3);
	    my $distances = distance($x1, $y1, $x2, $y2) * 
		distance($x2, $y2, $x3, $y3);
	    my $lat = $y2 * 111.11;
	    my $lon = $x2 * cos ( $y2 / 360 * 3.14 * 2 ) * 111.11;
	    print join("\t", $wayId, $highway, $name, $nodeId_1, 
		       $lat, $lon, $cosangle, $distances);
	    print "\n";
	}
	$nodeId_2 = $nodeId_1;
	$nodeId_1 = $nodeId;
    }
}
print STDERR " done\n";


sub vector {
    my ($x1, $y1, $x2, $y2) = @_ ;
    my ($d_lat) = ($y2 - $y1) * 111.11 ;
    my ($d_lon) = ($x2 - $x1) * cos ( $y1 / 360 * 3.14 * 2 ) * 111.11;
    return ($d_lat, $d_lon) ;
}

sub distance {
    my ($d_lat, $d_lon) = vector (@_);
    return(sqrt ($d_lat*$d_lat+$d_lon*$d_lon));
}

sub cosangle {
    my ($x1, $y1, $x2, $y2, $x3, $y3) = @_ ;
    if (($x1 == $x2 && $y1 == $y2) || ($x2 == $x3 && $y2 == $y3)) {
	warn "two nodes in way with same coordinates";
	return 0;
    }
    my ($d_lat1, $d_lon1) = vector($x1, $y1, $x2, $y2);
    my ($d_lat2, $d_lon2) = vector($x2, $y2, $x3, $y3);
    return(($d_lat1*$d_lat2 + $d_lon1*$d_lon2) / 
	   sqrt(($d_lat1*$d_lat1+$d_lon1*$d_lon1) *
		($d_lat2*$d_lat2+$d_lon2*$d_lon2)));
}
