首页 > 解决方案 > 使用geotools开发wms服务时如何将地图图像输出到浏览器?

问题描述

我正在使用 geotools 开发 wms 服务。我创建了一个地图图层并将其添加到MapContent. 然后我开发了一个 GetMap 服务。我在浏览器上显示地图成功,但地图位置总是错误。像这样:

错误的地图

请求参数为:

SERVICE: WMS
VERSION: 1.1.0
REQUEST: GetMap
FORMAT: image/png
TRANSPARENT: true
LAYERS: layer
SRS: EPSG:4326
STYLES: 
WIDTH: 997
HEIGHT: 499
BBOX: 63.2958984375,3.1494140625,150.9228515625,47.0068359375

响应预览如下:

预习

我想在正确的位置显示点。

这是我处理 GetMap 请求的代码:

double x1, y1, x2, y2;
String[] BBOX = request.getParameter("BBOX").split(",");
x1 = Double.parseDouble(BBOX[0]);
y1 = Double.parseDouble(BBOX[1]);
x2 = Double.parseDouble(BBOX[2]);
y2 = Double.parseDouble(BBOX[3]);

int width = Integer.parseInt(request.getParameter("WIDTH")),
        height = Integer.parseInt(request.getParameter("HEIGHT"));
CoordinateReferenceSystem crs = CRS.decode(request.getParameter("SRS"));

ReferencedEnvelope mapArea = new ReferencedEnvelope(x1, y1, x2, y2, crs);//I think some wrong here,but I try to modify many times,it is not work
response.setContentType("image/png");
ServletOutputStream out = response.getOutputStream();


WMSRequest wmsRequest = new WMSRequest();
wmsRequest.getGetMap();


BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);

Graphics graphics = bi.getGraphics();


Rectangle rectangle = new Rectangle(0, 0, width, height);

MapViewport mv = new MapViewport();
mv.setBounds(mapArea);
mv.setCoordinateReferenceSystem(crs);
mv.setScreenArea(rectangle);
mapContent.setViewport(mv);

//AffineTransform atf = geometryManage.getRenderingTransform(width, height, mv.getBounds());

StreamingRenderer sr = new StreamingRenderer();
sr.setMapContent(mapContent);
sr.paint((Graphics2D) graphics, rectangle, mapArea);
ImageIO.write(bi, "png", out);
out.close();

标签: javageometrygisgeotoolswms

解决方案


我解决它。错误就在这里:</p>

ReferencedEnvelope mapArea = new ReferencedEnvelope(x1, y1, x2, y2, crs);

我用这个语句来选择地图的显示区域。但是参数的顺序是错误的。

请求中的 BBOX 有 4 个参数,顺序为 [longitude,latitude,longitude,latitude],在 CRS WGS 84 中,经度定义为y,纬度定义为x。但是 ReferencedEnvelope 构造函数是:

ReferencedEnvelope(double x1, double x2, double y1, double y2, CoordinateReferenceSystem crs)

ReferencedEnvelope的更多细节:ReferencedEnvelope的文档

所以我改变了代码:

double x1, y1, x2, y2;

        y1 = Double.parseDouble(BBOX[0]);
        x1 = Double.parseDouble(BBOX[1]);
        y2 = Double.parseDouble(BBOX[2]);
        x2 = Double.parseDouble(BBOX[3]);


        ReferencedEnvelope mapArea = new ReferencedEnvelope(x1, x2, y1, y2, crs);

然后就可以了。

不同的坐标系有不同的坐标序列,我们可以通过打印它的文字信息来查看,比如

GEOGCS["WGS84(DD)", 
  DATUM["WGS84", 
    SPHEROID["WGS84", 6378137.0, 298.257223563]], 
  PRIMEM["Greenwich", 0.0], 
  UNIT["degree", 0.017453292519943295], 
  AXIS["Geodetic longitude", EAST], 
  AXIS["Geodetic latitude", NORTH]]

首先定义经度,然后

GEOGCS["WGS 84", 
  DATUM["World Geodetic System 1984", 
    SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], 
    AUTHORITY["EPSG","6326"]], 
  PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], 
  UNIT["degree", 0.017453292519943295], 
  AXIS["Geodetic latitude", NORTH], 
  AXIS["Geodetic longitude", EAST], 
  AUTHORITY["EPSG","4326"]]

先定义纬度


推荐阅读