| | 1 | = anno_crvt.pl = |
| | 2 | |
| | 3 | The parcel.tar.gz url is http://www.highwayengineer.co.medina.oh.us/parcel.tar.gz |
| | 4 | {{{ |
| | 5 | #!perl |
| | 6 | #!/usr/bin/perl |
| | 7 | # |
| | 8 | # Copyright (C) 2002, Lowell Filak |
| | 9 | # You may distribute this file under the terms of the Artistic |
| | 10 | # License. |
| | 11 | # |
| | 12 | # Given an arcinfo coverage name this routine will convert the annotations |
| | 13 | # (TX6/TX7 ONLY) from the first annotation subclass into a line shapefile. |
| | 14 | # |
| | 15 | # Required modules are mapscript (installed as part of make install) |
| | 16 | # & Getopt (normally included with Perl). |
| | 17 | # Please download parcel.tar.gz also, and: |
| | 18 | # tar -xf parcel.tar.gz --ungzip |
| | 19 | # |
| | 20 | # Additional requirements are a working copy of avcexport |
| | 21 | # (http://pages.infinit.net/danmo/e00/index.html) & a working copy of egrep. |
| | 22 | # |
| | 23 | # All of the information regarding the layout of the TX6&TX7 sections can |
| | 24 | # be found with the avcexport package. |
| | 25 | # |
| | 26 | # Suggested run line = ./anno_cnvt.pl -cover=parcel |
| | 27 | # |
| | 28 | # Include the mapscript module. |
| | 29 | use mapscript; |
| | 30 | # |
| | 31 | # Include the xbase module for creating the dbf records. |
| | 32 | use XBase; |
| | 33 | # |
| | 34 | # Include the getopt module to read input. |
| | 35 | use Getopt::Long; |
| | 36 | # |
| | 37 | # Grab the filename from the input. |
| | 38 | &GetOptions("cover=s", \$cover); |
| | 39 | # |
| | 40 | # Check the input filename. |
| | 41 | if(!$cover) { |
| | 42 | print "Syntax: anno_cnvt.pl -cover=[coverage_name]\n"; |
| | 43 | exit 0; |
| | 44 | } |
| | 45 | # |
| | 46 | # Create a unique name for the export file. |
| | 47 | # |
| | 48 | # Grab the time. |
| | 49 | my $sec = 0; |
| | 50 | my $min = 0; |
| | 51 | my $hr = 0; |
| | 52 | my $mnth = 0; |
| | 53 | my $yr = 0; |
| | 54 | my $wdy = 0; |
| | 55 | my $ydy = 0; |
| | 56 | my $isdst = 0; |
| | 57 | ($sec,$min,$hr,$mdy,$mnth,$yr,$wdy,$ydy,$isdst) = localtime; |
| | 58 | # |
| | 59 | # Grab the process id. |
| | 60 | $spid = $$; |
| | 61 | # |
| | 62 | # Create the name & make sure it is no longer than 8 characters. |
| | 63 | $efile = "$hr$min$sec$spid"; |
| | 64 | # |
| | 65 | # Create a name for the new shapefile from the original coverage name. |
| | 66 | # No longer than 8 characters. |
| | 67 | $sfile = substr($cover, -6) . "xa"; |
| | 68 | # |
| | 69 | # Use avcexport to create an export file of the coverage. |
| | 70 | system("avcexport $cover $efile.e00"); |
| | 71 | # |
| | 72 | # Use grep to quickly clip out everything before the annotation. |
| | 73 | system("grep -A 1000000000 '^TX' $efile.e00 > $efile.clp; mv $efile.clp $efile.e00"); |
| | 74 | # |
| | 75 | # Open the export file for reading in the annotation information. |
| | 76 | open(E00, "<$efile.e00"); |
| | 77 | # |
| | 78 | # Set the number of annotation coordinates to 0 to start with. |
| | 79 | my $num_cords = 0; |
| | 80 | # |
| | 81 | # Set the number of annotation characters to 0 to start with. |
| | 82 | my $num_chars = 0; |
| | 83 | # |
| | 84 | # Set the input file to an array so shift & cousins can be used. |
| | 85 | my @export = <E00>; |
| | 86 | # |
| | 87 | # Close the export file. |
| | 88 | close E00; |
| | 89 | # |
| | 90 | # Shift off the annotation type marker and record it. |
| | 91 | my $ano_type = shift(@export); |
| | 92 | # |
| | 93 | # Shift off the subclass name and record it. |
| | 94 | my $ano_name = shift(@export); |
| | 95 | $ano_name =~ s/\015\012|\015|\012//g; |
| | 96 | # |
| | 97 | # How many remaining lines are there. |
| | 98 | my $line_cnt = scalar(@export); |
| | 99 | # |
| | 100 | # Create the xbase call. |
| | 101 | my $xbcall = 'XBase->create(name => "' . $sfile . '.dbf", field_names => ["RECNO", "TEXT" ], field_types => ["N", "C"], field_lengths => ["6", "254"], field_decimals => ["undef", "undef"]) or die XBase->errstr;'; |
| | 102 | # |
| | 103 | # Create the dbf file. |
| | 104 | $dbh = eval($xbcall); |
| | 105 | # |
| | 106 | # Create the shapefile. |
| | 107 | my $shapef = new shapefileObj("$sfile",$mapscript::MS_SHAPEFILE_ARC); |
| | 108 | # |
| | 109 | # Create a point object for holding the retrieved coordinates. |
| | 110 | my $point = new pointObj(); |
| | 111 | # |
| | 112 | # Start the dbf record count at 0. |
| | 113 | my $dbfreccnt = 0; |
| | 114 | # |
| | 115 | # Loop through each line of the export file. |
| | 116 | for ($ln=0; $ln<$line_cnt; $ln++) { |
| | 117 | # |
| | 118 | # Create a line object for holding the created lines. |
| | 119 | my $line = new lineObj(); |
| | 120 | # |
| | 121 | # Create a shape object for holding the created line shapes. |
| | 122 | my $shape = new shapeObj($mapscript::MS_SHAPE_LINE); |
| | 123 | # |
| | 124 | # Split the 1st line apart. |
| | 125 | my @ln1_prts = split(' ', shift(@export)); |
| | 126 | # |
| | 127 | # Pull out any good values (there should be at least 7). |
| | 128 | my @gd_prts = grep { defined $_ } @ln1_prts; |
| | 129 | # |
| | 130 | # Check for end of annotation section. |
| | 131 | if ( $gd_prts[0] == -1 ) { |
| | 132 | last; |
| | 133 | } |
| | 134 | # |
| | 135 | # Clear and reset the values for the 1st line. |
| | 136 | @ln1_prts = (); |
| | 137 | @ln1_prts = @gd_prts; |
| | 138 | # |
| | 139 | # How many anno vertices are there. |
| | 140 | my $vrt_cnt = $ln1_prts[2]; |
| | 141 | # |
| | 142 | # How many arrow vertices are there. |
| | 143 | my $vrt_arr = $ln1_prts[3]; |
| | 144 | # |
| | 145 | # How many characters in text string. |
| | 146 | my $chr_cnt = $ln1_prts[6]; |
| | 147 | # |
| | 148 | # Is the text string longer than 0. |
| | 149 | if ( $chr_cnt > 0 ) { |
| | 150 | # |
| | 151 | # Divide the character count by 80 to set the number of text lines. |
| | 152 | $chr_cnt = $chr_cnt / 80; |
| | 153 | } |
| | 154 | else { |
| | 155 | $chr_cnt = 1; |
| | 156 | } |
| | 157 | # |
| | 158 | # Print out the counts to see if we got this right. |
| | 159 | #print "Annotation Vetices = $vrt_cnt\nArrow Vertices = $vrt_arr\nText Characters = $chr_cnt\n"; |
| | 160 | # |
| | 161 | # Drop lines 2-9. |
| | 162 | for ($drop=1; $drop<9; $drop++) { |
| | 163 | my $grbg = shift(@export); |
| | 164 | } |
| | 165 | # |
| | 166 | # Read in the first vertex. |
| | 167 | my @vrt1_prts = split(' ', shift(@export)); |
| | 168 | # |
| | 169 | # Pull out any good values (there should be at least 2). |
| | 170 | @gd_prts = grep { defined $_ } @vrt1_prts; |
| | 171 | # |
| | 172 | # Clear and reset the values for the 1st vertex line. |
| | 173 | @vrt1_prts = (); |
| | 174 | @vrt1_prts = @gd_prts; |
| | 175 | $vrt1_prts[1] =~ s/\015\012|\015|\012//g; |
| | 176 | # |
| | 177 | # If there is only one coordinate then manufacture a second coordinate. |
| | 178 | if ( $vrt_cnt < 2 ) { |
| | 179 | $vrtl_prts[0] = $vrt1_prts[0] + 1; |
| | 180 | $vrtl_prts[1] = $vrt1_prts[0]; |
| | 181 | } |
| | 182 | else { |
| | 183 | # |
| | 184 | # Read in the last vertex. |
| | 185 | # At this point everything except the first and last can be dropped |
| | 186 | # because of how feature labels are handled. |
| | 187 | for ($vrtx=1; $vrtx<$vrt_cnt; $vrtx++) { |
| | 188 | @vrtl_prts = split(' ', shift(@export)); |
| | 189 | } |
| | 190 | # |
| | 191 | # Pull out any good values (there should be at least 2). |
| | 192 | my @gd_prts = grep { defined $_ } @vrtl_prts; |
| | 193 | # |
| | 194 | # Clear and reset the values for the last vertex line. |
| | 195 | @vrtl_prts = (); |
| | 196 | @vrtl_prts = @gd_prts; |
| | 197 | $vrtl_prts[1] =~ s/\015\012|\015|\012//g; |
| | 198 | } |
| | 199 | # |
| | 200 | # Drop all the arrow vertices. |
| | 201 | for ($drop=0; $drop<$vrt_arr; $drop++) { |
| | 202 | my $grbg = shift(@export); |
| | 203 | } |
| | 204 | # |
| | 205 | # Set the initial text string to blank; |
| | 206 | my $text = ''; |
| | 207 | # |
| | 208 | # Loop through each text line and append together. |
| | 209 | for ($txt=0; $txt<$chr_cnt; $txt++) { |
| | 210 | my $strng = shift(@export); |
| | 211 | $strng =~ s/\015\012|\015|\012//g; |
| | 212 | $text = $text . $strng; |
| | 213 | } |
| | 214 | # |
| | 215 | # If the text string is blank then jump to the next annotation. |
| | 216 | if ( !$text ) { |
| | 217 | next; |
| | 218 | } |
| | 219 | else { |
| | 220 | } |
| | 221 | # |
| | 222 | # Print the results to see if we got this right. |
| | 223 | #print "Text String = $text\n"; |
| | 224 | # |
| | 225 | # Convert from scientific notation. |
| | 226 | # This may not be needed but just in case... |
| | 227 | $vrt1_prts[0] = $vrt1_prts[0] - 0; |
| | 228 | $vrt1_prts[1] = $vrt1_prts[1] - 0; |
| | 229 | # |
| | 230 | # Assign the point x & y for the first point. |
| | 231 | $point->{x} = $vrt1_prts[0]; |
| | 232 | $point->{y} = $vrt1_prts[1]; |
| | 233 | # |
| | 234 | # Add the point to the line. |
| | 235 | $line->add($point); |
| | 236 | # |
| | 237 | # Do the same for the second point. |
| | 238 | $vrtl_prts[0] = $vrtl_prts[0] - 0; |
| | 239 | $vrtl_prts[1] = $vrtl_prts[1] - 0; |
| | 240 | # |
| | 241 | # Assign the point x & y for the first point. |
| | 242 | $point->{x} = $vrtl_prts[0]; |
| | 243 | $point->{y} = $vrtl_prts[1]; |
| | 244 | # |
| | 245 | # Add the point to the line. |
| | 246 | $line->add($point); |
| | 247 | # |
| | 248 | # Add the line to the shape. |
| | 249 | $shape->add($line); |
| | 250 | # |
| | 251 | # Add the shape to the shapefile. |
| | 252 | $shapef->add($shape); |
| | 253 | # |
| | 254 | # Clear out the line object. |
| | 255 | undef $line; |
| | 256 | # |
| | 257 | # Clear out the shape object. |
| | 258 | undef $shape; |
| | 259 | # |
| | 260 | # Add the text & record number to the dbf as attributes. |
| | 261 | # Record number is not needed but it will help if at some point |
| | 262 | # there is a need to select all annotation containing 'COUNTY'. |
| | 263 | # |
| | 264 | # Create the xbase add record call. |
| | 265 | my $xbadd = '$dbh->set_record($dbfreccnt, $dbfreccnt, "$text");'; |
| | 266 | # |
| | 267 | # Add the record to the dbf file. |
| | 268 | eval($xbadd); |
| | 269 | # |
| | 270 | # Increment the dbf record counter. |
| | 271 | $dbfreccnt = $dbfreccnt + 1; |
| | 272 | } |
| | 273 | # |
| | 274 | # Close the new shapefile. |
| | 275 | undef $shapef; |
| | 276 | # |
| | 277 | # Close the dbf handle/file. |
| | 278 | undef $dbh; |
| | 279 | # |
| | 280 | # Print the number of converted annotations. |
| | 281 | print "$dbfreccnt Annotations Were Converted from Subclass $ano_name into $sfile.shp.\n"; |
| | 282 | # |
| | 283 | # Get rid of the export file. |
| | 284 | unlink "$efile.e00"; |
| | 285 | }}} |
| | 286 | ---- |
| | 287 | back to PerlMapScript |