NAME

Data::Douglas_Peucker

DESCRIPTION

Data::Douglas_Peucker processes a list of 2 dimensional data and reduces the number of records in the list using the Douglas/Peucker algoritm. So it produces a set of 2 dimensional data that is reduced in number, but approximates the original set.

A typical application is to reduce a set of 2 dimensional points that fall along a curve to a smaller set of 2 dimensional points that approximates the same curve. An example of this is a GPS track (waypoints along a GPS track).

Note that the value assigned to $tolerance is roughly the number of meters distance that a point can be from the straight line drawn between two latitude/longitude points, one on each side, and the point can be discarded. So a higher number used for $tolerance removes more points from the original set of lat/longs.

SYNOPSIS

# Test Program: douglasp.pl

# Douglas - Peucker Test Program # Author. John D. Coryat 01/2007 USNaviguide.com # Maintainer: Mike Flannigan (temp4@mflan.com) # #

use strict; use Data::Douglas_Peucker;

my $infile = $ARGV[0]; my $outfile = $ARGV[1]; my $tolerance = $ARGV[2]; my @Ipoints = ( ); my @Opoints = ( ); my $data = '';

if(!$infile or !$outfile or !$tolerance) { print "Usage: douglas-peucker.pl <input file name> <output file name> <tolerance in meters>\n"; print "Data format: lat,lng\n"; exit; }

if ( $tolerance <= 0 ) { print "Tolerance (meters) must be greater than zero.\n"; exit; }

if ( !(-s $infile) ) { print "Input File ($infile) not found.\n"; exit; }

#if (-s $outfile) { # print "Output File ($outfile) exists.\n"; # exit; #}

open IN, $infile;

while ( $data = <IN> ) { if ( $data =~ /(-?\d+\.\d*),(-?\d+\.\d*)/ ) { push( @Ipoints, [$1,$2] ); } } close IN;

@Opoints = &Douglas_Peucker( \@Ipoints, $tolerance );

open OUT, ">$outfile";

foreach $data (@Opoints) { print OUT "$$data[0],$$data[1]\n"; }

close OUT;

print "\nInput: " . $#Ipoints . " Output: " . $#Opoints . " Tolerance: $tolerance\n\n";

__END__

# Create a $infile, such as 'proc.txt' with this in the file: -107.49414,46.81526 -107.49559,46.81524 -107.49558,46.81798 -107.49558,46.81886 -107.49415,46.81888 -107.49414,46.81526

# Copy the program above (the text between '=head1 SYNOPSIS' and # '__END__' and paste it into a file named douglasp.pl. # Place the file in your Perl script directory and run # this command in a command-line interpreter, shell, # command prompt, terminal, or whatever it is called on # your system: # perl douglasp.pl proc.txt procout.txt 1 # # The expected output is: 'Input: 5 Output: 4 Tolerance: 1' to the command-line interpreter # and this output in the 'procout.txt' file: -107.49414,46.81526 -107.49559,46.81524 -107.49558,46.81886 -107.49415,46.81888 -107.49414,46.81526

# So one of the six records was removed. # # Remember that a higher number used for $tolerance removes more # points from the original set of lat/longs. # #