使用 geotools28.6,运行会出现异常java.lang.NoSuchFieldError: JAVA_9
bash
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.demo</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>demo</description>
<properties>
<java.version>11</java.version>
<geotools.version>28.6</geotools.version>
<commons-lang3.version>3.4</commons-lang3.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-main</artifactId>
<version>${geotools.version}</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-shapefile</artifactId>
<version>${geotools.version}</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-geojson</artifactId>
<version>${geotools.version}</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-geotiff</artifactId>
<version>${geotools.version}</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-coverage</artifactId>
<version>${geotools.version}</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-epsg-hsql</artifactId>
<version>${geotools.version}</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-referencing</artifactId>
<version>${geotools.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
java
package com.seven7m;
import org.geotools.coverage.grid.GridCoordinates2D;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.coverage.grid.GridEnvelope2D;
import org.geotools.data.FileDataStore;
import org.geotools.data.FileDataStoreFinder;
import org.geotools.data.collection.ListFeatureCollection;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.gce.geotiff.GeoTiffReader;
import org.geotools.geometry.DirectPosition2D;
import org.geotools.geometry.jts.JTS;
import org.geotools.referencing.CRS;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.Point;
import org.opengis.feature.Property;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class RasterMaskExample {
private static final String ID_FIELD = "WSCD";
public static void main(String[] args) throws Exception {
String rasterPath = "E:\\sevenM\\河图\\tst\\ludishuiwen\\nc\\202506210000.tif";
String shpPath = "E:\\sevenM\\河图\\tst\\ludishuiwen\\nc\\WATA1.shp";
String tmStr = parseTimeFromFilename(rasterPath);
GeoTiffReader reader = new GeoTiffReader(new File(rasterPath));
GridCoverage2D coverage = reader.read(null);
CoordinateReferenceSystem rasterCRS = coverage.getCoordinateReferenceSystem2D();
GridEnvelope2D gridRange = coverage.getGridGeometry().getGridRange2D();
int width = gridRange.width;
int height = gridRange.height;
// 读取 Shapefile
FileDataStore store = FileDataStoreFinder.getDataStore(new File(shpPath));
SimpleFeatureCollection features = store.getFeatureSource().getFeatures();
CoordinateReferenceSystem shpCRS = features.getSchema().getCoordinateReferenceSystem();
if (!CRS.equalsIgnoreMetadata(shpCRS, rasterCRS)) {
features = reprojectFeatures(features, shpCRS, rasterCRS);
}
// 构建流域网格掩膜
boolean[][] mask = new boolean[height][width]; // true 表示网格在流域内
List<String> wsCodes = new ArrayList<>();
try (SimpleFeatureIterator it = features.features()) {
while (it.hasNext()) {
SimpleFeature feature = it.next();
Geometry geom = (Geometry) feature.getDefaultGeometry();
String wsCode = feature.getAttribute(ID_FIELD).toString();
wsCodes.add(wsCode);
// 计算覆盖范围,避免整个栅格遍历
GridCoordinates2D minCoord = coverage.getGridGeometry().worldToGrid(new DirectPosition2D(geom.getEnvelopeInternal().getMinX(), geom.getEnvelopeInternal().getMinY()));
GridCoordinates2D maxCoord = coverage.getGridGeometry().worldToGrid(new DirectPosition2D(geom.getEnvelopeInternal().getMaxX(), geom.getEnvelopeInternal().getMaxY()));
int xStart = Math.max(0, Math.min(minCoord.x, maxCoord.x));
int xEnd = Math.min(width - 1, Math.max(minCoord.x, maxCoord.x));
int yStart = Math.max(0, Math.min(minCoord.y, maxCoord.y));
int yEnd = Math.min(height - 1, Math.max(minCoord.y, maxCoord.y));
for (int y = yStart; y <= yEnd; y++) {
for (int x = xStart; x <= xEnd; x++) {
GridCoordinates2D coord = new GridCoordinates2D(x, y);
DirectPosition2D pos = (DirectPosition2D) coverage.getGridGeometry().gridToWorld(coord);
Point pt = geom.getFactory().createPoint(new Coordinate(pos.x, pos.y));
if (geom.contains(pt)) {
mask[y][x] = true;
}
}
}
}
}
// 只对 mask=true 的网格进行读取
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if (!mask[y][x]) continue;
GridCoordinates2D coord = new GridCoordinates2D(x, y);
double[] values = new double[1];
coverage.evaluate(coord, values);
double drp = values[0];
if (drp <= 0) continue;
DirectPosition2D pos = (DirectPosition2D) coverage.getGridGeometry().gridToWorld(coord);
System.out.println(String.format("{GRID_ID: R%d_C%d, X: %.3f, Y: %.3f, DRP: %.2f, TM: %s}",
y, x, pos.x, pos.y, drp, tmStr));
}
}
store.dispose();
reader.dispose();
}
private static SimpleFeatureCollection reprojectFeatures(SimpleFeatureCollection collection,
CoordinateReferenceSystem sourceCRS,
CoordinateReferenceSystem targetCRS) throws Exception {
SimpleFeatureType schema = collection.getSchema();
SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
tb.init(schema);
tb.setCRS(targetCRS);
SimpleFeatureType newSchema = tb.buildFeatureType();
MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
ListFeatureCollection reprojected = new ListFeatureCollection(newSchema);
try (SimpleFeatureIterator it = collection.features()) {
while (it.hasNext()) {
SimpleFeature feature = it.next();
Geometry geom = (Geometry) feature.getDefaultGeometry();
Geometry reprojectedGeom = JTS.transform(geom, transform);
SimpleFeatureBuilder fb = new SimpleFeatureBuilder(newSchema);
for (Property prop : feature.getProperties()) {
if (prop.getName().getLocalPart().equals(schema.getGeometryDescriptor().getLocalName())) {
fb.set(schema.getGeometryDescriptor().getLocalName(), reprojectedGeom);
} else {
fb.set(prop.getName().getLocalPart(), prop.getValue());
}
}
reprojected.add(fb.buildFeature(feature.getID()));
}
}
return reprojected;
}
private static String parseTimeFromFilename(String filename) throws Exception {
String base = new File(filename).getName().split("\\.")[0];
SimpleDateFormat input = new SimpleDateFormat("yyyyMMddHHmm");
SimpleDateFormat output = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d = input.parse(base);
return output.format(d);
}
}
异常信息:java.lang.NoSuchFieldError: JAVA_9
bash
Exception in thread "main" java.lang.NoSuchFieldError: JAVA_9
at org.geotools.util.NIOUtilities.clean(NIOUtilities.java:188)
at org.geotools.util.NIOUtilities.clean(NIOUtilities.java:168)
at org.geotools.data.shapefile.dbf.DbaseFileHeader.readHeader(DbaseFileHeader.java:645)
at org.geotools.data.shapefile.dbf.DbaseFileReader.doInit(DbaseFileReader.java:226)
at org.geotools.data.shapefile.dbf.DbaseFileReader.init(DbaseFileReader.java:186)
at org.geotools.data.shapefile.dbf.DbaseFileReader.<init>(DbaseFileReader.java:148)
at org.geotools.data.shapefile.ShapefileSetManager.openDbfReader(ShapefileSetManager.java:132)
at org.geotools.data.shapefile.ShapefileFeatureSource.readAttributes(ShapefileFeatureSource.java:500)
发现在properties
中定义了commons-lang3.version
,会导致异常,注释掉就可以了
运行截图:
