# # PERL mapweaver module by gary68 # # # # # Copyright (C) 2011, Gerhard Schwanz # # This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 3 of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along with this program; if not, see # package mwOccupy ; use strict ; use warnings ; use List::Util qw[min max] ; use mwMap ; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK); require Exporter ; @ISA = qw ( Exporter AutoLoader ) ; @EXPORT = qw ( boxOccupyLines boxOccupyArea boxLinesOccupied boxAreaOccupied boxDrawOccupiedAreas ) ; my $boxSize = 5 ; my %box = () ; # ------------------------------------------------------------- sub boxOccupyLines { my ($refCoords, $buffer, $value) = @_ ; my @coordinates = @$refCoords ; my @lines = () ; for ( my $i = 0; $i < $#coordinates-2; $i += 2 ) { push @lines, [$coordinates[$i], $coordinates[$i+1], $coordinates[$i+2], $coordinates[$i+3]] ; } foreach my $line ( @lines ) { my $x1 = $line->[0] ; my $y1 = $line->[1] ; my $x2 = $line->[2] ; my $y2 = $line->[3] ; # print "$x1, $y1, $x2, $y2\n" ; if ( $x1 != $x2) { my $m = ($y2 - $y1) / ($x2 - $x1) ; my $b = $y1 - $m * $x1 ; if ( abs ( $x1 - $x2 ) > abs ( $y1 - $y2 ) ) { # calc points on x axis my $x = $x1 ; my $stepX = $boxSize ; if ( $x2 < $x1 ) { $stepX = - $boxSize ; } while ( ( $x >= min ($x1, $x2) ) and ( $x <= max ($x1, $x2) ) ) { my $y = $m * $x + $b ; # ACTUAL COORDINATE $x, $y my $ax1 = $x - $buffer ; my $ax2 = $x + $buffer ; my $ay1 = $y - $buffer ; my $ay2 = $y + $buffer ; boxOccupyArea ($ax1, $ay1, $ax2, $ay2, 0, $value) ; $x += $stepX ; } } else { # calc points on y axis my $y = $y1 ; my $stepY = $boxSize ; if ( $y2 < $y1 ) { $stepY = - $boxSize ; } while ( ( $y >= min ($y1, $y2) ) and ( $y <= max ($y1, $y2) ) ) { my $x = ($y - $b) / $m ; # ACTUAL COORDINATE $x, $y my $ax1 = $x - $buffer ; my $ax2 = $x + $buffer ; my $ay1 = $y - $buffer ; my $ay2 = $y + $buffer ; boxOccupyArea ($ax1, $ay1, $ax2, $ay2, 0, $value) ; $y += $stepY ; } } # abs } else { my $x = $x1 ; # calc points on y axis my $y = $y1 ; my $stepY = $boxSize ; if ( $y2 < $y1 ) { $stepY = - $boxSize ; } while ( ( $y >= min ($y1, $y2) ) and ( $y <= max ($y1, $y2) ) ) { # ACTUAL COORDINATE $x, $y my $ax1 = $x - $buffer ; my $ax2 = $x + $buffer ; my $ay1 = $y - $buffer ; my $ay2 = $y + $buffer ; boxOccupyArea ($ax1, $ay1, $ax2, $ay2, 0, $value) ; $y += $stepY ; } } } } sub boxLinesOccupied { my ($refCoords, $buffer) = @_ ; my @coordinates = @$refCoords ; my @lines = () ; my $result = 0 ; for ( my $i = 0; $i < $#coordinates-2; $i += 2 ) { push @lines, [$coordinates[$i], $coordinates[$i+1], $coordinates[$i+2], $coordinates[$i+3]] ; } foreach my $line ( @lines ) { my $x1 = $line->[0] ; my $y1 = $line->[1] ; my $x2 = $line->[2] ; my $y2 = $line->[3] ; # print "$x1, $y1, $x2, $y2\n" ; if ( $x1 != $x2) { my $m = ($y2 - $y1) / ($x2 - $x1) ; my $b = $y1 - $m * $x1 ; if ( abs ( $x1 - $x2 ) > abs ( $y1 - $y2 ) ) { # calc points on x axis my $x = $x1 ; my $stepX = $boxSize ; if ( $x2 < $x1 ) { $stepX = - $boxSize ; } while ( ( $x >= min ($x1, $x2) ) and ( $x <= max ($x1, $x2) ) ) { my $y = $m * $x + $b ; # ACTUAL COORDINATE $x, $y my $ax1 = $x - $buffer ; my $ax2 = $x + $buffer ; my $ay1 = $y - $buffer ; my $ay2 = $y + $buffer ; my $tmp = boxAreaOccupied ($ax1, $ay1, $ax2, $ay2) ; if ($tmp > $result) { $result = $tmp ; } $x += $stepX ; } } else { # calc points on y axis my $y = $y1 ; my $stepY = $boxSize ; if ( $y2 < $y1 ) { $stepY = - $boxSize ; } while ( ( $y >= min ($y1, $y2) ) and ( $y <= max ($y1, $y2) ) ) { my $x = ($y - $b) / $m ; # ACTUAL COORDINATE $x, $y my $ax1 = $x - $buffer ; my $ax2 = $x + $buffer ; my $ay1 = $y - $buffer ; my $ay2 = $y + $buffer ; my $tmp = boxAreaOccupied ($ax1, $ay1, $ax2, $ay2) ; if ($tmp > $result) { $result = $tmp ; } $y += $stepY ; } } # abs } else { my $x = $x1 ; # calc points on y axis my $y = $y1 ; my $stepY = $boxSize ; if ( $y2 < $y1 ) { $stepY = - $boxSize ; } while ( ( $y >= min ($y1, $y2) ) and ( $y <= max ($y1, $y2) ) ) { # ACTUAL COORDINATE $x, $y my $ax1 = $x - $buffer ; my $ax2 = $x + $buffer ; my $ay1 = $y - $buffer ; my $ay2 = $y + $buffer ; my $tmp = boxAreaOccupied ($ax1, $ay1, $ax2, $ay2) ; if ($tmp > $result) { $result = $tmp ; } $y += $stepY ; } } } return $result ; } # ------------------------------------------------------------- sub boxOccupyArea { my ($x1, $y1, $x2, $y2, $buffer, $value) = @_ ; if ( $x2 < $x1) { my $tmp = $x1 ; $x1 = $x2 ; $x2 = $tmp ; } if ( $y2 < $y1) { my $tmp = $y1 ; $y1 = $y2 ; $y2 = $tmp ; } $x1 -= $buffer ; $x2 += $buffer ; $y1 -= $buffer ; $y2 += $buffer ; for ( my $x = $x1; $x <= $x2; $x += $boxSize) { for ( my $y = $y1; $y <= $y2; $y += $boxSize) { my $bx = int ( $x / $boxSize ) ; my $by = int ( $y / $boxSize ) ; $box{$bx}{$by} = $value ; # print "box $bx, $by occupied\n" ; } } return ; } sub boxAreaOccupied { my ($x1, $y1, $x2, $y2) = @_ ; my $result = 0 ; if ( $x2 < $x1) { my $tmp = $x1 ; $x1 = $x2 ; $x2 = $tmp ; } if ( $y2 < $y1) { my $tmp = $y1 ; $y1 = $y2 ; $y2 = $tmp ; } for ( my $x = $x1; $x <= $x2; $x += $boxSize) { my $bx = int ($x / $boxSize) ; for ( my $y = $y1; $y <= $y2; $y += $boxSize) { my $by = int ($y / $boxSize) ; # print " $bx, $by\n" ; if ( defined $box{$bx}{$by} ) { if ( $box{$bx}{$by} > $result ) { # print "check box $bx, $by\n" ; $result = $box{$bx}{$by} ; } } } } return $result ; } # ------------------------------------------------------------- sub boxDrawOccupiedAreas { my $format1 = "fill=\"red\" fill-opacity=\"0.3\" " ; my $format2 = "fill=\"blue\" fill-opacity=\"0.3\" " ; my $format3 = "fill=\"green\" fill-opacity=\"0.5\" " ; foreach my $bx ( sort {$a <=> $b} keys %box ) { foreach my $by ( sort {$a <=> $b} keys %{$box{$bx}} ) { my $x1 = $bx * $boxSize ; my $x2 = $x1 + $boxSize ; my $y1 = $by * $boxSize ; my $y2 = $y1 + $boxSize ; if ( $box{$bx}{$by} == 1) { drawRect ($x1, $y1, $x2, $y2, 0, $format1, "occupied") ; } elsif ( $box{$bx}{$by} == 2) { drawRect ($x1, $y1, $x2, $y2, 0, $format2, "occupied") ; } else { drawRect ($x1, $y1, $x2, $y2, 0, $format3, "occupied") ; } # print "occupied $bx, $by\n" ; } } } 1 ;