package org.springblade.modules.dem; import lombok.SneakyThrows; import org.geotools.coverage.grid.GridCoordinates2D; import org.geotools.coverage.grid.GridCoverage2D; import org.geotools.gce.geotiff.GeoTiffReader; import org.geotools.geometry.DirectPosition2D; import org.geotools.referencing.CRS; import org.geotools.referencing.crs.DefaultGeographicCRS; import org.locationtech.jts.geom.Coordinate; import org.opengis.geometry.DirectPosition; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.operation.MathTransform2D; import java.io.File; public class DemUtils { /** * 根据点获取海拔高 * @param file * @param point * @return */ @SneakyThrows public static int calculateMaxByPoint(File file, Coordinate point) { //获取高程文件 GeoTiffReader reader = new GeoTiffReader(file); GridCoverage2D coverage = reader.read(null); CoordinateReferenceSystem crs = coverage.getCoordinateReferenceSystem2D(); DirectPosition position = new DirectPosition2D(crs, point.x, point.y); int[] pixelValue = (int[]) coverage.evaluate(position); return pixelValue[0]; } /** * 计算两点之间最高海拔 * @param file * @param start * @param end * @return */ @SneakyThrows public static Coordinate calculateMaxElevation(File file, Coordinate start, Coordinate end) { //获取高程文件 GeoTiffReader reader = new GeoTiffReader(file); GridCoverage2D coverage = reader.read(null); CoordinateReferenceSystem crs = coverage.getCoordinateReferenceSystem2D(); MathTransform2D toGrid = (MathTransform2D) CRS.findMathTransform(DefaultGeographicCRS.WGS84, crs, true); MathTransform2D fromGrid = (MathTransform2D) CRS.findMathTransform(crs, DefaultGeographicCRS.WGS84, true); DirectPosition2D startPos = new DirectPosition2D(start.x, start.y); DirectPosition2D endPos = new DirectPosition2D(end.x, end.y); GridCoordinates2D startGrid = new GridCoordinates2D(); GridCoordinates2D endGrid = new GridCoordinates2D(); toGrid.transform(startPos, startGrid); toGrid.transform(endPos, endGrid); int maxPixelValue = Integer.MIN_VALUE; Coordinate retCoordinate = new Coordinate(); // 线性插值,计算中间的点 for (int i = 0; i <= 10000; i++) { double t = i / 10000.0; double lon = start.x + t * (end.x - start.x); double lat = start.y + t * (end.y - start.y); DirectPosition position = new DirectPosition2D(crs, lon, lat); int[] pixelValue = (int[]) coverage.evaluate(position); if (pixelValue[0] > maxPixelValue) { maxPixelValue = pixelValue[0]; retCoordinate.setX(lon); retCoordinate.setY(lat); retCoordinate.setZ(maxPixelValue); } } return retCoordinate; } public static void main(String[] args) { Coordinate start = new Coordinate(115.856725497, 28.624514734); //// Coordinate end = new Coordinate(115.84832847430599, 28.629107705136526); // Coordinate end = new Coordinate(115.85650343813958, 28.62419061027172); // String demPath = "C:\\Users\\vip_x\\Desktop\\无人机\\高程\\江西省12.5米DEM_CGCS2000\\江西省12.5米DEM_CGCS2000.tif"; File file = new File(demPath); // // Coordinate height = calculateMaxElevation(file,start,end); // System.out.println("height:" + height); // //// double maxElevation = calculateMaxElevation(file, start, end); //// System.out.println("Maximum elevation between points: " + maxElevation); // int height2 = calculateMaxByPoint(file,start); System.out.println("height2 = " + height2); } }