Speed up scrolling and panning


I’m building a GoDocument that consists of a base topography map layer and three grid layers. The map layer contains png images (500KB/image). Sitting on top is three grid layers. Each grid layer contains images of grids (50KB/image). The grid images have a transparent background so that I can see the base map underneath. Depending on the zoom factor I display one, two, or all three grid layers. I notice that scrolling and panning is noticeably slow when the grid layers are turned on. Is there anything that I can do to speed it up?

Unfortunately the grids are not rule-based and therefore cannot be generated as vectors.

I’m on version 2.6.1. My machine is a Core 2 Duo E6550 with 3 Gig of RAM.



Are each of the 50KB images unique? How many of them are being displayed? Are the images read from a file or in an ImageList? What’s the video controller in your machine?

Can you send a screenshot to “godiagram” at this domain? thanks.

There are some GDI+ performance knobs you can access through GoView

property                Our Default          fast option
-------------           ------------         -------------
SmoothingMode           HighQuality          None
InterpolationMode       HighQualityBicubic   Low (or NearestNeighbor)
CompositingQuality      AssumeLinear         HighSpeed
PixelOffsetMode         HighQuality          None       
TextRenderingHint       ClearTypeGridFit     SingleBitPerPixel

There are multiple performance/quality tradeoff values for most of these enums.

Not all of these affect bitmap performance... more details here:

http://msdn.microsoft.com/en-us/library/z714w2y9.aspx  (smoothing)

Are each of the 50KB images unique? Yes, on each layer there could many images stitched next to each other. Each image contains a set of grids.

How many of them are being displayed? That depends on how large an area we’re looking at. In this case, I load 48 images (16 grid images/layer x 3 layers)

Are the images read from a file or in an ImageList? I load each image from disk.

What’s the video controller in your machine? ATI Radeon X1050. I had tried running the app on other machines in the office and sad to say I have the fastest machine.

The red lines (for example) are a separate layer? and you have a full set of images with just the red lines that you can add/remove as a layer?

Are the image sizes larger than you using? In other words, do you read in a 200x200 image that you set the Size to 50,50?

The red lines are part of the base map so I have no control there. The orange and green lines represent pipelines and they’re on the link layer. The nodes are well sites and they go on the default layer. You’re looking at a gas gathering system essentially.

The original grid image sizes are smaller (1448x873 for example) and I resize to make it almost square (1453x1450) for display purpose. Here’s the piece of code that does it,

        GoLayer goLayer = GetGoLayer(gridLayer, gridStyle, layerID, proView);
        Dictionary<Township, Image> gridImage = gridLayer.GetGridImages( extent, fieldWidthDocUnits, fieldHeightDocUnits, gridLevel, gridStyle );

        if (gridImage != null)
            foreach ( Township town in gridImage.Keys )
                GoImage goImage = new GoImage();
                Image image = gridImage[town];
                // resize grid image, because it's proportions are based on the unprojected grid. (latlongs). We just make it square for now, and the same size as the Yahoo map.
                // CoordinateSystemConverterGeographic.GetAspectRatio( north, south, east, west )
                int townDocWidth = Convert.ToInt32( CoordinateSystemAdaptor.DocUnitsPerConfigCoord * Math.Round( town.Width ) / CoordinateSystemConverterGeographic.METRES_PER_CONFIG_COORD );
                int townDocHeight = Convert.ToInt32( CoordinateSystemAdaptor.DocUnitsPerConfigCoord * Math.Round( town.Height ) / CoordinateSystemConverterGeographic.METRES_PER_CONFIG_COORD );
                Image resizedGridImage = new Bitmap( image, townDocWidth, townDocHeight );

                goImage.Image = resizedGridImage;
                goImage.Position = goImage.Location = CoordinateSystemAdaptor.GetDocCoords( CoordinateSystemConverterGeographic.GetConfigCoords( town.NorthWest, origin ) );
                goLayer.Add( goImage );

Well, I just ran a test with a background image of 2048 x 2048, and a 20 by 20 grid (400 objects) of 100x100 pixel bitmaps, with 3 separate layers of grid (total of 1200 objects).

the scroll rate seems fine to me… hard to perceive any delay at all.

that’s on what would have been considered a pretty high-end laptop 2 years ago.

I’ll send you the project via email…

You’ll have to update your profile with an email that works…

I fixed up my profile, please try again… Thanks.

OK, going through your numbers:

an image is 1453x1450 is 2,106,850 pixels, times 4 bytes per pixel is about 8.4 megabytes for each grid. If you have 48 of those, it comes to over 400 megabytes of images. And you’re merging them all with transparency.

So, yeah, I can see how that might be slow.

Are you setting the scale (zooming) to make these images the size you want on the screen?

The images are being saved with 4 bytes (32-bit) color depth. We could convert them to 1 byte (8-bit) color depth. Do you think it will help given the fact that we do resize them for display? Putting it another way, when we resize the images for display do they go back to being 32-bit in memory?

You don’t get transparency at 8 bits. Try reducing the resolution of the images.

A better solution would be to just use bitmaps for the background maps, and actually draw the pipelines and other bits.