Hi All,
I’m new to GeoServer but not to mapping technologies. I’m having some problems with a JTS Topology Exception called Non-noded intersection, see the stack trace.
Issues painting XXXX XXXX
com.vividsolutions.jts.geom.TopologyException: found non-noded intersection between LINESTRING ( 717.4488539707381 264.1920000000391, 727.7745516649447 271.1457557643298 ) and LINESTRING ( 7
30.6777796752285 272.8247309991857, 717.889584969962 265.2693424423924 ) [ (727.3354992491414, 270.8500795439296, NaN) ]
at com.vividsolutions.jts.noding.FastNodingValidator.checkValid(FastNodingValidator.java:109)
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.SnapOverlayOp.getResultGeometry(SnapOverlayOp.java:67)
at com.vividsolutions.jts.operation.overlay.snap.SnapOverlayOp.overlayOp(SnapOverlayOp.java:24)
at com.vividsolutions.jts.operation.overlay.snap.SnapIfNeededOverlayOp.getResultGeometry(SnapIfNeededOverlayOp.java:76)
at com.vividsolutions.jts.operation.overlay.snap.SnapIfNeededOverlayOp.overlayOp(SnapIfNeededOverlayOp.java:25)
at com.vividsolutions.jts.geom.Geometry.intersection(Geometry.java:1150)
at org.geotools.renderer.label.LabelCacheImpl.paintPolygonLabel(LabelCacheImpl.java:1119)
at org.geotools.renderer.label.LabelCacheImpl.paintLabels(LabelCacheImpl.java:586)
at org.geotools.renderer.label.LabelCacheImpl.end(LabelCacheImpl.java:520)
at org.geotools.renderer.shape.ShapefileRenderer.paint(ShapefileRenderer.java:1451)
at org.vfny.geoserver.wms.responses.DefaultRasterMapProducer.produceMap(DefaultRasterMapProducer.java:376)
at org.vfny.geoserver.wms.responses.map.metatile.MetatileMapProducer.produceMap(MetatileMapProducer.java:122)
at org.vfny.geoserver.wms.responses.GetMapResponse.execute(GetMapResponse.java:426)
at org.geoserver.ows.adapters.ResponseAdapter.getMimeType(ResponseAdapter.java:48)
at org.geoserver.ows.Dispatcher.response(Dispatcher.java:712)
at org.geoserver.ows.Dispatcher.handleRequestInternal(Dispatcher.java:234)
at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:809)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:501)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.vfny.geoserver.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:108)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:265)
at org.acegisecurity.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:107)
at org.acegisecurity.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:72)
at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
at org.acegisecurity.ui.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:124)
at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
at org.acegisecurity.providers.anonymous.AnonymousProcessingFilter.doFilter(AnonymousProcessingFilter.java:125)
at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
at org.acegisecurity.ui.basicauth.BasicProcessingFilter.doFilter(BasicProcessingFilter.java:174)
at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
at org.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilter(HttpSessionContextIntegrationFilter.java:249)
at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
at org.acegisecurity.util.FilterChainProxy.doFilter(FilterChainProxy.java:149)
at org.acegisecurity.util.FilterToBeanProxy.doFilter(FilterToBeanProxy.java:98)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.geoserver.filters.LoggingFilter.doFilter(LoggingFilter.java:73)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.geoserver.filters.ReverseProxyFilter.doFilter(ReverseProxyFilter.java:183)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.geoserver.filters.GZIPFilter.doFilter(GZIPFilter.java:41)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:859)
at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:579)
at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1555)
at java.lang.Thread.run(Thread.java:619)
This has been reported as a problem by Bart van den Eijnden on this mailing list previously (http://sourceforge.net/mailarchive/forum.php?thread_name=24768.145.50.39.11.1283259955.squirrel%40webmail.hostingdiscounter.nl&forum_name=geoserver-users)
I have tried the suggestions put by Andrea at the end of the thread to no avail.
For the past couple of days I have been looking at the source code of GeoServer v2.0.2, GeoTools v2.6.4 and JTS v1.10 in trying to track down the source of these JTS Exceptions; with no luck. I do have a better understanding of their respective code base.
A little about my environment and the understanding from looking at the code bases.
I am using a PostGIS (PostgreSQL v8.3.5 / PostGIS v1.5.1) database to server my spatial data. For the spatial layer (a labeled polygon layer) that is causing the exception, there is only one polygon that has an invalid geometry according to PostGIS. This invalid polygon is not within my testing bounding box, so for all intensive purposes there are no invalid polygons according to PostGIS. In GeoServer there are multiple polygons that have this labeling issue. I altered the code to tell me when a polygon that is to be labeled has an invalid geometry according to JTS. There are more polygons that are indicated as invalid (according to JTS) than there are polygon with the labeling issue. But for every polygon that has a labeling issue, it is invalid. What is happening (or trying to happen but not succeeding) is the computation of a point, centroid or some other point, for the placement of the label.
The alterations I made to make these observations was to GeoTools. More specifically I altered the class LabelCacheImpl (LabelCacheImpl.java) in gt-render-2.6.4.jar at line 1487 to include the following (all line numbers are of the unaltered file):
if (!g.isValid())
{
System.out.println(“A polygon geometry is invalid.”);
}
And at line 1492 to include the following:
if (!gg.isValid())
{
System.out.println(“A multipolygon geometry part is invalid.”);
}
To create a summary of the above to include the name of the geometry I add at line 1093 to include the following:
if (!geom.isValid())
{
System.out.println(labelItem.label + “: A geometry is invalid.”);
}
I tried the same thing using a Shape file as my data source for the particular layer. Things were no different. Still getting the same JTS exception being thrown.
I am using OpenLayers to view the data at three different zoom levels to see the effect that this has on rendering the data. I have noticed a particular polygon, call it polygon X, at the smallest of the three zoom level (smallest bounding box) is causing a non-noded intersection problem. I zoom out (bigger bounding box) and polygon X is not causing a problem. I zoom out again and polygon X is again causing a problem.
This leads me to suspect that a geometry in PostGIS world is not being correctly converted to a geometry in JTS world, more specifically that the source of the problem maybe in the scaling transformations being applied.
In coming to this conclusion I discovered that the Decimator at line 1557 was making things worse. It could make a valid geometry become an invalid geometry. While I made this part of the code more robust (not as many valid geometries becoming invalid), I could not stop the invalid geometries that are coming in, leaving as invalid geometries. (The changes I made to make it more robust are simple but not trivial and I think they would mislead the focus of this topic.)
Is this a known problem? Are there inadequacies in the scaling transformations? Or is this a precision problem (or a lack there of)?
It is curious that an invalid geometry may lead to problems when placing (rendering) a label but not in rendering the geometry itself!
While there is only one stack trace being seen on the console/log; there can be one, and in most cases three other exceptions thrown and caught before this exception is being generated. I think this is a serious performance problem also!
BrettWalker
brett.walker at geometryit.com
Software Developer / Analyst
www.geometryit.com