hey Peppe,

nice try, but no dice. the reason i created an explicit TiffUtilsV2 was
to make sure it contains no reference to RasterImageIO or TiffTags
anymore. the idea is to wrap GeoReferencedRaster functionality to reuse.
GeoReferencedRaster includes all functionality for retrieving an
Envelope or dimensions needed.

If you are lacking functionality in GeoReferencedRaster we may add it
accordingly.

i cut some code parts below and commented them which should be replaced
by using GeoReferencedRaster routines. ..ede



On 9/22/2020 11:26, jump-pilot-svn--- via Jump-pilot-devel wrote:
Revision: 6507
           http://sourceforge.net/p/jump-pilot/code/6507
Author:   ma15569
Date:     2020-09-22 09:26:19 +0000 (Tue, 22 Sep 2020)
Log Message:
-----------
Ported functionality from TiffUtils to TiffUtilsV2.
Make TiffUtils deprecated

SNIP
Modified: core/trunk/src/org/openjump/core/rasterimage/TiffUtils.java
===================================================================
--- core/trunk/src/org/openjump/core/rasterimage/TiffUtils.java 2020-09-21 
13:32:21 UTC (rev 6506)
+++ core/trunk/src/org/openjump/core/rasterimage/TiffUtils.java 2020-09-22 
09:26:19 UTC (rev 6507)
@@ -5,7 +5,6 @@
SNIP

Modified: core/trunk/src/org/openjump/core/rasterimage/TiffUtilsV2.java
===================================================================
--- core/trunk/src/org/openjump/core/rasterimage/TiffUtilsV2.java       
2020-09-21 13:32:21 UTC (rev 6506)
+++ core/trunk/src/org/openjump/core/rasterimage/TiffUtilsV2.java       
2020-09-22 09:26:19 UTC (rev 6507)
@@ -1,14 +1,37 @@
  package org.openjump.core.rasterimage;
SNIP
@@ -66,4 +89,283 @@
      renderedOp = JAI.create("scale", parameterBlock);
      return JAI.create("scale", parameterBlock);
    }
