Help for PolygonCategory FilterExpression Problem

Jan 14, 2011 at 6:39 PM

I have a simple form with a spatial tool strip and a map control and legend in separate panels along the lines of the sample in the Developers Corner document.  I added a button to the tool strip and then wrote the following code in an attempt to classify a polygon (county boundaries) shapefile.  My problem is that the two categories display properly in the legend, but nothing is displayed in the map frame.

While trying to troubleshoot this problem, I have found that if I do not execute the countyScheme.ClearCategories() line, I get a third category listed in the legend and the counties are displayed in the map frame using whatever default scheme was applied so it seems the map frame is working.  Going further, if I comment out the FilterExpression statement for a category, then it is displayed in the map frame with the correct formatting, but with no filter applied.  I have also checked to make sure that the filter expressions themselves work by selecting county.shp in the legend (after adding it using the code below), and then displaying the attribute table and querying it using the exact same text I have in the FilterExpressions.  I have also tried not including the square brackets around the field names in the FilterExpressions, so far nothing has worked if I use a FilterExpression.

I am using the most recent DotSpatial (x86) release and VS 2010.  My inability to apply a classification scheme to a polygon layer has become a major show-stopper, any advice will be greatly appreciated!

Steve

Public Class Form1
  Sub AddCountiesButton_Click() Handles AddCountiesButton.Click

    Dim fs As New FeatureSet(FeatureType.Polygon)
    fs.Open("P:\county.shp")
    Dim countyLayer As IMapPolygonLayer = Map1.Layers.Add(fs)
    Dim countyScheme As New PolygonScheme
    countyScheme.ClearCategories()

    Dim validCounties As PolygonCategory = New PolygonCategory(Color.LightGreen, Color.Black, 1)
    validCounties.FilterExpression = "[COUNTY] <> ''"
    validCounties.LegendText = "No Species Present"
    countyScheme.AddCategory(validCounties)

    Dim speciesPresent As PolygonCategory = New PolygonCategory(Color.Orange, Color.Black, 1)
    speciesPresent.FilterExpression = "[Present] = 1"
    speciesPresent.LegendText = "Species Present"
    countyScheme.AddCategory(speciesPresent)

    countyLayer.Symbology = countyScheme
  End Sub
End Class

Jan 16, 2011 at 12:29 PM
http://dotspatial.codeplex.com/Thread/View.aspx?ThreadId=239240
Jan 16, 2011 at 4:46 PM
Edited Jan 16, 2011 at 4:47 PM

I am sorry if I am being dense, but I am not seeing the solution.  Based on the other post you referred me to, I tried adding countyLayer.DataSet.InvalidateVertices() after applying the countyScheme but it made no difference.  Could you please elaborate?

Jan 17, 2011 at 7:16 PM

