#!/usr/bin/perl

# DATA STRUCTURE
# --------------
#
# NODES:
#   * represented as hashes with keys "id", "lat", "lon", "tags",
#     "layer", and "ways"
#     where "tags" is a hash ref and "ways" is an array ref,
#     containing way references (not way ids)
#   * stored in global hash $node_storage (key: node id)
# WAYS:
#   * represented as hashes with "id", "tags", "nodes"
#     where "tags" is a hash ref and "nodes" is an array ref,
#     containing node references (not node ids)
#   * stored in global hash $way_storage (key: way id)
# RELATIONS:
#   * represented as hashes with "id", "tags", "members"
#     where "tags" is a hash ref and "members" is an array ref,
#     each element again an array reference with two elements
#     (role and object reference)
#   * stored in global hash $relation_storage (key: relation id)
#
# INDEXES:
#   * $index_node_keys is a hash with one key for each tag key
#     present in nodes, the value is an array of node references
#   * $index_way_keys the same for way tag keys
#   * each object has a "relations" hash element whose value is
#     an array of ($role,$relation_ref) pairs
#
# LICENSE
# -------
#
# Written by Patrick 'Petschge' Kilian <osm@petschge.de> using code from orp
# which was written by Frederik Ramm <frederik@remote.org>, as a complete
# re-write of osmarender.xsl.
#
# osmarender.xsl is Copyright (C) 2006-2007  Etienne Cherdlu, Jochen Topf
# and released under GPL v2 or later.
#
# This program does not contain code from the original osmarender.xsl
# but since the logic has been copied from Osmarender, it is safe to
# assume that this triggers the viral element of the GPL, making orp.pl
# GPL v2 or later also. (It would have been Public Domain otherwise.)
#
# -----------------------------------------------------------------------------
use strict;
use warnings;
use bytes;

use XML::Parser::PerlSAX ();
use XML::XPath ();
use XML::XPath::XMLParser ();
use Math::Trig qw(great_circle_distance deg2rad pi);
use Set::Object ();
use Getopt::Long qw(GetOptions);
use XML::Writer ();
use IO::File ();
use FindBin qw($Bin);
use lib $Bin;
use SAXOsmHandler ();


our $node_storage = {};
our $way_storage = {};
our $relation_storage = {};

my $handler = SAXOsmHandler->new($node_storage, $way_storage, $relation_storage);
my $parser = XML::Parser::PerlSAX->new(Handler => $handler);
print("data file must be specified in rule or on command line\n") if (scalar(@ARGV) == 0);
my $input_file = $ARGV[0];

# parse the OSM input file and store data in $node_storage,
# $way_storage, $relation_storage.
my %parser_args = (Source => {SystemId => $input_file});
$parser->parse(%parser_args);
print "input file parsed\n";

foreach (values(%$way_storage)) {
	my @nodes = @{$_->{"nodes"}};
	if($nodes[0] == $nodes[-1]) {
		my $wayid = $_->{"id"};
		my $nodecount = scalar(@nodes);
		my $area = 0;
		for(my $i = 0; $i < $nodecount - 1; $i++) {
			$area += ($nodes[$i]->{"lat"})*($nodes[$i+1]->{"lon"}) - ($nodes[$i+1]->{"lat"})*($nodes[$i]->{"lon"});
		}
		$area += ($nodes[-1]->{"lat"})*($nodes[0]->{"lon"}) - ($nodes[0]->{"lat"})*($nodes[-1]->{"lon"});
		$area = sqrt($area * $area) / 2;
#		print("way $wayid has $nodecount nodes and an area of $area\n");
		print("way area of $area\n");
	}
}

foreach (values(%$relation_storage)) {
	my $relid = $_->{"id"};
	my @members = @{$_->{"members"}};
	my $memberscount = scalar(@members);
	my @ways = ();

	for(my $i = 0; $i < $memberscount; $i++) {
		my ($type, $id) = split(/:/, $members[$i][1]);
		if ($type eq 'way') {
			if(defined($way_storage->{$id})){
				push(@ways, $way_storage->{$id});
			}
		}
	}

	my $waycount = scalar(@ways);
	#print("relation $relid with $memberscount members and $waycount ways\n");

	my $nexti = 0;
	my @allnodes =();
	for(my $i = 0; $i < $waycount; $i++) {
		my $thisi = $nexti;
		my @nodes = @{ $ways[$thisi]->{"nodes"} };
		my $flat = $nodes[0]->{"lat"};
		my $flon = $nodes[0]->{"lon"};
		my $llat = $nodes[-1]->{"lat"};
		my $llon = $nodes[-1]->{"lon"};
		@allnodes = (@allnodes, @nodes);
		#print "way $thisi from $flat , $flon to $llat , $llon \n";
		my $wc = scalar(@ways);
		for(my $j = 0; $j < $wc; $j++) {
			my @n = @{ $ways[$j]->{"nodes"} };
			my $lat = $n[0]->{"lat"};
			my $lon = $n[0]->{"lon"};
			if($lat == $llat && $lon == $llon) {
				$nexti = $j;
				#print "nexti is $j\n";
			}
		}
		if($thisi == $nexti) {
			#print "Can't continue route\n";
			last;
		}
	}

	if( $allnodes[0]->{"lon"} == $allnodes[-1]->{"lon"} ) {
		if( $allnodes[0]->{"lat"} == $allnodes[-1]->{"lat"} ) {
			#print "Relation is closed\n";
			my $nodecount = scalar(@allnodes);
			my $area = 0;
			for(my $i = 0; $i < $nodecount - 1; $i++) {
				$area += ($allnodes[$i]->{"lat"})*($allnodes[$i+1]->{"lon"}) - ($allnodes[$i+1]->{"lat"})*($allnodes[$i]->{"lon"});
			}
			$area += ($allnodes[-1]->{"lat"})*($allnodes[0]->{"lon"}) - ($allnodes[0]->{"lat"})*($allnodes[-1]->{"lon"});
			$area = sqrt($area * $area) / 2;
			print("relation area of $area\n");
		}
	}
}
