瀏覽代碼

生成wkt矢量图片

gushoubang 9 月之前
父節點
當前提交
4c0b72767c
共有 10 個文件被更改,包括 185 次插入68 次删除
  1. 1 0
      D/bei.cpg
  2. 二進制
      D/bei.dbf
  3. 40 0
      D/bei.geojson
  4. 1 0
      D/bei.prj
  5. 26 0
      D/bei.qmd
  6. 二進制
      D/bei.shp
  7. 二進制
      D/bei.shx
  8. 11 1
      onemap-modules/onemap-spatial/pom.xml
  9. 106 67
      onemap-modules/onemap-spatial/src/main/java/com/onemap/spatial/service/impl/ImageServiceImpl.java
  10. 二進制
      states.png

+ 1 - 0
D/bei.cpg

@@ -0,0 +1 @@
+UTF-8

二進制
D/bei.dbf


+ 40 - 0
D/bei.geojson

@@ -0,0 +1,40 @@
+{
+  "type": "FeatureCollection",
+  "features": [
+    {
+      "type": "Feature",
+      "properties": {},
+      "geometry": {
+        "coordinates": [
+          [
+            [
+              116.3043617698678,
+              39.9950860331447
+            ],
+            [
+              116.2507003294885,
+              39.87785868533936
+            ],
+            [
+              116.44829350496468,
+              39.78417129374486
+            ],
+            [
+              116.44504496065588,
+              39.94835379839009
+            ],
+            [
+              116.34827773886082,
+              39.91217475088072
+            ],
+            [
+              116.3043617698678,
+              39.9950860331447
+            ]
+          ]
+        ],
+        "type": "Polygon"
+      }
+    }
+  ]
+}

+ 1 - 0
D/bei.prj

@@ -0,0 +1 @@
+GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]

+ 26 - 0
D/bei.qmd

@@ -0,0 +1,26 @@
+<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
+<qgis version="3.22.5-Bia?owie?a">
+  <identifier></identifier>
+  <parentidentifier></parentidentifier>
+  <language></language>
+  <type>dataset</type>
+  <title></title>
+  <abstract></abstract>
+  <links/>
+  <fees></fees>
+  <encoding></encoding>
+  <crs>
+    <spatialrefsys>
+      <wkt></wkt>
+      <proj4></proj4>
+      <srsid>0</srsid>
+      <srid>0</srid>
+      <authid></authid>
+      <description></description>
+      <projectionacronym></projectionacronym>
+      <ellipsoidacronym></ellipsoidacronym>
+      <geographicflag>false</geographicflag>
+    </spatialrefsys>
+  </crs>
+  <extent/>
+</qgis>

二進制
D/bei.shp


二進制
D/bei.shx


+ 11 - 1
onemap-modules/onemap-spatial/pom.xml

@@ -12,7 +12,7 @@
     <artifactId>onemap-modules-spatial</artifactId>
 
     <properties>
-        <org.geotools.version>24.6</org.geotools.version>
+        <org.geotools.version>26.0</org.geotools.version>
         <org.postgresql.version>42.3.6</org.postgresql.version>
     </properties>
 
