This is an automated email from the ASF dual-hosted git repository.

bchapuis pushed a commit to branch gdal
in repository https://gitbox.apache.org/repos/asf/incubator-baremaps.git

commit 499a2381fbc3ed0599065202dcfe8a79dbc00348
Author: Bertil Chapuis <[email protected]>
AuthorDate: Fri Mar 24 16:05:09 2023 +0100

    WIP - experiment with gdal
---
 baremaps-core/pom.xml                              |   4 +
 .../apache/baremaps/raster/ContourTileStore.java   |  94 ++++++++
 .../main/java/org/apache/baremaps/raster/Main.java | 257 +++++++++++++++++++++
 examples/contour/dem.xml                           |  29 +++
 pom.xml                                            |   6 +
 5 files changed, 390 insertions(+)

diff --git a/baremaps-core/pom.xml b/baremaps-core/pom.xml
index fe924eec..4b83e635 100644
--- a/baremaps-core/pom.xml
+++ b/baremaps-core/pom.xml
@@ -118,6 +118,10 @@ limitations under the License.
       <groupId>org.graalvm.sdk</groupId>
       <artifactId>graal-sdk</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.gdal</groupId>
+      <artifactId>gdal</artifactId>
+    </dependency>
     <dependency>
       <groupId>org.locationtech.jts</groupId>
       <artifactId>jts-core</artifactId>
