Closed categulario closed 2 years ago
The info()
method will give you a struct whose searchpath
field is a String
containing a :
-delimited list of the PROJ
search paths that are in use by the executable / library you built. I don't know if they're returned in any particular order, so you'll probably have to split on the :
and check each entry for the presence of proj.db
(mine is in the second entry in the list on macOS, for instance).
This works:
use proj::{Info, Proj};
use std::path::{Path, PathBuf};
let pb = PathBuf::from("proj.db");
let p = Proj::new("EPSG:4326").unwrap();
let info = p.info().unwrap();
let foundproj = info
.searchpath
.split(':')
.filter_map(|dir| {
let projdir = Path::new(dir).join(&pb);
projdir.exists().then(|| projdir)
})
.collect::<Vec<_>>();
// foundproj will either be empty or contain at least one PathBuf entry with the full proj.db path
// You may also want to assert that there's only a single entry in the vec, idk
and finally if you want, you can put proj.db (you'll have to download it yourself from wherever OSgeo host it for v9.0.0) wherever you want, then add the path to the directory (as opposed to path to the file) to the search path using https://docs.rs/proj/0.26.0/proj/struct.ProjBuilder.html#method.set_search_paths
Thanks for your answers @urschrei !
All of this was triggered by my attempts at building a container for an app that uses proj
. In the end the best solution I found was to use an intermediate container with alpine and use its proj.db
:/
(you'll have to download it yourself from wherever OSgeo host it for v9.0.0)
From what I've seen they don't host it, because it is built at compile time. It is a target for cmake.
Just for completeness of this thread and in case it is useful for somebody else:
I'm now doing these three things:
bundled_proj
feature enabledsrc/bin
with the only purpose of moving the built proj.db
file somewhere else.cargo run --release --bin moveprojdb /some/path
so I know where to find it and use it as a build artifact that I copy to the next stage.And this is the resulting code for finding proj.db
:
let proj = Proj::new("EPSG:4326").unwrap();
let searchpath = proj.info().unwrap().searchpath;
let foundproj = searchpath
.split(':')
.find_map(|dir| {
let projdb = Path::new(dir).join("proj.db");
projdb.is_file().then(|| projdb)
});
Ok, here is the situation I'm facing (similar to #66):
I'm trying to package a project built with
proj
for deployment. Since my build environment doesn't have a recent version ofproj
the build process just builds it from source. Everything is fine there when running locally. When I try to run the binary somewhere else I face aproj.db
not found. It makes sense, it is not there.Now, I know that one such database is being built as part of the building process of
proj-sys
. I even found it intarget/debug/build/proj-sys-3de39dabca2db38d/out/share/proj/proj.ini
the question now is, how do I find this path? Is it predictable? Is there another way to get the builtproj.db
?Thanks folks!