Quantcast
Channel: MapWinGIS ActiveX Map and GIS Component
Viewing all articles
Browse latest Browse all 2341

Closed Task: Shapefile optimizations [19911]

$
0
0
Here are some problems I work on currently which deal with shapefile drawing/optimizations.
I decided to list them here to provide some kind of documentation, while the details aren't forgotten ;)
 
OPTIMIZATION OF DRAWING SPEED.
There are 2 measures to take:
1. Implement caching the data for drawing in the most accessible way. CShapeData class will be used for this. To enable caching Shapefile.FastMode property is needed.
2. When objects are too small at the current scale, it's faster to draw only a single pixel to show their locations. The critical size of object will be possible to set through Shapefile.MinDrawingSize.
 
EXTENTS RECALCULATION IN EDITING MODE.
For disk-based shapefiles extents (the bounding rectangle) don't change. They are stored in shapefile explicitly and can be retrieved very fast.
When shapefile in edit mode extents of particular shapes or shapefile as a whole may change as particular shapes are moved, added or deleted.
The default behavior of MapWinGIS was to recalculate extents of ALL shapes before EVERY redraw of shapefile, which was very inefficient.
Shapefile.CacheExtents property and Shapefile.RefreshExtents/ReftreshShapeExtents methods were added as a partial solution. But that laid all the burden of updating extents on the client.
The best approach is store the state of extents in particular variable:
Shape._extentsChanged. Initially it's set to false, and changes to true when any editing of points has taken place. Afterwards if client requests bounding rectange, it will be recalculated in case it's needed.
 
SHAPEFILE SOURCE TYPE
There is some confusion with usage of in-memory mode for shapefiles.
When trying to use it myself some time ago I encountered some problems and unexpected behaviour.
So here are the steps to make the things clearer:
1. Add Shapefile.SourceType property with enumerated constants:
sstUninitialized = 0,
sstDiskBased = 1,
sstInMemory = 2,
2. When new instance of shapefile class is created Source type is set to sstUnitialized.
3. When Shapefile.Open is called successfully it will be set to sstDiskBased. Shapefile.CreateNew will set it to sstInMemory. Shapefile.Close will reset it back to uninitialized state.
4. To save the in-memory shapefile two methods will be used: Shapefile.SaveAs (in case no name was provided in Shapefile.CreateNew) and Shapefile.save (in case the name was provided). In both cases source type will be set to sstDiskBased.
 
PREVENTION OF LOSING THE DATA WHILE DISCARDING EDITS
The data which accompany each shape, let's call it shape-bound data, (category with drawing options, labels, charts, selection) is stored in the same structure with instance of Shape class.
This structures are stored in the vector: std::vector<ShapeData*> _shapeData;
ShapeData()
{
IShape* shape; // for edit mode
CFastShapeData* fastData; // for fast regular mode
bool selected;
int category;
bool isVisible;
CChartInfo* chart;
CLabelInfo* label
long Handle; // unique handle
}
While editing takes place the elements of vector can be deleted or can change their positions, but the shape-bound data will accompany each shape all the same.
The problem begins when we discard the changes made during the editing session.
The shapefile will be reread from the disk, but all the shape-bound options will be lost, as there is no way to bound it to shapes apart from pure guessing.
The solution to fix this is:
1. Add Handle property for each shape. Handles should start with 0, for every succeeding shapes handles will be incremented by one.
2. Every removed shape should be stored in the _deletedShapes vector along with its handle and shape bound data: std::vector<ShapeData*> _deletedShapes;
3. Every newly addeded shape will receive incremented handle (handles of the removed shapes
won't be used).
4. When discarding of changes is needed, the initial bounding data will be restored
from _shapeData and _deletedShapes vectors based on shape handles.
 
OPTIMIZATION OF DEFINITION QUERIES.
Shapefile.VisibilityExpression property was added in the last releases. It stores SQL-like
expression based on attribute table fields to define shapes visible shapes.
Currently the expression is recalculated for every dbf record on every redraw. But it proved to be slow for complex expressions. So single calculation is needed. Then the indices
of the visible shapes should be cached.
To recalculate the expressions in case changes were made to dbf the following methods are
needed:
Shapefile.RefreshVisiblityExpression;
Labels.RefreshVisiblityExpression;
Charts.RefreshVisibilityExpression.
Comments: There are too many various things in this one. Some of them were implemented, some not. It's faster to create a new wishlist rather than dealing with this one. Therefore closed.

Viewing all articles
Browse latest Browse all 2341

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>