summaryrefslogtreecommitdiff
path: root/navit/script
diff options
context:
space:
mode:
Diffstat (limited to 'navit/script')
-rw-r--r--navit/script/osm2navit_sea/osm2navit_sea.pl1010
-rw-r--r--navit/script/osm2navit_sea/way.pm121
2 files changed, 0 insertions, 1131 deletions
diff --git a/navit/script/osm2navit_sea/osm2navit_sea.pl b/navit/script/osm2navit_sea/osm2navit_sea.pl
deleted file mode 100644
index a65c74d78..000000000
--- a/navit/script/osm2navit_sea/osm2navit_sea.pl
+++ /dev/null
@@ -1,1010 +0,0 @@
-#!/usr/bin/perl -w
-#
-# Vincent "latouche" Touchard, vtouchar@latouche.info
-# 2008/09/10
-#
-# Transform a .osm file adding polygons representing the sea and islands.
-# The sea is a way with the tag natural=coastline_outer and the islands are
-# ways with the tag natural=coastline_inner.
-# Adding those tags to osm2navit allow the see to be viewed by navit
-#
-# To avoid big polygons, the map is divided into small tiles (0.5°x0.5°)
-#
-# usage:
-# osm2navit_sea.pl minlat minlon maxlat maxlon source_file output_file
-#
-# license: GPL
-#
-# history:
-# v1: first release
-# v2: 2008/09/06
-# - map split into tiles of 0.5x0.5°
-# v3: 2008/09/10
-# - detects islands vs lakes
-# takes each polygon and try to find is it is inside an other one. If true,
-# it is an island, if not, it is the sea. Should be a little more clever to detect
-# lake (tagged as natural=coastline instead of natural=water) inside islands.
-# This algo is not perfect but works in most cases
-# - sea tile with no way crossing are now drawn in a more clever way:
-# a node for each corner is added to nodes arrays and a way linking those
-# node is added. Those components are then added to the output file during
-# the last section of this script. This allow to detects islands in such tiles
-# as islands and not sea
-# v4: 2009/03/14
-# - new way to compute the intersection of a segment and the border of a tile
-# - don't use nodes that are out of the bbox specified as argument
-# - use lazy regex to parse the .osm file
-#
-# TODO:
-# - better lookup_handler (cf this fuction for more info)
-# - detect clockwise/anticlockwise ways => sea or land
-# for now -> every closed area is considered as land which is false.
-# some lakes are tags as natural=coastline instead of natural=water
-# ==> done, the algo should be improved for better results
-
-use strict;
-use warnings;
-
-use Math::Trig;
-use POSIX qw(ceil);
-use way;
-
-# lon € [-180, 180]
-# lat € [-85.0511, 85.0511]
-if ( @ARGV ne 6 ||
- abs($ARGV[0]) > 85.0511 || abs($ARGV[2]) > 85.0511 ||
- abs($ARGV[1]) > 180 || abs($ARGV[3]) > 180) {
- print "Usage: osm2navit_sea.pl minlat minlon maxlat maxlon source_file output_file\n";
- exit(1);
-}
-
-
-my $source=$ARGV[4];
-my $destination=$ARGV[5];
-
-my ($minlat, $minlong, $maxlat, $maxlong);
-my ($minlat2, $minlong2, $maxlat2, $maxlong2);
-
-$minlat=$ARGV[0];
-$minlong=$ARGV[1];
-$maxlat=$ARGV[2];
-$maxlong=$ARGV[3];
-
-#$minlat2=int($minlat*2)/2;
-#$minlong2=int($minlong*2)/2;
-#$maxlat2=ceil($maxlat*2)/2;
-#$maxlong2=ceil($maxlong*2)/2;
-
-$minlat2=$minlat;
-$minlong2=$minlong;
-$maxlat2=$maxlat;
-$maxlong2=$maxlong;
-
-
-#$rect_length=2*abs($maxlong-$minlong) + 2*abs($maxlat-$minlat);
-#
-#push (@corner_rect2lin, 0);
-#push (@corner_rect2lin, abs($maxlong-$minlong));
-#push (@corner_rect2lin, abs($maxlong-$minlong) + abs($maxlat-$minlat));
-#push (@corner_rect2lin, $rect_length - abs($maxlat-$minlat));
-
-my $osm_id=-1;
-
-my (%new_ways, %nodes, %ways, %tiles, @new_nodes);
-
-my ($i, $j, $way, $node, $tile);
-
-my $debug=0;
-
-sub debug {
- print shift if ( $debug );
-}
-
-# project a node on a bounding box
-sub get_projection {
- my ($lat, $lon, $minlat, $minlon, $maxlat, $maxlon) = @_;
-
- my ($a, $b, $c, $d);
-
- $a = abs( $lat - $minlat);
- $b = abs( $lat - $maxlat);
- $c = abs( $lon - $minlon);
- $d = abs( $lon - $maxlon);
-
-
- if ( $a <= $b ) {
- if ( $a <= $c ) {
- if ( $a <= $d ) {
- # a
- $lat=$minlat;
- #$lon=$node->{"lon"};
- } else {
- # d
- #$lat=$node->{"lat"};
- $lon=$maxlon;
- }
- } else {
- if ( $c <= $d ) {
- # c
- #$lat=$node->{"lat"};
- $lon=$minlon;
- } else {
- #d
- #$lat=$node->{"lat"};
- $lon=$maxlon;
- }
- }
- } else {
- if ( $b <= $c ) {
- if ( $b <= $d ) {
- #b
- $lat=$maxlat;
- #$lon=$node->{"lon"};
- } else {
- # d
- #$lat=$node->{"lat"};
- $lon=$maxlon;
- }
- } else {
- if ( $c <= $d ) {
- # c
- #$lat=$node->{"lat"};
- $lon=$minlon;
- } else {
- #d
- #$lat=$node->{"lat};
- $lon=$maxlon;
- }
- }
- }
-
- return (($lat, $lon));
-}
-
-# Projet a node on a rectangle to a segment
-sub get_proj_rect2lin {
- my ($lat, $lon, $minlat, $minlon, $maxlat, $maxlon) = @_;
-
-
- if ($lat eq $maxlat) {
- return abs($minlon - $lon);
- } else {
- if ($lon eq $maxlon) {
- return abs($maxlon-$minlon) + abs($maxlat - $lat);
- } else {
- if ($lat eq $minlat) {
- return abs($maxlon-$minlon) + abs($maxlat-$minlat) + abs($maxlon-$lon);
- } else {
- return 2*abs($maxlon-$minlon) + abs($maxlat-$minlat) + abs($minlat - $lat);
- }
- }
- }
-}
-
-# projet a node from a segment to a rectangle
-sub getnode_proj_lin2rect {
- my ($length, $minlat, $minlon, $maxlat, $maxlon) = @_;
- my ($lat, $lon);
-
- if ( $length > 2*abs($maxlon-$minlon) + abs($maxlat-$minlat)) {
- $lat = ($minlat + $length - 2*abs($maxlon-$minlon) - abs($maxlat-$minlat));
- $lon = ($minlon);
- } else {
- if ( $length > abs($maxlon-$minlon) + abs($maxlat-$minlat)) {
- $lat = ($minlat);
- $lon = ($maxlon - $length + abs($maxlon-$minlon) + abs($maxlat-$minlat));
- } else {
- if ( $length > abs($maxlon-$minlon)) {
- $lat = ($maxlat - $length + abs($maxlon-$minlon));
- $lon = ($maxlon);
- } else {
- $lat = ($maxlat);
- $lon = ($minlon + $length);
- }
- }
- }
-
- return (($lat, $lon));
-}
-
-
-
-# get the distance between to nodes on the same rectangle
-sub get_path_length {
- my ($lat1, $lon1, $lat2, $lon2, @box) = @_;
-
- my ($a, $b, $rect_length, $dist);
-
-
- $a = get_proj_rect2lin ( $lat1, $lon1, @box);
- $b = get_proj_rect2lin ( $lat2, $lon2, @box);
-
- $dist = $b - $a;
- $rect_length = 2*abs( $box[2] - $box[0]) + 2*abs( $box[3] - $box[1]);
- return $dist > 0 ? $dist : $dist + $rect_length;
-}
-
-# get the nodes to go through to join an other node over a rectangle
-sub get_path {
- my ($lat1, $lon1, $lat2, $lon2, @box) = @_;
-
- my ($a, $b, $rect_length, $dist, @corner_rect2lin);
- my @path=();
-
- $a = get_proj_rect2lin ( $lat1, $lon1, @box);
- $b = get_proj_rect2lin ( $lat2, $lon2, @box);
-
- $rect_length = 2*abs( $box[2] - $box[0]) + 2*abs( $box[3] - $box[1]);
-
- $dist = $b - $a;
- if ($dist <0) {
- $b+=$rect_length;
- }
-
- @corner_rect2lin = ( 0,
- abs( $box[3] - $box[1]),
- abs( $box[3] - $box[1]) + abs( $box[2] - $box[0]),
- $rect_length - abs( $box[2] - $box[0]));
-
- foreach (@corner_rect2lin) {
- if ($_ > $a && $_ < $b) {
- my ($lat, $lon) = getnode_proj_lin2rect ($_, @box);
- push (@path, {"lat" => $lat, "lon" => $lon});
- }
- }
-
- foreach (@corner_rect2lin) {
- if ($_ + $rect_length > $a && $_ + $rect_length < $b) {
- my ($lat, $lon) = getnode_proj_lin2rect ($_, @box);
- push (@path, {"lat" => $lat, "lon" => $lon});
- }
- }
-
-
- return @path;
-}
-
-# type of tile at zoom12 (land, sea, both, unknown.
-# Uses oceantiles_12.dat for tiles@home project
-# it checks the tile at level 12 containing the point ($lat, $lon)
-# dx and dy are used to specify an offset: read tile (x+dx, y+dy)
-# A more clever way whould be to check all the tile contained in and area
-# and guess the final type
-# one sea or more => sea
-# one land or more => land
-# only both or unknown => since tiles are quite big, should be land
-#
-sub lookup_handler {
- my ($lat, $lon, $dx, $dy) = @_;
-
- # http://wiki.openstreetmap.org/index.php/Slippy_map_tilenames
- # http://almien.co.uk/OSM/Tools/Coord
- my $zoom=12;
- # $tilex=int( ( $minlon +180)/360 *2**$zoom ) ;
- my $tilex=int( ( $lon +180)/360 *2**$zoom ) ;
- # $tiley=int( (1 - log(tan( $maxlat *pi/180) + sec( $maxlat *pi/180))/pi)/2 *2**$zoom ) ;
- my $tiley=int( (1 - log(tan( $lat *pi/180) + sec( $lat *pi/180))/pi)/2 *2**$zoom ) ;
-
-
- my $tileoffset = (($tiley+$dy) * (2**12)) + ($tilex+$dx);
-
- my $fh;
- open($fh, "<", "data/oceantiles_12.dat") or die ("Cannot open oceantiles_12.dat: $!");
-
-
- seek $fh, int($tileoffset / 4), 0;
- my $buffer;
- read $fh, $buffer, 1;
- $buffer = substr( $buffer."\0", 0, 1 );
- $buffer = unpack "B*", $buffer;
- my $str = substr( $buffer, 2*($tileoffset % 4), 2 );
-
- close($fh);
-
- #print "S" if $str eq "10";
- #print "L" if $str eq "01";
- #print "B" if $str eq "11";
- #print "?" if $str eq "00";
-
- return $str;
-}
-
-
-# return the intersection of a segment with the border of a tile
-sub intersec_way_tiles {
- my ($node_in_lat, $node_in_lon,
- $node_ext_lat,$node_ext_lon,
- $tile_minlat, $tile_minlon, $tile_maxlat, $tile_maxlon) = @_;
- my ($lat, $lon);
-
- debug "intersec_way_tiles - $node_in_lat, $node_in_lon && $node_ext_lat,$node_ext_lon && $tile_minlat, $tile_minlon, $tile_maxlat, $tile_maxlon\n";
-
- # case #1: node_ext above tile - try intersec with the top of the tile
- if ($node_ext_lat > $tile_maxlat || $node_ext_lat < $tile_minlat) {
- $lat = ($node_ext_lat > $tile_maxlat) ? $tile_maxlat : $tile_minlat;
- if ($node_in_lat != $node_ext_lat) {
- $lon = $node_in_lon + ($lat - $node_in_lat) * ($node_ext_lon - $node_in_lon) / ($node_ext_lat - $node_in_lat);
- } else { # node_ext == node
- $lon = $node_in_lon;
- }
- if ($lon > $tile_minlon && $lon < $tile_maxlon) {
- return ($lat, $lon);
- }
- }
- # case #2: node ext on the left or on the right of the tile
- if ($node_ext_lon > $tile_maxlon || $node_ext_lon < $tile_minlon) {
- $lon = ($node_ext_lon > $tile_maxlon) ? $tile_maxlon : $tile_minlon;
- if ($node_in_lon != $node_ext_lon) {
- $lat = $node_in_lat + ($lon - $node_in_lon) * ($node_ext_lat - $node_in_lat) / ($node_ext_lon - $node_in_lon); # thales
- } else { # node_ext == node
- $lat = $node_in_lat;
- }
- if ($lat > $tile_minlat && $lat < $tile_maxlat) {
- return ($lat, $lon);
- }
- }
-
- return ($node_ext_lat, $node_ext_lon);
-}
-
-# tells if a node is inside a polygon or not
-# not efficient a 100%, but quite good results
-# widely inspired from close-areas.pl from the T@h project
-sub polygon_contains_node {
- my ($way, $node) = @_;
-
-
- my $counter = 0;
-
- my @way_nodes = $way->nodes();
- my $p1 = $nodes{$way->first_node()};
- my $n = scalar(@way_nodes);
-
- for (my $i=1; $i < $n; $i++) {
- my $p2 = $nodes{$way_nodes[$i]};
-
- if ($node->{"lat"} > $p1->{"lat"} || $node->{"lat"} > $p2->{"lat"}) {
- if ($node->{"lat"} < $p1->{"lat"} || $node->{"lat"} < $p2->{"lat"}) {
- if ($node->{"lon"} < $p1->{"lon"} || $node->{"lon"} < $p2->{"lon"}) {
- if ($p1->{"lat"} != $p2->{"lat"}) {
- my $xint = ($node->{"lat"}-$p1->{"lat"})*($p2->{"lon"}-$p1->{"lon"})/($p2->{"lat"}-$p1->{"lat"})+$p1->{"lon"};
- if ($p1->{"lon"} == $p2->{"lon"} || $node->{"lon"} <= $xint) {
- $counter++;
- }
- }
- }
- }
- }
- $p1 = $p2;
- }
-
- return ($counter%2);
-}
-
-#################################
-print "initialising tiles\n";
-
-
-print "There will be ".ceil(abs($maxlong2-$minlong2)/0.5)."x".ceil(abs($maxlat2-$minlat2)/0.5)." tiles\n";
-
-my $nb_tiles_x = ceil(abs($maxlat2-$minlat2)/0.5);
-my $nb_tiles_y = ceil(abs($maxlong2-$minlong2)/0.5);
-
-for ($j=0; $j<$nb_tiles_x; $j++) {
- for ($i=0; $i<$nb_tiles_y; $i++) {
-
-
- my $type = lookup_handler ( $maxlat2-0.5*$j, $minlong2+0.5*$i, 0, 0);
-
- print "S" if $type eq "10";
- print "L" if $type eq "01";
- print "B" if $type eq "11";
- print "?" if $type eq "00";
- my $tile_maxlon = $minlong2+0.5*$i + 0.5 > $maxlong2 ? $maxlong2 : $minlong2+0.5*$i + 0.5;
- my $tile_minlat = $maxlat2-0.5*$j-0.5 < $minlat2 ? $minlat2 : $maxlat2-0.5*$j-0.5;
- $tiles{$nb_tiles_x * $i+$j} = { "minlon" => $minlong2+0.5*$i, "maxlat" => $maxlat2-0.5*$j,
- "maxlon" => $tile_maxlon, "minlat" => $tile_minlat,
- "type" => $type, "id" => ($nb_tiles_x * $i+$j), "crossed" => 0};
- }
- print "\n";
-}
-
-print "\n";
-
-
-
-################################
-# find coastlines and store the nodes id
-print "Reading osm source file\n";
-
-my $input;
-my $output;
-open($input, "<$source") or die "Can't open $source: $!";
-
-my $way_id=0;
-my $is_coastline=0;
-my @nodes;
-while (<$input>) {
-
- if ( /<way id=["'](\d+?)["']/) {
- $way_id=$1;
- $is_coastline=0;
- @nodes=();
- }
- if ($way_id != 0) {
- if ( /<nd ref=["'](\d+?)["']/) {
- push(@nodes, $1);
- }
- if ( /<tag k=["']natural["'] v=["']coastline["']/) {
- $is_coastline=1;
- }
- if ( /<\/way/ ) {
- # forget node with only one element -> disturb the algo
- if ( $is_coastline && scalar(@nodes) != 1 ) {
- my $way=way->new($way_id);
- $way->nodes(@nodes);
- debug( "found coastline ".$way->id()." from ".$way->first_node()." to ".$way->last_node()." with ".$way->size()." nodes\n");
- $ways{$way->id()}=$way;
- }
-
- $way_id=0;
- }
- }
-}
-
-close($input);
-
-
-
-
-###########################
-# to save memory, only retrieve usefull nodes
-print "Retrieving nodes:\n";
-
-$i=0;
-foreach (values %ways) {
- foreach ($_->nodes()) {
- $nodes{$_}={};
- $i++;
- }
-}
-debug("Created $i nodes\n");
-
-open($input, "<$source") or die "Can't open $source: $!";
-open($output, ">$destination") or die "Can't open $destination: $!";
-
-$i=0;
-while (<$input>) {
- if ( /<node id=['"](\d+?)['"].* lat=['"](.+?)['"] lon=['"](.+?)['"]/ ) {
- if ( exists($nodes{$1}) ) {
- $nodes{$1}->{"id"}=$1;
- $nodes{$1}->{"lat"}=$2;
- $nodes{$1}->{"lon"}=$3;
- $i++;
- }
- }
- print $output $_ unless ( /<\/osm>/ );
-}
-close($input);
-
-debug("Retrieved $i nodes\n");
-
-
-
-############################
-# If the bounding box given as arguments to the program is smaller than the one used to generate
-# the input file, some nodes may be outside -> check for this before adding them to a tile
-print "Spliting data into tiles:\n";
-
-
-foreach $way (values %ways) {
- #print "following new way\n";
-
- my $new_way = way->new($osm_id--);
- my @way_nodes = ();
- my ($tile_id, $new_tile_id);
- $tile_id = -1;
- my $prev_node;
-
- foreach $node ($way->nodes()) {
-
- # node out of bbox -> skip the nodes until we reenter the bbox
- if ($nodes{$node}->{"lat"} < $minlat2 || $nodes{$node}->{"lat"} > $maxlat2
- || $nodes{$node}->{"lon"} < $minlong2 || $nodes{$node}->{"lon"} > $maxlong2) {
-
- # previous node already skiped or 1st node out of the bbox
- if ( $tile_id == -1 ) {
- $prev_node = $node;
-
-
- } else { # previous node in bbox, we add a node at the intersection of the current tile border and the segment [$node, $prev_node]
-
- # find the intersection of the current way with the tiles
- my $tile = $tiles{$tile_id};
- my ($lat, $lon) = intersec_way_tiles (
- $nodes{$prev_node}->{"lat"}, $nodes{$prev_node}->{"lon"},
- $nodes{$node}->{"lat"}, $nodes{$node}->{"lon"},
- $tile->{"minlat"}, $tile->{"minlon"}, $tile->{"maxlat"}, $tile->{"maxlon"});
- my $mid_node = {"lat" => $lat, "lon" => $lon, "id" => $osm_id-- };
-
- $nodes{ $mid_node->{"id"} } = $mid_node;
- push( @new_nodes, $mid_node );
-
- push ( @way_nodes, $mid_node->{"id"} );
-
- # end way here
- $new_way->nodes(@way_nodes);
- $new_ways{$new_way->id()} = $new_way;
- $ways{$new_way->id()} = $new_way;
- push( @{$tiles{$tile_id}->{"ways"}}, $new_way->id());
- $tiles{$tile_id}->{"crossed"}=1;
-
- # begin new way
- $new_way = way->new($osm_id--);
- @way_nodes = ();
-
- # reset title_id
- $tile_id = -1;
-
- }
- } else {
-
- my $tile_lat = int( ($maxlat2 - $nodes{$node}->{"lat"} ) / 0.5);
- my $tile_lon = int( ($nodes{$node}->{"lon"} - $minlong2) / 0.5);
- $new_tile_id = $nb_tiles_x * $tile_lon + $tile_lat;
-
- if ( $tile_id == -1 ) {
- $tile_id = $new_tile_id;
-
- # we have reentered a tile -> add a node on its border at the intersec of the segment [$prev_node, $node]
- if (defined $prev_node) {
- # find the intersection of the current way with the tiles
- my $tile = $tiles{$tile_id};
- my ($lat, $lon) = intersec_way_tiles (
- $nodes{$node}->{"lat"}, $nodes{$node}->{"lon"},
- $nodes{$prev_node}->{"lat"}, $nodes{$prev_node}->{"lon"},
- $tile->{"minlat"}, $tile->{"minlon"}, $tile->{"maxlat"}, $tile->{"maxlon"});
- my $mid_node = {"lat" => $lat, "lon" => $lon, "id" => $osm_id-- };
-
- $nodes{ $mid_node->{"id"} } = $mid_node;
- push( @new_nodes, $mid_node );
-
- push ( @way_nodes, $mid_node->{"id"} );
-
- $tiles{$tile_id}->{"crossed"}=1;
- }
- }
- # we have reach an other tile
- if ( $new_tile_id != $tile_id ) {
-
- my $tile = $tiles{$tile_id};
- my $new_tile = $tiles{$new_tile_id};
-
- # find the intersection of the way with the tiles
- my ($lat, $lon) = intersec_way_tiles (
- $nodes{$prev_node}->{"lat"}, $nodes{$prev_node}->{"lon"},
- $nodes{$node}->{"lat"}, $nodes{$node}->{"lon"},
- $tile->{"minlat"}, $tile->{"minlon"}, $tile->{"maxlat"}, $tile->{"maxlon"});
- my $mid_node = {"lat" => $lat, "lon" => $lon, "id" => $osm_id-- };
-
- $nodes{ $mid_node->{"id"} } = $mid_node;
- push( @new_nodes, $mid_node );
-
- push ( @way_nodes, $mid_node->{"id"} );
-
- $new_way->nodes(@way_nodes);
- $new_ways{$new_way->id()} = $new_way;
- $ways{$new_way->id()} = $new_way;
- push( @{$tiles{$tile_id}->{"ways"}}, $new_way->id());
-
- # set both new and old tile as crossed by a way
- # the new one is important because when we rich the end
- # of the coast, there will be no "next way" to set it as
- # crossed
- $tiles{$tile_id}->{"crossed"}=1;
- $tiles{$new_tile_id}->{"crossed"}=1;
-
- $new_way = way->new($osm_id--);
-
- @way_nodes=();
-
-
- # first node on tile border
- ($lat, $lon) = intersec_way_tiles (
- $nodes{$node}->{"lat"}, $nodes{$node}->{"lon"},
- $nodes{$prev_node}->{"lat"}, $nodes{$prev_node}->{"lon"},
- $new_tile->{"minlat"}, $new_tile->{"minlon"}, $new_tile->{"maxlat"}, $new_tile->{"maxlon"});
- my $mid_node2 = {"lat" => $lat, "lon" => $lon, "id" => $osm_id-- };
-
- $nodes{ $mid_node2->{"id"} } = $mid_node2;
- push( @new_nodes, $mid_node2 );
-
- push ( @way_nodes, $mid_node2->{"id"} );
-
- $tile_id = $new_tile_id;
- }
-
- push (@way_nodes, $node);
- #print "Node $node added to tile $tile_id\n";
- $prev_node=$node;
- }
- }
-
- # if new way not empty, add it
- if ( scalar(@way_nodes) > 1 && $tile_id != -1) {
- $new_way->nodes(@way_nodes);
- $new_ways{$new_way->id()} = $new_way;
- $ways{$new_way->id()} = $new_way;
- push( @{$tiles{$tile_id}->{"ways"}}, $new_way->id());
- }
-
- $way->distroy();
-
-}
-
-
-
-
-
-
-
-##############################################
-print "\n\nWorking on tiles:\n";
-
-
-#$tile = $tiles{54};
-foreach $tile (values %tiles) {
-
- print( "->tile: ".$tile->{"id"}."\n");
-
- my @box = ($tile->{"minlat"}, $tile->{"minlon"}, $tile->{"maxlat"}, $tile->{"maxlon"});
-
- # No way going through the tile -> guess if it is sea or lanf
- # SHould check if it containds nodes -> type unknown + nodes should mean sea + islands
- unless ($tile->{"crossed"}) {
- my $tile_is_sea=0;
-
- # 00 => unknown
- # 01 => land
- # 10 => sea
- # 11 => coast
-
- # water
- if ($tile->{"type"} eq "10") {
- $tile_is_sea=1;
-
- } elsif ($tile->{"type"} ne "01") { # not land
-
- my %temp = ("00"=>0, "10"=>0, "01"=>0, "11"=>0);
- $temp{lookup_handler($tile->{"maxlat"}, $tile->{"minlon"}, -1, 0)}++;
- $temp{lookup_handler($tile->{"maxlat"}, $tile->{"minlon"}, +1, 0)}++;
- $temp{lookup_handler($tile->{"maxlat"}, $tile->{"minlon"}, 0, -1)}++;
- $temp{lookup_handler($tile->{"maxlat"}, $tile->{"minlon"}, 0, +1)}++;
-
- if( $temp{"10"} > $temp{"01"} ) {
- $tile_is_sea=1;
- } elsif ( ($tile->{"type"} eq "11") and ( $temp{"01"} == 0 ) ) {
- # if the tile is marked coast but no land near, assume it's a group of islands instead of lakes.
- $tile_is_sea=1;
- } # else = land
-
- }
-
- # add nodes and a way to draw the sea all over the tile
- if ($tile_is_sea) {
- my @way_nodes_id = ( $osm_id, $osm_id-1, $osm_id-2, $osm_id-3);
- my @way_nodes = (
- { "lat" => $tile->{"maxlat"}, "lon" => $tile->{"minlon"}, "id" => $osm_id--},
- { "lat" => $tile->{"maxlat"}, "lon" => $tile->{"maxlon"}, "id" => $osm_id--},
- { "lat" => $tile->{"minlat"}, "lon" => $tile->{"maxlon"}, "id" => $osm_id--},
- { "lat" => $tile->{"minlat"}, "lon" => $tile->{"minlon"}, "id" => $osm_id--});
-
- my $way = way->new($osm_id--);
- $way->nodes(@way_nodes_id);
-
- push( @new_nodes, @way_nodes );
- foreach (@way_nodes) {
- $nodes{$_->{"id"}} = $_;
- }
-
- $new_ways{$way->id()} = $way;
- $ways{$way->id()} = $way;
- push( @{$tile->{"ways"}}, $way->id());
- }
- }
-
- # next tile if there is nothing in this one
- next if ( ! $tile->{"ways"} );
-
- #========================================
- # merge ways that can be merged
- debug "\tBuilding tree:\n";
-
- foreach (@{$tile->{"ways"}}) {
- $way = $new_ways{$_};
- debug( "node ".$way->id()." (size: ".$way->size().")\n" );
- # only for not yet complete polygons and ways without prev and next
- if ($way->next() == 0 || $way->prev() == 0) {
- foreach (@{$tile->{"ways"}}) {
- my $way2=$new_ways{$_};
- if ($way->last_node() == $way2->first_node() ) {
- if ($way->next() == 0) {
- debug( "\tnext = ".$way2->id()."\n");
- $way->next($way2->id());
- } else {
- debug( "\t error: next way duplicated: old:".$way->next()." new:".$way2->id()." - node: ".$way->last_node()."\n");
- }
- }
- if ($way->first_node() == $way2->last_node() ) {
- if ($way->prev() == 0) {
- debug( "\tprev = ".$way2->id()."\n");
- $way->prev($way2->id());
- } else {
- debug( "\t error: prev way duplicated: old:".$way->prev()." new:".$way2->id()." - node: ".$way->first_node()."\n");
- }
- }
- }
- } else {
- debug( "\tAlready ok\n" );
- }
- }
- #=============================
- # if some ways are not closed, we need to close them.
- # It is done by adding new nodes on the border of the tile
- # and joining them
- debug ("\n\nClosing loops:\n");
-
- my (@first_nodes, @last_nodes);
-
- # project nodes on the border of the tile
- # Some nodes are already on the border of the tile (mainly because of
- # intersec_way_tiles)
- foreach (@{$tile->{"ways"}}) {
- my $way = $new_ways{$_};
-
- next if ( $way->first_node() == $way->last_node()); # already a loop
-
- if ( $way->prev() == 0) {
- my @way_nodes = $way->nodes();
-
- my $lat = $nodes{$way_nodes[0]}->{"lat"};
- my $lon = $nodes{$way_nodes[0]}->{"lon"};
- ($lat, $lon) = get_projection( $lat, $lon, $tile->{"minlat"}, $tile->{"minlon"}, $tile->{"maxlat"}, $tile->{"maxlon"} );
- my $node = { "lat" => $lat, "lon" => $lon, "id" => ($osm_id--)};
- unshift( @way_nodes, $node->{"id"} );
- push( @new_nodes, $node );
- $nodes{$node->{"id"}}=$node;
- push( @first_nodes, $node->{"id"});
-
- $way->nodes(@way_nodes);
- }
- if ( $way->next() == 0) {
-
- my @way_nodes = $way->nodes();
-
- my $lat = $nodes{$way_nodes[ @way_nodes - 1 ]}->{"lat"};
- my $lon = $nodes{$way_nodes[ @way_nodes - 1 ]}->{"lon"};
- ($lat, $lon) = get_projection( $lat, $lon, $tile->{"minlat"}, $tile->{"minlon"}, $tile->{"maxlat"}, $tile->{"maxlon"} );
- my $node = { "lat" => $lat, "lon" => $lon, "id" => $osm_id--};
- push( @way_nodes, $node->{"id"} );
- push( @new_nodes, $node );
- $nodes{$node->{"id"}}=$node;
- push( @last_nodes, $node->{"id"});
-
- $way->nodes(@way_nodes);
-
- }
-
- }
-
- # link nodes -> find a way around the tile
-
-
- my $last;
- foreach $last (@last_nodes) {
- debug "Looking for path ...\n";
- my ($path1, $path2);
- $path1=0;
-
- # find the sortest path between nodes
- # -> will give the next node around the tile
- my $first;
- my $first_elected;
- foreach $first (@first_nodes) {
- $path2=get_path_length($nodes{$last}->{"lat"},
- $nodes{$last}->{"lon"},
- $nodes{$first}->{"lat"},
- $nodes{$first}->{"lon"},
- @box);
- if ($path1 == 0 || $path1 > $path2) {
- $path1=$path2;
- $first_elected=$first;
- }
- }
-
- # get the path around the tile between the two nodes
- my @path = get_path ( $nodes{$last}->{"lat"},
- $nodes{$last}->{"lon"},
- $nodes{$first_elected}->{"lat"},
- $nodes{$first_elected}->{"lon"},
- @box);
-
- foreach (@path) {
- $_->{"id"} = $osm_id--;
- push(@new_nodes, $_);
- $nodes{$_->{"id"}} = $_;
- }
-
-
- unshift(@path, $nodes{$last});
- push(@path, $nodes{$first_elected});
-
- my $way = way->new($osm_id--);
- my @way_nodes=();
- debug( "new way ".$way->id().":\n");
- foreach (@path) {
- push(@way_nodes, $_->{"id"});
- debug( "nodes id: ".$_->{"id"}."\tlat: ".$_->{"lat"}." - long: ".$_->{"lon"}."\n");
- }
- $way->nodes(@way_nodes);
-
- push( @{$tiles{$tile->{"id"}}->{"ways"}}, $way->id());
- $new_ways{$way->id()} = $way;
- $ways{$way->id()} = $way;
-
-
-
- }
-
-
- # linking the ways
- # This time all ways should be loops because of the ways we added before
- debug "\n\nBuilding tree with new ways:\n";
-
- foreach (@{$tile->{"ways"}}) {
- my $way = $new_ways{$_};
- debug( "node ".$way->id()." (size: ".$way->size().")\n" );
- # only for not yet complete polygons and ways without prev and next
- if ($way->next() == 0 || $way->prev() == 0) {
- foreach (@{$tile->{"ways"}}) {
- my $way2=$new_ways{$_};
- if ($way->last_node() == $way2->first_node() ) {
- if ($way->next() == 0) {
- debug( "\tnext = ".$way2->id()."\n");
- $way->next($way2->id());
- } else {
- debug( "\t error: next way duplicated: old:".$way->next()." new:".$way2->id()." - node: ".$way->last_node()."\n");
- }
- }
- if ($way->first_node() == $way2->last_node() ) {
- if ($way->prev() == 0) {
- debug( "\tprev = ".$way2->id()."\n");
- $way->prev($way2->id());
- } else {
- debug( "\t error: prev way duplicated: old:".$way->prev()." new:".$way2->id()." - node: ".$way->first_node()."\n");
- }
- }
- }
- } else {
- debug( "\tAlready ok\n" );
- }
- }
-
-
- #merge ways to have only simple ways that are circular
- debug "merge ways\n";
-
- # copy into @a because we add new ways to the array inside the loop
- # -> otherwise it creates an infinite loop
- my @a = @{$tile->{"ways"}};
- foreach (@a) {
-# print "way $_\n";
- my $way = $new_ways{$_};
- next unless ($way->is_alive());
-
- my @way_nodes;
- while ($way->is_alive()) {
-
- push (@way_nodes, $way->nodes());
-
- # Distroy the way -> it won't be counted twince thus this will stop the loop
- # and it will free some memory
- $way->distroy();
- last if ($way->next() == 0);
- $way=$new_ways{ $way->next() };
- }
- my $new_way = way->new($osm_id--);
- $new_way->nodes(@way_nodes);
-
- push( @{$tiles{$tile->{"id"}}->{"ways"}}, $new_way->id());
- $new_ways{$new_way->id()} = $new_way;
- $ways{$new_way->id()} = $new_way;
-
- }
-
-
- ## sort the ways between sea and land
- foreach (@{$tile->{"ways"}}) {
- my $way = $new_ways{$_};
- next unless ($way->is_alive());
-# print "---- ".$way->id().": ".$way->first_node()." -> ".$way->last_node()."\n";
- foreach (@{$tile->{"ways"}}) {
- my $way2 = $new_ways{$_};
- # - don't check if a way is included in itself
- # - check only for ways of type "outer" which is the default type
- # => actualy should ckeck it. if a not is inside a "inner" way then it belongs
- # to a lake that is in an island
- if ($way2->is_alive() && $way2->id() != $way->id() && $way2->type() eq "outer") {
- if (polygon_contains_node($way2, $nodes{$way->first_node()})) {
- $way->type("inner");
- last;
- }
- }
- }
- }
-}
-
-
-
-
-
-
-
-
-
-
-
-
-########################################
-print "\n\nGenerating new data:\n";
-
-# add new nodes to output file
-foreach $node (@new_nodes) {
- debug( "adding node ".$node->{"id"}." to osm file\n");
- print $output " <node id=\"".$node->{"id"}."\" timestamp=\"2008-07-02T22:57:53Z\" user=\"latouche\" lat=\"".$node->{"lat"}."\" lon=\"".$node->{"lon"}."\"/>\n";
-}
-
-# add new ways (highway=motorway for debug)
-#foreach $way (values %new_ways) {
-# print $output " <way id=\"".$way->id()."\" timestamp=\"2008-07-02T22:57:53Z\" user=\"latouche\">\n";
-# foreach $node ($way->nodes()) {
-# print $output " <nd ref=\"".$node."\"/>\n" if defined $node;
-# }
-#
-# print $output " <tag k=\"highway\" v=\"motorway\"/>\n";
-# print $output " </way>\n";
-#
-#}
-
-
-# add new ways to output file
-foreach $tile (values %tiles) {
- print( "Writing tile: ".$tile->{"id"}."\n");
- foreach (@{$tile->{"ways"}}) {
- my $way = $new_ways{$_};
- my $type = "inner";
- next unless ($way->is_alive());
- print $output " <way id=\"".($osm_id--)."\" timestamp=\"2008-07-02T22:57:53Z\" user=\"latouche\">\n";
- while ($way->is_alive()) {
-
- $type = ($way->type() eq "outer") ? "water" : "land";
-
- foreach $node ($way->nodes()) {
- print "undef node in ".$way->id()."\n" unless defined $node;
- print $output " <nd ref=\"".$node."\"/>\n" if defined $node;
- }
- $way->distroy();
- last if ($way->next() == 0);
- $way=$new_ways{ $way->next() };
- }
- print $output " <tag k=\"natural\" v=\"".$type."\"/>\n";
- print $output " </way>\n";
- }
-}
-
-
-print $output "</osm>\n";
-
-close($output);
-
-exit(0);
diff --git a/navit/script/osm2navit_sea/way.pm b/navit/script/osm2navit_sea/way.pm
deleted file mode 100644
index e6bc76002..000000000
--- a/navit/script/osm2navit_sea/way.pm
+++ /dev/null
@@ -1,121 +0,0 @@
-#!/usr/bin/perl -w
-#
-
-package way;
-
-use strict;
-use warnings;
-
-sub new {
- my($class, $way_id) = @_;
- my $self = bless({}, $class);
-
- $self->{id} = $way_id;
- $self->{first_node} = $self->{last_node} = $self->{prev} = $self->{next} = $self->{size} = 0;
-
- $self->{type} = "outer";
-
- $self->{is_alive} = 1;
-
- $self->{nodes}=[];
-
- return $self;
-}
-
-# id of the way
-sub id {
- my $self = shift;
-
- return $self->{id};
-}
-
-# way killed or not
-sub is_alive {
- my $self = shift;
-
- return $self->{is_alive};
-}
-
-# way type: outer or inner multipolygon => island or sea
-sub type {
- my $self = shift;
-
- if( @_ ) {
- $self->{type} = shift;
- }
-
- return $self->{type};
-}
-
-# distroy way -> remove @nodes to free memory
-sub distroy {
- my $self = shift;
-
- $self->{nodes}=[];
- $self->{is_alive} = 0;
-}
-
-# first node of the way
-sub first_node {
- my $self = shift;
- if( @{$self->{nodes}} ) {
- return @{$self->{nodes}}[0];
- } else {
- return 0;
- }
-}
-
-# last node the way
-sub last_node {
- my $self = shift;
- if( @{$self->{nodes}} ) {
- return @{$self->{nodes}}[ $self->{size} -1 ];
- } else {
- return 0;
- }
-}
-
-# next way
-sub next {
- my $self = shift;
- if( @_ ) {
- $self->{next} = shift;
- }
- return $self->{next};
-}
-
-sub prev {
- my $self = shift;
- if( @_ ) {
- $self->{prev} = shift;
- }
- return $self->{prev};
-}
-
-# number of node in the way
-sub size {
- my $self = shift;
- return $self->{size};
-}
-
-#nodes
-sub nodes {
- my $self = shift;
- if( @_ ) {
-
- @{$self->{nodes}}=();
- my $prev=0;
- foreach (@_) {
- unless ($_ eq $prev) {
- $prev=$_;
- push ( @{$self->{nodes}} , $_);
- }
- }
-
- $self->{size} = scalar(@{$self->{nodes}});
- }
-
- return @{$self->{nodes}};
-}
-
-1;