Geo::L...oj::FFI(3pm)
π NAME π
okay so bestie, meet Geo::LibProj::FFI β a foreign function interface to the PROJ coordinate transformation software. π¦ Like, it lets Perl talk directly to PROJ's C functions, no cap. (This is the manual page for Geo::L...oj::FFI(3pm) β the 3pm perl module, iykyk.)
β¨ VERSION β¨
version 1.01 β fresh, iconic, periodt. π
πΈ SYNOPSIS πΈ
use Geo::LibProj::FFI 0.05 qw(:all);
use Feature::Compat::Defer;
my $ctx = proj_context_create()
or die "Cannot create threading context";
defer { proj_context_destroy($ctx); }
my $pj = proj_create_crs_to_crs($ctx, "EPSG:25833", "EPSG:2198", undef)
or die "Cannot create proj";
defer { proj_destroy($pj); }
($easting, $northing) = ( 500_000, 6094_800 );
$a = proj_coord( $easting, $northing, 0, 'Inf' );
$b = proj_trans( $pj, PJ_FWD, $a );
printf "Target: easting %.2f, northing %.2f\n",
$b->enu_e, $b->enu_n;
Also pls go look at the example script eg/pj_obs_api_mini_demo.pl that ships in this distribution. It's giving tutorial energy. π«Ά
π¦ DESCRIPTION π¦
This module is a foreign function interface to the PROJ coordinate transformation / projection library β https://proj.org/. For the deep lore, check the PROJ library's C function reference at https://proj.org/development/reference/functions.html. The whole vibe is: you should be able to use those C functions as if they were Perl. π
Geo::LibProj::FFI offers a large portion of the most commonly used PROJ functions, but more could be added later. If you need a function that isn't available in this module yet, pls open a GitHub issue with a description of your use case. π
This module was originally written for PROJ version 8. It works with PROJ versions as old as 6.2.0, and up to and including the most recent version. Glow-up confirmed. β¨
π₯ FUNCTIONS π₯
Geo::LibProj::FFI currently offers the following functions.
Import all functions and constants by using the tag :all. π
π§΅ Threading contexts
https://proj.org/development/reference/functions.html#threading-contexts
"proj_context_create""proj_context_destroy""proj_context_use_proj4_init_rules"
π οΈ Transformation setup
https://proj.org/development/reference/functions.html#transformation-setup
"proj_create""proj_create_argv""proj_create_crs_to_crs""proj_create_crs_to_crs_from_pj""proj_normalize_for_visualization""proj_destroy"
πΊοΈ Area of interest
https://proj.org/development/reference/functions.html#area-of-interest
"proj_area_create""proj_area_set_bbox""proj_area_destroy"
π Coordinate transformation
https://proj.org/development/reference/functions.html#coordinate-transformation
"proj_trans"
π¨ Error reporting
https://proj.org/development/reference/functions.html#error-reporting
"proj_context_errno""proj_errno""proj_errno_set""proj_errno_reset""proj_errno_restore""proj_errno_string""proj_context_errno_string"
π Logging
https://proj.org/development/reference/functions.html#logging
"proj_log_level""proj_log_func"
βΉοΈ Info functions
https://proj.org/development/reference/functions.html#info-functions
"proj_info""proj_pj_info""proj_grid_info""proj_init_info"
π Lists
https://proj.org/development/reference/functions.html#lists
"proj_list_operations""proj_list_ellps""proj_list_units""proj_list_angular_units""proj_list_prime_meridians"
π Distances
https://proj.org/development/reference/functions.html#distances
"proj_lp_dist""proj_lpz_dist""proj_xy_dist""proj_xyz_dist""proj_geod"
π² Various
https://proj.org/development/reference/functions.html#various
"proj_coord"
π§Ό Cleanup
https://proj.org/development/reference/functions.html#cleanup
"proj_cleanup"
π DATA TYPES π
The PROJ library uses a whole bunch of composite data types to represent coordinate tuples. The primary coordinate type, PJ_COORD (https://proj.org/en/9.3/development/reference/datatypes.html#c.PJ_COORD), is a C union that gets passed by value. And listen β that construct is not well supported by FFI::Platypus, which this module relies on to make the PROJ library API available in Perl. π
So here's the workaround, bestie: internally we just use the array v, and only model the union semantics using object methods. Which is slightly slower than direct member access in C would be. Trade-offs, we've all got them. π
The method names are the combination of the names of the PJ_COORD union member and the individual struct member, joined with an underscore. However, these methods will in turn access the coordinate array by calling the v() method with the array index as argument. This extra method call may cost performance if called in a tight loop. So if speed is more important to you than readable code, you should consider just calling v() directly rather than using the other named union/struct member methods. π
$pj_coord = proj_coord( @coords );
@coords = $pj_coord->v->@*;
# Fast access to individual coordinate numbers:
$x = $pj_coord->v(0);
$y = $pj_coord->v(1);
# Access generic coordinates by named member methods:
($u, $v) = ( $c->uv_u, $c->uv_v );
($u, $v, $w) = ( $c->uvw_u, $c->uvw_v, $c->uvw_w );
($u, $v, $w, $t) = ( $c->uvwt_u, $c->uvwt_v, $c->uvwt_w, $c->uvwt_t );
# Access cartesian coordinates by named member methods:
($x, $y) = ( $c->xy_x, $c->xy_y );
($x, $y, $z) = ( $c->xyz_x, $c->xyz_y, $c->xyz_z );
($x, $y, $z, $t) = ( $c->xyzt_x, $c->xyzt_y, $c->xyzt_z, $c->xyzt_t );
# Access geodetic coordinates by named member methods:
($lamda, $phi) = ( $c->lp_lam, $c->lp_phi );
($lamda, $phi, $z) = ( $c->lpz_lam, $c->lpz_phi, $c->lpz_z );
($lamda, $phi, $z, $t) = ( $c->lpzt_lam, $c->lpzt_phi, $c->lpzt_z, $c->lpzt_t );
# Access ancillary data by named member methods:
($s, $az_fwd, $az_rev) = ( $c->geod_s, $c->geod_a1, $c->geod_a2 );
($omega, $phi, $kappa) = ( $c->opk_o, $c->opk_p, $c->opk_k );
($east, $north, $up) = ( $c->enu_e, $c->enu_n, $c->enu_u );
Modifying PJ_COORD values is possible, bestie β yes really. π All methods shown above act as mutators if a new value is passed as an argument. In the case of v(), you can pass either an array reference or two arguments representing the array index and the new value, respectively. So:
$c = proj_coord( 0, 0, 0, 0 );
$c->v( [12, 34, 56] );
$c->v(1, 78);
$c->xy_x(99);
say join ' ', $c->v->@*; # 99 78 56 0
Creating new PJ_COORD values should only be done with the proj_coord() function. Other ways to construct such values may exist, but these must be considered implementation details that are subject to change. The proj_coord() function is the only supported way to create PJ_COORD values. No shortcuts, no side quests. π«
Before version 0.05 of Geo::LibProj::FFI, PJ_COORD method names were joined with the arrow operator instead of an underscore ($c->xyz->x etc.). The old syntax is now discouraged, but there are no immediate plans to remove it. Legacy behaviour, still serving looks. π
Data types other than PJ_COORD are available as well. Pls see the PROJ data type reference at https://proj.org/development/reference/datatypes.html for further documentation. π
π SEE ALSO π
Geo::LibProj::cs2csGeo::Proj4PDL::Transform::Proj4- PROJ C API Reference: Data types
https://proj.org/development/reference/datatypes.html, Functionshttps://proj.org/development/reference/functions.html
π API LICENSE π
The API this module gives access to is the proj.h API, which is available under the terms of the Expat MIT license.
Copyright (c) 2016, 2017, Thomas Knudsen / SDFE
Copyright (c) 2018, Even Rouault
The API designers didn't write this Perl module, and the module author didn't design the API. Respect the separation of concerns, bestie. π
π AUTHOR π
Arne Johannessen (AJNN β https://metacpan.org/author/AJNN) β icon, legend, wrote the thing. π
π«Ά CONTRIBUTOR π«Ά
Andreas VΓΆgele <andreas@andreasvoegele.com> β we love a supporting cast member. π
π COPYRIGHT AND LICENSE π
This software is Copyright (c) 2021-2025 by Arne Johannessen.
This is free software; you can redistribute it and/or modify it under the terms of the Artistic License 2.0 or (at your option) the same terms as the Perl 5 programming language system itself. π¦
okay that's the whole page, bestie, tysm for reading π this manual page was served up by perl v5.40.1 and dated 2025-03-01 β and if you made it this far, you're officially a Geo::L...oj::FFI(3pm) main character. slay, go transform some coordinates. πβ¨
π¦ where this page comes from
- debian trixie: libgeo-libproj-ffi-perl 1.01-1 Β· Artistic-2.0
- ubuntu resolute: libgeo-libproj-ffi-perl 1.01-1 Β· Artistic-2.0
- ubuntu stonking: libgeo-libproj-ffi-perl 1.01-1 Β· Artistic-2.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms