|
@@ -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;
|
|
|
}
|
|
|
}
|
|
|
|