GeoTools加载瓦片并合成Tiff文件,附带经纬度坐标-Java

1 篇文章 0 订阅
1 篇文章 0 订阅

背景

在日常工作中,需要根据某个经纬度范围获取当前的瓦片数据,再输出成Tiff文件数据,并追加经纬度信息。

代码

1、下面是主程序

package com.sungrow.admin.service.impl;

import com.sungrow.admin.service.TiffService;
import com.sungrow.admin.util.WGSUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.coverage.grid.GridCoverageFactory;
import org.geotools.coverage.grid.io.AbstractGridFormat;
import org.geotools.gce.geotiff.GeoTiffFormat;
import org.geotools.gce.geotiff.GeoTiffWriteParams;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.opengis.coverage.grid.GridCoverageWriter;
import org.opengis.parameter.GeneralParameterValue;
import org.opengis.parameter.ParameterValueGroup;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import javax.media.jai.TiledImage;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;

import static jdk.nashorn.internal.runtime.regexp.joni.Config.log;

@Slf4j
@Service
@RequiredArgsConstructor
public class TiffServiceImpl implements TiffService {

    @Value("${system.google-images-path}")
    private String googleSatellitePath;

    private String image_ext = ".jpg";


    @Override
    public void tile2Tiff(String source, double left, double top, double right, double bottom) {
        // 获取x、y的数字最大值和最小值
        int[] minXY = WGSUtil.wgs_to_tile(left, top);
        int[] maxXY = WGSUtil.wgs_to_tile(right, bottom);
        int posi1x = minXY[0];
        int posi1y = minXY[1];
        int posi2x = maxXY[0];
        int posi2y = maxXY[1];

        int lenX = posi2x - posi1x + 1;
        int lenY = posi2y - posi1y + 1;
        BufferedImage image = null;
        WritableRaster raster = null;
        BufferedImage defaultImage = null;
        try {
            defaultImage = ImageIO.read(this.getDefaultSatelliteFile());
        } catch (IOException e) {
            log.error("读取默认卫星影像栅格图片失败,请检查文件是否存在");
            return;
        }

        BufferedImage blank = new BufferedImage(lenX * 256, lenY * 256, BufferedImage.TYPE_3BYTE_BGR);
        raster = blank.copyData(null);

        // 循环获取图片并生成WritableRaster对象
        for (int i = posi1x; i <= posi2x; i++) {
            for (int j = posi1y; j <= posi2y; j++) {
                try {
                    image = ImageIO.read(this.getSatelliteFile(i, j));
                } catch (IOException e) {
                    image = defaultImage;
                }
                raster.setRect((i - posi1x) * 256, (j - posi1y) * 256, image.getRaster());
            }
        }

        // 设置包围盒
        ReferencedEnvelope envelope = new ReferencedEnvelope(left, right, bottom, top, DefaultGeographicCRS.WGS84);

        // 创建网格
        GridCoverageFactory factory = new GridCoverageFactory();
        GridCoverage2D gridCoverage = factory.create("my_grid", raster, envelope);

        // 创建tiff生成参数
        GeoTiffFormat format = new GeoTiffFormat();
        GeoTiffWriteParams wp = new GeoTiffWriteParams();
        wp.setCompressionMode(GeoTiffWriteParams.MODE_EXPLICIT);
        wp.setCompressionType("Deflate");
        ParameterValueGroup params = format.getWriteParameters();
        params.parameter(AbstractGridFormat.GEOTOOLS_WRITE_PARAMS.getName().toString()).setValue(wp);
        GeneralParameterValue[] writeParameters = params.values().toArray(new GeneralParameterValue[1]);

        // gridCoverage
        GeoTiffFormat format1 = new GeoTiffFormat();
        File out = new File("D:\\123.tiff");
        GridCoverageWriter writer = format1.getWriter(out);
        try {
            writer.write(gridCoverage, writeParameters);
            writer.dispose();
        } catch (IOException e) {
            log.error("生成tiff失败:{}", e.getMessage());
        }

        gridCoverage.dispose(true);
    }

    /**
     * 获取卫星影像图片
     *
     * @param x
     * @param y
     * @return
     */
    private File getSatelliteFile(int x, int y) {
        return new File(this.googleSatellitePath + 18 + File.separator + x + File.separator + y + this.image_ext);
    }

    /**
     * 获取默认的卫星影像图片
     *
     * @return
     */
    private File getDefaultSatelliteFile() {
        return new File(this.googleSatellitePath + File.separator + "default_satellite" + this.image_ext);
    }
}

2、下面是工具转换操作

package com.sungrow.admin.util;

public class WGSUtil {

