This package allows you to create shaded-relief raster images from Digital Elevation Models (DEM).
Relief shading (sometimes referred to as hill shading, or shaded relief) refers to a technique used in cartography and computer graphics to create a three-dimensional representation of a surface on a flat map or image. This is achieved by simulating the effects of sunlight falling on the surface and casting shadows. The shadows are created by calculating the angles of the sun and the surface and mapping those angles to grayscale values, which are then applied to the surface. This creates a sense of depth and topography, making it easier to visualize and interpret the features of the surface.
Digital Elevation Models (DEM) provide nice inputs to see relief shading. You may use Shuttle Radar Topography Mission (.hgt) files directly.
1 arc-second (90 meter) quad, 37-38 degrees north latitude, 107-108 degrees west longitude.
Create shaded relief image:
// Create shaded relief image from .hgt file.
final String filename = "./N37W108.hgt";
ZFactorDem zFactorDem = new ZFactorSrtmDem(FilenameSRTM.create(filename));
GridClassifier classifier = GridClassifier
.shaded(Preferences.createDefault(), zFactorDem);
Grid grid = DemReader.shuttleRadarTopographyMissionHGT(path).read();
BufferedImage image = classifier.classify(grid);
Path output = Paths.get("shaded.png");
ImageIO.write(image, "png", output.toFile());
Create color-filled image:
// Create color-filled image from .hgt file.
final String filename = "./N37W108.hgt";
GridClassifier classifier = GridClassifier
.color(ColorPaletteDefaults.DEM.colorPalette());
Grid grid = DemReader.shuttleRadarTopographyMissionHGT(path).read();
BufferedImage image = classifier.classify(grid);
Path output = Paths.get("color.png");
ImageIO.write(image, "png", output.toFile());
Create color-filled image with custom z bounds:
// Create color-filled image from .hgt file.
final String filename = "./N37W108.hgt";
Bounds zBounds = Bounds.of(2250, 4310);//meters
GridClassifier classifier = GridClassifier
.color(ColorPaletteDefaults.DEM.colorPalette(), zBounds);
Grid grid = DemReader.shuttleRadarTopographyMissionHGT(path).read();
BufferedImage image = classifier.classify(grid);
Path output = Paths.get("color-z.png");
ImageIO.write(image, "png", output.toFile());
Shaded image with 30% opacity overlaid onto color image.
// Create overlay (final) image.
final String filename = "./N37W108.hgt";
Grid grid = DemReader.shuttleRadarTopographyMissionHGT(path).read();
GridClassifier classifier = GridClassifier
.color(ColorPaletteDefaults.DEM.colorPalette());
BufferedImage colorImage = classifier.apply(grid);
ZFactorDem zFactorDem = new ZFactorSrtmDem(FilenameSRTM.create(DEMO_FILENAME));
Preferences preferences = new PreferencesBuilder()
.opacityPercent(30)
.build();
classifier = GridClassifier
.shaded(preferences, zFactorDem);
BufferedImage shadedImage = classifier.apply(loadGrid());
int width = shadedImage.getWidth();
int height = shadedImage.getHeight();
BufferedImage combined = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics g = combined.getGraphics();
((Graphics2D)g).setComposite(AlphaComposite.SrcOver);
g.drawImage(colorImage, 0, 0, null);
g.drawImage(shadedImage, 0, 0, null);
Path output = Paths.get("N37w108-overlay.png");
ImageIO.write(combined, "png", output.toFile());
g.dispose();
The two key settings for relief shading are:
- azimuth the azimuth of the sun (0-360 degrees), default is 315. Think of this as a circle laid flat on the map, where 0 is north. So, a value of 315 means the sun is coming from the north-west, while a value of 180 is coming from the south.
- altitude the elevation of the sun (0-90 degrees), default is 45. The lower the value, the more accentuated the features should become, while the higher the value, the features will become less severe.
These may be adjusted in the Preferences class.
// Set preferences
Preferences preferences = new PreferencesBuilder()
.altitudeDegrees(30)
.azimuthDegrees(225)
.build();
GridClassifier classifier = GridClassifier
.shaded(preferences, zFactorDem);