Geo Tools Vector grids 矢量栅格
矢量栅格化
GeoTools 矢量網格類使建立由多邊形或線元素組成的矢量網格(也稱為晶格)變得容易,每個網格都表示為SimpleFeature。
使用“網格”或“線”實用程式類可以輕松生成簡單的網格,而當需要對網格布局和屬性進行更多控制時,可以使用較低級别的類。

<repositories>
<repository>
<id>osgeo</id>
<name>OSGeo Release Repository</name>
<url>https://repo.osgeo.org/repository/release/</url>
<snapshots><enabled>false</enabled></snapshots>
<releases><enabled>true</enabled></releases>
</repository>
<repository>
<id>osgeo-snapshot</id>
<name>OSGeo Snapshot Repository</name>
<url>https://repo.osgeo.org/repository/snapshot/</url>
<snapshots><enabled>true</enabled></snapshots>
<releases><enabled>false</enabled></releases>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-grid</artifactId>
<version>${geotools.version}</version>
</dependency>
</dependencies>
/**
* 擷取栅格化後的 BoundingBox 集合
*
* @param srcGeometry 栅格前的 geometry
* @param srcBoundingBox 栅格前的 boundingBox
* @return 栅格化後的 BoundingBox 集合
* @throws Exception 異常
*/
private List<BoundingBox> gridGeometry(Geometry srcGeometry, BoundingBox srcBoundingBox) throws Exception {
//擷取栅格精度 (機關 度 °)
double sideLen = getSideLen(srcBoundingBox);
//擷取 envelope
ReferencedEnvelope envelope = getReferencedEnvelope(srcBoundingBox, sideLen);
//栅格化
SimpleFeatureSource grid = Grids.createSquareGrid(envelope, sideLen);
SimpleFeatureCollection features = grid.getFeatures();
SimpleFeatureIterator iterator = features.features();
List<BoundingBox> boundingBoxes = new LinkedList<>();
while (iterator.hasNext()) {
SimpleFeature feature = iterator.next();
Geometry geometry = (Geometry) feature.getDefaultGeometry();
//相交計算
if (srcGeometry.intersects(geometry)) {
BoundingBox bounds = feature.getBounds();
boundingBoxes.add(bounds);
}
}
return boundingBoxes;
}
//================================================= Gird ========================================================
/**
* 擷取栅格化的 Envelope
*
* @param boundingBox 原 boundingBox
* @param sideLen 栅格精度
* @return Envelope
*/
private ReferencedEnvelope getReferencedEnvelope(BoundingBox boundingBox, double sideLen) {
double maxX = getDoubleValueUp(boundingBox.getMaxX(), sideLen);
double maxY = getDoubleValueUp(boundingBox.getMaxY(), sideLen);
double minX = getDoubleValueDown(boundingBox.getMinX(), sideLen);
double minY = getDoubleValueDown(boundingBox.getMinY(), sideLen);
return new ReferencedEnvelope(minX, maxX, minY, maxY, DefaultGeographicCRS.WGS84);
}
/**
* 擷取栅格精度值
*
* @param boundingBox box
* @return 栅格精度 以 度 為機關
*/
private double getSideLen(BoundingBox boundingBox) {
double maxX = boundingBox.getMaxX();
double maxY = boundingBox.getMaxY();
double minX = boundingBox.getMinX();
double minY = boundingBox.getMinY();
double xBetween = Math.abs(new BigDecimal(Double.toString(maxX)).subtract(new BigDecimal(Double.toString(minX))).doubleValue());
double yBetween = Math.abs(new BigDecimal(Double.toString(maxY)).subtract(new BigDecimal(Double.toString(minY))).doubleValue());
// SIDE_LEN_SIZE = 邊長格網數 可根據實際情況自定義
double SIDE_LEN_SIZE = 50.0;
double result = new BigDecimal(Double.toString(Math.min(xBetween, yBetween))).divide(new BigDecimal(SIDE_LEN_SIZE)).doubleValue();
result = Math.max(result, 0.01);
return Double.parseDouble(String.format("%.4f", result));
}
/**
* 向上取值
*
* @param value 值
* @param sideLen 栅格精度
* @return 值
*/
private double getDoubleValueUp(double value, double sideLen) {
NumberFormat nf = NumberFormat.getNumberInstance();
nf.setMaximumFractionDigits(2);
nf.setRoundingMode(RoundingMode.UP);
String format = nf.format(value);
return Math.min(Double.parseDouble(format) + sideLen, 180);
}
/**
* 向下取值
*
* @param value 值
* @param sideLen 栅格精度
* @return 值
*/
private double getDoubleValueDown(double value, double sideLen) {
NumberFormat nf = NumberFormat.getNumberInstance();
nf.setMaximumFractionDigits(2);
nf.setRoundingMode(RoundingMode.DOWN);
String format = nf.format(value);
return Math.max(Double.parseDouble(format) - sideLen, -180);
}
效果圖
geojson.io
Mr.superbeyone