| 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 |