[
https://issues.apache.org/jira/browse/IMAGING-266?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17413674#comment-17413674
]
Gary Lucas commented on IMAGING-266:
------------------------------------
Well, it took a couple of tries, but I have just submitted changes to address
this issue. This new feature allows developers to use the Commons Imaging API
to access the extensive set of high-resolution, global elevation data available
through the Shuttle Radar Topography Mission (SRTM) as well as many other
geophysical data sources.
Here's an example image produced from a TIFF file that contains elevation data
for a 1-degree square in the vicinity of Auckland, New Zealand. The original
TIFF file gives a 3601-by-3601 grid of elevation data points at a 1 second of
arc spacing (about 30 meters). This image shown below is reduced to 25 percent
of the original size.
!Imaging266_SRTM.jpg!
The image above was produced using a modified version of my DemoCOG
application. I've written a web article describing the techniques used for
rendering numerical data from GeoTIFFs. If you are interested, you can read it
at [https://gwlucastrig.github.io/gridfour/notes/ElevationGeoTiff1.html]
An earlier version of the Imaging API implemented a method called
getFloatingPointRasterData() to read data from TIFF files that contained
floating-point data. However, the elevation data in SRTM products is stored in
a short-integer format. So the access method has been changed to handle both
floating-point and integral data types and its name has been changed to
getRasterData().
The example code below shows how to use the API:
{code:java}
import java.io.File;
import org.apache.commons.imaging.FormatCompliance;
import org.apache.commons.imaging.common.bytesource.ByteSourceFile;
import org.apache.commons.imaging.formats.tiff.TiffContents;
import org.apache.commons.imaging.formats.tiff.TiffDirectory;
import org.apache.commons.imaging.formats.tiff.TiffRasterData;
import org.apache.commons.imaging.formats.tiff.TiffRasterDataType;
import org.apache.commons.imaging.formats.tiff.TiffReader;
public class ExampleRasterReader {
public static void main(String[] args) throws Exception {
File target = new File(args[0]);
ByteSourceFile byteSource = new ByteSourceFile(target);
// Establish a TiffReader. This is just a simple constructor that
// does not actually access the file. So the application cannot
// obtain the byteOrder, or other details, until the contents has
// been read.
TiffReader tiffReader = new TiffReader(true);
// Read the directories in the TIFF file. Directories are the
// main data element of a TIFF file. They usually include an image
// element, but sometimes just carry metadata. This example
// reads all the directories in the file. Typically, reading
// the directories is not a time-consuming operation.
TiffContents contents = tiffReader.readDirectories(
byteSource,
true, // indicates that application should read image data, if
present
FormatCompliance.getDefault());
// Read the first Image File Directory (IFD) in the file. A practical
// implementation could use any of the directories in the file.
// By convention, the main payload (image or raster data) is
// stored in the first TIFF directory with optional thumbnail images
// or metadata directories to follow.
TiffDirectory directory = contents.directories.get(0);
// Check that the first directory in the file has raster data.
if (!directory.hasTiffRasterData()) {
System.out.println(
"Specified directory does not contain raster data");
System.exit(-1);
}
// read all the raster data for the first directory.
// The return value may carry short integers or single-precision
// floating point values. The optional parameter, which is set to
// null in this example, could be used to fetch only a subset
// of the overall data.
TiffRasterData raster = directory.getRasterData(null);
// THe data type may be integral or floating point.
TiffRasterDataType rasterDataType = raster.getDataType();
System.out.println("Data type for raster: " + rasterDataType.name());
int width = raster.getWidth();
int height = raster.getHeight();
int nSamples = 0;
double sumSamples = 0;
if (rasterDataType == TiffRasterDataType.INTEGER) {
// data type is integral, so we use getIntValue()
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int sample = raster.getIntValue(x, y);
if (sample > 0) {
nSamples++;
sumSamples += sample;
}
}
}
} else {
// data type is floating point, so we use getValue()
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
float sample = raster.getValue(x, y);
if (sample > 0) {
nSamples++;
sumSamples += sample;
}
}
}
}
double avgSampleValue = 0;
if (nSamples > 0) {
avgSampleValue = sumSamples / nSamples;
}
System.out.println("Number of sample values > 0 is " + nSamples);
System.out.println("Average sample value is " + avgSampleValue);
}
}
{code}
Finally, I'd like to thank Bruno Kinoshita for his help and excellent guidance
in bringing this new API into the Commons Imaging code base.
> Read integer data from GeoTIFFS
> --------------------------------
>
> Key: IMAGING-266
> URL: https://issues.apache.org/jira/browse/IMAGING-266
> Project: Commons Imaging
> Issue Type: New Feature
> Components: Format: TIFF
> Affects Versions: 1.0-alpha3
> Reporter: Gary Lucas
> Assignee: Bruno P. Kinoshita
> Priority: Major
> Fix For: 1.0-alpha3
>
> Attachments: Imaging266_SRTM.jpg
>
> Time Spent: 5.5h
> Remaining Estimate: 0h
>
> I recently discovered that there is a large amount of digital elevation data
> available in the form of 16-bit integer coded data in GeoTIFF files (TIFF
> files with geographic tags). I propose to enhance the Commons Imaging API to
> read these files. This work will be similar to the work I did for reading
> floating-point raster data under ISSUE-251.
> Available data include the nearly-global coverage of one-second of arc
> elevation data produced from the Shuttle Radar Topography Mission (SRTM) and
> other sources. These products give grids of elevation data with a 30 meter
> cell spacing for most of the world's land masses. They are available at NASA
> Earthdata and Japan Space Systems websites, see
> [https://asterweb.jpl.nasa.gov/gdem.asp|https://asterweb.jpl.nasa.gov/gdem.asp]
> There is also a ocean bathymetry data set available in this format at
> [http://www.shadedrelief.com/blue-earth/]
> This new feature will continue to expand the usefulness of the Commons
> Imaging API in accessing GeoTIFF products.
> Request for Feedback
> So far, the data products I've found (ASTER and Blue Earth Bathymetry) give
> elevation and ocean depth data in meters recorded as a short integer. I
> haven't found an example of where the 32-bit integer format is used. For
> now, I am planning on only coding the 16-bit integer variation. Does anyone
> know if the 32-bit version is worth supporting? My criteria for determining
> that would be based on whether there is a significant number of projects
> using that format (life is too short to chase rarely used data formats).
> Currently, one of the code-analysis operations conducted by the Commons
> Imaging build process is coverage by JUnit tests. Lacking any test data for
> the 32-bit case, I am reluctant to include it in the code base because it
> would mean putting uncovered code into the distribution.
> Also, I am wondering about the best design for the access API. The current
> TiffImageParser class has a method called getFloatingPointRasterData() that
> returns an instance of TiffRasterData. TiffRasterData is pretty much
> hard-wired to floating point data. I am thinking of creating a new method
> called getIntegerRasterData() that would return an instance of a new class
> called TiffIntegerRasterData. Does this seem reasonable? I considered trying
> to combine both kinds of results into a unified class and method, but it
> seems more unwieldy than useful.
>
>
--
This message was sent by Atlassian Jira
(v8.3.4#803005)