ngageoint / elasticgeo

ElasticGeo provides a GeoTools data store that allows geospatial features from an Elasticsearch index to be published via OGC services using GeoServer.
GNU General Public License v3.0
169 stars 85 forks source link

aggregation - URL encoded viewparams throws org.geoserver.platform.ServiceException #25

Closed nreese closed 7 years ago

nreese commented 7 years ago

I am attempting to use leaflet to experiment with a WMS layer generated from elasticsearch with geogrid aggregation.

I am using elasticsearch 5.1.2. I have an index with a geo_point field called location. I created a new layer in geoserver. I created a new style, geohashgrid, copied from gs-web-elasticsearch/doc/index.rst (replacing <ogc:PropertyName>geo</ogc:PropertyName></Geometry> with <ogc:PropertyName>location</ogc:PropertyName></Geometry>). All tile requests result in the exception org.geoserver.platform.ServiceException.

html

<html>
  <head>
    <link rel="stylesheet" href="https://unpkg.com/leaflet@0.7.7/dist/leaflet.css" />
    <script src="https://unpkg.com/leaflet@0.7.7/dist/leaflet.js"></script>
  </head>
  <body>
    <div id="mapid" style="height: 500px; width: 1000px;"></div>
    <script type="text/javascript">
      var mymap = L.map('mapid').setView([39.7, -104.9], 9);
      L.tileLayer(
        'http://a.tile.openstreetmap.org/{z}/{x}/{y}.png', 
        {
          attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors'
        }).addTo(mymap);

      var wmsOptions = {
        format: 'image/png',
        layers: 'denver:report',
        transparent: true,
        version: '1.1.1',
        styles: 'geohashgrid',
        viewparams: 'a:{"agg": {"geohash_grid": {"field": "location"\, "precision": 3}}}'
      };
      L.tileLayer.wms(
        'http://localhost:8080/geoserver/denver/wms', 
        wmsOptions).addTo(mymap);
    </script>
  </body>
</html>

Generated WMS url

http://localhost:8080/geoserver/denver/wms?SERVICE=WMS&REQUEST=GetMap&VERSION=1.1.1&LAYERS=denver%3Areport&STYLES=geohashgrid&FORMAT=image%2Fpng&TRANSPARENT=true&HEIGHT=256&WIDTH=256&VIEWPARAMS=a%3A%7B%22agg%22%3A%20%7B%22geohash_grid%22%3A%20%7B%22field%22%3A%20%22location%22%2C%20%22precision%22%3A%203%7D%7D%7D&SRS=EPSG%3A3857&BBOX=-11662456.027639052,4774562.53480525,-11623320.26915704,4813698.293287256

Server exception

org.geoserver.platform.ServiceException: 1 layers requested, but found 2 view params specified. 
    at org.geoserver.wms.map.GetMapKvpRequestReader.read(GetMapKvpRequestReader.java:487)
    at org.geoserver.wms.map.GetMapKvpRequestReader.read(GetMapKvpRequestReader.java:85)
    at org.geoserver.ows.Dispatcher.parseRequestKVP(Dispatcher.java:1498)
    at org.geoserver.ows.Dispatcher.dispatch(Dispatcher.java:673)
    at org.geoserver.ows.Dispatcher.handleRequestInternal(Dispatcher.java:258)
    at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:147)
    at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:50)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:968)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:859)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:844)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at StaticHeaders.doFilter(StaticHeaders.java:22)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.geoserver.filters.ThreadLocalsCleanupFilter.doFilter(ThreadLocalsCleanupFilter.java:28)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.geoserver.filters.SpringDelegatingFilter$Chain.doFilter(SpringDelegatingFilter.java:75)
    at org.geoserver.wms.animate.AnimatorFilter.doFilter(AnimatorFilter.java:71)
    at org.geoserver.filters.SpringDelegatingFilter$Chain.doFilter(SpringDelegatingFilter.java:71)
    at org.geoserver.filters.SpringDelegatingFilter.doFilter(SpringDelegatingFilter.java:46)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.geoserver.platform.AdvancedDispatchFilter.doFilter(AdvancedDispatchFilter.java:50)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)

I can manually replace the URL encoded viewparams attribute and then the request returns an empty tile.

http://localhost:8080/geoserver/denver/wms?SERVICE=WMS&REQUEST=GetMap&VERSION=1.1.1&LAYERS=denver%3Areport&STYLES=geohashgrid&FORMAT=image%2Fpng&TRANSPARENT=true&HEIGHT=256&WIDTH=256&VIEWPARAMS=a:{"agg": {"geohash_grid": {"field": "location"\, "precision": 3}}}&SRS=EPSG%3A3857&BBOX=-11818999.061567092,4774562.53480525,-11740727.544603072,4852834.051769271

How can leaflet be used to view WMS tiles generated via geogrid aggregation?

sjudeng commented 7 years ago

The first encoded URL is missing the backslash to escape the comma. See below (note the escaped \, %5C).

http://localhost:8080/geoserver/denver/wms?SERVICE=WMS&REQUEST=GetMap&VERSION=1.1.1&LAYERS=denver%3Areport&STYLES=geohashgrid&FORMAT=image%2Fpng&TRANSPARENT=true&HEIGHT=256&WIDTH=256&VIEWPARAMS=a%3A%7B%22agg%22%3A%20%7B%22geohash_grid%22%3A%20%7B%22field%22%3A%20%22location%22%5C%2C%20%22precision%22%3A%203%7D%7D%7D&SRS=EPSG%3A3857&BBOX=-11662456.027639052,4774562.53480525,-11623320.26915704,4813698.293287256

Maybe in the layer definition you need a double backslash to make sure it's included in the request?

nreese commented 7 years ago

Thanks for the extra set of eyes - adding an additional backslash resolved the error.

viewparams: 'a:{"agg": {"geohash_grid": {"field": "location"\\, "precision": 3}}}'

Now all of my tiles are empty. Is there a simple SLD that will display grids with counts greater than zero one color and empty grids another?

sjudeng commented 7 years ago

I'd expect you'd see something with the example SLD from the docs but you could try updating ColorMapEntry quantity values with better max value for your expected doc counts.

<ColorMapEntry color="#FFFFFF" quantity="0" label="nodata" opacity="0"/>
<ColorMapEntry color="#00FF00" quantity="1" label="values"/>
<ColorMapEntry color="#0000FF" quantity="1000" label="label"/>

If this doesn't help you might turn up logging and check the queries that are being executed.

nreese commented 7 years ago

Putting some debug code into GeoHashGrid, I get the following when initalize is called.

num buckets: 0
precision: 2
cellWidth: 11.25
cellHeight: 5.625

The number of buckets should not be zero. Is there a way to print the Elasticsearch aggregation request and response?

nreese commented 7 years ago

Found the problem. My elastic store was using port 9300 instead of port 9200 for REST client like the documentation stated. I am out of the starting blocks.