+  public static ImageAndMetadata readImage(File tiffFile, Envelope 
viewportEnvelope, Resolution requestedRes,
+             Overviews overviews, Stats stats) throws 
NoninvertibleTransformException, IOException, FileNotFoundException,
+             TiffTags.TiffReadingException, Exception {
+
+           // Try to read geotiff tags
+           TiffTags.TiffMetadata tiffMetadata = 
TiffTags.readMetadata(tiffFile);
+           int originalImageWidth = tiffMetadata.getColsCount();
+           int originalImageHeight = tiffMetadata.getRowsCount();
+           Resolution cellSize = tiffMetadata.getResolution();
+           Double noData = tiffMetadata.getNoData();
+
+           // Now try with tfw
+           if (cellSize == null) {
+             WorldFileHandler worldFileHandler = new 
WorldFileHandler(tiffFile.getAbsolutePath(), true);
+             Envelope envelope = 
worldFileHandler.readWorldFile(originalImageWidth, originalImageHeight);
+             cellSize = new Resolution(envelope.getWidth() / 
originalImageWidth, envelope.getHeight() / originalImageHeight);
+           }

not needed. should be retrievable from GeoReferencedRaster

+           Envelope wholeImageEnvelope = 
RasterImageIO.getGeoReferencing(tiffFile.getAbsolutePath(), true,
+               new Point(originalImageWidth, originalImageHeight));

Envelope as well.

+           if (requestedRes == null) {
+             requestedRes = cellSize;
+           }
+
+           int overviewLevel = overviews.pickOverviewLevel(requestedRes);
+
+           if (stats == null) {
+             // Statistics on all pixels
+             stats = calculateStats(tiffFile, noData, tiffFile);
+           }
+
SNIP
+             return imageAndMetadata;
+
+           }
+
+         }
+
+         private static ImageAndMetadata readImage(File tiffFile, int 
overviewIndex, int indexStart, Point originalSize,
+             Resolution originalCellSize, Envelope wholeImageEnvelope, 
Envelope viewportEnvelope, double noDataValue,
+             Stats stats) throws IOException, NoninvertibleTransformException {
+
+           ImageInputStream imageInputStream = 
ImageIO.createImageInputStream(tiffFile);
+           Iterator<ImageReader> iterator = 
ImageIO.getImageReaders(imageInputStream);

this seems to be a leftover. we want to enforce a specific TIFF reader, which 
seems not to be done here.

why exactly are there two readImage() methods needed anyway? one should 
suffice. can you remove it?

+           if (iterator != null && iterator.hasNext()) {
+
+             ImageReader imageReader = iterator.next();
+             imageReader.setInput(imageInputStream);
+             for (int i = 0; i < imageReader.getNumImages(true); i++) {
+               if (i + indexStart == overviewIndex) {
+
+                 Resolution subsetResolution = new 
Resolution(wholeImageEnvelope.getWidth() / imageReader.getWidth(i),
+                     wholeImageEnvelope.getHeight() / 
imageReader.getHeight(i));
+
+                 Rectangle imageSubset = 
RasterImageIO.getDrawingRectangle(imageReader.getWidth(i), 
imageReader.getHeight(i),
+                     wholeImageEnvelope, viewportEnvelope, subsetResolution);
+
+                 BufferedImage bufferedImage;
+                 Envelope imagePartEnvelope;
+                 int imageWidth;
+                 int imageHeight;
+                 if (imageSubset == null) {
+                   bufferedImage = null;
+                   imagePartEnvelope = null;
+                   imageWidth = 0;
+                   imageHeight = 0;
+                 } else {
+                   ImageReadParam imageReadParam = new ImageReadParam();
+                   imageReadParam.setSourceRegion(imageSubset);
+                   bufferedImage = imageReader.read(i, imageReadParam);
+                   imagePartEnvelope =  
getImageSubsetEnvelope(wholeImageEnvelope, imageSubset, subsetResolution);
+                   imageWidth = bufferedImage.getWidth();
+                   imageHeight = bufferedImage.getHeight();
+                 }
+
+//                         double originalCellSize = subsetResolution.getX();
+//                         int cellsCount = imageReader.getWidth(i) * 
imageReader.getHeight(i);
+//                         int sampleSize = 10000;
+//                         double lowResCellSize = Math.sqrt(Math.max(1, 
cellsCount/(double)sampleSize)) * originalCellSize;
+
+//                         if(stats == null) {
+//                             BufferedImage statsBufferedImage = 
imageReader.read(imageReader.getNumImages(true) - 1, null);
+//                             stats = calculateStats(statsBufferedImage, 
noDataValue);
+//                         }
+
+                 Metadata metadata = new Metadata(wholeImageEnvelope, 
imagePartEnvelope, originalSize,
+                     new Point(imageWidth, imageHeight), 
(originalCellSize.getX() + originalCellSize.getY()) / 2,
+                     (subsetResolution.getX() + subsetResolution.getY()) / 2, 
noDataValue, stats);
+
+                 return new ImageAndMetadata(bufferedImage, metadata);
+
+               }
+             }
+
+           }
+
+           return null;
+
+         }
+
+         private static Stats calculateStats(File tiffFile, double 
noDataValue, File imageFile)
+             throws ParserConfigurationException, TransformerException, 
ImageReadException, IOException, SAXException {
+
+           Stats stats = null;
+
+           // Look for internal stats tag
+           try {
+             TiffImageParser parser = new TiffImageParser();
+             TiffImageMetadata metadata = (TiffImageMetadata) 
parser.getMetadata(tiffFile);
+             List<TiffField> tiffFields = metadata.getAllFields();
+             for (TiffField tiffField : tiffFields) {
+               if (tiffField.getTag() == TiffTags.TIFFTAG_GDAL_METADATA) {
+                 GDALInternalMetadata gdalParser = new GDALInternalMetadata();
+                 stats = gdalParser.readStatistics(tiffField.getStringValue());
+                 break;
+               }
+             }
+           } catch (Exception ex) {
+             stats = null;
+           }
+
+           if (stats != null) {
+             return stats;
+           }
+
+           // Look for aux.xml file
+           File auxXmlFile = new File(imageFile.getParent(), imageFile.getName() + 
".aux.xml");
+           if (auxXmlFile.exists()) {
+             GDALPamDataset gdalPamDataset = new GDALPamDataset();
+             try {
+               stats = gdalPamDataset.readStatistics(auxXmlFile);
+               return stats;
+             } catch (Exception ex) {
+               Logger.error("Failed to read statistics.", ex);
+               return createStatsXml(tiffFile, noDataValue, auxXmlFile);
+             }
+           }
+           return createStatsXml(tiffFile, noDataValue, auxXmlFile);
+
+         }
+
+         private static Stats createStatsXml(File tiffFile, double 
noDataValue, File auxXmlFile)
+             throws ParserConfigurationException, TransformerException, 
TransformerConfigurationException, SAXException,
+             IOException {
+
+           BufferedImage bufferedImage = readSubsampled(tiffFile, 1, 
1).getAsBufferedImage();
+           int bandCount = bufferedImage.getRaster().getNumBands();
+
+           double minValue[] = new double[bandCount];
+           double maxValue[] = new double[bandCount];
+           double sum[] = new double[bandCount];
+           double sumSquare[] = new double[bandCount];
+           long cellsCount[] = new long[bandCount];
+
+           for (int b = 0; b < bandCount; b++) {
+             minValue[b] = Double.MAX_VALUE;
+             maxValue[b] = -Double.MAX_VALUE;
+           }
+
+           for (int r = 0; r < bufferedImage.getHeight(); r++) {
+             Raster raster = bufferedImage.getData(new Rectangle(0, r, 
bufferedImage.getWidth(), 1));
+             for (int c = 0; c < bufferedImage.getWidth(); c++) {
+
+               for (int b = 0; b < bandCount; b++) {
+
+                 double value = raster.getSampleDouble(c, r, b);
+                 if (value != noDataValue && (float) value != (float) noDataValue 
&& !Double.isNaN(value)
+                     && !Double.isInfinite(value)) {
+                   if (value < minValue[b])
+                     minValue[b] = value;
+                   if (value > maxValue[b])
+                     maxValue[b] = value;
+                   cellsCount[b]++;
+                   sum[b] += value;
+                   sumSquare[b] += value * value;
+                 }
+
+               }
+
+             }
+           }
+
+           Stats stats = new Stats(bandCount);
+           for (int b = 0; b < bandCount; b++) {
+             double meanValue = sum[b] / cellsCount[b];
+             double stdDevValue = Math.sqrt(sumSquare[b] / cellsCount[b] - 
meanValue * meanValue);
+             stats.setStatsForBand(b, minValue[b], maxValue[b], meanValue, 
stdDevValue);
+           }
+
+           // Write aux.xml
+           GDALPamDataset gdalPamDataset = new GDALPamDataset();
+           gdalPamDataset.writeStatistics(auxXmlFile, stats);
+
+           return stats;
+
+         }

