#!/usr/bin/perl # PLSS point ids to addresses, for South St. Paul, Minnesota # Author: Dan Jacobson https://www.jidanni.org/ # Copyright: https://www.gnu.org/licenses/gpl.htm # Created: 2024-01-27T09:44:01+0000 # Last-Updated: 2024-04-24T00:57:36+0000 # Update #: 152 # use strict; use warnings q(all); use PointId2Address; use Data::Dumper; my %grid = ( origin => { # Virtual corner of Marie Ave. and 0th Street. id => 'MN460280N0220W0_440300', }, num_per_mile => [ 1600, 800 ] ); ## Generate a sample file of where to put labels. ## Like one made by hand. if ( $ARGV[0] eq "--make-samples" ) { #X, Y, Label my @o; for ( 1 .. 17 ) { next unless $_ % 2; for ( $_ * 100 ) { if ( $_ == 700 ) { push @o, "$_ W, 200 S, 200 S" } else { push @o, "$_ W, 150 S, $_ W" } } } push @o, "1700 W, $_ N, $_ N" for 200, 400; print "$_$/" for @o; print <) { s/\s*#.*//; #strip comments next unless /\S/; last if /__END__/; chomp; my @F = split /,/; for (@F) { s/^\s+//; s/\s+$//; } $_ = unfold_100($_) for @F[ 0, 1 ]; $_ = PointId2Address::canon $_ for @F[ 0, 1 ]; my $id = PointId2Address::addr2id( \%grid, @F[ 0, 1 ] ); die "I messed up with $_" unless $id; printf "%s,,%s\n", $id, $F[2]; } } else { # PIDs to addresses while (<>) { chomp; my @F = split /,/; $grid{target} = { id => $F[2] }; #we wipe out any previous {target}{miles} my @p = fold_100( PointId2Address::id2addr( \%grid ) ); die "No address for $_" unless @p; printf "%s,%s,%s\n", @F[ 0, 1 ], "@p"; } } ## There are no 0-99 blocks. They start with 100. sub fold_100 { my @a = @_; for ( 0, 2 ) { $a[$_] += 100; } return @a; } sub unfold_100 { #not exactly symmetrical with fold_100 though my $s = $_[0]; for ($s) { /\d+/ or die "@_: no number found"; my $num = $&; die "@_: $num is an address too low to be valid in this area." unless $num >= 100; s/$num/$num-=100/e; } return $s; }