Geoserver - GetFeatureInfo of raster/wms layer multiple points/location or bounding box

我是研究僧i 提交于 2019-12-04 17:54:22

I don't believe there is a good way to do that without writing new code server side, either a new operation in the ncWMS extensions or a custom WPS process doing the same.

I solved the problem after trying many ways, but couldn't find the time to post the answer here until now.

First, I was developing my own WPS process. However, during searching for code examples, I discovered Geoserver already had a WPS process for getting original Raster data. So, I decided to try that out.

First important note before reading steps; If you are using SOAP Ui or sth similar to test requesting, instead of trying it with writing code. You should know that getting response from the request takes milliseconds for me, however Soap Ui takes 10-15 minutes to parse the returning json data. So, don't worry about the process being slow, it is fast actually.

  1. Activate WPS in Geoserver through this guide
  2. Then go to Demos -> WPS Request Builder
  3. Choose Process as gs:RasterAsPointCollection
  4. input raster should be the one you want. Select it from the combobox there. In my case WindWaveModel:u10
  5. TargetCRS as yours; in my case EPSG:4326
  6. interpolation must be nearest as you are trying to get data for each cell
  7. Process outputs you must select application/json from combobox there. If you select any other GeoServer throws exception.
  8. Don't fill emisphere (I think stands for hemisphere) and scale.
  9. Optional: If you want to discover more, you can press DescribeProcess on the screen.
  10. For the request body, Geoserver provides Generate XML from process inputs/outputs button at the bottom of the page. You must click this button for Geoserver to create the request XML. First, have a look at the XML and try to understand what it is.
  11. First, you will realize, what you filled in the page form is there in the XML as input. Then, you will see there is more than what filled in the form; like the bounding box of your raster layer. It is automatically extracted from layer information and gs:RasterAsPointCollection process provides you with bounding box input. So that you can get only some part of your raster layer, instead of all of it.
  12. Second, you will see there is process chaining, as the first <wps:input> is output of a wcs:GetCoverage service. Here was somewhat challenging for me, because I have time dimensions in my netcdf layers. And gs:RasterAsPointCollection was using wcs:1.1.1 specification. If you look at the wcs:1.1.1 specification you will see no time dimension input. There were so many try&fails for me there, I will skip the detail, as I will provide you with the final result in the XML form with the addition of time dimension input.

<?xml version="1.0" encoding="UTF-8"?><wps:Execute version="1.0.0" service="WPS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opengis.net/wps/1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:wcs="http://www.opengis.net/wcs/1.1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd">
  <ows:Identifier>gs:RasterAsPointCollection</ows:Identifier>
  <wps:DataInputs>
    <wps:Input>
      <ows:Identifier>data</ows:Identifier>
      <wps:Reference mimeType="image/tiff" xlink:href="http://geoserver/wcs" method="POST">
        <wps:Body>
          <wcs:GetCoverage service="WCS" version="1.1.1">
            <ows:Identifier>yourWorkspace:yourRasterLayer(e.g. it.geosolutions:u10)</ows:Identifier>
            <wcs:DomainSubset>
              <ows:BoundingBox crs="http://www.opengis.net/gml/srs/epsg.xml#4326">
                <ows:LowerCorner>minLon minLat(e.g. 20.0 30.0)</ows:LowerCorner>
                <ows:UpperCorner>maxLon maxLat(e.g. 55.0 48.0)</ows:UpperCorner>
              </ows:BoundingBox>
              <wcs:TemporalSubset>
                <gml:TimePosition>yourTimeDimesion(e.g.2017-03-15T06:00:00.000Z)</gml:TimePosition>
              </wcs:TemporalSubset>
            </wcs:DomainSubset>
            <wcs:Output format="image/tiff"/>
          </wcs:GetCoverage>
        </wps:Body>
      </wps:Reference>
    </wps:Input>
    <wps:Input>
      <ows:Identifier>targetCRS</ows:Identifier>
      <wps:Data>
        <wps:LiteralData>EPSG:4326</wps:LiteralData>
      </wps:Data>
    </wps:Input>
    <wps:Input>
      <ows:Identifier>interpolation</ows:Identifier>
      <wps:Data>
        <wps:LiteralData>nearest</wps:LiteralData>
      </wps:Data>
    </wps:Input>
  </wps:DataInputs>
  <wps:ResponseForm>
    <wps:RawDataOutput mimeType="application/json">
      <ows:Identifier>result</ows:Identifier>
    </wps:RawDataOutput>
  </wps:ResponseForm>
</wps:Execute>

HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("http://localhost:8090/geoserver/ows?Service=WPS");
HttpEntity entity = new ByteArrayEntity(xmlString.getBytes("UTF-8"));
post.setEntity(entity);
HttpResponse response = client.execute(post);
// parse the json data in the response with a streaming model as it will be big

Right now, I am querying both u10 and v10 raster layers (making 2 WPS calls) for getting eastward_wind and northward_wind values. Then I calculate euclidian sum for each cell and in the end create a color map out of result values. I also calculate wind arrow directions in a similar geometric equation.

I hope this helps other people too.

Please let me know, if I can make this process faster, or optimize it any other way.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!