Mike Barry 2023-03-27 06:44:07 -04:00
rodzic b31fa90b75
commit 6cc291b917
2 zmienionych plików z 99 dodań i 4 usunięć

Wyświetl plik

@ -1,10 +1,41 @@
package com.onthegomap.planetiler.contour;
import static java.util.Map.entry;
import com.carrotsearch.hppc.IntIntHashMap;
import com.carrotsearch.hppc.IntIntMap;
import com.onthegomap.planetiler.config.PlanetilerConfig;
import com.onthegomap.planetiler.util.Downloader;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.Map;
import javax.imageio.ImageIO;
public class EsaWorldcover {
// stack:
// nothing / built-up / moss / water
// 1: shrub / grass / herbacious wetland
// 2: crop
// 3: tree / mangrove
// 4: very tree / mangrove
// ice ?
private static final Map<Integer, String> colors = Map.ofEntries(
entry(new Color(0, 100, 0, 255).getRGB(), "treecover"),
entry(new Color(255, 187, 34, 255).getRGB(), "shrubland"),
entry(new Color(255, 255, 76, 255).getRGB(), "grassland"),
entry(new Color(240, 150, 255, 255).getRGB(), "cropland"),
entry(new Color(250, 0, 0, 255).getRGB(), "builtup"),
entry(new Color(180, 180, 180, 255).getRGB(), "bare"),
entry(new Color(240, 240, 240, 255).getRGB(), "snow"),
entry(new Color(0, 100, 200, 255).getRGB(), "water"),
entry(new Color(0, 150, 160, 255).getRGB(), "wetland"),
entry(new Color(0, 207, 117, 255).getRGB(), "mangrove"),
entry(new Color(250, 230, 160, 255).getRGB(), "moss")
);
static String getCoord(double ilon, double ilat) {
int lon = (int) (Math.floor(ilon / 3) * 3);
int lat = (int) (Math.floor(ilat / 3) * 3);
@ -16,12 +47,29 @@ public class EsaWorldcover {
public static void main(String[] args) throws IOException {
var config = PlanetilerConfig.defaults();
String entry = "ESA_WorldCover_10m_2021_v200_" + getCoord(-71.5, 42.2) + "_Map.tif";
String entry = "ESA_WorldCover_10m_2021_v200_" + getCoord(-72, 42) + "_Map.tif";
String url = "https://esa-worldcover.s3.amazonaws.com/v200/2021/map/" + entry;
// ESA_WorldCover_10m_2021_v200_N42W072_Map.tif
System.err.println("Getting " + url);
try (var is = Downloader.openStream(url, config)) {
System.err.println(is.readAllBytes().length);
BufferedImage image = ImageIO.read(new URL(url));
System.err.println("width=" + image.getWidth());
System.err.println("height=" + image.getHeight());
IntIntMap counts = new IntIntHashMap();
int idx = 0;
int[] arr = new int[image.getWidth() * image.getHeight()];
image.getRGB(0, 0, image.getWidth(), image.getHeight(), arr, 0, image.getWidth());
System.err.println("got pixels");
for (int y = 0; y < image.getHeight(); y++) {
for (int x = 0; x < image.getWidth(); x++) {
int color = arr[idx];
counts.put(color, counts.getOrDefault(color, 0) + 1);
idx++;
}
}
for (var e : counts.keys()) {
System.err.println(e.value + " " + colors.get(e.value) + " " +
((counts.get(e.value) * 100L) / ((long) image.getWidth() * image.getHeight())) + "%");
}
}
}

Wyświetl plik

@ -0,0 +1,47 @@
# Raster DEM status
## Contour Lines
This appears to work fine with the following caveat:
- AsterV3.java generates one contour shape from hi-res DEM then scales it down to lower zoom levels, this can result in
bad looking contour lines at low zooms. A better approach would be to downsample the DEM data to something appropriate
for each zoom level, then generate contour lines for that zoom.
## Vector Hillshade
Sort of works, caveats:
- The polygons don't look right where the 1 degree tiles meet.
- It would probably be better to adopt maplibre GL JS's hillshading algorithm which adds shadows based on the slope more
so than the aspect so you can see details better on south and southwest sides when the illumination is from
northwest: https://github.com/maplibre/maplibre-gl-js/blob/main/src/shaders/hillshade.fragment.glsl
- It's _very_ slow
## Landcover
`EsaWorldcover.java` Doesn't do anything, but I did find out:
- ESA worldcover dataset is hosted in a public S3 dataset so it's easy to download the 3 degree x 3 degree tiff
files https://registry.opendata.aws/esa-worldcover-vito/index.html
- The values are encoded by unique colors - see `EsaWorldcover.java` for an example parsing them
- We probably want to create "stacked" output polygons to create a greening effect when going from desert to grass to
forest, something like:
- omit built-up, moss, and water
- emit "ice" polygons
- emit a "greening stack" with:
- level 1 includes shrub/grass/herbacious wetland
- level 2 include all of level 1 plus also crop
- level 3 includes level 1 and 2 plus also tree and mangrove
- Most vector landcover datasets I see in the wild don't include features <300m wide, so we can downsample this 10m
dataset at least 30x to get started with.
- When downsampling, we probably want a bitmap for each output polygon, then consider a downsampled pixel a 1 if % of
matching raw input pixels within that output pixel is > 50% or so.
The rough approach would look like:
- generate bitmaps corresponding to each output polygon from raw input
- downsample initial bitmaps 30x
- vectorize, smooth, emit polygons
- repeat until you get down to z0:
- downsample another 2x, then vectorize, smooth, and emit polygons at the lower zoom level