using shapefilecolorscheme

Mar 27, 2011 at 1:57 AM

Im trying to use the shapefilecolorscheme to change the color of road types within a shapefile. here is my code so far:

For Each a In sf_list
            Dim shapefile As MapWinGIS.Shapefile = New MapWinGIS.Shapefile
            Dim colorscheme As MapWinGIS.ShapefileColorScheme = New MapWinGIS.ShapefileColorScheme
            Dim table As MapWinGIS.Table = New MapWinGIS.Table

            shapefile.Open(curdir & "\shapefiles\" & a)
            table.Open(curdir & "\shapefiles\" & a.Substring(0, a.Length() - 5) & ".dbf")
            ihandler = AxMap1.AddLayer(shapefile, True)
            colorscheme.LayerHandle = ihandler

            For Each vp As Generic.KeyValuePair(Of String, String) In shp_attr_array
                parse5 = vp.Key.Trim.Split(":")
                If a = parse5(0).Trim Then
                    If InStr(parse5(1).Trim, "A", CompareMethod.Text) Then
                        parse6 = vp.Value.Split(":")
                        Dim colorbreak As MapWinGIS.ShapefileColorBreak = New MapWinGIS.ShapefileColorBreak
                        Dim cfccfield As String
                        Dim field As MapWinGIS.Field = New MapWinGIS.Field

                        colorbreak.StartValue = parse5(1)
                        colorbreak.EndValue = parse5(1)

                        If parse5(1).Trim.Length = 2 Then
                            cfccfield = "CFCC2"
                        Else
                            cfccfield = "CFCC"
                        End If

                        For b = 1 To table.NumFields
                            field = table.Field(b)
                            If field.Name = cfccfield.Trim Then
                                colorscheme.FieldIndex = b
                            End If
                        Next

                        If parse6(0).Trim = "red" Then
                            colorbreak.StartColor = red
                            colorbreak.EndColor = red
                            colorscheme.Add(colorbreak)
                        End If
                        shapefile.VisibilityExpression = "[CFCC2] = 'A1'"

                    End If
                End If
            Next
            AxMap1.ApplyLegendColors(colorscheme)
        Next

The code loops through a list of shp names, opens it, and creates a layer for it. These are road shps so I want to change the color of the A1 roads to red and display only those roads. so far with this code the road color is not changed. Is there something wrong here?

Developer
Mar 27, 2011 at 1:19 PM

You should use Shapefile.ShapefileCategories class instead of ColorBreaks.  Just add categories with different colors in the same way you have added ColorBreaks.

Then loop through the table records and set Shapefile.ShapeCategory(Index) property based upon the values in the table.

Also consider using Shapefile.ShapefileCategories.Generate method for automatic generation of categories.

It's obvious lack of documentation on the subject. I plan to write some in the next month.

Mar 27, 2011 at 7:04 PM

Not sure if I fully understand but here is what I have after your post. Its still not displaying right so let me know if you see anything that is wrong. Thank you.

For Each a In sf_list
            Dim shapefile As MapWinGIS.Shapefile = New MapWinGIS.Shapefile
            'Dim colorscheme As MapWinGIS.ShapefileColorScheme = New MapWinGIS.ShapefileColorScheme
            Dim table As MapWinGIS.Table = New MapWinGIS.Table
            Dim shp_caties As MapWinGIS.ShapefileCategories = New MapWinGIS.ShapefileCategories

            shapefile.Open(curdir & "\shapefiles\" & a)
            table.Open(curdir & "\shapefiles\" & a.Substring(0, a.Length() - 5) & ".dbf")
            ihandler = AxMap1.AddLayer(shapefile, True)

            For Each vp As Generic.KeyValuePair(Of String, String) In shp_attr_array
                parse5 = vp.Key.Trim.Split(":")
                If a = parse5(0).Trim Then
                    If InStr(parse5(1).Trim, "A", CompareMethod.Text) Then
                        parse6 = vp.Value.Split(":")
                        Dim cfccfield As String
                        Dim field As MapWinGIS.Field = New MapWinGIS.Field
                        Dim shp_cat As MapWinGIS.ShapefileCategory = New MapWinGIS.ShapefileCategory
                        Dim shp_draw As MapWinGIS.ShapeDrawingOptions = New MapWinGIS.ShapeDrawingOptions

                        If parse5(1).Trim.Length = 2 Then
                            cfccfield = "CFCC2"
                        Else
                            cfccfield = "CFCC"
                        End If

                        For b = 1 To table.NumFields
                            field = table.Field(b)
                            If field.Name = cfccfield.Trim Then

                            End If
                        Next
                 
                        If parse6(0).Trim = "red" Then
                            shp_draw.LineColor = red
                            shp_draw.LineWidth = parse6(2)
                            shp_cat.Expression = "[" & cfccfield & "] = " & parse5(1).Trim
                            shp_cat.Name = parse5(0).Trim
                            shp_cat.DrawingOptions = shp_draw
                            shp_caties.Add(parse5(0).Trim)

                        End If
                    End If
                    AxMap1.set_LayerVisible(ihandler, True)
                    AxMap1.set_ShapeLayerFillTransparency(ihandler, 0)
                End If
            Next
        Next

Developer
Mar 28, 2011 at 12:05 PM

After adding all the categories you need to call ShapefileCategories.ApplyExpressions().

Also don't call AxMap1.set_ShapeLayerFillTransparency. All the options should be set through Categories/ShapeDrawingOptions class.

The older properties were left for compatibility only.

Here is a sample.

        private void btnCategories_Click(object sender, EventArgs e)
        {
            MapWinGIS.Shapefile sf = new MapWinGIS.Shapefile();
            openFileDialog1.Filter = sf.CdlgFilter;
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                if (sf.Open(openFileDialog1.FileName, null))
                {
                    sf.DefaultDrawingOptions.FillColor = Convert.ToUInt32(ColorTranslator.ToOle(Color.LightYellow));

                    ShapefileCategory cat = sf.Categories.Add("First");
                    cat.Expression = "[Area] > 1000 and [FEMALES] > [MALES]";
                    cat.DrawingOptions.FillColor = Convert.ToUInt32(ColorTranslator.ToOle(Color.Pink));

                    cat = sf.Categories.Add("Second");
                    cat.Expression = "[Area] > 10^3 AND [Area] <= 10^4";
                    cat.DrawingOptions.FillColor = Convert.ToUInt32(ColorTranslator.ToOle(Color.LightBlue));

                    cat = sf.Categories.Add("Third");
                    cat.Expression = "(([DIVORCED] + [NEVERMARRY]) * 2 + ([SEPARATED] + [WIDOWED]) / 2) > [MARRIED]";
                    cat.DrawingOptions.FillColor = Convert.ToUInt32(ColorTranslator.ToOle(Color.LightGreen));

                    sf.Categories.ApplyExpressions();
                    axMap2.AddLayer(sf, true);
                    axMap2.Redraw();
                }
            }
        }

Mar 28, 2011 at 10:33 PM

thank you for the help. Im still have troubles though. Im trying to give the lines the defaultdrawingoption = green but when I display the shapefile all I get is gray. Any ideas?

For Each a In sf_list
            Dim shapefile As MapWinGIS.Shapefile = New MapWinGIS.Shapefile
            Dim shp_cat As MapWinGIS.ShapefileCategory = New MapWinGIS.ShapefileCategory

            shapefile.Open(curdir & "\shapefiles\" & a)
            shapefile.DefaultDrawingOptions.FillVisible = False

            For Each vp As Generic.KeyValuePair(Of String, String) In shp_attr_array
                parse5 = vp.Key.Trim.Split(":")
                If a = parse5(0).Trim Then

                    If parse5(1).Trim = "color" Then
                        If vp.Value = "red" Then
                            shapefile.DefaultDrawingOptions.LineColor = red
                        ElseIf vp.Value = "black" Then
                            shapefile.DefaultDrawingOptions.LineColor = black
                        ElseIf vp.Value = "yellow" Then
                            shapefile.DefaultDrawingOptions.LineColor = yellow
                        ElseIf vp.Value = "green" Then
                            shapefile.DefaultDrawingOptions.LineColor = green
                        ElseIf vp.Value = "blue" Then
                            shapefile.DefaultDrawingOptions.LineColor = blue
                        ElseIf vp.Value = "purple" Then
                            shapefile.DefaultDrawingOptions.LineColor = purple
                        ElseIf vp.Value = "white" Then
                            shapefile.DefaultDrawingOptions.LineColor = white
                        ElseIf vp.Value = "tan" Then
                            shapefile.DefaultDrawingOptions.LineColor = tan
                        End If
                    ElseIf parse5(1).Trim = "width" Then
                        shapefile.DefaultDrawingOptions.LineWidth = Int(Val(vp.Value))
                    End If
                End If
            Next
            ihandler = AxMap1.AddLayer(shapefile, True)
        Next

Developer
Mar 28, 2011 at 10:45 PM

And what is red, tan, green, etc? Are they really OLE colors? Green should be something like 65280 (255 + 255^2).

Mar 28, 2011 at 11:09 PM

green = System.Convert.ToInt32(RGB(80, 240, 120))

I have also tried the call:

shapefile.DefaultDrawingOptions.LineColor = Convert.ToUInt32(ColorTranslator.ToOle(Color.Green))

while gray still showing up.

Developer
Mar 29, 2011 at 2:06 AM
Edited Mar 29, 2011 at 2:07 AM

Ok. It appears that's not the case.  But after looking at your code more closely, I can see other issues.

It rather should be something like this (in loose VB.NET notation):

sf.DefaultDrawingOptions.LineColor = SOME_COLOR    ' for shapes that don't fall into any category

 

' variant 1 without expressions

' ----------------------------------------------------------

' adding categories

dim cat as ShapefileCategory

cat = sf.Categories.Add("Red");

cat.LineColor = ConvertToOle(Color.Red);

cat = sf.Categories.Add("Green");

cat.LineColor = ConvertToOle(Color.Green);

' now we determine which shape belongs to which category

for i as integer = 0 to sf.numShapes - 1

 dim s as string = sf.get_cellValue(i, ...);  ' some value from table

 if val = "red" then

sf.ShapeCategory(i) = 0    ' the index of the red category, 0 - because it was added first

elseif val = "green" then

sf.ShapeCategory(i) = 1    ' the index of the green category

end if

next i

 

' variant 2 with expressions

' ----------------------------------------------------------

dim cat as ShapefileCategory

cat = sf.Categories.Add("Red");

cat.LineColor = ConvertToOle(Color.Red);

cat.Expression = "[ColorField] = "red""    ' ColorField - the name of the field in the attribute table

cat = sf.Categories.Add("Green");

cat.LineColor = ConvertToOle(Color.Green);

cat.Expression = "[ColorField] = "green""

sf.ApplyExpressions() ' in this line MapWinGIS loop through the shapes and changes their Shapefile.ShapeCategory property

' in the same manner we did it manually in variant 1.