From 36a8d883b2283ccac1b283ae00b2935fc5437290 Mon Sep 17 00:00:00 2001 From: Artavazd Balaian Date: Wed, 18 Jan 2023 15:55:27 +0800 Subject: [PATCH] feat: Add proj.db to resource and copy it every time to the location from env variable `PROJ_DATA` --- .gitattributes | 1 + README.md | 5 +++ build.gradle | 2 +- docker/extract_native.sh | 3 ++ scripts/generate_native_modules.sh | 5 ++- .../com/github/reasy/gdal/GdalExample.java | 1 + .../com/github/reasy/gdal/JNIGdalLoader.java | 41 +++++++++++++++---- src/main/resources/proj/proj.db | 3 ++ 8 files changed, 50 insertions(+), 11 deletions(-) create mode 100644 src/main/resources/proj/proj.db diff --git a/.gitattributes b/.gitattributes index 4c6f71e..3a9528a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,4 @@ *.jar filter=lfs diff=lfs merge=lfs -text src/main/resources/native/linux-x86-64/* filter=lfs diff=lfs merge=lfs -text *.gpkg filter=lfs diff=lfs merge=lfs -text +*.db filter=lfs diff=lfs merge=lfs -text diff --git a/README.md b/README.md index ce7fef5..067b5ad 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ gdal-jni-with-native ====== +[](https://jitpack.io/#REASY/gdal-jni-with-native) + This project builds GDAL, extract native libraries and makes it available as Java library. At the moment it only supports GDAL on Ubuntu x64 (Linux) ### Build @@ -14,3 +16,6 @@ All of this is done in a script [generate_native_modules.sh](scripts/generate_na ```bash ./scripts/generate_native_modules.sh ``` + +### Note on the usage +Please, make sure that you set an environment variable PROJ_DATA to writable (preferably temporary) folder, for example `/tmp/gdal-jni-with-native/proj/`. That env variable is expected by PROJ, so it cannot be set on runtime by the same process. diff --git a/build.gradle b/build.gradle index e4e9033..748e8b4 100755 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ group = 'gdal-jni-with-native' -version = '3.5.3.1' +version = '3.5.3.2' buildscript { repositories { diff --git a/docker/extract_native.sh b/docker/extract_native.sh index 5588aea..f6a0307 100755 --- a/docker/extract_native.sh +++ b/docker/extract_native.sh @@ -53,3 +53,6 @@ do echo $lib >> $path_native_modules_to_load done +# Copy proj.db +cp /usr/local/share/proj/proj.db "${copy_path}/proj" +echo "/usr/local/share/proj/proj.db to ${copy_path}/proj" diff --git a/scripts/generate_native_modules.sh b/scripts/generate_native_modules.sh index 17189fd..206e563 100755 --- a/scripts/generate_native_modules.sh +++ b/scripts/generate_native_modules.sh @@ -33,5 +33,8 @@ docker run -u $(id -u):$(id -g) \ -v $(pwd)/src/main/resources/:/resources qartez-engine/lddtopo:"$GDAL_VERSION" /usr/share/java/libgdalalljni.so /resources # Build and test GDAL native library -./gradlew build && java -cp build/libs/gdal-jni-with-native-3.5.3.0.jar com.github.reasy.gdal.GdalExample +lib_name=$(./gradlew properties | grep ^name | sed 's/name: //g') +lib_version=$(./gradlew properties | grep ^version | sed 's/version: //g') +lib_full_name="$lib_name-$lib_version.jar" +./gradlew clean build && PROJ_DATA=/tmp/gdal-jni-with-native/proj/ java -cp "build/libs/$lib_full_name" com.github.reasy.gdal.GdalExample diff --git a/src/main/java/com/github/reasy/gdal/GdalExample.java b/src/main/java/com/github/reasy/gdal/GdalExample.java index 68388cd..be1e8f8 100644 --- a/src/main/java/com/github/reasy/gdal/GdalExample.java +++ b/src/main/java/com/github/reasy/gdal/GdalExample.java @@ -49,6 +49,7 @@ private static void writeCogGeoTiff() throws IOException { Dataset memDs = drv.Create("", xSize, ySize, 1, type); System.out.printf("Created %d x %d dataset with 1 band and type %d\n", xSize, ySize, type); + memDs.SetProjection("EPSG:32611"); memDs.GetRasterBand(1).WriteRaster(0, 0, xSize, ySize, data); memDs.BuildOverviews("NEAREST", new int[]{2, 4, 8, 16, 32}); diff --git a/src/main/java/com/github/reasy/gdal/JNIGdalLoader.java b/src/main/java/com/github/reasy/gdal/JNIGdalLoader.java index ab066a2..d4267e6 100644 --- a/src/main/java/com/github/reasy/gdal/JNIGdalLoader.java +++ b/src/main/java/com/github/reasy/gdal/JNIGdalLoader.java @@ -7,27 +7,39 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; import java.util.ArrayList; import java.util.List; import java.util.Objects; public class JNIGdalLoader { public static final String[] MODULES_TO_LOAD; - public static final boolean IS_LOADED; - public static final String PATH_TO_MODULES = String.format("native/%s.txt", Platform.RESOURCE_PREFIX); + public static final String PROJ_DB_PATH = "proj/proj.db"; + public static final String TEMP_PATH_FOR_PROJ_DATA; static { + if (System.getenv("PROJ_DATA") == null) { + throw new IllegalStateException("There must be an env variable `PROJ_DATA` set to writable (preferably temporary) folder, for example `/tmp/gdal-jni-with-native/proj/`"); + } + TEMP_PATH_FOR_PROJ_DATA = System.getenv("PROJ_DATA"); + try { - MODULES_TO_LOAD = GetModules(); - System.out.printf("JNIGdalLoader java: loading %d shared library...\n", MODULES_TO_LOAD.length); + MODULES_TO_LOAD = getModules(); + System.out.printf("JNIGdalLoader: loading %d shared library...\n", MODULES_TO_LOAD.length); NativeLibraryLoader loader = new NativeLibraryLoader("/native"); for (String module : MODULES_TO_LOAD) { loader.load(module); } - System.out.println("JNIGdalLoader java: loaded all shared libraries"); + System.out.println("JNIGdalLoader: loaded all shared libraries"); + + copyProjDb(); + IS_LOADED = true; } catch (Exception ex) { System.out.println(ex.getMessage()); @@ -37,17 +49,18 @@ public class JNIGdalLoader { } } + public static void load() { // Just make sure it that it is loaded. // If we reach here, it must always be true (because otherwise the RuntimeException should have been thrown before in static ctor) assert IS_LOADED; } - static String[] GetModules() throws IOException { + private static String[] getModules() throws IOException { List modules = new ArrayList<>(); - try (InputStream inputStream = JNIGdalLoader.class.getClassLoader().getResourceAsStream(PATH_TO_MODULES)) { - Objects.requireNonNull(inputStream, String.format("Resource as stream for '%s' is null", PATH_TO_MODULES)); - try (InputStreamReader streamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8); + try (InputStream in = JNIGdalLoader.class.getClassLoader().getResourceAsStream(PATH_TO_MODULES)) { + Objects.requireNonNull(in, String.format("Resource as stream for '%s' is null", PATH_TO_MODULES)); + try (InputStreamReader streamReader = new InputStreamReader(in, StandardCharsets.UTF_8); BufferedReader reader = new BufferedReader(streamReader)) { String line; while ((line = reader.readLine()) != null) { @@ -58,4 +71,14 @@ static String[] GetModules() throws IOException { return modules.toArray(new String[0]); } + private static void copyProjDb() throws IOException { + try (InputStream in = NativeLibraryLoader.class.getResourceAsStream("/" + PROJ_DB_PATH)) { + Objects.requireNonNull(in, String.format("Resource as stream for '%s' is null", PROJ_DB_PATH)); + Files.createDirectories(Paths.get(TEMP_PATH_FOR_PROJ_DATA)); + String destPath = TEMP_PATH_FOR_PROJ_DATA + "/proj.db"; + Files.copy(in, Paths.get(destPath), StandardCopyOption.REPLACE_EXISTING); + System.out.printf("JNIGdalLoader java: Copied resource at %s to %s\n", PROJ_DB_PATH, destPath); + } + } + } diff --git a/src/main/resources/proj/proj.db b/src/main/resources/proj/proj.db new file mode 100644 index 0000000..4901f62 --- /dev/null +++ b/src/main/resources/proj/proj.db @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:da051c20522043a049a965a90f2c96914ecdba3a64d99068f3bc46e18dab68c3 +size 8282112