Packages

A simple Erlang/Elixir NIF wrapper for the Proj C library

Current section

Files

Jump to
proj_nif zig_src proj_nif.zig
Raw

zig_src/proj_nif.zig

const build_options = @import("build_options");
const std = @import("std");
const e = @cImport({
@cInclude("erl_nif.h");
});
const proj = @cImport({
@cInclude("proj.h");
});
/// nif: convert_crs_to_crs/4
fn convert_crs_to_crs(env: ?*e.ErlNifEnv,
argc: c_int,
argv: [*c]const c_ulong) callconv(.C) e.ERL_NIF_TERM {
if(argc != 4) {
std.log.err("wrong number of arguments", .{});
return e.enif_make_badarg(env);
}
const STR_SIZE = 100;
var crs_from: [100]u8 = undefined;
if(e.enif_get_string(env, argv[0], &crs_from, STR_SIZE, e.ERL_NIF_LATIN1) == 0) {
std.log.err("cannot get string crs_from", .{});
return e.enif_make_badarg(env);
}
var crs_to: [100]u8 = undefined;
if(e.enif_get_string(env, argv[1], &crs_to, STR_SIZE, e.ERL_NIF_LATIN1) == 0) {
std.log.err("cannot get string crs_to", .{});
return e.enif_make_badarg(env);
}
var pt_from: f64 = 0.0;
if(e.enif_get_double(env, argv[2], &pt_from) == 0) {
std.log.err("cannot get pt_from", .{});
return e.enif_make_badarg(env);
}
var pt_to: f64 = 0.0;
if(e.enif_get_double(env, argv[3], &pt_to) == 0) {
std.log.err("cannot get pt_to", .{});
return e.enif_make_badarg(env);
}
//const C = proj.PJ_DEFAULT_CTX;
const C = proj.proj_context_create();
defer _ = proj.proj_context_destroy(C);
//const P0 = proj.proj_create_crs_to_crs(C, @ptrCast([*c] const u8, &crs_from), @ptrCast([*c] const u8, &crs_to), null);
const P0 = proj.proj_create_crs_to_crs(C, &crs_from, &crs_to, null);
defer _ = proj.proj_destroy(P0);
// This will ensure that the order of coordinates for the input CRS
// will be longitude, latitude, whereas EPSG:4326 mandates latitude,
// longitude
const P = proj.proj_normalize_for_visualization(C, P0);
defer _ = proj.proj_destroy(P);
const a = proj.proj_coord(pt_from, pt_to, 0, 0);
const b = proj.proj_trans(P, proj.PJ_FWD, a);
// var tuple_slice = [_]f64{ 0.0, 0.0 };
// tuple_slice[0] = b.enu.e;
// tuple_slice[1] = b.enu.n;
//return tuple_slice;
return e.enif_make_tuple2(env,
e.enif_make_double(env, b.enu.e),
e.enif_make_double(env, b.enu.n));
}
export var nif_funcs = [_]e.ErlNifFunc{
.{.name = "convert_crs_to_crs",
.arity = 4,
.fptr = convert_crs_to_crs,
.flags = 0}
};
const entry = e.ErlNifEntry{
.major = 2,
.minor = 16,
.name = if(build_options.use_elixir) "Elixir.ProjNif" else "proj_nif",
.num_of_funcs = 1,
.funcs = &(nif_funcs[0]),
.load = null,
.reload = null,
.upgrade = null,
.unload = null,
.vm_variant = "beam.vanilla",
.options = 1,
.sizeof_ErlNifResourceTypeInit = @sizeOf(e.ErlNifResourceTypeInit),
.min_erts = "erts-12.0"
};
export fn nif_init() *const e.ErlNifEntry {
return &entry;
}
//e.ERL_NIF_INIT(proj_nif, nif_funcs, null, null, null, null);