3

I am running GeoServer 2.8 WAR on an Ubuntu machine in Tomcat 7. I have GeoWebCache integrated directly and it does cache and serve some tiles. However, in some areas I get errors when I attempt to view the location or seed the cache. The relevant part of the log is as follows (which suggests a topology error):

2015-08-01 17:40:47,976 ERROR [geoserver.ows] - 
org.geoserver.platform.ServiceException: Rendering process failed
    at org.geoserver.wms.map.RenderedImageMapOutputFormat.produceMap(RenderedImageMapOutputFormat.java:569)
    at org.geoserver.wms.map.RenderedImageMapOutputFormat.produceMap(RenderedImageMapOutputFormat.java:260)
    at org.geoserver.wms.map.RenderedImageMapOutputFormat.produceMap(RenderedImageMapOutputFormat.java:132)
    at org.geoserver.wms.GetMap.executeInternal(GetMap.java:504)
    at org.geoserver.wms.GetMap.run(GetMap.java:248)
    at org.geoserver.wms.GetMap.run(GetMap.java:119)
    at org.geoserver.wms.DefaultWebMapService.getMap(DefaultWebMapService.java:320)
    at sun.reflect.GeneratedMethodAccessor282.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:319)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    at org.geoserver.kml.WebMapServiceKmlInterceptor.invoke(WebMapServiceKmlInterceptor.java:34)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.geoserver.gwc.wms.CacheSeedingWebMapService.invoke(CacheSeedingWebMapService.java:62)
    at org.geoserver.gwc.wms.CacheSeedingWebMapService.invoke(CacheSeedingWebMapService.java:36)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.geoserver.gwc.wms.CachingWebMapService.invoke(CachingWebMapService.java:80)
    at org.geoserver.gwc.wms.CachingWebMapService.invoke(CachingWebMapService.java:55)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.geoserver.ows.util.RequestObjectLogger.invoke(RequestObjectLogger.java:55)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    at com.sun.proxy.$Proxy58.getMap(Unknown Source)
    at sun.reflect.GeneratedMethodAccessor235.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.geoserver.ows.Dispatcher.execute(Dispatcher.java:841)
    at org.geoserver.ows.Dispatcher.handleRequestInternal(Dispatcher.java:275)
    at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
    at org.geoserver.gwc.GWC.dispatchOwsRequest(GWC.java:1209)
    at org.geoserver.gwc.layer.GeoServerTileLayer.dispatchGetMap(GeoServerTileLayer.java:625)
    at org.geoserver.gwc.layer.GeoServerTileLayer.getMetatilingReponse(GeoServerTileLayer.java:569)
    at org.geoserver.gwc.layer.GeoServerTileLayer.seedTile(GeoServerTileLayer.java:764)
    at org.geowebcache.seed.SeedTask.doActionInternal(SeedTask.java:136)
    at org.geowebcache.seed.GWCTask.doAction(GWCTask.java:76)
    at org.geowebcache.seed.MTSeeder.call(MTSeeder.java:36)
    at org.geowebcache.seed.MTSeeder.call(MTSeeder.java:25)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
