天天看點

矢量栅格網格化操作

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