Layer - Initial Zoom Level

Feb 3, 2009 at 9:45 PM
Edited Feb 3, 2009 at 9:46 PM
tool ref : winform/ogr

Hopefully i can explain myself well enough. This is part of our evaluation of sharpmap to replace mapinfo and we seem to have hit a brick wall here.

We have street directory of the entire country stored in a .tab file (mapinfo format ) . Use the ogr provider to load this.

SharpMap.Map myMap = new SharpMap.Map(new System.Drawing.Size(500,250)); //Initialize map object
SharpMap.Layers.VectorLayer layRoads= new SharpMap.Layers.VectorLayer("Roads"); //Create layer
layRoads.DataSource = new SharpMap.Data.Providers.Ogr(@"DATA\SDB\a_ST.TAB");

map.Layers.Add(layer);

however the initial load of the layer takes far too long as sharpmap tries to load the entire layer which is quite huge as it contains the entire street directory of the country.  even after a successful load after a very long time it results in memory corrupted error.

solution requirement
hoping to do something  much similar to google maps. where it displays only high level roads intially and as the user zooms in street levels are displayed.

i am not even sure whether this is a problem with the sharpmap or the way we have done the coding here . or does the .tab file (which we have no control over) need to be set up in a certain way ?

Any help in getting around this would be highly appreciated.

Regards

Bijoy










Coordinator
Feb 3, 2009 at 10:00 PM
Edited Feb 3, 2009 at 10:09 PM
Hi Bijoy, I dont use the ogr provider so someone else may have more /better info.. but.. It looks like there is no way currently of limiting by attributes (eg road importance).. However it would be trivial to implement.. Add a FilterDelegate property to the OgrProvider and use it as part of the ExecuteIntersectionQuery / GetGeometriesInView etc.. You can use the same routines in the Shapefile provider as reference. Otherwise you will have to split your tab files.. cheers jd

EDIT: looking into it slightly further the _OgrLayer object used internally has a SetAttributeFilter(string ) method so really you only need to expose a public property on the provider where you can set the 'Definition Query' and then set it on the _OgrLayer object before querying..
Feb 5, 2009 at 10:07 PM
Edited Feb 5, 2009 at 10:10 PM
John,  let me thank you first for taking the pain to dig through object heirararchy and finding out the setattibute filter . great. your suggestion to SetAttributeFilter has improved the performance manifold on the OGR provider.  I have been playing around with this for the last couple of days and have to say its been such a interesting learning curve for me

However I still seem to have a nagging issue with the OGR provider.

_OgrLayer.GetNextFeature() seems to be incredible slow in  geometry areas which contain a large no of features.
For eg .  the below method would return a 50000 features (all features) at a suburb level zomm lightning fast .
 but it struggles to return even 1000 features (filtered to show only state highways)
at say a state level zoom.  I suspect although not sure that this is because it iterates through all the features and ignores the ones that dont match the filter .

Any workarounds to this would be immensely appreciated

Below is the modified method i had modified in the Ogr Provider .

        public Collection<SharpMap.Geometries.Geometry> GetGeometriesInView(SharpMap.Geometries.BoundingBox bbox)
        {
            Collection<SharpMap.Geometries.Geometry> geoms = new Collection<SharpMap.Geometries.Geometry>();
            _OgrLayer.ResetReading();
            _OgrLayer.SetSpatialFilterRect(bbox.Left, bbox.Bottom, bbox.Right, bbox.Top);


            OSGeo.OGR.Feature _OgrFeature = null;
            FeatureDataTable myDt = new FeatureDataTable();

            if (_attributeFilter == HIDE_LAYER)
            {
                //dont display any thing .
                return geoms;
            }

            _OgrLayer.SetAttributeFilter(_attributeFilter);



            while ((_OgrFeature = _OgrLayer.GetNextFeature()) != null)
            {

                geoms.Add(this.ParseOgrGeometry(_OgrFeature.GetGeometryRef()));
                _OgrFeature.Dispose();
            }

            return geoms;
        }
 

 

Coordinator
Feb 6, 2009 at 8:52 AM
Hi Bijoy, I'm glad it helped. I would assume that underneath the covers the provider is testing each feature as you describe - the equivalent of a database Table Scan. In db terms you can add indexes to limit the required scan so I wonder if your performance could be improved by some kind of indexing of your Tab files (Wikipedia says there is such a thing as an index file for Tab format) - how you would go about this I dont know, and I am not sure whether or not the underlying OGR component would use it if present. hth jd