not sure about stats or what they actually do. we might need to extend 
GeoReferencedraster in that regard.

+         private static Envelope getImageSubsetEnvelope(Envelope 
wholeImageEnvelope, Rectangle imageSubset,
+             Resolution subsetResolution) {
+
+           double ulX = Math.max(wholeImageEnvelope.getMinX(),
+               wholeImageEnvelope.getMinX() + imageSubset.getX() * 
subsetResolution.getX());
+           double ulY = Math.min(wholeImageEnvelope.getMaxY(),
+               wholeImageEnvelope.getMaxY() - imageSubset.getY() * 
subsetResolution.getY());
+           double lrX = Math.min(wholeImageEnvelope.getMaxX(), 
wholeImageEnvelope.getMinX()
+               + imageSubset.getX() * subsetResolution.getX() + 
imageSubset.getWidth() * subsetResolution.getX());
+           double lrY = Math.max(wholeImageEnvelope.getMinY(), 
wholeImageEnvelope.getMaxY()
+               - imageSubset.getY() * subsetResolution.getY() - 
imageSubset.getHeight() * subsetResolution.getY());
+           Coordinate ulCoord = new Coordinate(ulX, ulY);
+           Coordinate lrCoord = new Coordinate(lrX, lrY);
+
+           Envelope imagePartEnvelope = new Envelope(ulCoord, lrCoord);
+
+           return imagePartEnvelope;
+
+         }
+
+         public static Double readCellValue(File tiffFile, int col, int row, 
int band)  throws Exception {
+           Rectangle rectangle = new Rectangle(col, row, 1, 1);
+           return 
getRenderedOp(tiffFile).getData(rectangle).getSampleDouble(col, row, band);
+         }
+
  }

this looks clean, original code. nor reference to the "old" framework :)



_______________________________________________
Jump-pilot-devel mailing list
Jump-pilot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel

Reply via email to