diff --git 
a/baremaps-core/src/main/java/org/apache/baremaps/raster/ContourTileStore.java 
b/baremaps-core/src/main/java/org/apache/baremaps/raster/ContourTileStore.java
new file mode 100644
index 00000000..a352fa20
--- /dev/null
+++ 
b/baremaps-core/src/main/java/org/apache/baremaps/raster/ContourTileStore.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not 
use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software 
distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
KIND, either express
+ * or implied. See the License for the specific language governing permissions 
and limitations under
+ * the License.
+ */
+
+package org.apache.baremaps.raster;
+
+import java.net.URL;
+import java.nio.ByteBuffer;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.Vector;
+import org.apache.baremaps.database.tile.Tile;
+import org.apache.baremaps.database.tile.TileStore;
+import org.apache.baremaps.database.tile.TileStoreException;
+import org.gdal.gdal.gdal;
+import org.gdal.gdalconst.gdalconstConstants;
+import org.gdal.ogr.FieldDefn;
+import org.gdal.ogr.ogr;
+import org.gdal.osr.SpatialReference;
+
+public class ContourTileStore implements TileStore {
+  @Override
+  public ByteBuffer read(Tile tile) throws TileStoreException {
+    var file = Paths.get(String.format("%s/%s/%s.tif", tile.z(), tile.x(), 
tile.y()));
+    var source = 
String.format("https://s3.amazonaws.com/elevation-tiles-prod/geotiff/%s";, file);
+
+    try {
+      Files.deleteIfExists(file);
+      Files.createDirectories(file.getParent());
+      Files.createFile(file);
+      try (var stream = new URL(source).openStream()) {
+        Files.copy(stream, file);
+      }
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+
+    var dataset = gdal.Open(file.toString(), gdalconstConstants.GA_ReadOnly);
+
+    dataset.GetGeoTransform();
+    dataset.GetRasterXSize();
+    dataset.GetRasterYSize();
+
+
+    var band = dataset.GetRasterBand(1);
+
+    band.ReadRaster_Direct(0, 0, 100, 100);
+
+    var wkt = dataset.GetProjection();
+    var srs = new SpatialReference(wkt);
+
+    var driver = ogr.GetDriverByName("Memory");
+    var dataSource = driver.CreateDataSource("memory_name");
+
+    var layer = dataSource.CreateLayer("contour", srs, ogr.wkbLineString);
+
+    var field = new FieldDefn("ID", ogr.OFTInteger);
+    field.SetWidth(8);
+    layer.CreateField(field, 0);
+    field.delete();
+
+    gdal.ContourGenerateEx(band, layer, new Vector<>(List.of(
+        "LEVEL_INTERVAL=" + 10)));
+
+    for (int i = 0; i < layer.GetFeatureCount(); i++) {
+      var feature = layer.GetFeature(i);
+      var geometry = feature.GetGeometryRef();
+      // System.out.println(geometry.ExportToWkt());
+    }
+
+    dataSource.delete();
+    dataset.delete();
+    return null;
+  }
+
+  @Override
+  public void write(Tile tile, ByteBuffer blob) throws TileStoreException {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public void delete(Tile tile) throws TileStoreException {
+    throw new UnsupportedOperationException();
+  }
+}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/raster/Main.java 
b/baremaps-core/src/main/java/org/apache/baremaps/raster/Main.java
new file mode 100644
index 00000000..4e37b4d5
--- /dev/null
+++ b/baremaps-core/src/main/java/org/apache/baremaps/raster/Main.java
@@ -0,0 +1,257 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not 
use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software 
distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
KIND, either express
+ * or implied. See the License for the specific language governing permissions 
and limitations under
+ * the License.
+ */
+
+package org.apache.baremaps.raster;
+
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.List;
+import java.util.Vector;
+import org.gdal.gdal.*;
+import org.gdal.gdalconst.gdalconstConstants;
+import org.gdal.ogr.*;
+import org.gdal.osr.SpatialReference;
+
+public class Main {
+
+  public static void main(String[] args) {
+
+    // var sourceFilename = 
Paths.get("examples/contour/liecthenstein-aster-dem-v2-3857.tif")
+    // .toAbsolutePath().toString();
+    // var hillshadeFilename =
+    // 
Paths.get("examples/contour/liecthenstein-aster-dem-v2-3857-hillshade.tif").toAbsolutePath()
+    // .toString();
+    // var outputFilename = 
Paths.get("examples/contour/liecthenstein-aster-dem-v2-3857.shp")
+    // .toAbsolutePath().toString();
+    // var warpFilename = 
Paths.get("examples/contour/liecthenstein-aster-dem-v2-3857-warp.tif")
+    // .toAbsolutePath().toString();
+
+
+    var dem = Paths.get("examples/contour/dem.xml")
+        .toAbsolutePath().toString();
+
+    gdal.AllRegister();
+    ogr.RegisterAll();
+
+    
planetContour("https://s3.amazonaws.com/elevation-tiles-prod/geotiff/%s/%s/%s.tif";);
+
+    // hillshade(sourceFilename, 1, hillshadeFilename, 45d, 315d);
+    // contourEx(hillshadeFilename, 1, outputFilename, 50, 0);
+    // warp(sourceFilename, warpFilename);
+    // shadow(hillshadeFilename, outputFilename);
+  }
+
+  public static void planetContour(String source) {
+    var file = Paths.get(String.format("%s/%s/%s.tif", 14, 8514, 5816));
+    var url = 
String.format("https://s3.amazonaws.com/elevation-tiles-prod/geotiff/%s";, file);
+    System.out.println(url);
+
+    try {
+      Files.deleteIfExists(file);
+      Files.createDirectories(file.getParent());
+      Files.createFile(file);
+      try (var stream = new URL(url).openStream()) {
+        Files.copy(stream, file, StandardCopyOption.REPLACE_EXISTING);
+      }
+      System.out.println(Files.size(file));
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+
+
+    var dataset = gdal.Open(file.toString(), gdalconstConstants.GA_ReadOnly);
+
+    var band = dataset.GetRasterBand(1);
+
+    band.ReadRaster_Direct(0, 0, 100, 100);
+
+    var wkt = dataset.GetProjection();
+    var srs = new SpatialReference(wkt);
+
+    var driver = ogr.GetDriverByName("Memory");
+    var dataSource = driver.CreateDataSource("memory_name");
+
+    var layer = dataSource.CreateLayer("contour", srs, ogr.wkbLineString);
+
+    var field = new FieldDefn("ID", ogr.OFTInteger);
+    field.SetWidth(8);
+    layer.CreateField(field, 0);
+    field.delete();
+
+    gdal.ContourGenerateEx(band, layer, new Vector<>(List.of(
+        "LEVEL_INTERVAL=" + 10)));
+
+    for (int i = 0; i < layer.GetFeatureCount(); i++) {
+      var feature = layer.GetFeature(i);
+      var geometry = feature.GetGeometryRef();
+      System.out.println(geometry.ExportToWkt());
+    }
+
+    dataSource.delete();
+    dataset.delete();
+  }
+
+  public static void contour(String source, Integer sourceBand, String target,
+      Integer contourInterval,
+      Integer contourBase) {
+
+    var dataset = gdal.Open(source, gdalconstConstants.GA_ReadOnly);
+    var band = dataset.GetRasterBand(sourceBand);
+    var wkt = dataset.GetProjection();
+    var srs = new SpatialReference(wkt);
+
+    var driver = ogr.GetDriverByName("ESRI Shapefile");
+    var dataSource = driver.CreateDataSource(target);
+    var layer = dataSource.CreateLayer("contour", srs, ogr.wkbLineString);
+    var field = new FieldDefn("ID", ogr.OFTInteger);
+
+    field.SetWidth(8);
+    layer.CreateField(field, 0);
+    field.delete();
+
+    var feature = layer.GetLayerDefn();
+    gdal.ContourGenerate(band, contourInterval, contourBase, null,
+        0, 0, layer, feature.GetFieldIndex("ID"),
+        -1);
+
+    dataSource.delete();
+    dataset.delete();
+  }
+
+  public static void contourEx(String source, Integer sourceBand, String 
target,
+      Integer contourInterval,
+      Integer contourBase) {
+
+    var dataset = gdal.Open(source, gdalconstConstants.GA_ReadOnly);
+    var band = dataset.GetRasterBand(sourceBand);
+    var wkt = dataset.GetProjection();
+    var srs = new SpatialReference(wkt);
+
+    var driver = ogr.GetDriverByName("ESRI Shapefile");
+    var dataSource = driver.CreateDataSource(target);
+    var layer = dataSource.CreateLayer("contour", srs, ogr.wkbLineString);
+    var field = new FieldDefn("ID", ogr.OFTInteger);
+
+    field.SetWidth(8);
+    layer.CreateField(field, 0);
+    field.delete();
+
+    gdal.ContourGenerateEx(band, layer, new Vector<>(List.of(
+        "LEVEL_BASE=" + contourBase,
+        "LEVEL_INTERVAL=" + contourInterval,
+        "POLYGONIZE=YES")));
+
+    dataSource.delete();
+    dataset.delete();
+  }
+
+  public static void polygonize(String source, Integer sourceBand, String 
target) {
+    var dataset = gdal.Open(source, gdalconstConstants.GA_ReadOnly);
+    var band = dataset.GetRasterBand(sourceBand);
+    var wkt = dataset.GetProjection();
+    var srs = new SpatialReference(wkt);
+
+    var driver = ogr.GetDriverByName("ESRI Shapefile");
+    var dataSource = driver.CreateDataSource(target);
+    var layer = dataSource.CreateLayer("polygonize", srs, ogr.wkbPolygon);
+    var field = new FieldDefn("ID", ogr.OFTInteger);
+
+    field.SetWidth(8);
+    layer.CreateField(field, 0);
+    field.delete();
+
+    var feature = layer.GetLayerDefn();
+    gdal.Polygonize(band, null, layer, feature.GetFieldIndex("ID"),
+        null, null);
+
+    dataSource.delete();
+    dataset.delete();
+  }
+
+  public static void warp(String source, String target) {
+    var dataset = gdal.Open(source, gdalconstConstants.GA_ReadOnly);
+    var transform = dataset.GetGeoTransform();
+    var xRes = transform[1];
+    var yRes = transform[5];
+
+    var options = new Vector<>(List.of(
+        "-tr", Double.toString(xRes * 10), Double.toString(yRes * 10)));
+
+    var warp = gdal.Warp(target, new Dataset[] {dataset}, new 
WarpOptions(options));
+
+    warp.delete();
+    dataset.delete();
+  }
+
+
+  public record ShadowClass(int a, int b, int c) {
+  }
+
+  private static final List<ShadowClass> shadowClasses = List.of(
+      new ShadowClass(1, 250, 255),
+      new ShadowClass(2, 240, 255),
+      new ShadowClass(3, 1, 150),
+      new ShadowClass(4, 1, 100),
+      new ShadowClass(5, 1, 65),
+      new ShadowClass(6, 1, 2));
+
+  private static void shadow(String source, String target) {
+    var dataset = gdal.Open(source, gdalconstConstants.GA_ReadOnly);
+    var band = dataset.GetRasterBand(1);
+    var wkt = dataset.GetProjection();
+    var srs = new SpatialReference(wkt);
+
+    var driver = ogr.GetDriverByName("ESRI Shapefile");
+    var dataSource = driver.CreateDataSource(target);
+
+    for (var shadowClass : shadowClasses) {
+      var layer = dataSource.CreateLayer("shadow-" + shadowClass.a(), srs, 
ogr.wkbPolygon);
+      var field = new FieldDefn("ID", ogr.OFTInteger);
+
+      field.SetWidth(8);
+      layer.CreateField(field, 0);
+      field.delete();
+
+      gdal.ContourGenerateEx(band, layer, new Vector<>(List.of(
+          "LEVEL_BASE=" + shadowClass.b(),
+          "LEVEL_INTERVAL=" + shadowClass.c(),
+          "POLYGONIZE=YES")));
+    }
+
+    dataSource.delete();
+    dataset.delete();
+
+  }
+
+
+  public static void hillshade(String source, Integer sourceBand, String 
target, Double azimuth,
+      Double altitude) {
+    var options = new Vector<>(List.of(
+        "-az", azimuth.toString(),
+        "-alt", altitude.toString(),
+        "-z", "1.0",
+        "-s", "1.0",
+        "-b", sourceBand.toString(),
+        "-of", "GTiff",
+        "-combined"));
+
+    var dataset = gdal.Open(source, gdalconstConstants.GA_ReadOnly);
+    var hillshadeDataset =
+        gdal.DEMProcessing(target, dataset, "hillshade", null, new 
DEMProcessingOptions(options));
+
+    hillshadeDataset.delete();
+    dataset.delete();
+  }
+
+}
diff --git a/examples/contour/dem.xml b/examples/contour/dem.xml
new file mode 100644
index 00000000..178ca466
--- /dev/null
+++ b/examples/contour/dem.xml
@@ -0,0 +1,29 @@
+<GDAL_WMS>
+    <!--
+    Generate contour lines for the planet.
+    gdal_contour -a elevation -nln contour -i 10 -f GPKG dem.xml dem.gpkg
+    -->
+    <Service name="TMS">
+        
<ServerUrl>https://s3.amazonaws.com/elevation-tiles-prod/geotiff/${z}/${x}/${y}.tif</ServerUrl>
+    </Service>
+    <DataWindow>
+        <UpperLeftX>-20037508.34</UpperLeftX>
+        <UpperLeftY>20037508.34</UpperLeftY>
+        <LowerRightX>20037508.34</LowerRightX>
+        <LowerRightY>-20037508.34</LowerRightY>
+        <TileLevel>14</TileLevel>
+        <TileCountX>1</TileCountX>
+        <TileCountY>1</TileCountY>
+        <YOrigin>top</YOrigin>
+    </DataWindow>
+    <Projection>EPSG:3857</Projection>
+    <BlockSizeX>512</BlockSizeX>
+    <BlockSizeY>512</BlockSizeY>
+    <BandsCount>1</BandsCount>
+    <DataType>Int16</DataType>
+    <ZeroBlockHttpCodes>403,404</ZeroBlockHttpCodes>
+    <DataValues>
+        <NoData>-32768</NoData>
+    </DataValues>
+    <Cache/>
+</GDAL_WMS>
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 83662488..e0d6812f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -89,6 +89,7 @@ limitations under the License.
     <version.lib.commons-compress>1.21</version.lib.commons-compress>
     <version.lib.fastutil>8.5.9</version.lib.fastutil>
     <version.lib.flatgeobuf>3.24.0</version.lib.flatgeobuf>
+    <version.lib.gdal>3.6.3</version.lib.gdal>
     <version.lib.geopackage>6.5.0</version.lib.geopackage>
     <version.lib.graalvm>22.2.0</version.lib.graalvm>
     <version.lib.guava>31.1-jre</version.lib.guava>
@@ -393,6 +394,11 @@ limitations under the License.
         <version>${version.lib.awaitability}</version>
         <scope>test</scope>
       </dependency>
+      <dependency>
+        <groupId>org.gdal</groupId>
+        <artifactId>gdal</artifactId>
+        <version>${version.lib.gdal}</version>
+      </dependency>
       <dependency>
         <groupId>org.glassfish.jaxb</groupId>
         <artifactId>jaxb-runtime</artifactId>

Reply via email to