I will make those changes. Statistics are calculated in order to reuse on
raster analysis (sextante). It is also saved into a special .aux.xml
sidecar file.
At this moment there is no need to implement GeoReferencedRaster with
Statistic read as it is uìused only by Sextante.

Il giorno mar 22 set 2020 alle ore 11:59 <edgar.sol...@web.de> ha scritto:

> 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
>
_______________________________________________
Jump-pilot-devel mailing list
Jump-pilot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel

Reply via email to