geotools实现wmts服务

/**
     * wmts服务
     * @param params
     */
    @Override
    public void wmts(GeoEntityWmtsParams params) throws IOException, ServiceException, FactoryException {
        HttpServletResponse response = ServletUtils.getResponse();
        // 创建时间格式化对象,指定时间格式
        DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");
        String layerName = params.getLayer();
        String srs = params.getTilematrixset();
        //列 == x
        Integer tilecol = params.getTilecol();
        //行 == y
        Integer tilerow = params.getTilerow();
        String version = params.getVersion();
        String format = params.getFormat();
        //放大倍数
        Integer zoomLevel = params.getTilematrix();
        String tileMatrixSet = params.getTilematrixset();
        URL url = null;
        try {
            url = new URL("http://localhost:8080/geoserver/gwc/service/wmts?REQUEST=GetCapabilities");
        } catch (MalformedURLException e) {
            // will not happen
        }
        WebMapTileServer wmts = new WebMapTileServer(url);
        WMTSCapabilities capabilities = wmts.getCapabilities();
        WMTSLayer layer = capabilities.getLayer(layerName);
        CoordinateReferenceSystem crs = CRS.decode(srs);
        // Find the TileMatrixSet for the specified zoom level
        TileMatrixSet matrixSet = wmts.getCapabilities().getMatrixSet(tileMatrixSet);


        MapContent mapContent = new MapContent();
        try {



            //CoordinateReferenceSystem crs = CRS.decode(srs);
            List<GeoEntityWmsVo> res = geoEntityMapper.wms(layer.getTitle(),null,null,null,null);

            //feature
            SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder();
            typeBuilder.setName("WMSFeatureType");
            //typeBuilder.setCRS(DefaultGeographicCRS.WGS84);
            typeBuilder.setCRS(crs);
            typeBuilder.add("geom", MultiPolygon.class);
            SimpleFeatureType featureType = typeBuilder.buildFeatureType();
            DefaultFeatureCollection featureCollection = new DefaultFeatureCollection(null, featureType);
            if(res!=null&&res.size()>0){
                Style style = SLD.createSimpleStyle(featureType, Color.GRAY);
                List<Layer> layerList = new ArrayList<>();
                System.out.println("=====遍历前时间========"+ LocalTime.now().format(timeFormatter));
                res.stream().forEach((a)->{
                    Geometry geometry = a.getGeom();
                    SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(featureType);
                    featureBuilder.add(geometry);
                    SimpleFeature feature = featureBuilder.buildFeature(null);
                    featureCollection.add(feature);
                    SimpleFeatureSource featureSource = DataUtilities.source(featureCollection);
                    FeatureLayer featureLayer = new FeatureLayer(featureSource, style);
                    featureLayer.setTitle(layerName);
                    layerList.add(featureLayer);
                });

                ReferencedEnvelope tileEnvelope = getTileEnvelope(tilecol, tilerow, matrixSet,crs,zoomLevel);
                mapContent.setTitle("WMS Image");
                mapContent.addLayers(layerList);

                GTRenderer renderer = new StreamingRenderer();
                renderer.setMapContent(mapContent);
                BufferedImage image = new BufferedImage(256, 256, BufferedImage.TYPE_INT_RGB);

                //根据以上信息渲染图片
                Graphics2D graphics = (Graphics2D) image.getGraphics();
                Rectangle rectangle = new Rectangle(256, 256);
                //ReferencedEnvelope referencedEnvelope = new ReferencedEnvelope(minX, maxX, minY, maxY, crs);
                System.out.println("=====paint前时间========"+ LocalTime.now().format(timeFormatter));
                renderer.paint(graphics, rectangle, tileEnvelope);
                System.out.println("=====paint后时间========"+ LocalTime.now().format(timeFormatter));

                //输出流输出到前端
                System.out.println("=====write前时间========"+ LocalTime.now().format(timeFormatter));
                ImageIO.write(image, "png", response.getOutputStream());
                System.out.println("=====write后时间========"+ LocalTime.now().format(timeFormatter));


            }
        }catch (Exception e){
            String message = e.getMessage();
            if (!message.contains("transform: latitude or longitude exceeded limits (-14)")) {
                log.error("图片输出异常:参数【" + JSON.toJSONString(params) + "】",e);
            } else {
                log.error("图片输出异常:参数【" + JSON.toJSONString(params) + "】" + e.getMessage());
            }
        }finally {
            mapContent.dispose();
        }
    }

    /**
     * 代码从geotools源码中拷贝  col row zoomlevel 转 minx,miny,maxx,maxy
    * @param tileCol
     * @param tileRow
     * @param matrixSet
     * @param crs
     * @return
     */
    private ReferencedEnvelope getTileEnvelope(int tileCol, int tileRow, TileMatrixSet matrixSet,CoordinateReferenceSystem crs,Integer zoomLevel) {
//
        //new WebMapTileServer();
        CoordinateSystem coordinateSystem = crs.getCoordinateSystem();
        Unit<Length> unit = (Unit<Length>) coordinateSystem.getAxis(0).getUnit();
        Point topLeft = matrixSet.getMatrices().get(17).getTopLeft();
        TileMatrix tileMatrix = matrixSet.getMatrices().get(zoomLevel);
        double denominator =tileMatrix.getDenominator();
        double pixelSpan = denominator * 0.28e-3;
        if (unit.equals(NonSI.DEGREE_ANGLE)) {
            pixelSpan /= 111319;
        }else{
            UnitConverter metersperunit = unit.getConverterTo(SI.METRE);
            pixelSpan /= metersperunit.convert(1);
        }
        double tileSpanY = (tileMatrix.getTileHeight() * pixelSpan);
        double tileSpanX = (tileMatrix.getTileWidth() * pixelSpan);
        double tileMatrixMinX;
        double tileMatrixMaxY;
        boolean longFirst = coordinateSystem.getAxis(0).getDirection().equals(AxisDirection.EAST);
        if (longFirst) {
            tileMatrixMinX = topLeft.getX();
            tileMatrixMaxY = topLeft.getY();
        } else {
            tileMatrixMaxY = topLeft.getX();
            tileMatrixMinX = topLeft.getY();
        }
        ReferencedEnvelope ret = new ReferencedEnvelope(crs);
        double minX = tileCol * tileSpanX + tileMatrixMinX;
        double maxY = tileMatrixMaxY - tileRow * tileSpanY;
        double maxX = minX + tileSpanX;
        double minY = maxY - tileSpanY;
        if (longFirst) {
            ret.expandToInclude(minX, minY);
            ret.expandToInclude(maxX, maxY);
        } else {
            ret.expandToInclude(minY, minX);
            ret.expandToInclude(maxY, maxX);
        }
        return ret;

    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WMTS (Web Map Tile Service)是一种基于HTTP的网络地图服务,它提供了地图切片(tiles)的标准接口,使得客户端可以快速高效地请求并渲染地图数据。下面我将介绍如何使用Java实现一个WMTS服务。 首先,我们需要创建一个Maven项目,并在`pom.xml`中添加以下依赖: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.geotools</groupId> <artifactId>gt-tile</artifactId> <version>23.2</version> </dependency> ``` 接着,我们需要创建一个Controller类,来处理WMTS请求: ``` import org.geotools.data.ows.Layer; import org.geotools.tile.Tile; import org.geotools.tile.TileService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.OutputStream; @RestController @RequestMapping("/wmts") public class WmtsController { @Autowired private TileService tileService; @GetMapping(value = "/{layer}/{z}/{x}/{y}", produces = MediaType.IMAGE_PNG_VALUE) public void getTile(@PathVariable("layer") String layerName, @PathVariable("z") int z, @PathVariable("x") int x, @PathVariable("y") int y, HttpServletResponse response) throws IOException { Layer layer = tileService.getLayer(layerName); Tile tile = tileService.getTile(layer, z, x, y); response.setContentType(MediaType.IMAGE_PNG_VALUE); OutputStream outputStream = response.getOutputStream(); outputStream.write(tile.getData()); outputStream.close(); } } ``` 在这个Controller中,我们定义了一个`getTile`方法,该方法接收WMTS请求中的`layer`、`z`、`x`和`y`参数,并通过`tileService`对象获取相应的切片数据。最后,我们将切片数据写入响应输出流,以返回给客户端。 接下来,我们需要在`application.properties`文件中配置WMTS服务的参数: ``` server.port=8080 server.servlet.context-path=/wmts geotools.tile.factory.cache.memory.maxsize=1000 geotools.tile.factory.cache.file.maxsize=10000 geotools.tile.factory.cache.file.directory=/tmp/geotools-tiles geotools.tile.factory.cache.file.cleanupdelay=60000 ``` 在这里,我们指定了WMTS服务的端口和上下文路径,以及TileService对象的缓存设置。 最后,我们可以启动这个应用程序,并访问以下URL来获取切片数据: ``` http://localhost:8080/wmts/{layer}/{z}/{x}/{y} ``` 其中,`{layer}`表示地图图层的名称,`{z}`、`{x}`和`{y}`表示切片的缩放级别、横向索引和纵向索引。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值