I'll start by adding a better logging method to BasicFeatureRenderer.
With regards to your error. It is a strange one. WFSFilterVisitor
parses the query filter to obtain the bbox of the request. But I can't
think of any reason that is would work with the normal renderer and not
yours. Could you extend the BasicFeatureRenderer ala the
ShapefileRenderer. That why there would be less potential for errors.
Mark Presling wrote:
I'm starting to get somewhere...
I have just found that the error handling in the render() method is to
blame for most of the time that I have spent trying to figure this out.
An exception has been getting swallowed. Adding this to the end of the
render() method:
}finally{
if (listener.exception != null) {
--> listener.exception.printStackTrace(); <--
if (!(listener.exception instanceof TopologyException)){
produces:
RoadEventFeatureRenderer.render()
java.lang.Exception: Exception rendering layer DefaultMapLayer[ Test, VISIBLE, style=StyleImpl<NO_PARENT.styles[0]>[ name=Default Styler], data="" query=Query:
feature type: topp:roadevent_pnt
filter: Filter.ALL
[properties: ALL ]]
at org.geotools.renderer.lite.StreamingRenderer.paint(StreamingRenderer.java:503)
at org.geotools.renderer.lite.StreamingRenderer.paint(StreamingRenderer.java:407)
at net.refractions.udig.render.internal.feature.basic.RoadEventFeatureRenderer.render(RoadEventFeatureRenderer.java:195)
at net.refractions.udig.render.internal.feature.basic.RoadEventFeatureRenderer.render(RoadEventFeatureRenderer.java:162)
at net.refractions.udig.project.internal.render.impl.RenderExecutorImpl$RenderJob.startRendering(RenderExecutorImpl.java:273)
at net.refractions.udig.project.internal.render.impl.RenderExecutorImpl$RenderJob.run(RenderExecutorImpl.java:334)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:76)
Caused by: java.util.EmptyStackException
at java.util.Stack.peek(Stack.java:79)
at java.util.Stack.pop(Stack.java:61)
at org.geotools.data.wfs.WFSFilterVisitor.visit(WFSFilterVisitor.java:161)
at org.geotools.filter.Filter$2.accept(Filter.java:99)
at org.geotools.data.wfs.WFSDataStore.splitFilters(WFSDataStore.java:882)
at org.geotools.data.wfs.WFSDataStore.getFeatureReader(WFSDataStore.java:708)
at org.geotools.data.DefaultFeatureResults.reader(DefaultFeatureResults.java:147)
at org.geotools.renderer.lite.StreamingRenderer.getReader(StreamingRenderer.java:957)
at org.geotools.renderer.lite.StreamingRenderer.processStylers(StreamingRenderer.java:1055)
at org.geotools.renderer.lite.StreamingRenderer.paint(StreamingRenderer.java:501)
... 6 more
And on the GeoServer side I discovered this deep down in the log:
1841446948 [INFO] org.vfny.geoserver.wfs.servlets.WfsDispatcher - req_type is -1
1841446949 [WARNING] org.vfny.geoserver.ServiceException - encountered error: No request recognized. The REQUEST parameter must be one of GetFeature, GetFeatureWithLock, DescribeFeatureType, LockFeature, or Transaction.
StackTrace: org.vfny.geoserver.wfs.WfsException: No request recognized. The REQUEST parameter must be one of GetFeature, GetFeatureWithLock, DescribeFeatureType, LockFeature, or Transaction.
at org.vfny.geoserver.wfs.servlets.WfsDispatcher.doResponse(WfsDispatcher.java:305)
at org.vfny.geoserver.wfs.servlets.WfsDispatcher.doGet(WfsDispatcher.java:213)
So... once again... can anyone think of a reason for this happening
when I use my own MetricsFactory defined in the extension point (see
previous email(s) for more information on what I have done)? As I said
previously, when I modify the BasicFeatureMetricsFactory to return my
renderer it works fine. But when I point the renderer extension point
at my own MetricsFactory (which is an almost exact copy of
BasicFeatureMetricsFactory) it errors out.
I guess the first thing to take from this is that someone needs to look
at the error handling in the render() method, because it swallowed the
exceptions even when tracing and -consoleLog was turned on.
Thanks in advance,
Mark
Mark Presling wrote:
Hi
Jesse,
This just gets wierder...
The style is fine. I have done all sorts of validation on it (and found
that the style editor tool creates invalid SLD by default when you
validate it with it's own validator - which I know you are working on).
And it does work... see below.
After aother day of head banging and debugging I just tried something
new. I modified BasicFeatureMetricsFactory and BasicFeatureMetrics to
return my renderer instead of BasicFeatureRenderer, and guess what...
it worked!
So I can confirm that my renderer does actually work (because it's an
exact copy of BasicFeatureRenderer, it's just that when I use my own
Metrics and MetricsFactory classes in the extension it does not. Even
when I remove the extension definition for BasicFeatureMetricsFactory
it still doesn't render anything on the map.
I have even tried to put my classes in the render.feature.basic plugin
to make sure it's not a classloading issue or something.
Here are the Metrics classes:
package net.refractions.udig.render.internal.feature.basic;
import net.refractions.udig.project.internal.render.SelectionLayer;
import net.refractions.udig.project.render.IRenderContext;
import net.refractions.udig.project.render.IRenderMetrics;
import net.refractions.udig.project.render.IRenderMetricsFactory;
import net.refractions.udig.project.render.IRenderer;
import org.geotools.data.FeatureSource;
public class RoadEventFeatureMetricsFactory implements
IRenderMetricsFactory {
/**
* @see
net.refractions.udig.project.render.IRenderMetricsFactory#createMetrics(net.refractions.udig.project.render.IRenderContext)
*/
public IRenderMetrics createMetrics(IRenderContext context) {
return new RoadEventFeatureMetrics(context, this);
}
/**
* @see
net.refractions.udig.project.render.IRenderMetricsFactory#canRender(net.refractions.udig.project.render.IRenderContext)
*/
public boolean canRender( IRenderContext context ) {
try {
FeatureSource fs =
context.getGeoResource().resolve(FeatureSource.class, null);
String layerName = context.getLayer().getName();
if (context.getLayer() instanceof SelectionLayer &&
fs != null) {// && "roadevent_pnt".equalsIgnoreCase(layerName)
System.err.println("RoadEventFeatureMetricsFactory
returning true for " + layerName);
return true;
}
System.err.println("RoadEventFeatureMetricsFactory returning false for
" + layerName);
return false;
} catch (Throwable t) {
t.printStackTrace();
return false;
}
}
/**
* @see IRenderMetricsFactory#getRendererType()
*/
public Class<? extends IRenderer> getRendererType() {
return RoadEventFeatureRenderer.class;
}
}
package net.refractions.udig.render.internal.feature.basic;
import net.refractions.udig.project.ILayer;
import net.refractions.udig.project.internal.render.Renderer;
import net.refractions.udig.project.render.IRenderContext;
import net.refractions.udig.project.render.IRenderMetrics;
import net.refractions.udig.project.render.IRenderMetricsFactory;
import org.geotools.styling.Style;
public class RoadEventFeatureMetrics implements IRenderMetrics {
private IRenderContext context;
private RoadEventFeatureMetricsFactory factory;
/**
* Construct <code>RoadEventFeatureMetrics</code>.
*
* @param context2
* @param factory
*/
public RoadEventFeatureMetrics( IRenderContext context2,
RoadEventFeatureMetricsFactory factory ) {
this.context=context2;
this.factory=factory;
}
/**
* @see
net.refractions.udig.project.render.IRenderMetrics#createRenderer()
*/
public Renderer createRenderer() {
Renderer renderer=new RoadEventFeatureRenderer();
renderer.setContext(context);
renderer.setName(context.getLayer().getName());
return renderer;
}
/**
* @see
net.refractions.udig.project.render.IRenderMetrics#getRenderContext()
*/
public IRenderContext getRenderContext() {
return context;
}
/**
* @see
net.refractions.udig.project.render.IRenderMetrics#getRenderMetricsFactory()
*/
public IRenderMetricsFactory getRenderMetricsFactory() {
return factory;
}
public boolean canAddLayer( ILayer layer ) {
return true;
}
public boolean canStyle( String SyleID, Object value ) {
return value != null && value instanceof Style;
}
public boolean isOptimized() {
return false;
}
}
Any more ideas? Has anyone else out there implemented their own
renderer and noticed any strange behaviour like this?
Thanks,
Mark
ps I like the Theme part of the SLD editor... very cool!
Jesse Eichar wrote:
Nothing is jumping out at me right away.
Maybe the style is somehow crazy? Seems unlikely but possible. Could
you send the style to us?
Jesse
Mark Presling wrote:
Hi. Sorry to bug the list again, but I
have
been trying to create my own renderer based on BasicFeatureRenderer to
render the features of a WFS layer.
What I have done is this:
1. Make a copy of BasicFeatureRenderer called
RoadEventFeatureRenderer. The only thing different at this
stage is the name and package
2. Make a copy of BasicFeatureMetricsFactory called called
RoadEventFeatureMetricsFactory. The differences are the
name/package, what it returns in createMetrics() and and
getRendererType() and a check in canRender() that returns true
only for a particular layer name
String layerName = context.getLayer().getName();
String layerName = context.getLayer().getName();if
(context.getLayer() instanceof SelectionLayer && fs != null
&& *"roadevent_pnt".equalsIgnoreCase(layerName)*) {
System.err.println("RoadEventFeatureMetricsFactory
returning true for " + layerName);
return true;
}
3. Make a copy of BasicFeatureMetrics called called
RoadEventFeatureMetrics. Changed types to match those above.
4. Modify BasicFeatureMetricsFactory to return false for the
particular layer identified above.
5. Register my renderer with the extension point
net.refractions.udig.project.renderer in my plugin.xml
<extension
point="net.refractions.udig.project.renderer">
<renderer
class="nz.govt.transit.callcenter.RoadEventFeatureMetricsFactory"/>
</extension>
6. Run app.
What I find through debugging is that the renderer is called as
expected, but for some reason it is not outputting anything. Please
note that I have not modified the actual rendering code... it still
uses the StreamingRenderer as the existing one does.
I have noticed that the filter/queries that are set on the layer are
different to the ones set when using BasicFeatureRenderer. In BFR the
filter is:
Query: [Request All Features]
feature type: null
filter: Filter.NONE
[properties: ALL ]
but in mine it was Filter.ALL (which I believe means filter OUT
everything - return nothing). So I explicitly set the query to
Query.ALL in the setQueries() method of my BFR clone.
So, this meant that the feature collection returned in the
StreamingRenderer had 24 items in it now. Good. However, still nothing
is rendered and when you click on the layer it says "Layer not
rendered" in the status bar.
Another thing of concern is that on the console I see this:
Current Renderers:
CompositeRendererImpl
RenderExecutorImpl:BasicWMSRenderer2-highway
RenderExecutorImpl:BasicFeatureRenderer-nmcregion_poly
I have 1 WMS layer and 2 WFS layers - one of which I want to render
with my renderer. As you can see, my renderer doesn't appear in this
list, but it is definitely instantiated and the render method is
definitely called on it.
Is there something that I am missing in terms of extensions or classes
that I need to implement? My intention is to just implement a renderer,
not the whole stack of DataSource/FeatureSource/etc.
Thanks,
Mark
--
This message has been scanned for viruses and dangerous
content by *MailScanner* <http://www.mailscanner.info/>*,
and is
believed to be clean. *
*_______________________________________________
User-friendly Desktop Internet GIS (uDig)
http://udig.refractions.net
http://lists.refractions.net/mailman/listinfo/udig-devel
*
*
--
This message has been scanned for viruses and dangerous
content by *MailScanner* <http://www.mailscanner.info/>,
and is
believed to be clean. *
*
*
------------------------------------------------------------------------
*
_______________________________________________
User-friendly Desktop Internet GIS (uDig)
http://udig.refractions.net
http://lists.refractions.net/mailman/listinfo/udig-devel
*
_______________________________________________
User-friendly Desktop Internet GIS (uDig)
http://udig.refractions.net
http://lists.refractions.net/mailman/listinfo/udig-devel
--
This message has been scanned for viruses and dangerous
content by MailScanner,
and is believed to be clean.
_______________________________________________
User-friendly Desktop Internet GIS (uDig)
http://udig.refractions.net
http://lists.refractions.net/mailman/listinfo/udig-devel
|