@@ -104,6 +104,16 @@
             <artifactId>gt-geotiff</artifactId>
             <version>${org.geotools.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.geotools</groupId>
+            <artifactId>gt-swing</artifactId>
+            <version>${org.geotools.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.geotools</groupId>
+            <artifactId>gt-shapefile</artifactId>
+            <version>${org.geotools.version}</version>
+        </dependency>
         <dependency>
             <groupId>org.locationtech.jts</groupId>
             <artifactId>jts-core</artifactId>

+ 106 - 67
onemap-modules/onemap-spatial/src/main/java/com/onemap/spatial/service/impl/ImageServiceImpl.java

@@ -1,22 +1,38 @@
 package com.onemap.spatial.service.impl;
 
-import com.onemap.common.core.utils.uuid.UUID;
 import com.onemap.spatial.mapper.ImageMapper;
 import com.onemap.spatial.service.IImageService;
+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.geometry.jts.JTSFactoryFinder;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.geotools.map.FeatureLayer;
+import org.geotools.map.Layer;
+import org.geotools.map.MapContent;
+import org.geotools.referencing.crs.DefaultGeographicCRS;
+import org.geotools.renderer.GTRenderer;
+import org.geotools.renderer.label.LabelCacheImpl;
+import org.geotools.renderer.lite.StreamingRenderer;
+import org.geotools.styling.*;
+import org.geotools.styling.Stroke;
+import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.io.WKTReader;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.filter.FilterFactory2;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
 import javax.imageio.ImageIO;
+import javax.imageio.stream.ImageOutputStream;
 import java.awt.*;
 import java.awt.image.BufferedImage;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.OutputStream;
-import java.util.Base64;
 import java.util.HashMap;
 import java.util.Map;
-
 /**
  * 生成图片服务
  */
@@ -28,77 +44,100 @@ public class ImageServiceImpl implements IImageService {
 
     @Override
     public String getSensingImage(String wkt) throws Exception {
-        String uuid = UUID.randomUUID().toString();
-        String rasterFilePath = uuid + "raster.png";
-        String wktFilePath = uuid + "wkt.png";
-
-        String base64RasterImage = imageMapper.getRasterImage(wkt);
-        base64ToImage(base64RasterImage, rasterFilePath);
-
-
-        File imageFile = new File(rasterFilePath); // 替换成你的图片路径
-        BufferedImage image = ImageIO.read(imageFile);
-
-        int width = image.getWidth();
-        int height = image.getHeight();
-
-        Map<String, Object> mapParam = new HashMap<>();
-        mapParam.put("wkt", wkt);
-        mapParam.put("width", width);
-        mapParam.put("height", height);
-        String base64WktImage = imageMapper.getWktImage(mapParam);
-        base64ToImage(base64WktImage, wktFilePath);
-
-        // 将两个图片合并
-        mergeImage(wktFilePath, rasterFilePath);
-        System.out.println("Image saved as " + rasterFilePath + " " + wktFilePath);
+        // 创建一个 MapContent 对象
+        MapContent mapContent = new MapContent();
+        mapContent.setTitle("Quickstart");
+
+        // 将 WKT 转换为几何对象并添加到图层
+        WKTReader wktReader = new WKTReader(JTSFactoryFinder.getGeometryFactory());
+        Geometry geometry = wktReader.read(wkt);
+
+        SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder();
+        typeBuilder.setName("geometry");
+        typeBuilder.setCRS(DefaultGeographicCRS.WGS84);
+        typeBuilder.add("the_geom", Geometry.class);
+        SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(typeBuilder.buildFeatureType());
+
+        featureBuilder.add(geometry);
+        SimpleFeature feature = featureBuilder.buildFeature(null);
+
+        DefaultFeatureCollection featureCollection = new DefaultFeatureCollection();
+        featureCollection.add(feature);
+
+        Style wktStyle = createStyle();
+        Layer wktLayer = new FeatureLayer(featureCollection, wktStyle);
+        mapContent.addLayer(wktLayer);
+
+        // 获取几何对象的外接矩形
+        ReferencedEnvelope combinedBounds = new ReferencedEnvelope(DefaultGeographicCRS.WGS84);
+        combinedBounds.expandToInclude(featureCollection.getBounds());
+
+        // 增加长和宽的10%
+        double expandWidth = combinedBounds.getWidth() * (1+0.10);
+        double expandHeight = combinedBounds.getHeight() * (1+0.10);
+        combinedBounds.expandBy(expandWidth, expandHeight);
+
+        // 将地图绘制到图片
+        File outputFile = new File("states.png");
+        try (FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
+             ImageOutputStream outputImageFile = ImageIO.createImageOutputStream(fileOutputStream);) {
+
+            int w = 1000;
+            int h = (int) (w * (combinedBounds.getHeight() / combinedBounds.getWidth()));
+            BufferedImage bufferedImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
+            Graphics2D g2d = bufferedImage.createGraphics();
+
+            mapContent.getViewport().setMatchingAspectRatio(true);
+            mapContent.getViewport().setScreenArea(new Rectangle(w, h));
+            mapContent.getViewport().setBounds(combinedBounds);
+
+            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+
+            Rectangle outputArea = new Rectangle(w, h);
+
+            GTRenderer renderer = new StreamingRenderer();
+            LabelCacheImpl labelCache = new LabelCacheImpl();
+            Map<Object, Object> hints = renderer.getRendererHints();
+            if (hints == null) {
+                hints = new HashMap<>();
+            }
+            hints.put(StreamingRenderer.LABEL_CACHE_KEY, labelCache);
+            renderer.setRendererHints(hints);
+            renderer.setMapContent(mapContent);
+            renderer.paint(g2d, outputArea, combinedBounds);
+            ImageIO.write(bufferedImage, "png", outputImageFile);
+        } catch (IOException ex) {
+            ex.printStackTrace();
+        }
         return "";
     }
 
+    private Style createStyle() {
+        // 创建样式工厂和过滤工厂
+        StyleFactory styleFactory = CommonFactoryFinder.getStyleFactory();
+        FilterFactory2 filterFactory = CommonFactoryFinder.getFilterFactory2();
 
-    /**
-     * 合并两个图片
-     *
-     * @param rasterFilePath 在下面
-     * @param wktFilePath    在上面
-     * @throws Exception
-     */
-    private void mergeImage(String wktFilePath, String rasterFilePath) throws Exception {
-        BufferedImage image1 = ImageIO.read(new File(rasterFilePath));
-        BufferedImage image2 = ImageIO.read(new File(wktFilePath));
-
-        // 计算第二张图片在第一张图片中的位置
-        int overlayX = (image1.getWidth() - image2.getWidth()) / 2;
-        int overlayY = (image1.getHeight() - image2.getHeight()) / 2;
-
-        // 创建一个合并后的图片对象,支持透明度
-        BufferedImage mergedImage = new BufferedImage(image1.getWidth(), image1.getHeight(), BufferedImage.TYPE_INT_ARGB);
+        // 创建笔刷和填充样式
+        Stroke stroke = styleFactory.createStroke(
+                filterFactory.literal(Color.BLUE),
+                filterFactory.literal(1)
+        );
 
-        // 获取画布对象
-        Graphics2D g2d = mergedImage.createGraphics();
-        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_OVER, 0.1f));
-        // 将第一张图片绘制到合并图片的左上角
-        g2d.drawImage(image1, 0, 0, null);
+        Fill fill = styleFactory.createFill(
+                filterFactory.literal(Color.CYAN),
+                filterFactory.literal(0.5)
+        );
 
-        // 将第二张图片绘制到合并图片的中心位置
-        g2d.drawImage(image2, overlayX, overlayY, null);
+        // 创建符号样式
+        PolygonSymbolizer polygonSymbolizer = styleFactory.createPolygonSymbolizer(stroke, fill, null);
+        Rule rule = styleFactory.createRule();
+        rule.symbolizers().add(polygonSymbolizer);
 
-        // 释放画布
-        g2d.dispose();
-
-        // 保存合并后的图片,保留透明度
-        File output = new File("overlayedImage.png");
-        ImageIO.write(mergedImage, "png", output);
-
-        System.out.println("叠加图片成功保存至:" + output.getAbsolutePath());
-    }
+        FeatureTypeStyle fts = styleFactory.createFeatureTypeStyle(new Rule[]{rule});
+        Style style = styleFactory.createStyle();
+        style.featureTypeStyles().add(fts);
 
-    void base64ToImage(String base64Str, String filePath) throws IOException {
-        base64Str = base64Str.replaceAll("\n", "");
-        base64Str = base64Str.replaceAll("\r", "");
-        byte[] imageRasterBytes = Base64.getDecoder().decode(base64Str);
-        OutputStream osRater = new FileOutputStream(filePath);
-        osRater.write(imageRasterBytes);
+        return style;
     }
 }
 

二進制
states.png