用geotools自己写WMS服务

作者: 牛老师讲webgis | 来源:发表于2017-11-08 22:00 被阅读200次

    概述

    本文讲述如何结合geotools写一个类似于WMS的地图服务,并实现在OL4中的调用展示。

    效果

    image.png

    实现

    1. 后端代码
      在后端,先创建一个MapContent,再添加一个layer并通过一个sld文件给layer设置样式,最后通过servlet实现WMS服务的转发,代码如下:
    package com.lzugis.web.servlet;
    
    import com.lzugis.web.helper.CommonConfig;
    
    import org.geotools.data.shapefile.ShapefileDataStore;
    import org.geotools.data.simple.SimpleFeatureSource;
    import org.geotools.factory.CommonFactoryFinder;
    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;
    import org.geotools.renderer.lite.StreamingRenderer;
    import org.geotools.styling.SLD;
    import org.geotools.styling.SLDParser;
    import org.geotools.styling.Style;
    import org.geotools.styling.StyleFactory;
    import org.geotools.swing.JMapFrame;
    import org.opengis.referencing.crs.CoordinateReferenceSystem;
    
    import javax.imageio.ImageIO;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.*;
    import java.nio.charset.Charset;
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * Created by lzugis on 2017/9/10.
     */
    @WebServlet(description = "wms services", urlPatterns =  {"/wms"})
    public class WmsServiceServlet extends HttpServlet {
        private static MapContent map = null;
    
        public WmsServiceServlet() {
            super();
            try{
                String shpPath = "", sldPath = "";
                shpPath = CommonConfig.getVal("wms.shp");
                sldPath = CommonConfig.getVal("wms.sld");
                map = new MapContent();
                this.addShapeLayer(shpPath, sldPath);
            }
            catch(Exception e){
                e.printStackTrace();
            }
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doGet(request, response);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            String LAYERS = request.getParameter("LAYERS"),
                    WIDTH = request.getParameter("WIDTH"),
                    HEIGHT = request.getParameter("HEIGHT"),
                    BBOX = request.getParameter("BBOX");
    
            int _w = Integer.parseInt(WIDTH),
                    _h = Integer.parseInt(HEIGHT);
    
            String[] BBOXS = BBOX.split(",");
            double[] _bbox = new double[]{
                Double.parseDouble(BBOXS[0]),
                Double.parseDouble(BBOXS[1]),
                Double.parseDouble(BBOXS[2]),
                Double.parseDouble(BBOXS[3])
            };
            Map paras = new HashMap();
            paras.put("bbox", _bbox);
            paras.put("width", _w);
            paras.put("height", _h);
            this.getMapContent(paras, response);
        }
    
        private void addShapeLayer(String shpPath, String sldPath){
            try {
                File file = new File(shpPath);
                ShapefileDataStore shpDataStore = null;
                shpDataStore = new ShapefileDataStore(file.toURL());
                //设置编码
                Charset charset = Charset.forName("GBK");
                shpDataStore.setCharset(charset);
                String typeName = shpDataStore.getTypeNames()[0];
                SimpleFeatureSource featureSource = null;
                featureSource = shpDataStore.getFeatureSource(typeName);
    
                Style style = SLD.createSimpleStyle(featureSource.getSchema());
                if (sldPath != "") {
                    //SLD的方式
                    File sldFile = new File(sldPath);
                    StyleFactory styleFactory = CommonFactoryFinder.getStyleFactory();
                    SLDParser stylereader = new SLDParser(styleFactory, sldFile.toURI().toURL());
                    Style[] stylearray = stylereader.readXML();
                    style = stylearray[0];
                } else {
                    SLD.setPolyColour(style, Color.RED);
                }
    
                Layer layer = new FeatureLayer(featureSource, style);
                map.addLayer(layer);
            }
            catch(Exception e){
                e.printStackTrace();
            }
        }
    
        private void getMapContent(Map paras, HttpServletResponse response){
            try{
                double[] bbox = (double[]) paras.get("bbox");
                double x1 = bbox[0], y1 = bbox[1],
                        x2 = bbox[2], y2 = bbox[3];
                int width = (Integer) paras.get("width"),
                        height=(Integer) paras.get("height");
    
                // 设置输出范围
                CoordinateReferenceSystem crs = CRS.decode("EPSG:3857");
                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);
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                boolean flag = ImageIO.write(bi, "png", out);
                byte[] wmsByte = out.toByteArray();
    
                OutputStream os = response.getOutputStream();
                InputStream is = new ByteArrayInputStream(wmsByte);
                try {
                    int count = 0;
                    byte[] buffer = new byte[1024 * 1024];
                    while ((count = is.read(buffer)) != -1) {
                        os.write(buffer, 0, count);
                    }
                    os.flush();
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
                finally {
                    os.close();
                    is.close();
                }
            }
            catch(Exception e){
                e.printStackTrace();
            }
        }
    }
    
    1. 前段代码
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <title>Ol3 wms</title>
        <link rel="stylesheet" type="text/css" href="plugin/ol4/ol.css"/>
        <style type="text/css">
            body, #map {
                border: 0px;
                margin: 0px;
                padding: 0px;
                width: 100%;
                height: 100%;
                font-size: 13px;
            }
        </style>
        <script type="text/javascript" src="plugin/ol4/ol.js"></script>
        <script type="text/javascript" src="plugin/jquery/jquery-3.1.1.min.js"></script>
        <script type="text/javascript">
            var map;
            function init() {
                var vec_w = getTdtLayer("ter_w");
                var wms = new ol.layer.Image({
                    source: new ol.source.ImageWMS({
                        ratio: 1,
                        url: 'wms',
                        params: {
                            "LAYERS": 'ordosMap'
                        }
                    })
                });
                var wms = new ol.layer.Tile({
                    visible: true,
                    source: new ol.source.TileWMS({
                        url: 'wms',
                        params: {
                            tiled: true,
                            LAYERS: 'lzugis:capital'
                        }
                    })
                });
                var projection = new ol.proj.Projection({
                    code: 'EPSG:3857',
                    units: 'm'
                });
                map = new ol.Map({
                    controls: ol.control.defaults({
                        attribution: false
                    }),
                    target: 'map',
                    layers: [
                        vec_w,
                        wms
                    ],
                    view: new ol.View({
                        projection: projection,
                        center: [0, 0],
                        zoom: 1
                    })
                });
            }
            function getTdtLayer(lyr) {
                var url = "http://t0.tianditu.com/DataServer?T=" + lyr + "&X={x}&Y={y}&L={z}";
                var layer = new ol.layer.Tile({
                    source: new ol.source.XYZ({
                        url: url
                    })
                });
                return layer;
            }
        </script>
    </head>
    <body onLoad="init()">
    <div id="map">
    </div>
    </body>
    </html>
    

    类型 内容
    qq 1004740957
    公众号 lzugis15
    e-mail niujp08@qq.com
    webgis群 1004740957
    Android群 337469080
    GIS数据可视化群 458292378

    技术博客
    CSDN:http://blog.csdn.NET/gisshixisheng
    博客园:http://www.cnblogs.com/lzugis/
    在线教程
    http://edu.csdn.Net/course/detail/799
    Github
    https://github.com/lzugis/
    联系方式

    类型 内容
    qq 1004740957
    公众号 lzugis15
    e-mail niujp08@qq.com
    webgis群 1004740957
    Android群 337469080
    GIS数据可视化群 458292378
    LZUGIS

    相关文章

      网友评论

        本文标题:用geotools自己写WMS服务

        本文链接:https://www.haomeiwen.com/subject/gckumxtx.html