How to center filtered .shp layer?

Topics: SharpMap Project
Mar 9, 2010 at 2:48 PM

Hi,

  I have this problem. For example, I have EuropeMap.shp layer. I want to show and center in picturebox only England.  I decided to use FilterDelegate to do that (something like this code).

************************************************

VectorLayer vLayer = new VectorLayer("layername");
SharpMap.Data.Providers.ShapeFile sf = new SharpMap.Data.Providers.ShapeFile(@"EuropeMap.shp");
 vLayer.DataSource = sf;

Map _map=new Map(800,600);

List<double>coordinate=new List<double>();

sf.FilterDelegate = delegate(SharpMap.Data.FeatureDataRow row)
{
   bool result = false;
   if (row["countryname"].ToString() == "England")
   {
      SharpMap.Geometries.BoundingBox box = row.Geometry.GetBoundingBox();
      coordinate.Add(box.Max.X);
      coordinate.Add(box.Min.X); ...etc.
      result = true;
   }
 return result

};
 _map.Layers.Add(vLayer);

BoundingBox bbox=new BoundingBox(coordinate[0],coordinate[1],coordinate[2],coordinate[3]);

_map.ZoomToBox(bbox);

***************************************

My problem is, that my collection "coordinate" is empty and I don't know why. If I use for example: BoundingBox bbox=new BoundingBox(-10,100,-100,10); ,it works fine. Is there any other way to solve my problem?(I don't want to use MouseClick to set centeroid)

Tomino

Coordinator
Mar 10, 2010 at 12:33 PM

hi tomino,

please try the following:

- declare a BoundingBox (e.g. _bbEngland) at class level

- set _bbEngland = row.Geometry.GetBoundingBox() the first time your condition evalueates 'true'.
  If there are several features to make up England _bbEngland.Join(bbOther) to expand.

- call _map.ZoomToBox(_bbEngland);

Hth FObermaier

 

Mar 10, 2010 at 1:41 PM

hi fobermaier,

Thank you for your response. I followed your advice, but my BoundingBox _bbEngland is NULL.

*******************************************************************

BoundingBox _bbEngland;

... //code ...

sf.FilterDelegate = delegate(SharpMap.Data.FeatureDataRow row)
{
bool result = false;
if (row["countryname"].ToString() == "England")
{
 _bbEngland = row.Geometry.GetBoundingBox();//  _bbEngland CONTAINS RIGHT VALUES
result = true;
}
return result

};
_map.Layers.Add(vLayer);

_map.ZoomToBox(_bbEngland);// BUT HERE _bbEngland is NULL.

******************************************************* 

Do I do something wrong? 

Coordinator
Mar 11, 2010 at 6:15 PM

Hello tomino,

maybe you have several features with countryname="England"?

Please try this delegate function:

sf.FilterDelegate = delegate(SharpMap.Data.FeatureDataRow) {
    if (row["countryname"] == "England")
    {
        if (_bbEngland == null)
            _bbEngland = row.Geometry.GetBoundingBox();
        else
            _bbEngland = _bbEngland.Join(row.Geometry.GetBoundingBox());
        return true;
    }
    return false;   
};
Hth FObermaier

 

 

Coordinator
Mar 11, 2010 at 9:03 PM

Hi tomino,

the delegate is invoked if you render or query the layer. Therefore _bbEngland must be null in your case (stupid me)

Prior to _map.ZoomToBox(_bbEngland); add the following lines:

System.Diagnostics.Debug.Assert(_bbEngland == null);
_map.GetMap();
System.Diagnostics.Debug.Assert(_bbEngland != null);
//you probably don't need the filterdelegate anymore
sf.FilterDelegate = null;

Hth FObermaier

Mar 12, 2010 at 7:53 AM

Hi fobermaier,

  thank you very much for your good advice. It helped me a lot. I didn't know the delegate is invoked after render or query the layer. Problem is solved by this code:

sf.FilterDelegate = delegate(SharpMap.Data.FeatureDataRow) {
if (row["countryname"] == "England")
{
if (_bbEngland == null)
_bbEngland = row.Geometry.GetBoundingBox();
else
_bbEngland = _bbEngland.Join(row.Geometry.GetBoundingBox());
return true;
}
return false; 
};

_map.GetMap(); //I didn't have this line before

_map.ZoomToBox(_bbEngland);

Have a nice day, tomino