Could you offer any insights as to how to correct/workaround the performance problem described below. We are creating on-screen buffers of polygons by
re-drawing existing polygons using a calibrated wider stroke width for the polygon boundaries.

The problem is that although performance for complex polygons is good when zoomed out, zooming in causes a serious performance
degradation. I also converted the polygon layer into a line data type to compare performance.

Any suggestions? I'm assuming the problem is with Java 2D.

I've included the buffering (stroking) source code at the bottom of this email.

Thanks for your help,

Len
 

Below are buffer (stroking) draw times for clinker polygons (clinkers are areas of coal exposed at the surface but burned by such events as lightning strikes). I tested
two layers: clinker (poly) and clinker (line). The objects visible in the test from each layer had approximately the same number of vertices: clinker  (line) = 27400
vertices , clinker (poly) = 27382 vertices. Only the data type is different.

I buffered (stroked) the layers at different zoom levels or the same objects for all tests i.e. the map window always showed the same objects for each zoom level.

Full extent
 

Tight zoom

Summary of results:  For each clinker layer, buffering (i.e. stroking) becomes significantly slower as you zoom in. If you zoom in to 2X the previous view, the rendering
time is approximately 2X that of the previous view. The ultimate performance effect is much greater with the clinker (polygon) layer. A tight zoom (as shown above)
on the test objects from the clinker test area is: (1) 5 times slower (27 sec) than at full extent for clinker (line), and (2) 11 times slower (1 min 16 sec) than at full
extent for clinker (polygon).

Since there are some reports of pixel manipulation of images being significantly slower in JDK 2, the only thing I can think of is that as you zoom in (since number of
vertices and number of objects are held constant) the number of pixels being manipulated increases and performance is degraded.
 

Detailed results.

To display layer at full extent:

clinker (poly) - 12 sec
clinker (line) - 5 sec

Create 20k foot buffer:

1. at full extent

clinker (poly) - 7 sec
clinker (line) - 5 sec

2. zoom to 2x full extent

clinker (poly) - 23 sec
clinker (line) - 10 sec

3. zoom to 4x full extent

clinker (poly) - 47 sec
clinker (line) - 18 sec

4. zoom to tightest zoom

clinker (poly) - 1 min 16 sec
clinker (line) - 27 sec
 

THE BUFFERING CODE:

<from LavaShape.java>
//called once before any buffered polygons are drawn

//calculate the size of the buffer in screen coordinates.  layer.properties.value[7] is the buffer size in feet.
WRectangle wr = layer.getMapView().getProjection().getWorldBounds(); // current bounding box
float screenScaleX =  layer.getProjection().screen_width / (float)wr.w*layer.properties.value[7]*2;

bufferSize = new BasicStroke( screenScaleX,
            BasicStroke.CAP_ROUND,
            BasicStroke.JOIN_ROUND);

//clear the buffered offscreen image (MapCanvasUSGS.buf is a static BufferedImage object, MapCanvasUSGS.bufG is the Graphics2D object for it)
int w = MapCanvasUSGS.buf.getWidth( null );
int h = MapCanvasUSGS.buf.getHeight( null );

MapCanvasUSGS.bufG.setBackground( new Color( Color.white.getRed(), Color.white.getGreen(), Color.white.getBlue(), 100 ));
MapCanvasUSGS.bufG.clearRect( 0, 0, w, h );
//set the stroke
MapCanvasUSGS.bufG.setStroke( bufferSize );
<from USGSPolygonLavaShape.java>
//called for each polygon in the layer.  sPVS is the PGS structure for storing polygons
for(int i = 0; i < sPVS.size; i++)
     PolylineLavaShape.drawWidth(g2, sPVS.sPV[i].x, sPVS.sPV[i].y,
     sPVS.sPV[i].size, borderWidth-1, true);

<from LavaShape.java>
//called once after all the buffered polygons are drawn
MapCanvasUSGS.bufG.setStroke( oldbufferSize );

//set transparency.  layer.properties.value[9] is the value from 0 - 255.
float f = layer.properties.value[9] / 255f;
g.setComposite( AlphaComposite.getInstance(AlphaComposite.SRC_OVER, f ));
//draw the offscreen image to the screen
g.drawImage( MapCanvasUSGS.buf, 0, 0, null );
//reset the transparency
g2.setComposite( AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f) );

Reply via email to