ThinkGeo.com    |     Documentation    |     Premium Support

Omitting features from being drawn or handling by attribute

For a particular scenario, if I would like to omit a feature from being drawn based on a match or mismatch of data. There is a column named "TOWN" and if the value says "IPSWICH" I want the layer not to be drawn. I would like the ability to easily add columns and criteria to match mismatch etc.


 


Currently, the example requires adding event handlers on a per layer basis, which isn't lending itself to scalability and configurability all that well.  Is there another method of obtaining this goal? A lot of similar products do offer this type of functionality, sometimes under the term "Definition Query" or some free products offer this functionality with regular expressions but I'm not sure either apply to your component.


 


Thanks,



Nelson, 



Yes, you can use the Regular expressions in our product, that’s RegexStyle. 

RegexStyle is the style that is applied to the features which match the regular expression you provide. You can specify the expression to exclude the features you don’t want to draw for this case, see the code below for example. 




Dim regexStyle As New RegexStyle() 
regexStyle.ColumnName = "TOWN" 
regexStyle.RegexItems.Add(New RegexItem("[^(IPSWICH)]", PointStyles.City3)) 

Dim citiesLayer As New ShapeFileFeatureLayer(MapPath("~/data.shp")) 
citiesLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(regexStyle) 
citiesLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20 
Map1.StaticOverlay.Layers.Add("CityLayer", citiesLayer)





Ben 

 



I am trying to write a function that returns a RegExStyle(), I am running into a problem with RegexItem, however. For styles, it looks as though it takes all of the available styles (Area, Text, Line, and Point) but only if they are explicitly designated.


I thought that Style was an interface for this and that I could insert interchangeably any of these styles into the RegExItem but this is not the case. If I specify layerStyle as Style, I get errors of "Overload resolution failed because no accessible 'New' can be found without a narrowing conversion".


I understand why this error is occuring but am wondering if this can be changed or worked around effectively. I do not really want to have to manually overload my function just for the same of addressing these four style types if nothing functionally even changes...


Is there an interface for all of the different 'Styles' or must I overload my function several times to address this? Is this intentional or inadvertant?


    Public Shared Function CreateRegExStyleFromLID(ByVal LayerID As Integer, ByVal connString As String, ByVal layerStyle As AreaStyle) As RegexStyle
        Dim strSQLForStyle As String = "EXEC sp_GetRegExFromLID " & LayerID
        Dim conn As New SqlConnection(connString)

        conn.Open()

        Dim readerStyle As SqlDataReader
        Dim cmdStyle As New SqlCommand(strSQLForStyle, conn)

        readerStyle = cmdStyle.ExecuteReader()

        Dim regexCustomStyle As New RegexStyle

        Dim X As Integer

        Try

            If readerStyle.HasRows Then
                While readerStyle.Read()
                    If X = 0 Then regexCustomStyle.ColumnName = readerStyle.Item("ColumnName")
                    'continue here
                    regexCustomStyle.RegexItems.Add(New RegexItem(readerStyle.Item("RegularExpression"), layerStyle))
                    X += 1
                End While

                CreateRegExStyleFromLID = regexCustomStyle
            Else
                CreateRegExStyleFromLID = Nothing
            End If

        Catch ex As SqlException
            'MsgBox(ex.Message)
            CreateRegExStyleFromLID = Nothing
        Finally
            If Not readerStyle Is Nothing Then readerStyle.Close()
            If Not conn Is Nothing Then conn.Close()
        End Try
    End Function


Also, I noticed when adding multiple Items to the RegexItems, all of my expressions become ignored... If only one expression is entered, it is honored. The two items for example are [^(LYNN)] and [^(NAHANT)]

Why is this? I would ideally like to be able to stack expressions

Nelson, 
  
 Sure you can pass the abstract Style to a RegexItem, you need to add a style to a collection, and pass it to RegexItem. Code will be like this: 
  
 
Dim customStyles As Collection (Of Style) = New Collection (Of Style) ()
customStyles.Add(layerStyle)
regexCustomStyle.RegexItems.Add(New RegexItem(readerStyle.Item("RegularExpression"), customStyles))                 
 
  
 The reason of that is for the normal users, they will only use the predefined styles (Point, Text, Area and Line). So we have 4 overloads for each styles to make it easier to use. If a people want to pass in a custom Style, he must be an advanced user with some advanced scenarios, then maybe it’s better we provide a collection of Styles which can handle the most advanced scenario. We cannot provide an overload which only accepts one Style, in that case if user input a PointStyle, we have no idea which overloads method he(she) is using. 
  
 The relationship between RegexItems are “OR”, not “AND”. The feature will be drawn even only one condition meets. For your case, the Feature “LYNN” doesn’t meet the condition [^(LYNN)]  but meets the condition [^(NAHANT)], so it will still be draw.  To make it easier, let’s say the 2 RegexItems are LYNN and NAHANT, the result is only the 2 towns are displayed, that makes sense right? It has the same reason behind that feature “NAHANT” doesn’t meet the first condition but meets the second, so it is displayed. 
  
 Let me know for any queries. 
  
 Ben  