Any other thoughts?  Or is there a source of documentation (other than the Developer's Corner document) that I can refer to?  We support the concept / philosophy behind dotSpatial and are hoping to use it instead of ArcObjects for our application(s) but the lack of documentation and formal support is making it difficult to commit to developing commercial products using this technology.  I am sure this will change over time, but we unfortunately cannot wait much longer to make decisions on which technology to use.  If there is something I am missing or some documentation that anyone can point me to in order to try to make this work, we are happy to make the effort to try to move forward with dotSpatial.  Thanks.

Developer
Jan 17, 2011 at 9:17 PM

Calling InvalidateVertices is not helpful for this situation.  So obviously if you can clear the filter expression and get the content to draw then the filter expression is either causing the problem, or there is a bug in the works that happens to be triggered when you apply your particular filter expressions.  The expressions look ok, but here are some general pointers to troublesome things that come up when working with expressions.  Testing for equality with '' doesn't usually work, since most of the time the field is actually DBNull.  I think you are supposed to use something like [COUNTY] IS NOT NULL.  Another thing that can cause trouble is if "[Present]" is supposed to be all caps like county.  Finally, if Present is actually a text field, the expression might not work without the single quotes.  I assume you would have checked all that stuff out, however, since you claim that these filter expressions work elsewhere when pasted as is.  Moving on to possible bugs.  One thing might be if the attributes were somehow loaded schema wise, but had no values.  You can try to force fs.FillAttributes(); sometime before setting the Symbology property using your scheme.  Another possible bug might be that the Category constructors you are using might not be correctly setting up the actual symbolizer correctly.  You might want to try other ways of creating the category.  That isn't a very likely source of the problem though.  Finally, maybe for some reason the Symbology assignment isn't working right.  You could try countyLayer.AssignFastDrawnStates() after your Symbology assignment and see if that helps.  Technically it shouldn't.  If you add a breakpoint in the code, you can check the "DrawnStates" array on countyLayer and ensure that each shape has a category that is one or the other of your two categories.  If not, then somehow the filter expression is not working right.  If that is the case, you can experiment with the fs.DataTable.Select command using the same filter expression.  You can check the number of datarows returned to see if it looks right.  If this is not working, then this is a .Net microsoft DataTable, so there is simply a formatting issue with your filter expression and you can experiment with the Select command until you get the filter expression to return rows correctly.

While we have a reasonably active community, it is in it's very early stages.  We are in the alpha stage of development, which means that changes are still being made to the core way this program behaves.  With open source, you don't have licensing fees and the associated costs of the software, but the trade off is that that means that there is minimal funding to support testing and documentation, which tend to be exhaustive for expensive commercial software.  You end up having to invest more man hours both to understand the software and either help troubleshoot actual bugs, or else report them and hope the community fixes them fast enough to meet your deadline.  If your product does not have a large re-distribution model, that is you only have one client and they only need one commercial license to use your software, or else you are designing something for a group that would already have commercial licenses, then it is a no-brainer.  In such a case, definitely go commercial since you will spend more of your project dollars on teaching yourself how to use the open source software, only to learn at some stage that there is a game ending bug or else that you need a standard GIS feature that is not standard in the open source software.  If, on the other hand, your business model could not support each individual copy of your software adding the cost for a commercial license, then welcome to the open source game.  You choose open source not because it is easier, but because the licensing of commercial software would make your product nonviable.  As to which open source project you choose, that is more based on your platform and language.

The more people that use the open source solution, however, the more viable it becomes for everyone.  Hopefully you will pick that road, but understand it is likely fraught with perils and frustrations.  Novice programmers should especially beware because they are not likely to know whether they have hit a bug, have an error in their code, or are using the program incorrectly.  Open source tends to remain the tools chosen by experts that are talented enough to fix what does not work as they expect.

Good luck, and I'm sorry I don't see anything obvious to fix your problem.  If the filter is working, the results are being returned and the DrawnStates are assigned correctly but still nothing draws, go ahead and post this as an issue if you haven't already.  (Rather than a discussion.)  Thanks.

Ted

 

Coordinator
Jan 18, 2011 at 12:15 AM
Ted's right about the costs associated with using open source software like this. I'm certainly hopeful that you'll be able to make DotSpatial work for you needs though since hopefully, along the way, you'll learn much and be able to contribute back to the community through discussion forums etc. Maybe your company could sponsor the development of some documentation and or training videos. As Ted said, we're still at the outset with DS (less than a year old!) but thanks to great contributions of existing code from Ted and many others, we're quickly ramping up to speed. Our first full release will be part of the MapWindow/DotSpatial conference in June in San Diego. At that point we should have at least basic documentation and a fairly locked in core set of components for people to work with. - Dan

On Mon, Jan 17, 2011 at 3:17 PM, shade1974 <notifications@codeplex.com> wrote:

From: shade1974

Calling InvalidateVertices is not helpful for this situation. So obviously if you can clear the filter expression and get the content to draw then the filter expression is either causing the problem, or there is a bug in the works that happens to be triggered when you apply your particular filter expressions. The expressions look ok, but here are some general pointers to troublesome things that come up when working with expressions. Testing for equality with '' doesn't usually work, since most of the time the field is actually DBNull. I think you are supposed to use something like [COUNTY] IS NOT NULL. Another thing that can cause trouble is if "[Present]" is supposed to be all caps like county. Finally, if Present is actually a text field, the expression might not work without the single quotes. I assume you would have checked all that stuff out, however, since you claim that these filter expressions work elsewhere when pasted as is. Moving on to possible bugs. One thing might be if the attributes were somehow loaded schema wise, but had no values. You can try to force fs.FillAttributes(); sometime before setting the Symbology property using your scheme. Another possible bug might be that the Category constructors you are using might not be correctly setting up the actual symbolizer correctly. You might want to try other ways of creating the category. That isn't a very likely source of the problem though. Finally, maybe for some reason the Symbology assignment isn't working right. You could try countyLayer.AssignFastDrawnStates() after your Symbology assignment and see if that helps. Technically it shouldn't. If you add a breakpoint in the code, you can check the "DrawnStates" array on countyLayer and ensure that each shape has a category that is one or the other of your two categories. If not, then somehow the filter expression is not working right. If that is the case, you can experiment with the fs.DataTable.Select command using the same filter expression. You can check the number of datarows returned to see if it looks right. If this is not working, then this is a .Net microsoft DataTable, so there is simply a formatting issue with your filter expression and you can experiment with the Select command until you get the filter expression to return rows correctly.

While we have a reasonably active community, it is in it's very early stages. We are in the alpha stage of development, which means that changes are still being made to the core way this program behaves. With open source, you don't have licensing fees and the associated costs of the software, but the trade off is that that means that there is minimal funding to support testing and documentation, which tend to be exhaustive for expensive commercial software. You end up having to invest more man hours both to understand the software and either help troubleshoot actual bugs, or else report them and hope the community fixes them fast enough to meet your deadline. If your product does not have a large re-distribution model, that is you only have one client and they only need one commercial license to use your software, or else you are designing something for a group that would already have commercial licenses, then it is a no-brainer. In such a case, definitely go commercial since you will spend more of your project dollars on teaching yourself how to use the open source software, only to learn at some stage that there is a game ending bug or else that you need a standard GIS feature that is not standard in the open source software. If, on the other hand, your business model could not support each individual copy of your software adding the cost for a commercial license, then welcome to the open source game. You choose open source not because it is easier, but because the licensing of commercial software would make your product nonviable. As to which open source project you choose, that is more based on your platform and language.

The more people that use the open source solution, however, the more viable it becomes for everyone. Hopefully you will pick that road, but understand it is likely fraught with perils and frustrations. Novice programmers should especially beware because they are not likely to know whether they have hit a bug, have an error in their code, or are using the program incorrectly. Open source tends to remain the tools chosen by experts that are talented enough to fix what does not work as they expect.

Good luck, and I'm sorry I don't see anything obvious to fix your problem. If the filter is working, the results are being returned and the DrawnStates are assigned correctly but still nothing draws, go ahead and post this as an issue if you haven't already. (Rather than a discussion.) Thanks.

Ted

Read the full discussion online.

To add a post to this discussion, reply to this email (DotSpatial@discussions.codeplex.com)

To start a new discussion for this project, email DotSpatial@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com




--
Daniel P. Ames, Ph.D. PE
Associate Professor, Geosciences
Idaho State University - Idaho Falls
amesdani@isu.edu
geology.isu.edu
www.mapwindow.org


Jan 18, 2011 at 12:32 AM

For what it's worth, I was having problems symbolizing by polygon as well using a filter expression and found that if I call "FillAttributes" on the feature set object just prior to setting up the categories, it would draw, otherwise everything was blank.  Here is my code:

            mFeatureSet.FillAttributes();
            this.SymbolizePolygons();

        //'---------------------------------------------------------
        //' METHOD:                                        
        //'---------------------------------------------------------
       
        private void SymbolizePolygons()
        {
            //PolygonSymbolizer polySym = new PolygonSymbolizer(Color.LightGray, Color.DarkGray, 1);
            //mFeatureLayer.Symbolizer = polySym;//new PolygonSymbolizer(Color.CadetBlue, Color.DarkBlue);

            //' Symbolize polygons by to show where available graves are located
            PolygonScheme scheme = (PolygonScheme)mFeatureLayer.Symbology; //new PolygonScheme();
            System.Data.DataSet ds = new System.Data.DataSet();
            StringBuilder sbPlotsAvailable = new StringBuilder();
            int i = 0;

            //'---------------------------------------------------------
            //' Get all the plot_id's where available graves are located
            //'---------------------------------------------------------
            string sSql = "SELECT DISTINCT plot_id from " + Strings.gravesTable + " WHERE interred = 0";
            ds = Db_ExecuteQuery_ReturnDataSet(sSql, ds, Strings.gravesTable, "SymbolizePolygons");
     
            foreach (DataRow drRow in ds.Tables[Strings.gravesTable].Rows)
            {
                if (i > 0)
                    sbPlotsAvailable.Append(",");
                if (!string.IsNullOrEmpty(drRow["plot_id"].ToString()))
                {
                    sbPlotsAvailable.Append(drRow["plot_id"].ToString());
                    i++;
                }
            }

            PolygonCategory plotsAvail = new PolygonCategory(Color.LightGreen, Color.DarkGreen, 1);
            plotsAvail.FilterExpression = "[plot_id] IN (" + sbPlotsAvailable.ToString() + ")";
            plotsAvail.LegendText = "Has Available Graves";

           //' Do not apply a filter expression so everything gets colored
            PolygonCategory plotsNotAvail = new PolygonCategory(Color.Gray, Color.DarkGray, 1);
            //plotsNotAvail.FilterExpression = "[plot_id] IN (" + sbPlotsAvailable.ToString() + ")";
            plotsNotAvail.LegendText = "No Available Graves";

            //' Clear any schemes first
            //' By adding the categories this way, I can color ALL the plots gray, then overlay the available plots
            scheme.ClearCategories();
            scheme.AddCategory(plotsNotAvail);
            scheme.AddCategory(plotsAvail);

            mFeatureLayer.Symbology = scheme;  //' Null reference exceptionm thrown here if FillAttributes is not called
            mFeatureLayer.ApplyScheme(scheme);
        }

Jan 18, 2011 at 5:01 AM
Edited Jan 18, 2011 at 5:05 AM

eklundjb, thank you VERY much for your post as calling FillAttributes() on my featureset as you suggested did the trick!  I really appreciate you taking the time to post, it was a huge help.

Ted & Dan, thank you for your responses as well.  I didn't mean to seem negative and I do appreciate you taking the time to respond.  I have been developing (off and on) for close to 20 years and definitely understand the pros and cons of open source as you expressed them.  I didn't realize how early in the development cycle DS is, and the progress made is impressive.  As I said originally, I would like to do what we can to support your endeavors with DS and am interested in Dan's suggestion to help fund the documentation effort.  I will contact you offline to discuss what we might be able to do.

Thanks again to all.

Steve

Coordinator
Jan 18, 2011 at 1:48 PM
Sounds good! Thanks...

On Mon, Jan 17, 2011 at 11:01 PM, SAK <notifications@codeplex.com> wrote:

From: SAK

eklundjb, thank you VERY much for your post as calling FillAttributes() on my featureset as you suggested did the trick! I really appreciate you taking the time to post, it was a huge help.

Ted & Dan, thank you for your responses as well. I didn't mean to seem negative and I do appreciate you taking the time to respond. I have been developing (off and on) for close to 20 years and definitely understand the pros and cons of open source as you expressed them. I didn't realize how early in the development cycle DS is, and the progress made is impressive. As I said originally, I would like to do what we can to support your endeavors with dotSpatial and am interested in Dan's suggestion to help fund the documentation effort. I will contact you offline to discuss what we might be able to do.

Thanks again to all.

Steve

Read the full discussion online.

To add a post to this discussion, reply to this email (DotSpatial@discussions.codeplex.com)

To start a new discussion for this project, email DotSpatial@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com




--
Daniel P. Ames, Ph.D. PE
Associate Professor, Geosciences
Idaho State University - Idaho Falls
amesdani@isu.edu
geology.isu.edu
www.mapwindow.org


Developer
Jan 18, 2011 at 11:50 PM

I have added some documentation, which you can find at http://www.mapwindow.org/downloads/documentation/dotspatial/web-friendly/Index.html

Jan 18, 2011 at 11:55 PM

Thank you mudnug, that is truly a huge help!