zoukankan      html  css  js  c++  java
  • 基于GeoTools的WMS设计与实现

    GeoTools是一个Java软件包地理实现。

    WMS是一种服务设计理念。

     由上图可见,后端一共有三个函数GetCapabilities、GetMap和GetFeatureInfo,根据接收到的客户端的参数来分别进行调用。并将结果返回给客户端,WMS一般是返回图像格式的文件。

    基于GeoTools的WMS的设计与实现,可以直接看GeoServer,它就是基于GeoTools的WMS实现。而且还包含了Jetty服务器,可以直接使用。当然也可以使用War包版本,放在Tomcat服务器下面。

    第一步:拦截请求参数

    public void doService(HttpServletRequest request,
            HttpServletResponse response) throws IOException {
        Map map = request.getParameterMap();
        Map param = new HashMap();
        for (String k : map.keySet()) {
            String s1 = "";
            if (param.containsKey(k.toUpperCase())) {
                s1 = param.get(k.toUpperCase()) + ",";
            }
            String[] s2 = (String[]) map.get(k);
            for (int i = 0; i < s2.length; i++) {
                s1 += s2[i] + (i == 0 ? "" : ",");
            }
            param.put(k.toUpperCase(), s1);
        }
        if (!param.containsKey("REQUEST")) {
            WMSException.exception(response);
        } else {
            String wmsRequest = param.get("REQUEST");
            if (wmsRequest.equals("GetCapabilities")) {
                GetCapabilitiesRequest gcr = new GetCapabilitiesRequest(param);
                doGetCapabilities(gcr, response);
            } else if (wmsRequest.equals("GetMap")) {
                GetMapRequest gmr = new GetMapRequest(param);
                doGetMap(gmr, response);
            } else if (wmsRequest.equals("GetFeatureInfo")) {
                GetFeatureInfoRequest gfr = new GetFeatureInfoRequest(param);
                doGetFeatureInfo(gfr, response);
            } else {
                WMSException.exception(response);
            }
        }
    }

    第二步:

    private static void addShapeLayer(String name) throws Exception {
        File file = new File("C:data" + name + ".shp");
        File sldFile = new File("C:data" + name + ".sld");
        FileDataStore store = FileDataStoreFinder.getDataStore(file);
        ((ShapefileDataStore) store).setStringCharset(Charset.forName("GB2312"));
        FeatureSource featureSource = store
                .getFeatureSource();
        Configuration config = new SLDConfiguration();
        Parser parser = new Parser(config);
        InputStream sld = new FileInputStream(sldFile);
        StyledLayerDescriptor styleSLD = (StyledLayerDescriptor) parser.parse(sld);
        Style style = SLD.defaultStyle(styleSLD);
        map.addLayer(featureSource, style);
    }

    第三步:

    private void doGetMap(GetMapRequest gmr, HttpServletResponse response)
            throws IOException {
        double x1, y1, x2, y2;
        int width, height;
        try {
            x1 = Double.parseDouble(gmr.getBBOX()[0]);
            y1 = Double.parseDouble(gmr.getBBOX()[1]);
            x2 = Double.parseDouble(gmr.getBBOX()[2]);
            y2 = Double.parseDouble(gmr.getBBOX()[3]);
            width = Integer.parseInt(gmr.getWidth());
            height = Integer.parseInt(gmr.getHeight());
        } catch (Exception e) {
            WMSException.exception(response);
            return;
        }
        // 设置输出范围
        ReferencedEnvelope mapArea = new ReferencedEnvelope(x1, x2, y1, y2, crs);
        // 初始化渲染器
        StreamingRenderer sr = new StreamingRenderer();
        sr.setContext(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);
        // 编码图像
        PNGEncodeParam encodeParam = PNGEncodeParam.getDefaultEncodeParam(bi);
        if (encodeParam instanceof PNGEncodeParam.Palette) {
            PNGEncodeParam.Palette p = (PNGEncodeParam.Palette) encodeParam;
            byte[] b = new byte[] { -127 };
            p.setPaletteTransparency(b);
        }
        //将图像数据输出到Servlet相应中
        response.setContentType("image/png");
        ServletOutputStream out = response.getOutputStream();
        com.sun.media.jai.codec.ImageEncoder encoder = ImageCodec
                .createImageEncoder("PNG", out, encodeParam);
        encoder.encode(bi.getData(), bi.getColorModel());
        bi.flush();
    }

     第四步:

    private void doGetFeatureInfo(GetFeatureInfoRequest gfr,
            HttpServletResponse response) throws IOException {
        double x1, y1, x2, y2;
        int width, height, i, j;
        try {
            x1 = Double.parseDouble(gfr.getBBOX()[0]);
            y1 = Double.parseDouble(gfr.getBBOX()[1]);
            x2 = Double.parseDouble(gfr.getBBOX()[2]);
            y2 = Double.parseDouble(gfr.getBBOX()[3]);
            width = Integer.parseInt(gfr.getWidth());
            height = Integer.parseInt(gfr.getHeight());
            i = Integer.parseInt(gfr.getI());
            j = Integer.parseInt(gfr.getJ());
        } catch (Exception e) {
            WMSException.exception(response);
            return;
        }
        // 计算点选范围的地图坐标
        double cx1, cy1, cx2, cy2;
        cx1 = x1 * (width - i + 0.5 + GET_FEATURE_INFO_BUFFUR) / width + x2
                * (i - 0.5 - GET_FEATURE_INFO_BUFFUR) / width;
        cx2 = x1 * (width - i + 0.5 - GET_FEATURE_INFO_BUFFUR) / width + x2
                * (i - 0.5 + GET_FEATURE_INFO_BUFFUR) / width;
        cy1 = y1 * (j - 0.5 + GET_FEATURE_INFO_BUFFUR) / height + y2
                * (height - j + 0.5 - GET_FEATURE_INFO_BUFFUR) / height;
        cy2 = y1 * (j - 0.5 - GET_FEATURE_INFO_BUFFUR) / height + y2
                * (height - j + 0.5 + GET_FEATURE_INFO_BUFFUR) / height;
        ReferencedEnvelope clickArea = new ReferencedEnvelope(cx1, cx2, cy1, cy2, crs);
        MapLayer[] maplayers = map.getLayers();
        FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2(null);
        response.setContentType("text/html");
        response.setCharacterEncoding("GBK");
        PrintWriter out = response.getWriter();
        out.println("location: " + ((cx1 + cx2) / 2.0) + ", "
                + ((cy1 + cy2) / 2.0) + "<br/>");
        // 分别在每个图层中查找点选范围内的对象
        for (int k = 0; k < maplayers.length; k++) {
            FeatureSource fs =
                (FeatureSource) maplayers[k].getFeatureSource();
            String geometryPropertyName = fs.getSchema().getGeometryDescriptor().getLocalName();
            Filter filter = ff.bbox(ff.property(geometryPropertyName), clickArea);
            FeatureCollection fc = fs.getFeatures(filter);
            SimpleFeatureType schema = fc.getSchema();
            FeatureIterator fi = fc.features();
            if (fi.hasNext()) {
                out.println("Selected feature(s) in layer ["+schema.getTypeName()+"]:<br/>");
                while (fi.hasNext()) {
                    SimpleFeature f = fi.next();
                    out.println("id:" + f.getID() + "<br/>");
                    for (AttributeDescriptor type : schema
                            .getAttributeDescriptors()) {
                        String name = type.getLocalName();
                        if (!name.equals(geometryPropertyName))
                            out.println(name + ":"
                                    + f.getProperty(name).getValue().toString()
                                    + "<br/>");
                    }
                    out.println("<br/>");
                }
            }
        }
        out.flush();
        out.close();
    }
  • 相关阅读:
    Intent属性详解
    LIBGDX游戏引擎平台介绍与搭建
    android教程之intent对象
    android教程之日期时间控件DatePicker/TimePicker
    DotNet Core 3.1 EF Core 数据库迁移(Migration)
    微服务介绍
    Asp.Net Core 认证授权:Cookie-based
    IdentityServer4 实现自定义 GrantType 授权模式
    SqlServer配置主从复制
    在【Stimulsoft-Reports-Net-2016.1】中使用DataSet做数据源新建报表
  • 原文地址:https://www.cnblogs.com/2008nmj/p/13773528.html
Copyright © 2011-2022 走看看