Brian,


I will only be using the four preset types of styles, I think. At least at this point those are about all I have used. I would like to createthe RegExStyle Generating function to accept any of these four styles without having to replicate this function four times for each different type. I think you understood what I meant but I just wanted to clarify just in case.


I understood you to recommend using the collection of styles as an input and add any of the four styles mentioned above into the collection to acheive this. Unfortunately, this is causing my layer not to draw at all.


This code is the function definition:


    Public Shared Function CreateRegExStyleFromLID(ByVal LayerID As Integer, ByVal connString As String, ByVal layerStyle As Collection(Of Style)) As RegexStyle
        Dim strSQLForStyle As String = "EXEC sp_GetRegExFromLID " & LayerID
        Dim conn As New SqlConnection(connString)

        conn.Open()

        Dim readerStyle As SqlDataReader
        Dim cmdStyle As New SqlCommand(strSQLForStyle, conn)

        readerStyle = cmdStyle.ExecuteReader()

        Dim regexCustomStyle As New RegexStyle

        Dim X As Integer

        Try

            If readerStyle.HasRows Then
                While readerStyle.Read()
                    If X = 0 Then regexCustomStyle.ColumnName = readerStyle.Item("ColumnName")
                    'continue here
                    regexCustomStyle.RegexItems.Add(New RegexItem(readerStyle.Item("RegularExpression"), layerStyle))
                    X += 1
                End While

                CreateRegExStyleFromLID = regexCustomStyle
            Else
                CreateRegExStyleFromLID = Nothing
            End If

        Catch ex As SqlException
            'MsgBox(ex.Message)
            CreateRegExStyleFromLID = Nothing
        Finally
            If Not readerStyle Is Nothing Then readerStyle.Close()
            If Not conn Is Nothing Then conn.Close()
        End Try
    End Function


This code is the implementation:


                                With layerToAdd.ZoomLevelSet.GetZoomLevels(layerZoomOn)
                                    Select Case layerPolyType
                                        Case "LINE"
                                            Dim layerStyle As New LineStyle()
                                            layerStyle.InnerPen.Color = layerLineColor
                                            layerStyle.InnerPen.Width = layerLineWidth

                                            layerStyleCollection.Add(layerStyle)
                                            Dim layerRegExStyle As New RegexStyle()
                                            layerRegExStyle = CreateRegExStyleFromLID(layerID, connStr, layerStyleCollection)
                                            layerStyleCollection.Clear()

                                            .CustomStyles.Add(layerRegExStyle)


                                        Case "POLYGON"
                                            Dim layerStyle As New AreaStyle()
                                            layerStyle = AreaStyles.CreateSimpleAreaStyle(layerAreaFill)
                                            layerStyle.OutlinePen.Color = layerOutlineColor
                                            layerStyle.OutlinePen.Width = layerOutlineWidth

                                            layerStyleCollection.Add(layerStyle)
                                            Dim layerRegExStyle As New RegexStyle()
                                            layerRegExStyle = CreateRegExStyleFromLID(layerID, connStr, layerStyleCollection)
                                            layerStyleCollection.Clear()

                                            .CustomStyles.Add(layerRegExStyle)
                                    End Select


While it isn't included in the tiny snippet of code supplied, there is an ApplyUntilZoomLevel call and any layer that does not utilize RegEx works fine. No exceptions raise and the Regular Expressions are unchanged.



Nelson, 
  
 The LayerStyleCollection should not be cleared. As it has been related with RegexExStyle BY REFERENCE, clearing the separate LayerStyleCollection also means clearing the style collection within the layerRegExStyle. Comment out the “Clear” statement and everything will be fine.  
  
 
With layerToAdd.ZoomLevelSet.GetZoomLevels(layerZoomOn)
         Select Case layerPolyType
              Case “LINE”
                  Dim layerStyle As New LineStyle()
                  layerStyle.InnerPen.Color = layerLineColor
                  layerStyle.InnerPen.Width = layerLineWidth

                  layerStyleCollection.Add(layerStyle)
                  Dim layerRegExStyle As New RegexStyle()
                  layerRegExStyle = CreateRegExStyleFromLID(layerID, connStr, layerStyleCollection)
                  'layerStyleCollection.Clear() 'Comment out this line

                  .CustomStyles.Add(layerRegExStyle)

             Case “POLYGON”
                   Dim layerStyle As New AreaStyle()
                   layerStyle = AreaStyles.CreateSimpleAreaStyle(layerAreaFill)
                   layerStyle.OutlinePen.Color = layerOutlineColor
                   layerStyle.OutlinePen.Width = layerOutlineWidth

                   layerStyleCollection.Add(layerStyle)
                   Dim layerRegExStyle As New RegexStyle()
                   layerRegExStyle = CreateRegExStyleFromLID(layerID, connStr, layerStyleCollection)
                   'layerStyleCollection.Clear() 'Comment out this line

                   .CustomStyles.Add(layerRegExStyle)
          End Select
 
  
 Ben.

Excellent. Thanks again and Happy Hoidays!



The same to you! Merry Christmas and Happy New Year!