cap program drop gtiffdisp_core program define gtiffdisp_core,rclass version 18.0 syntax anything,[*] if "`options'"!=""{ di as error `"Invalid option ignored: `options'"' } local using `anything' removequotes,file(`using') local using = usubinstr(`"`using'"',"\","/",.) // 判æ–路径是å¦ä¸ºç»å¯¹è·¯å¾„ if !strmatch("`using'", "*:/*") & !strmatch("`using'", "/*") { // 如果是相对路径,拼接当å‰å·¥ä½œç›®å½• local using = "`c(pwd)'/`using'" } local using = usubinstr(`"`using'"',"\","/",.) local rc = fileexists("`using'") if `rc'==0{ di as error `"`using'" NOT found' exit } java: GtiffReader.info("`using'") /* ///bandsã€widthã€heightã€minXã€minYã€xRes å’Œ yRes return scalar nband = bands return scalar ncol = width return scalar nrow = height return scalar minX = minX return scalar minY = minY return scalar Xcellsize = xRes return scalar Ycellsize = yRes */ end //////////////////////// cap program drop removequotes program define removequotes,rclass version 16 syntax, file(string) return local file `file' end //////////////////// java: /cp gt-main-32.0.jar /cp gt-referencing-32.0.jar /cp gt-epsg-hsql-32.0.jar /cp gt-epsg-extension-32.0.jar /cp gt-geotiff-32.0.jar /cp gt-coverage-32.0.jar /cp gt-process-raster-32.0.jar import org.geotools.api.coverage.grid.GridCoverage; import org.geotools.api.geometry.Bounds; import org.geotools.api.parameter.GeneralParameterValue; import org.geotools.api.referencing.crs.CoordinateReferenceSystem; import org.geotools.coverage.GridSampleDimension; import org.geotools.coverage.grid.GridCoverage2D; import org.geotools.coverage.grid.io.GridCoverage2DReader; import org.geotools.gce.geotiff.GeoTiffReader; import org.geotools.referencing.CRS; import org.geotools.util.factory.Hints; import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import com.stata.sfi.Scalar; public class GtiffReader { public static void info(String filePath) { //String filePath = "E:/qwc_working/SynologyDrive/气候å˜åŒ–_电力消费/ç¯å…‰æ•°æ®å¤„ç†/data/light/DMSP-like2019.tif"; readGeoTiffMetadata(filePath); } public static void readGeoTiffMetadata(String filePath) { File file = new File(filePath); if (!file.exists()) { System.err.println("File does not exist: " + filePath); return; } GridCoverage2DReader reader = null; try { // 1. Read with axis order handling reader = new GeoTiffReader(file, new Hints( Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER, Boolean.TRUE // Set FALSE if coordinates look incorrect )); GridCoverage2D coverage = (GridCoverage2D) reader.read((GeneralParameterValue[]) null); // // 2. Band information // GridSampleDimension[] bands = coverage.getSampleDimensions(); // System.out.println("\n=== Band Information ==="); // System.out.println("Number of bands: " + bands.length); // Scalar.setValue("bands", bands.length); // for (int i = 0; i < bands.length; i++) { // System.out.printf("Band %d: %s%n", i+1, bands[i].getDescription().toString()); // } // 2. Band information GridSampleDimension[] bands = coverage.getSampleDimensions(); System.out.println("\n=== Band Information ==="); System.out.println("Number of bands: " + bands.length); Scalar.setValue("bands", bands.length); for (int i = 0; i < bands.length; i++) { // 获å–NoData值 double[] noDataValues = bands[i].getNoDataValues(); String noDataInfo = "NoData: "; if (noDataValues != null && noDataValues.length > 0) { // 处ç†å¤šNoData值情况 if (noDataValues.length > 1) { noDataInfo += Arrays.toString(noDataValues); } else { // æ™ºèƒ½æ ¼å¼åŒ–输出 if (noDataValues[0] == (int)noDataValues[0]) { noDataInfo += String.format("%d", (int)noDataValues[0]); } else { noDataInfo += String.format("%.4f", noDataValues[0]); } } } else { noDataInfo += "Not defined"; } // æ¸…ç†æè¿°æ–‡æœ¬å¹¶è¾“å‡º String cleanDescription = bands[i].getDescription().toString() .replaceAll("[\\[\\]]", "") // ç§»é™¤æ–¹æ‹¬å· .replaceAll("^\\s+", ""); // 移除å‰å¯¼ç©ºæ ¼ System.out.printf("Band %-2d: %-20s | %s%n", i+1, (cleanDescription.length() > 20 ? cleanDescription.substring(0, 17) + "..." : // 截æ–é•¿æè¿° cleanDescription), noDataInfo ); } // 3. Spatial extent & resolution Bounds envelope = coverage.getEnvelope(); double minX = envelope.getMinimum(0); double maxX = envelope.getMaximum(0); double minY = envelope.getMinimum(1); double maxY = envelope.getMaximum(1); int width = coverage.getRenderedImage().getWidth(); int height = coverage.getRenderedImage().getHeight(); double xRes = (maxX - minX) / width; double yRes = (maxY - minY) / height; System.out.println("\n=== Spatial Characteristics ==="); System.out.printf("X range: [%.4f ~ %.4f]%n", minX, maxX); System.out.printf("Y range: [%.4f ~ %.4f]%n", minY, maxY); System.out.printf("Resolution: X=%.4f units/pixel, Y=%.4f units/pixel%n", xRes, yRes); Scalar.setValue("width", width); Scalar.setValue("height", height); Scalar.setValue("xRes", xRes); Scalar.setValue("yRes", yRes); Scalar.setValue("minX", minX); Scalar.setValue("minY", minY); Scalar.setValue("maxX", maxX); Scalar.setValue("maxY", maxY); // 4. Coordinate system verification CoordinateReferenceSystem crs = coverage.getCoordinateReferenceSystem(); System.out.println("\n=== Coordinate System ==="); System.out.println("CRS Name: " + CRS.toSRS(crs)); System.out.println("CRS WKT: " + crs.toWKT()); // Full projection parameters // 5. Unit verification System.out.println("\n=== Units ==="); System.out.println("X unit: " + crs.getCoordinateSystem().getAxis(0).getUnit()); System.out.println("Y unit: " + crs.getCoordinateSystem().getAxis(1).getUnit()); // 6. Filtered metadata System.out.println("\n=== Filtered Metadata ==="); Set<String> excludeKeys = new HashSet<>(Arrays.asList( "tile_cache_key", "tile_cache", "JAI.ImageReader", "JAI.ImageReadParam", "PamDataset" )); for (String key : coverage.getPropertyNames()) { if (!excludeKeys.contains(key)) { Object value = coverage.getProperty(key); if (value != null) { String valStr = value.toString(); valStr = valStr.length() > 50 ? valStr.substring(0, 47) + "..." : valStr; System.out.printf("%-28s: %s%n", key, valStr); } } } } catch (IOException e) { System.err.println("File read error: " + e.getMessage()); } finally { // 7. Proper resource closure if (reader != null) { try { reader.dispose(); // Correct disposal method } catch (IOException e) { System.err.println("Error closing reader: " + e.getMessage()); } } } } } end