一个有用的geotools上传sld样式与shp文件以生成缩略图的方法
一个有用的geotools上传sld样式与shp文件以生成缩略图的方法
文章目录
- 一个有用的geotools上传sld样式与shp文件以生成缩略图的方法
- 前言
- 一、geotools缩略图工具类方法
- 二、结果展示
- 总结
前言
发布一些图层的时候觉得图层的缩略图上传太麻烦,又想偷懒上传Shp数据怎么办
其实我觉得解决一点点问题就可以了,只需要SLD文件和SHP文件上传上去,用geotools渲染出缩略图即可。
但是bbox我虽然用了一个自适应的方法来,但是还是有点bug。
由于QGIS我用的SLD文件导出是1.1.0版本,不兼容我这个版本的geotools,所以,写了一个方法来读取1.1.0版本的SLD文件,来兼容到1.0.0版本,方法是createStyleFromSld
一、geotools缩略图工具类方法
下面的
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.simple.SimpleFeatureSource;
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.lite.StreamingRenderer;
import org.geotools.styling.*;
import org.geotools.xsd.Configuration;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;public class Shape2Image {private static MapContent map = new MapContent();public Style createStyleFromSld(String uri)throws XPathExpressionException, IOException, ParserConfigurationException, SAXException {File sldFile = new File(uri);DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();DocumentBuilder db = dbf.newDocumentBuilder();Document xmlDocument = db.parse(new InputSource(new FileInputStream(sldFile)));XPath xPath = XPathFactory.newInstance().newXPath();String version = xPath.compile("/StyledLayerDescriptor/@version").evaluate(xmlDocument);Configuration sldConf;if (version != null && version.startsWith("1.1")) {sldConf = new org.geotools.sld.v1_1.SLDConfiguration();} else {sldConf = new org.geotools.sld.SLDConfiguration();}StyledLayerDescriptor sld = (StyledLayerDescriptor) new org.geotools.xsd.DOMParser(sldConf, xmlDocument).parse();NamedLayer l = (NamedLayer) sld.getStyledLayers()[0];Style style = l.getStyles()[0];return style;}public void addShapeLayer(String shpPath, String sldPath){try{File file = new File(shpPath);ShapefileDataStore shpDataStore = null;shpDataStore = new ShapefileDataStore(file.toURL());//设置编码Charset charset = Charset.forName("GB18030");shpDataStore.setCharset(charset);String typeName = shpDataStore.getTypeNames()[0];SimpleFeatureSource featureSource = null;featureSource = shpDataStore.getFeatureSource (typeName);//SLD的方式File sldFile = new File(sldPath);//适配1.0.0版本的Sld文件Style style = createStyleFromSld(sldPath);//StyleFactory styleFactory = CommonFactoryFinder.getStyleFactory();//SLDParser stylereader = new SLDParser(styleFactory, sldFile.toURI().toURL());//Style[] stylearray = stylereader.readXML();//Style style = stylearray[0];//默认的方式//Style style = SLD.createSimpleStyle(featureSource.getSchema());//SLD.setPolyColour(style, Color.RED );Layer layer = new FeatureLayer(featureSource, style);map.addLayer(layer);}catch(Exception e){e.printStackTrace();}}/*** 根据四至、长、宽获取地图内容,并生成图片* @param paras* @param imgPath*/public void getMapContent(Map paras, String imgPath){try{double[] bbox = (double[]) paras.get("bbox");double x1 = bbox[0], y1 = bbox[1],x2 = bbox[2], y2 = bbox[3];int width = (int) paras.get("width"),height=(int) paras.get("height");// 设置输出范围CoordinateReferenceSystem crs = DefaultGeographicCRS.WGS84;ReferencedEnvelope mapArea = new ReferencedEnvelope(x1, x2, y1, y2, crs);// 初始化渲染器StreamingRenderer sr = new StreamingRenderer();sr.setMapContent(map);// 初始化输出图像BufferedImage bi = new BufferedImage(width, height,BufferedImage.TYPE_INT_ARGB);Graphics g = bi.getGraphics();((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);((Graphics2D) g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);Rectangle rect = new Rectangle(0, 0, width, height);// 绘制地图sr.paint((Graphics2D) g, rect, mapArea);//将BufferedImage变量写入文件中。ImageIO.write(bi,"png",new File(imgPath));}catch(Exception e){e.printStackTrace();}}/*** 计算指定 SHP 文件的 BBOX** @param shpPath SHP 文件路径* @return 计算得到的 BBOX,格式为 double 数组,包含 minX、minY、maxX、maxY*/public static double[] calculateBounds(String shpPath) {try {File file = new File(shpPath);ShapefileDataStore shpDataStore = new ShapefileDataStore(file.toURI().toURL());shpDataStore.setCharset(Charset.forName("GBK"));SimpleFeatureSource featureSource = shpDataStore.getFeatureSource();ReferencedEnvelope bounds = featureSource.getBounds();CoordinateReferenceSystem crs = bounds.getCoordinateReferenceSystem();double[] bbox = new double[]{bounds.getMinX(), bounds.getMinY(), bounds.getMaxX(), bounds.getMaxY()};return bbox;} catch (Exception e) {e.printStackTrace();return null;}}/*** 工具类测试方法* @param args*/public static void main(String[] args){long start = System.currentTimeMillis();Shape2Image shp2img = new Shape2Image();String shpPath = "E:\\fanwei\\HED_dataset.shp";String sldPath = "E:\\fanwei\\HED_dataset.sld";String imgPath = "E:\\fanwei\\HED_dataset.png";Map paras = new HashMap();//自动计算shp矢量的bboxdouble[] bbox = calculateBounds(shpPath);//厦门市的bbox
// double[] bbox = new double[]{117.8833, 24.3833, 118.4333, 24.9};paras.put("bbox", bbox);paras.put("width", 768);paras.put("height", 506);shp2img.addShapeLayer(shpPath, sldPath);shp2img.getMapContent(paras, imgPath);System.out.println("图片生成完成,共耗时"+(System.currentTimeMillis() - start)+"ms");}
}
二、结果展示
我人很话不多的,直接看结果
QGIS的样式规则为1.1.0,但是代码里的有方法处理
生成的文件可以作为缩略图,自己看情况改接口
总结
此方法供代码开发使用,使用geotools来生成缩略图
pom.xml自己看
<!--GeoServer--><dependency><groupId>it.geosolutions</groupId><artifactId>geoserver-manager</artifactId><version>1.7.0</version></dependency><dependency><groupId>org.geotools</groupId><artifactId>gt-shapefile</artifactId><version>23-SNAPSHOT</version></dependency><dependency><groupId>org.geotools</groupId><artifactId>gt-main</artifactId><version>23-SNAPSHOT</version></dependency><dependency><groupId>org.geotools</groupId><artifactId>gt-referencing</artifactId><version>23-SNAPSHOT</version></dependency><dependency><groupId>org.geotools</groupId><artifactId>gt-swing</artifactId><version>23-SNAPSHOT</version></dependency><dependency><groupId>org.geotools</groupId><artifactId>gt-render</artifactId><version>23-SNAPSHOT</version></dependency><dependency><groupId>org.geotools</groupId><artifactId>gt-xml</artifactId><version>23-SNAPSHOT</version></dependency><dependency><groupId>org.postgresql</groupId><artifactId>postgresql</artifactId><version>42.2.25</version></dependency><!-- https://mvnrepository.com/artifact/org.geotools.xsd/gt-xsd-sld --><dependency><groupId>org.geotools.xsd</groupId><artifactId>gt-xsd-sld</artifactId><version>23-SNAPSHOT</version></dependency></dependencies><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><repository><id>maven-central</id><url>https://repo.maven.apache.org/maven2</url></repository><repository><id>GeoSolutions</id><url>http://maven.geo-solutions.it/</url></repository></repositories>