Caused by: com.vividsolutions.jts.geom.TopologyException: found non-noded intersection between LINESTRING ( -446792.34 6930399.07, -440903.77 6936464.74 ) and LINESTRING ( -437011.5849751517 6937523.641382978, -447860.88 6934195.51 ) [ (-441090.5017453493, 6936272.392257541, NaN) ]
    at com.vividsolutions.jts.noding.FastNodingValidator.checkValid(FastNodingValidator.java:130)
    at com.vividsolutions.jts.geomgraph.EdgeNodingValidator.checkValid(EdgeNodingValidator.java:94)
    at com.vividsolutions.jts.geomgraph.EdgeNodingValidator.checkValid(EdgeNodingValidator.java:59)
    at com.vividsolutions.jts.operation.overlay.OverlayOp.computeOverlay(OverlayOp.java:170)
    at com.vividsolutions.jts.operation.overlay.OverlayOp.getResultGeometry(OverlayOp.java:127)
    at com.vividsolutions.jts.operation.overlay.OverlayOp.overlayOp(OverlayOp.java:66)
    at com.vividsolutions.jts.operation.overlay.snap.SnapIfNeededOverlayOp.getResultGeometry(SnapIfNeededOverlayOp.java:96)
    at com.vividsolutions.jts.operation.overlay.snap.SnapIfNeededOverlayOp.overlayOp(SnapIfNeededOverlayOp.java:58)
    at com.vividsolutions.jts.geom.Geometry.difference(Geometry.java:1423)
    at org.geotools.filter.function.StaticGeometry.difference(StaticGeometry.java:313)
    at org.geotools.filter.function.FilterFunction_difference.evaluate(FilterFunction_difference.java:66)
    at org.geotools.filter.expression.ExpressionAbstract.evaluate(ExpressionAbstract.java:65)
    at org.geotools.renderer.lite.StreamingRenderer.findGeometry(StreamingRenderer.java:2797)
    at org.geotools.renderer.lite.StreamingRenderer.access$100(StreamingRenderer.java:178)
    at org.geotools.renderer.lite.StreamingRenderer$RenderableFeature.getShape(StreamingRenderer.java:3100)
    at org.geotools.renderer.lite.StreamingRenderer.processSymbolizers(StreamingRenderer.java:2679)
    at org.geotools.renderer.lite.StreamingRenderer.process(StreamingRenderer.java:2585)
    at org.geotools.renderer.lite.StreamingRenderer.drawPlain(StreamingRenderer.java:2409)
    at org.geotools.renderer.lite.StreamingRenderer.processStylers(StreamingRenderer.java:2113)
    at org.geotools.renderer.lite.StreamingRenderer.paint(StreamingRenderer.java:832)
    at org.geoserver.wms.map.RenderedImageMapOutputFormat.produceMap(RenderedImageMapOutputFormat.java:539)

However, when I investigate my data in PostGIS, ST_isValid and ST_IsValidReason, return no errors on the entire database. So, as far as PostGIS is concerned, all my data is valid. Furthermore, the non-noded intersection always seems to be on the same line, suggesting a self-intersection or self touching. When I identify the individual line using detective work from the coordinates (I am using a layer-group and sadly the logs don't tell me which dataset or give an id of which feature GWC thinks has the error). I re-check the specific feature in PostGIS and again, no error.

Can anybody suggest why GWC is upset if PostGIS can't see the error. Is this a known bug or something else? Suggestions of solutions to fix it would be welcome as ST_MakeValid is pointless if PosGIS thinks all the data are already valid.

2
  • 1
    Turn up the logging level and use the layer preview of the individual layers to narrow the issue down.
    – Ian Turton
    Commented Aug 1, 2015 at 17:51
  • I started down the route you suggest and then the penny dropped as to the real cause of the error (see my answer). This is a classic 'doh!' moment. The cache is now seeding happily as I type this. Commented Aug 3, 2015 at 10:30

1 Answer 1

2

The reason that I could not find any errors in the data in PostGIS appears to be because there are none. So why did GWC fail to seed the cache and report a topology error? The answer is because I was using a style which involved an internal buffer of some polygons to get a graduated 'fade in' effect with a colour transition on the stroke. Since you can't currently offset the stroke from the line, you must use ECQL filters on the geometry. This works very well and produces a great style when zoomed in, but when zoomed out it can result in polygons that self-intersect. These buffer-polygons only exist as far as the renderer is concerned so, of course, you won't find them in your original data and can't find any error. It's fairly obvious, now I've discovered it, that this would be the reason. but it's maybe worth posting this answer in case anybody else has a similar 'baffling' situation.

The ultimate solution was (sadly) to scrap my pretty style and go with something much less attractive. I semi-faked the effect by creating a 1-pixel-wide png symbol, where the top half of the image was transparent (so that the fade-in effect starts on the line). This also works, but is not as good.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.