end0tknr's kipple - web写経開発

太宰府天満宮の狛犬って、妙にカワイイ

postgisである地点からの距離を算出

http://d.hatena.ne.jp/end0tknr/20100703/1278175849
http://d.hatena.ne.jp/end0tknr/20100703/1278182070
http://d.hatena.ne.jp/end0tknr/20100709/1278662395

最近、mapserverやpostgisのinstall、google map apiによるgeocodingを記載してきていますが、最後にある地点(緯度 経度)から海岸線までの距離を算出するperl scriptを記載しておきます。

特に難しいことは行っておらず、postgisのST_Distance_Sphere()を使用しているだけです。
postgisは、ver.1.5.1を使用していますが、日本語版のリファレンスは次のurlを参考にさせていただきました。

http://www.finds.jp/docs/pgisman/index.html

#!/usr/local/bin/perl
use strict;
use DBI;
use Data::Dumper;

my $DB_CONF =
    {db_name => 'dbi:Pg:dbname=kaigan;host=localhost;port=5432;',
     user => 'postgres',
     passwd => '',
     option => {AutoCommit => 0,
	       pg_enable_utf8 => 1}};

main(@ARGV);

sub main {
    my ($lon_lat_file) = @_;

    my $dbh = connect_db();

    open (my $fh,"<:encoding(utf8)",$lon_lat_file) or
	die "can't open file: $lon_lat_file: $!";
    my @lines = <$fh>;
    close($fh) or die "can't close file: $lon_lat_file: $!";

    my $i = 0;
    for my $line ( @lines ){
	next if $i++ < 1000;

	$line =~ s/\s+$//go;
	my ($address_org,
	    $address_parse,
	    $latitude, #緯度
	    $longitude, #経度
	    $accuracy)  #住所parseの精度?
	    = split("\t",$line);
	my $kaigan_dist = calc_kaigan_distance($dbh,$latitude,$longitude);
	print $i, "\t$kaigan_dist\n";
    }

    $dbh->disconnect();
}

sub calc_kaigan_distance {
    my ($dbh,$latitude,$longitude) = @_;
    my $sql =<<EOF;
select min(ST_Distance_Sphere(?,the_geom)) from kaigan
EOF
    my $sth = $dbh->prepare($sql);
    $sth->execute("POINT($longitude $latitude)");
    return $sth->fetchrow_array();
}

sub connect_db {
    return DBI->connect($DB_CONF->{db_name},
			$DB_CONF->{user},
			$DB_CONF->{passwd},
			$DB_CONF->{option});
}