Geo-LibProj-cs2cs
view release on metacpan or search on metacpan
lib/Geo/LibProj/cs2cs.pm view on Meta::CPAN
use 5.014;
use strict;
use warnings;
package Geo::LibProj::cs2cs;
# ABSTRACT: IPC interface to PROJ cs2cs
$Geo::LibProj::cs2cs::VERSION = '1.03';
use Carp qw(carp croak);
use File::Basename qw(basename);
use File::Spec;
use Scalar::Util 1.10 qw(looks_like_number);
use IPC::Run3 qw(run3);
our $CMD = 'cs2cs';
our @PATH = ();
BEGIN {
# optional modules
eval "require Alien::proj" or eval "require Alien::Proj4";
}
eval { unshift @PATH, File::Spec->catdir(Alien::proj->dist_dir, 'bin') };
eval { push @PATH, undef, File::Spec->catdir(Alien::Proj4->dist_dir, 'bin') };
# default stringification formats for cs2cs stdin and stdout
our $FORMAT_IN = '%.15g';
our $FORMAT_OUT = '%.12g';
our %PARAMS = (
-f => $FORMAT_OUT,
);
sub new {
my $class = shift;
my ($source_crs, $target_crs, $user_params);
if ( ref($_[0]) eq 'HASH' ) {
($user_params, $source_crs, $target_crs) = @_;
}
else {
($source_crs, $target_crs, $user_params) = @_;
}
my $self = bless {}, $class;
my $params = { %PARAMS, defined $user_params ? %$user_params : () };
$self->_special_params($params);
$self->{format_in} = $FORMAT_IN;
# assemble cs2cs call line
for my $key (keys %$params) {
delete $params->{$key} unless defined $params->{$key};
}
my @source_crs = split m/ /, $source_crs // 'undef';
my @target_crs = split m/ /, $target_crs // 'undef';
$self->{cmd} = $self->_cmd();
$self->{call} = [$self->{cmd}, %$params, @source_crs, '+to', @target_crs, '-'];
$self->_ffi_init($source_crs, $target_crs, $params);
return $self;
}
sub _special_params {
my ($self, $params) = @_;
# support -d even for older cs2cs versions
if (defined $params->{-d} && defined $params->{-f}) {
$params->{-f} = '%.' . (0 + $params->{-d}) . 'f';
delete $params->{-d};
}
croak "-E is unsupported" if defined $params->{'-E'};
croak "-t is unsupported" if defined $params->{'-t'};
croak "-v is unsupported" if defined $params->{'-v'};
# -w3 must be supplied as a single parameter to cs2cs
if (defined $params->{-w}) {
$params->{"-w$params->{-w}"} = '';
delete $params->{-w};
}
if (defined $params->{-W}) {
$params->{"-W$params->{-W}"} = '';
delete $params->{-W};
}
$self->{ffi} = $INC{'Geo/LibProj/FFI.pm'}
&& ( $params->{XS} || ! defined $params->{XS} );
$self->{ffi_warn} = $params->{XS};
delete $params->{XS};
}
sub _cmd {
# try to find the cs2cs binary
foreach my $path (@PATH) {
if (defined $path) {
my $cmd = File::Spec->catfile($path, $CMD);
return $cmd if -e $cmd;
}
else {
# when the @PATH element is undefined, try the env PATH
eval { run3 [$CMD, '-lp'], \undef, \undef, \undef };
return $CMD if ! $@ && $? == 0;
}
}
# no luck; let's just hope it'll be on the PATH somewhere
return $CMD;
}
sub _ffi_init {
my ($self, $source_crs, $target_crs, $params) = @_;
( run in 1.301 second using v1.01-cache-2.11-cpan-71847e10f99 )