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 )