Skip to content

Commit

Permalink
feat: Add proj.db to resource and copy it every time to the location …
Browse files Browse the repository at this point in the history
…from env variable `PROJ_DATA`
  • Loading branch information
REASY committed Jan 18, 2023
1 parent b51c10c commit 36a8d88
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 11 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -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
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
gdal-jni-with-native
======
[<img src="https://jitpack.io/v/REASY/gdal-jni-with-native.svg">](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
Expand All @@ -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.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
group = 'gdal-jni-with-native'
version = '3.5.3.1'
version = '3.5.3.2'

buildscript {
repositories {
Expand Down
3 changes: 3 additions & 0 deletions docker/extract_native.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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"
5 changes: 4 additions & 1 deletion scripts/generate_native_modules.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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

1 change: 1 addition & 0 deletions src/main/java/com/github/reasy/gdal/GdalExample.java
Original file line number Diff line number Diff line change
Expand Up @@ -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});

Expand Down
41 changes: 32 additions & 9 deletions src/main/java/com/github/reasy/gdal/JNIGdalLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand All @@ -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<String> 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) {
Expand All @@ -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);
}
}

}
3 changes: 3 additions & 0 deletions src/main/resources/proj/proj.db
Git LFS file not shown

0 comments on commit 36a8d88

Please sign in to comment.