[Mapserver-users] PERL mapscript polygon shapefile creation

Joe Bussell joe at otsys.com
Tue Feb 25 14:41:56 EST 2003


This is a multi-part message in MIME format.
--------------020907060906090201030909
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit

Greetings Listers,
    I am having difficulty porting a technique we use to create point 
and line type shapefiles to create a polygon shapefile.  Has anyone used 
PERL to create polygon shapefiles from data files?  I have attached my 
attempt for review.  The script creates a shapefile that is readable by 
dump.pl, but I have not been able to use it in a map render.
    I tried this with a data file with the following lines:
40.0 -116.0
45.0 -116.0
45.0 -120.0
40.0 -120.0

The script "closes" the polygon by inserting the first record at the end.

    Any ideas?

Cordially,

Joe Bussell

--------------020907060906090201030909
Content-Type: application/x-perl;
 name="getNavZone.pl"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="getNavZone.pl"

#!/usr/bin/perl -w

use strict;
use Carp;
use Getopt::Std qw(getopts);
use File::Copy qw(copy move);
use Date::Manip;

use mapscript;
use XBase;

use vars qw{ $v $shapeFile $dbfTable };
my $lineNumber = 0;

#get command line parameters
my %args = ();
getopts("I:O:vs", \%args);

$v = ( defined $args{v} );

if ( $v )
{
    print "Build shapefile with one polygon from a text file.\n";
}

if ( !defined $args{I} || !defined $args{O} )
{
    croak "getNavZone.pl [-v] -I inputFileName -O outputFileNameBase\n"
         ."    extracts lines with enough geocoding information into a shapefile and an associated DBF.\n"
}

my $inputFileName = $args{I};
my $outputFileNameBase = $args{O};

if ( $args{v} )                
{
    print "Input file = $inputFileName\n";
    print "Output shapefile = $outputFileNameBase.shp\n";
    print "Output dbf file = $outputFileNameBase.dbf\n";
}

open( IN_FILE, "< $inputFileName" ) or croak "Cannot open $inputFileName  $!\n";

my $shapeFileName = $outputFileNameBase . ".shp";
my $dbfFileName = $outputFileNameBase . ".dbf";
my $idxFileName = $outputFileNameBase . ".shx";

my $tempShapeFileName = "./temp.shp";
my $tempDbfFileName = "./temp.dbf";
my $tempIdxFileName = "./temp.shx";

unlink $tempShapeFileName or carp "Could not delete $tempShapeFileName $!\n";
unlink $tempDbfFileName or carp "Could not delete $tempDbfFileName $!\n";
unlink $tempIdxFileName or carp "Could not delete $tempIdxFileName $!\n";

$shapeFile = new shapefileObj( $tempShapeFileName, $mapscript::MS_SHAPEFILE_POLYGON ) 
    or croak "Cannot open $tempShapeFileName $!\n";

$dbfTable = XBase->create(    "name"            => $tempDbfFileName, 
                              "field_names"     => [ "ID" ], 
                              "field_types"     => [ "N" ],
                              "field_lengths"   => [ 10 ],
                              "field_decimals"  => [ 0 ] )      or croak "Cannot create dbfTable $!\n";

sub createPolygon
{
    my $latRef = shift;
    my $lonRef = shift;
    my $id = shift;
    
    my $shape = new shapeObj($mapscript::MS_SHAPE_POLYGON);
    
    my @latRA = @$latRef;
    my @lonRA = @$lonRef;

    my $len = @latRA;
    for( my $i = 0; $i < $len; $i++ ) 
    {
        my $lat = $latRA[ $i ];
        my $lon = $lonRA[ $i ];

        my $point = new pointObj();
        my $line = new lineObj();
        
        $point->{x} = $lon;
        $point->{y} = $lat;
        $line->add( $point );
        $shape->add( $line );
        $lineNumber++;
    }
    $shapeFile->add( $shape );
    $dbfTable->set_record( $id, $id );
    
    print "Should have made a point in the polygon shapefile = $id $lineNumber\n";
}

sub trim
{
    my @out = @_;
    for ( @out )
    {
        s/^\s+//;
        s/\s+$//;
    }

    return wantarray ? @out : $out[0];
}


my $num = 0;
my $numSuccesses = 0;
my $numFailures = 0;

my $center = "";
my @lats;
my @lons;
my $id = 0;

my $firstLat = 0;
my $firstLon = 0;

while ( <IN_FILE> )
{    
    chop;
    
    my $line = &trim( $_ );
   
    if ( /^\s*$/ )
    {
        carp "$num: No data\n" if ( $v );
        ++$num;
        next;
    }
    elsif ( /^(\S+)\s+(\S+)$/ )
    {
        push( @lats, $1 );
        push( @lons, $2 );
        carp( "$1, $2\n" );

        if ( $num == 0 )
        {
            $firstLat = $1;
            $firstLon = $2;
        }
    }
    else
    {
        carp "ERROR $num $line\n";
        ++$num;
        next;
    }

    ++$num;
}

push( @lats, $firstLat );
push( @lons, $firstLon );

&createPolygon( \@lats, \@lons, $id );

undef $shapeFile;
undef $dbfTable;

if ( !copy( $tempShapeFileName, $shapeFileName ) )
{
    carp "Can't cp $tempShapeFileName $shapeFileName\n";
}
if ( !copy( $tempDbfFileName, $dbfFileName ) )
{
    carp "Can't cp $tempDbfFileName $dbfFileName\n";
}
if ( !copy( $tempIdxFileName, $idxFileName ) )
{
    carp "Can't cp $tempIdxFileName $idxFileName\n";
}

`/usr/bin/shptree $shapeFileName`;

close IN_FILE;

1;

exit;


--------------020907060906090201030909--




More information about the mapserver-users mailing list