package org.sxkj.odm.utils;
|
|
import com.google.common.collect.Lists;
|
import org.geotools.coverage.grid.GridCoverage2D;
|
import org.geotools.gce.geotiff.GeoTiffReader;
|
import org.geotools.geometry.jts.JTS;
|
import org.geotools.referencing.CRS;
|
import org.geotools.referencing.crs.DefaultGeographicCRS;
|
import org.jetbrains.annotations.NotNull;
|
import org.locationtech.jts.geom.Coordinate;
|
import org.locationtech.jts.geom.GeometryFactory;
|
import org.locationtech.jts.geom.Point;
|
import org.locationtech.jts.geom.PrecisionModel;
|
import org.opengis.geometry.DirectPosition;
|
import org.opengis.geometry.Envelope;
|
import org.opengis.referencing.crs.CoordinateReferenceSystem;
|
import org.opengis.referencing.operation.MathTransform;
|
import org.sxkj.odm.entity.MyPoint;
|
|
import javax.imageio.ImageIO;
|
import java.awt.*;
|
import java.awt.geom.Line2D;
|
import java.awt.image.BufferedImage;
|
import java.io.File;
|
import java.io.FileInputStream;
|
import java.util.ArrayList;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.Map;
|
|
/**
|
* tif 文件读取工具
|
*/
|
public class ParseTifUtils {
|
|
/**
|
* 获取tif四角位置
|
*
|
* @return
|
*/
|
public static void getTifFour(String path) {
|
try {
|
// 读取 TIF 文件
|
GeoTiffReader reader = new GeoTiffReader(new File(path));
|
//获取文件的坐标系信息
|
CoordinateReferenceSystem crs = reader.getCoordinateReferenceSystem();
|
GridCoverage2D coverage = reader.read(null);
|
// 获取 TIF 文件的四角坐标,并转换为经纬度坐标系
|
Envelope envelope = coverage.getEnvelope();
|
Envelope transformedEnvelope = CRS.transform(envelope, crs);
|
double maxLon = transformedEnvelope.getMaximum(0); // 最大经度
|
double maxLat = transformedEnvelope.getMaximum(1); // 最大纬度
|
double minLon = transformedEnvelope.getMinimum(0); // 最小经度
|
double minLat = transformedEnvelope.getMinimum(1); // 最小纬度
|
DirectPosition lowerCorner = transformedEnvelope.getLowerCorner();// 左下角
|
DirectPosition upperCorner = transformedEnvelope.getUpperCorner();// 右上角
|
//获取tif 文件的宽度,高度
|
double width = coverage.getGridGeometry().getGridRange2D().getWidth();
|
double height = coverage.getGridGeometry().getGridRange2D().getHeight();
|
// 左上角(最小经度,最大纬度) 右下角(最大经度,最小纬度)
|
// 输出结果
|
System.out.println("lowerCorner: " + lowerCorner);
|
System.out.println("upperCorner: " + upperCorner);
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
|
/**
|
* 获取经纬度在当前tif文件中的地理坐标(单点)
|
* @param path
|
* @param longitude
|
* @param latitude
|
* @return
|
*/
|
public static Point getTifPosByLngLat(String path, Double longitude, Double latitude) {
|
try {
|
//类型
|
PrecisionModel precisionModel = new PrecisionModel(PrecisionModel.FLOATING);
|
//84坐标
|
GeometryFactory geometryFactory = new GeometryFactory(precisionModel, 4326);
|
// 读取 TIF 文件
|
GeoTiffReader reader = new GeoTiffReader(new File(path));
|
//获取文件的坐标系信息
|
GridCoverage2D coverage = reader.read(null);
|
// 创建一个点对象,并定义其经纬度
|
Point point = geometryFactory.createPoint(new Coordinate(longitude, latitude));
|
// 转换坐标系统
|
MathTransform transform = CRS.findMathTransform(DefaultGeographicCRS.WGS84, coverage.getCoordinateReferenceSystem());
|
// 转为地理坐标
|
Point reprojectedPoint = (Point) JTS.transform(point, transform);
|
// 返回
|
return reprojectedPoint;
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
return null;
|
}
|
|
/**
|
* 获取经纬度在当前tif文件中的地理坐标(多点)
|
* @param path
|
* @param coordinateList 经纬度坐标集合
|
* @return
|
*/
|
public static List<Point> getTifPosByMoreLngLat(String path, List<Coordinate> coordinateList) {
|
List<Point> list = new ArrayList<>();
|
try {
|
FileInputStream fileInputStream = new FileInputStream(path);
|
//类型
|
PrecisionModel precisionModel = new PrecisionModel(PrecisionModel.FLOATING);
|
//84坐标
|
GeometryFactory geometryFactory = new GeometryFactory(precisionModel, 4326);
|
// 读取 TIF 文件
|
GeoTiffReader reader = new GeoTiffReader(fileInputStream);
|
//获取文件的坐标系信息
|
GridCoverage2D coverage = reader.read(null);
|
for (Coordinate coordinate : coordinateList) {
|
// 创建一个点对象,并定义其经纬度
|
Point point = geometryFactory.createPoint(coordinate);
|
// 转换坐标系统
|
MathTransform transform = CRS.findMathTransform(DefaultGeographicCRS.WGS84, coverage.getCoordinateReferenceSystem());
|
// 转为地理坐标
|
Point reprojectedPoint = (Point) JTS.transform(point, transform);
|
// 加入集合
|
list.add(reprojectedPoint);
|
}
|
// 关闭流
|
fileInputStream.close();
|
// 返回
|
return list;
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
return list;
|
}
|
|
|
/**
|
* 在 tif 文件上画线
|
* @param tifFilePath tif 读取路径
|
* @param outPath 输出路径
|
* @param map
|
*/
|
public static void drawLineTif(String tifFilePath,String outPath, Map<String, Double> map) {
|
try {
|
FileInputStream fileInputStream = new FileInputStream(tifFilePath);
|
// 读取TIF图片
|
BufferedImage bufferedImage = ImageIO.read(fileInputStream);
|
// 创建Graphics2D对象
|
Graphics2D g2d = (Graphics2D) bufferedImage.getGraphics();
|
// 设置红色,、画笔粗细
|
g2d.setColor(Color.RED);
|
g2d.setStroke(new BasicStroke(3f));
|
// 画线
|
drawLine(g2d, map);
|
// 释放图形上下文资源
|
g2d.dispose();
|
// 输出图片
|
File outputFile = new File(outPath);
|
// 写入
|
ImageIO.write(bufferedImage, "tif", outputFile);
|
// 关闭流
|
fileInputStream.close();
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
|
/**
|
* 在 tif 文件上批量画线
|
* @param tifFilePath tif 读取路径
|
* @param outPath 输出路径
|
* @param points
|
*/
|
public static void drawLineListTif(String tifFilePath,String outPath, List<MyPoint> points) {
|
try {
|
FileInputStream fileInputStream = new FileInputStream(tifFilePath);
|
// 读取TIF图片
|
BufferedImage bufferedImage = ImageIO.read(fileInputStream);
|
// 创建Graphics2D对象
|
Graphics2D g2d = (Graphics2D) bufferedImage.getGraphics();
|
// 设置红色,、画笔粗细
|
g2d.setColor(Color.RED);
|
g2d.setStroke(new BasicStroke(3f));
|
List<Map<String, Double>> maps = new ArrayList<>();
|
int size = points.size();
|
// 将点分成多个线,当前点和下一个点组成一条线,末尾和首个点组成一条线
|
for (int i = 0; i < points.size(); i++) {
|
Map<String, Double> map = new HashMap<>();
|
MyPoint current = points.get(i);
|
map.put("x1",current.getX());
|
map.put("y1",current.getY());
|
MyPoint next = (i == size - 1) ? points.get(0) : points.get(i + 1);
|
map.put("x2",next.getX());
|
map.put("y2",next.getY());
|
maps.add(map);
|
}
|
for (Map<String, Double> map : maps) {
|
// 画线
|
drawLine(g2d, map);
|
}
|
// 释放图形上下文资源
|
g2d.dispose();
|
// 输出图片
|
File outputFile = new File(outPath);
|
// 写入
|
ImageIO.write(bufferedImage, "tif", outputFile);
|
// 关闭流
|
fileInputStream.close();
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
|
/**
|
* 在 tif 文件上画面
|
* @param tifFilePath tif 读取路径
|
* @param outPath 输出路径
|
* @param points
|
*/
|
public static boolean drawPolygonByPoints(String tifFilePath,String outPath, List<MyPoint> points, String suffix) {
|
try {
|
FileInputStream fileInputStream = new FileInputStream(tifFilePath);
|
// 读取TIF图片
|
BufferedImage bufferedImage = ImageIO.read(fileInputStream);
|
// 创建Graphics2D对象
|
Graphics2D g2d = (Graphics2D) bufferedImage.getGraphics();
|
// 设置红色,、画笔粗细
|
g2d.setColor(Color.RED);
|
g2d.setStroke(new BasicStroke(3f));
|
// 将点集合组装成画面的数组
|
Map<String, int[]> hashMap = getStringMap(points);
|
// 画面
|
drawPolygon(g2d,hashMap);
|
// 释放图形上下文资源
|
g2d.dispose();
|
// 输出图片
|
File outputFile = new File(outPath);
|
// 写入
|
ImageIO.write(bufferedImage, suffix, outputFile);
|
// 关闭流
|
fileInputStream.close();
|
// 返回
|
return true;
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
return false;
|
}
|
|
/**
|
* 将点集合组装成画面的数组
|
* @param points
|
* @return
|
*/
|
@NotNull
|
private static Map<String, int[]> getStringMap(List<MyPoint> points) {
|
Map<String, int []> hashMap = new HashMap<>();
|
List<Integer> lngList = new ArrayList<>();
|
List<Integer> latList = new ArrayList<>();
|
for (MyPoint point : points) {
|
lngList.add((int)Math.round(point.getX().doubleValue()));
|
latList.add((int)Math.round(point.getY().doubleValue()));
|
}
|
int[] lngArr = lngList.stream()
|
.mapToInt(Integer::intValue)
|
.toArray();
|
int[] latArr = latList.stream()
|
.mapToInt(Integer::intValue)
|
.toArray();
|
hashMap.put("lngs",lngArr);
|
hashMap.put("lats",latArr);
|
return hashMap;
|
}
|
|
|
/**
|
* 画线
|
* @param g2D
|
* @param map
|
*/
|
public static void drawLine(Graphics2D g2D, Map<String, Double> map) {
|
// 打印转换后的Map
|
Line2D.Double line = new Line2D.Double(map.get("x1"), map.get("y1"),
|
map.get("x2"), map.get("y2"));
|
g2D.draw(line);
|
}
|
|
/**
|
* 画面
|
* @param g2D
|
* @param map
|
*/
|
public static void drawPolygon(Graphics2D g2D, Map<String, int []> map) {
|
// 创建一个多边形
|
int[] xPoints = map.get("lngs");
|
int[] yPoints = map.get("lats");
|
Polygon polygon = new Polygon(xPoints, yPoints, xPoints.length);
|
// 画多边形
|
g2D.drawPolygon(polygon);
|
}
|
|
|
|
|
}
|