#!/usr/bin/perl -w use strict; use File::Copy; use File::Basename; use vars qw($VERSION $program $force $infile $newpath $count $B $b @ARRAY); $VERSION = '1.1'; =head1 NAME apredit - Arcview GIS project file command line editor. =head1 VERSION 1.1 =head1 SYNOPSIS apredit [-f] inputfile newpath =head1 DESCRIPTION apredit updates / edits path information of Arcview GIS project files in a command line fashion. My main reasoning behind writing this utility is I was constantly editing my .apr files as a result of data changing locations over time, so I thought a simple tool would be helpful. The -f option forces checking the new path given to exist on the host system. The script has been tested against .apr files of ArcView GIS version 2.0 and up. For portable .apr files, using the "rel" keyword will give coverages a relative linkage. For the project file entered, apredit creates a backup file (extension .bak) and edits the paths of each shapefile or coverage or theme to the user's input. =head1 PREREQUISITES / MODULES This script uses the File::Copy and File::Basename modules, both in the Standard Perl Library. =head1 OPTIONS / FLAGS -f Force checking of newpath on local system directory structure. =head1 ARGUMENTS inputfile - name of ArcView GIS .apr file to edit newpath - name of newpath to insert/update =head1 EXAMPLES To edit a file with your new path info: $ ./apredit myfile.apr /home/user/dem8/ To invoke force checking of new path: $ ./apredit -f myfile.apr /home/user/dem8/ To force relative coverages: $ ./apredit myfile.apr rel =head1 TODO - make this into a module instead; - checking of "info/" and grid directories =head1 AUTHOR Tom Kralidis http://www.kralidis.ca/gis/ =cut $B = "\33[1m"; $b = "\33[0m"; $program = "apredit"; $force = 0; if (@ARGV == 0 || @ARGV > 3) { usageBrief(); } # if one arg elsif (@ARGV == 1) { usageForce() if ($ARGV[0] eq '-f'); usageBrief() if ($ARGV[0] ne '-f'); } # if two args elsif (@ARGV == 2) { usageForce() && exit 0 if ($ARGV[0] eq '-f'); exit 1 if (checkFileExist() == 1); processFile(); } elsif (@ARGV == 3) { if ($ARGV[0] ne '-f') { usageBrief(); exit 1; } exit 1 if (checkFileExist() == 1); exit 2 if (forceCheckDir() == 1); processFile(); } exit 0; ################################################################################ sub checkFileExist { if (! -e $ARGV[-2]) { print "File does not exist: $ARGV[-2]\n"; return 1; } return 0; } sub forceCheckDir { # setup newpath and check for it's existence if '-f' is invoked print "Force checking mode enabled\n"; if (! -e $ARGV[-1]) { print "Path doesn't exist: $ARGV[-1]\nExiting. No changes made\n"; return 1; } return 0; } sub processFile { # the last two args always input file and the newpath ($infile, $newpath) = ($ARGV[-2], $ARGV[-1]); $newpath = "" if $newpath eq "rel"; $newpath .= '/' unless ($newpath =~ /\/$/ || $ARGV[1] eq "rel"); print "REL: " if $newpath eq "rel"; print "Backing up $infile to $infile.bak..."; copy("$infile", "$infile.bak") or die "Yikes: $!\n"; print "Done.\n"; print "Editing $infile........................."; open(FH,"+< $infile") or die "$!\n"; @ARRAY = ; foreach (@ARRAY) { if ($_ =~ /path/i) { my ($x, $name, $path); $x = $1 if $_ =~ /Path:\s+(.*)$/; ($name, $path) = fileparse($x); $_ =~ s#$path#\"$newpath#g; $count++; } } seek(FH,0,0) or die "Seeking: $!"; print FH @ARRAY or die "Printing: $!"; truncate(FH,tell(FH)) or die "Truncating: $!"; close(FH); print "Done.\nNumber of path edits(newpath=$newpath): $count\nDone.\n"; return 0; } sub usageBrief { print "Invalid inputs: @ARGV\n" if ((@ARGV != 0) && ($ARGV[0] ne '-f')); print <<" USAGE"; $B$program$b Version $VERSION Copyright Tom Kralidis Usage: $B$program$b -fh use 'perldoc $program' for help USAGE } sub usageForce { print "You must supply a file and pathname.\n"; usageBrief(); }