소스 검색

添加矢量数据

gushoubang 11 달 전
부모
커밋
b0c637ff61

+ 5 - 0
onemap-modules/onemap-spatial/pom.xml

@@ -98,6 +98,11 @@
             <artifactId>gt-geojson</artifactId>
             <version>${org.geotools.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.geotools</groupId>
+            <artifactId>gt-geotiff</artifactId>
+            <version>${org.geotools.version}</version>
+        </dependency>
         <dependency>
             <groupId>org.locationtech.jts</groupId>
             <artifactId>jts-core</artifactId>

+ 1 - 1
onemap-modules/onemap-spatial/src/main/java/com/onemap/spatial/domain/ImageRaster.java

@@ -9,6 +9,6 @@ import org.postgresql.util.PGobject;
 @Data
 public class ImageRaster {
     private Integer rid;
-    @TableField("rast")
+    @TableField(value = "rast", typeHandler = com.onemap.spatial.typehandler.PGobjectTypeHandler.class)
     private PGobject rast;
 }

+ 1 - 6
onemap-modules/onemap-spatial/src/main/java/com/onemap/spatial/mapper/ImageMapper.java

@@ -3,16 +3,11 @@ package com.onemap.spatial.mapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.onemap.spatial.domain.ImageRaster;
 import org.apache.ibatis.annotations.Param;
-import org.apache.ibatis.annotations.Select;
-import org.postgresql.util.PGobject;
 
 import java.util.List;
 
 public interface ImageMapper extends BaseMapper<ImageRaster> {
-    @Select("SELECT rast FROM image_16 WHERE public.ST_Intersects(rast, public.ST_GeomFromText(#{wkt}, 4326))")
-    List<PGobject> getRasterDataByWKT(@Param("wkt") String wkt);
+    List<ImageRaster> getRasterDataByWKT(@Param("wkt") String wkt);
 
-    // @Select("SELECT rid FROM image_16 WHERE rid=0")
-    // @Master
     List<Integer> getRids();
 }

+ 70 - 53
onemap-modules/onemap-spatial/src/main/java/com/onemap/spatial/service/impl/ImageServiceImpl.java

@@ -1,41 +1,42 @@
 package com.onemap.spatial.service.impl;
 
+import com.onemap.spatial.domain.ImageRaster;
 import com.onemap.spatial.mapper.ImageMapper;
 import com.onemap.spatial.service.IImageService;
-import org.geotools.data.DataUtilities;
-import org.geotools.data.collection.ListFeatureCollection;
-import org.geotools.data.simple.SimpleFeatureSource;
+import org.geotools.coverage.grid.GridCoverage2D;
+import org.geotools.coverage.grid.io.GridCoverage2DReader;
 import org.geotools.factory.CommonFactoryFinder;
 import org.geotools.feature.DefaultFeatureCollection;
 import org.geotools.feature.simple.SimpleFeatureBuilder;
 import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
-import org.geotools.geojson.feature.FeatureJSON;
+import org.geotools.gce.geotiff.GeoTiffFormat;
 import org.geotools.geometry.jts.JTSFactoryFinder;
-import org.geotools.map.FeatureLayer;
-import org.geotools.referencing.crs.DefaultGeographicCRS;
-import org.locationtech.jts.geom.Envelope;
-import org.opengis.style.Fill;
+import org.geotools.map.GridCoverageLayer;
 import org.geotools.map.MapContent;
 import org.geotools.map.MapViewport;
+import org.geotools.referencing.crs.DefaultGeographicCRS;
 import org.geotools.renderer.lite.StreamingRenderer;
-import org.geotools.styling.SLD;
-import org.geotools.styling.Style;
-import org.geotools.styling.StyleFactory;
+import org.geotools.styling.*;
+import org.locationtech.jts.geom.Envelope;
 import org.locationtech.jts.geom.Geometry;
 import org.locationtech.jts.io.WKTReader;
 import org.opengis.feature.simple.SimpleFeature;
 import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.filter.FilterFactory2;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.style.ContrastMethod;
 import org.postgresql.util.PGobject;
 import org.springframework.stereotype.Service;
-import org.opengis.filter.FilterFactory2;
 
 import javax.annotation.Resource;
 import javax.imageio.ImageIO;
 import java.awt.*;
 import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.IOException;
-import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * 生成图片服务
@@ -44,7 +45,6 @@ import java.io.StringWriter;
 public class ImageServiceImpl implements IImageService {
     @Resource
     private ImageMapper imageMapper;
-
     /**
      * 获取遥感图像
      *
@@ -53,47 +53,60 @@ public class ImageServiceImpl implements IImageService {
      */
     @Override
     public String getSensingImage(String wkt) throws Exception {
-        wktToImage(wkt);
-
-        // // QueryWrapper<ImageRaster> wrapper = new QueryWrapper<>();
-        // // wrapper.eq("rid", 0);
-        // //
-        // // imageMapper.selectOne(wrapper);
-        // // List<Integer> rids = imageMapper.getRids();
-        // List<PGobject> rasterDatas = imageMapper.getRasterDataByWKT(wkt);
-        //
-        // if (rasterDatas.isEmpty()) {
-        //     throw new IllegalArgumentException("No raster data found for the given WKT.");
-        // }
-        //
-        // // Convert raster data to BufferedImage (adjust based on your raster format)
-        // // ByteArrayInputStream bis = new ByteArrayInputStream(rasterData);
-        // ByteArrayInputStream bis = new ByteArrayInputStream(null);
-        // BufferedImage image = ImageIO.read(bis);
-        // bis.close();
-        //
-        // // Convert BufferedImage to byte[]
-        // ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        // ImageIO.write(image, "png", bos);
-        // bos.close();
-        //
-        // // Save image to file system or return image URL
-        // // For example, save to a temporary file
-        // File tempFile = File.createTempFile("raster_image", ".png");
-        // ImageIO.write(image, "png", tempFile);
-
-        // return tempFile.getAbsolutePath();
+        List<ImageRaster> rasterDataList = imageMapper.getRasterDataByWKT(wkt);
+        List<GridCoverageLayer> layers = new ArrayList<>();
+        for (ImageRaster imageRaster : rasterDataList) {
+            GridCoverage2D coverage = convertToGridCoverage2D(imageRaster.getRast());
+            GridCoverageLayer layer = new GridCoverageLayer(coverage, createDefaultStyle());
+            layers.add(layer);
+        }
+        wktToImage(wkt, layers);
         return "";
     }
 
-    private byte[] processRasterToImage(PGobject rast) {
-        // 使用适当的库将 PGobject 转换为图像
-        // 这里的具体实现取决于你的栅格数据格式和需求
-        // 可以使用 JAI、ImageIO 或其他图像处理库
-        return null;
+
+    // 读取栅格数据
+    private GridCoverage2D convertToGridCoverage2D(PGobject rast) throws IOException {
+        // 将PGobject的内容转换为byte[]
+        byte[] bytes = rast.getValue().getBytes();
+
+        // 创建输入流
+        ByteArrayInputStream dataInputStream = new ByteArrayInputStream(bytes);
+
+        // 使用GeoTiffFormat读取栅格数据
+        GeoTiffFormat format = new GeoTiffFormat();
+        GridCoverage2DReader reader = format.getReader(dataInputStream);
+        return reader.read(null);
+    }
+
+    // 创建栅格数据样式
+    private static Style createDefaultStyle() {
+        StyleFactory styleFactory = CommonFactoryFinder.getStyleFactory(null);
+        FilterFactory2 filterFactory = CommonFactoryFinder.getFilterFactory2(null);
+
+        // 创建RGB样式
+        ContrastEnhancement ce = styleFactory.contrastEnhancement(filterFactory.literal(1.0), ContrastMethod.NORMALIZE);
+        SelectedChannelType red = styleFactory.createSelectedChannelType("1", ce);
+        SelectedChannelType green = styleFactory.createSelectedChannelType("2", ce);
+        SelectedChannelType blue = styleFactory.createSelectedChannelType("3", ce);
+        ChannelSelection channelSelection = styleFactory.channelSelection(red, green, blue);
+        RasterSymbolizer symbolizer = styleFactory.createRasterSymbolizer();
+        symbolizer.setChannelSelection(channelSelection);
+
+        // 创建样式规则
+        Rule rule = styleFactory.createRule();
+        rule.symbolizers().add(symbolizer);
+
+        // 创建样式
+        FeatureTypeStyle featureTypeStyle = styleFactory.createFeatureTypeStyle(new Rule[]{rule});
+        Style style = styleFactory.createStyle();
+        style.featureTypeStyles().add(featureTypeStyle);
+
+        return style;
     }
 
-    private void wktToImage(String wkt) throws Exception {
+    // 矢量数据创建图片
+    private void wktToImage(String wkt, List<GridCoverageLayer> layers) throws Exception {
         // 创建一个 WKTReader 对象
         WKTReader reader = new WKTReader(JTSFactoryFinder.getGeometryFactory());
         Geometry geometry = reader.read(wkt);
@@ -115,8 +128,6 @@ public class ImageServiceImpl implements IImageService {
         DefaultFeatureCollection featureCollection = new DefaultFeatureCollection("internal", TYPE);
         featureCollection.add(feature);
 
-        // String geojson = convertToGeoJson(featureCollection);
-
         // 创建 MapContent
         MapContent map = new MapContent();
         map.setTitle("WKT to Image");
@@ -128,6 +139,11 @@ public class ImageServiceImpl implements IImageService {
 
         // 创建一个图层并添加到 MapContent
         org.geotools.map.FeatureLayer layer = new org.geotools.map.FeatureLayer(featureCollection, style);
+
+        for (GridCoverageLayer gridCoverageLayer : layers) {
+            map.addLayer(gridCoverageLayer);
+        }
+
         map.addLayer(layer);
 
         // 计算几何图形的包络并添加填充
@@ -137,7 +153,8 @@ public class ImageServiceImpl implements IImageService {
 
         // 设置 MapViewport
         MapViewport viewport = new MapViewport();
-        viewport.setBounds(new org.geotools.geometry.jts.ReferencedEnvelope(envelope, null));
+        CoordinateReferenceSystem crs = DefaultGeographicCRS.WGS84;
+        viewport.setBounds(new org.geotools.geometry.jts.ReferencedEnvelope(envelope, crs));
         map.setViewport(viewport);
 
         // 创建一个 StreamingRenderer

+ 33 - 0
onemap-modules/onemap-spatial/src/main/java/com/onemap/spatial/typehandler/PGobjectTypeHandler.java

@@ -0,0 +1,33 @@
+package com.onemap.spatial.typehandler;
+
+import org.apache.ibatis.type.BaseTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+import org.postgresql.util.PGobject;
+
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+public class PGobjectTypeHandler  extends BaseTypeHandler<PGobject> {
+
+    @Override
+    public void setNonNullParameter(PreparedStatement ps, int i, PGobject parameter, JdbcType jdbcType) throws SQLException {
+        ps.setObject(i, parameter);
+    }
+
+    @Override
+    public PGobject getNullableResult(ResultSet rs, String columnName) throws SQLException {
+        return (PGobject) rs.getObject(columnName);
+    }
+
+    @Override
+    public PGobject getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
+        return (PGobject) rs.getObject(columnIndex);
+    }
+
+    @Override
+    public PGobject getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
+        return (PGobject) cs.getObject(columnIndex);
+    }
+}

+ 11 - 0
onemap-modules/onemap-spatial/src/main/resources/mapper/postgresql/ImageMapper.xml

@@ -2,6 +2,17 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 
 <mapper namespace="com.onemap.spatial.mapper.ImageMapper">
+
+    <resultMap id="ImageRasterMap" type="com.onemap.spatial.domain.ImageRaster">
+        <id column="rid" property="rid"/>
+        <result column="rast" property="rast" typeHandler="com.onemap.spatial.typehandler.PGobjectTypeHandler"/>
+    </resultMap>
+
+    <select id="getRasterDataByWKT" resultMap="ImageRasterMap">
+        SELECT *
+        FROM image_16
+        WHERE public.ST_Intersects(rast, public.ST_GeomFromText(#{wkt}, 4326))
+    </select>
     <select id="getRids" resultType="Integer">
         SELECT rid
         FROM image_16

BIN
output.png