    /**
     * wgs转tile,zoom按照默认18层级
     *
     * @param j 经度
     * @param w 纬度
     * @return
     */
    public static int[] wgs_to_tile(double j, double w) {
        if (j < 0) {
            j = 180 + j;
        } else {
            j += 180;
        }
        j /= 360;
        w = Math.min(w, 85.0511287798);
        w = Math.max(w, -85.0511287798);
        w = Math.log(Math.tan((90 + w) * Math.PI / 360)) / (Math.PI / 180);
        w /= 180;
        w = 1 - (w + 1) / 2;
        int num = (int) Math.pow(2, 18);
        int x = (int) Math.floor(j * num);
        int y = (int) Math.floor(w * num);
        return new int[]{x, y};
    }
}

3、引入

<properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <geotools.version>27.0</geotools.version>
    
    </properties>

<!--geoTools-->
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-jdbc</artifactId>
            <version>${geotools.version}</version>
            <exclusions>
                <exclusion>
                    <artifactId>commons-collections</artifactId>
                    <groupId>commons-collections</groupId>
                </exclusion>
            </exclusions>
        </dependency>
       <!-- <dependency>
            <groupId>org.postgis</groupId>
            <artifactId>postgis-jdbc</artifactId>
            <version>${geotools.version}</version>
        </dependency>-->
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-cql</artifactId>
            <version>${geotools.version}</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-ysld</artifactId>
            <version>${geotools.version}</version>
        </dependency>


        <!--操作shape文件-->
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-shapefile</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-epsg-extension</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-geojson</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools.jdbc</groupId>
            <artifactId>gt-jdbc-postgis</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-swing</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-main</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-opengis</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-xml</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-referencing</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-geotiff</artifactId>
            <version>${geotools.version}</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.osgeo/proj4j 用于投影坐标转化 -->
        <dependency>
            <groupId>org.osgeo</groupId>
            <artifactId>proj4j</artifactId>
            <version>0.1.0</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-process</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-process-feature</artifactId>
            <version>${geotools.version}</version>
        </dependency>

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java GeoTools是一个开源的Java库,用于处理和分析地理空间数据。它提供了一组工具和API,可用于读取、写入、转换和分析各种地理空间数据格式。 PNG瓦片是一种常见的地图瓦片格式之一,它通常用于在Web地图应用程序中显示地图。GeoTools提供了一些类和方法,可以轻松地读取和处理PNG瓦片。 以下是一个简单的Java GeoTools示例,用于读取PNG瓦片并显示它们: ``` import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import org.geotools.data.DataUtilities; import org.geotools.data.collection.ListFeatureCollection; import org.geotools.geometry.jts.ReferencedEnvelope; import org.geotools.map.DefaultMapContext; import org.geotools.map.MapContext; import org.geotools.renderer.GTRenderer; import org.geotools.renderer.lite.StreamingRenderer; import org.geotools.styling.Style; import org.geotools.styling.StyleFactory; import org.geotools.styling.StyleFactoryImpl; import org.geotools.styling.SyledLayerDescriptor; import org.geotools.styling.SyledLayerDescriptorImpl; import org.geotools.styling.StyleBuilder; import org.geotools.styling.StyleBuilderImpl; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.referencing.crs.CoordinateReferenceSystem; public class PNGTileExample { public static void main(String[] args) throws IOException { // Load the PNG tile File pngFile = new File("path/to/my/tile.png"); BufferedImage image = ImageIO.read(pngFile); // Define the bounding box of the tile CoordinateReferenceSystem crs = // define the CRS of the tile ReferencedEnvelope envelope = new ReferencedEnvelope(xmin, xmax, ymin, ymax, crs); // Create a simple feature to represent the tile SimpleFeatureType featureType = DataUtilities.createType("Tile", "geometry:Polygon"); SimpleFeature feature = DataUtilities.template(featureType); feature.setDefaultGeometry(JTS.toGeometry(envelope)); // Wrap the feature in a feature collection ListFeatureCollection featureCollection = new ListFeatureCollection(featureType); featureCollection.add(feature); // Create a map context and add the feature collection to it MapContext mapContext = new DefaultMapContext(); mapContext.addLayer(featureCollection, createStyle()); // Create a renderer and render the map GTRenderer renderer = new StreamingRenderer(); renderer.setContext(mapContext); renderer.paint(image.createGraphics(), image.getBounds()); } private static Style createStyle() { StyleFactory sf = new StyleFactoryImpl(); StyleBuilder sb = new StyleBuilderImpl(); // Define the style for the tile return sb.createStyle(sb.createPolygonSymbolizer(), sb.createLineSymbolizer(), sb.createPointSymbolizer(), sb.createTextSymbolizer()); } } ``` 在这个例子中,我们加载一个PNG瓦片,并使用GeoTools创建一个简单的地图上下文。我们将瓦片表示为一个简单要素,并将其添加到地图上下文中。然后我们使用渲染器将地图渲染到瓦片上。 当然,这只是Java GeoTools和PNG瓦片的一个简单示例。GeoTools提供了许多其他功能,可用于处理和分析各种地理空间数据格式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值