Dim classBreakRenderer As IClassBreaksRenderer = New ClassBreaksRenderer classBreakRenderer.Field = "LAST_ACTIVITY_DATE" classBreakRenderer.BreakCount = 2 classBreakRenderer.Break(0) = " < #" & DateTime.Now.AddYears(-5).ToShortDateString & "#" classBreakRenderer.Break(1) = " >= #" & DateTime.Now.AddYears(-5).ToShortDateString & "#"
Private Sub UniqueValuePointRenderer(ByVal pFL As IFeatureLayer, ByVal inFlag1 As String, ByVal inFlag2 As String) Try Dim pFClass As IFeatureClass = pFL.FeatureClass Dim pfeature As IFeature Dim pQF As IQueryFilter = New QueryFilter '' Set the where clause Dim tStr, pStr As String tStr = "FlagType = '" & inFlag1 & "'" pStr = "FlagType = '" & inFlag2 & "'" pQF.WhereClause = tStr Dim pFeatureSelection As IFeatureSelection pFeatureSelection = pFL pFeatureSelection.SelectFeatures(pQF, esriSelectionResultEnum.esriSelectionResultNew, False) pFeatureSelection.SelectionChanged() Dim pSelectionSet As ISelectionSet pSelectionSet = pFeatureSelection.SelectionSet Dim pFeatureCursor As IFeatureCursor pFeatureCursor = Nothing pSelectionSet.Search(Nothing, True, pFeatureCursor) Dim symd As SimpleMarkerSymbol symd = New SimpleMarkerSymbol symd.Style = esriSimpleMarkerStyle.esriSMSCircle symd.Size = 4 'Create unique value renderer Dim pUVRenderer As IUniqueValueRenderer pUVRenderer = New UniqueValueRenderer pUVRenderer.FieldCount = 1 pUVRenderer.Field(0) = "FlagType" pUVRenderer.DefaultSymbol = symd Dim pSym As ISimpleMarkerSymbol Dim col1, col2 As IRgbColor col1 = New RgbColor col1.Red = 145 col1.Green = 145 col1.Blue = 145 col2 = New RgbColor col2.Red = 200 col2.Green = 200 col2.Blue = 200 pfeature = pFeatureCursor.NextFeature Do Until pfeature Is Nothing pSym = New SimpleMarkerSymbol pSym.Style = esriSimpleMarkerStyle.esriSMSCircle pSym.Size = 4 pSym.Outline = True pSym.Color = col1 pUVRenderer.AddValue(pfeature.Value(pFClass.FindField("FlagType")), "", pSym) pfeature = pFeatureCursor.NextFeature Loop 'reset the where clause of the queryfilter pQF.WhereClause = pStr pFeatureSelection.SelectFeatures(pQF, esriSelectionResultEnum.esriSelectionResultNew, False) pFeatureSelection.SelectionChanged() pSelectionSet = pFeatureSelection.SelectionSet pfeature = Nothing pFeatureCursor = Nothing pSelectionSet.Search(Nothing, True, pFeatureCursor) pfeature = pFeatureCursor.NextFeature Do Until pfeature Is Nothing pSym = New SimpleMarkerSymbol pSym.Style = esriSimpleMarkerStyle.esriSMSCircle pSym.Size = 8 pSym.Outline = True pSym.Color = col2 pUVRenderer.AddValue(pfeature.Value(pFClass.FindField("FlagType")), "", pSym) pfeature = pFeatureCursor.NextFeature Loop Dim pGFLayer As IGeoFeatureLayer pGFLayer = pFL pGFLayer.Renderer = pUVRenderer Catch ex As Exception MsgBox(ex.ToString) End Try End Sub
Thanks jamesfreddyc, your solution almost worked...
The only issue with it is that it creates a symbol for each unique date which looks rather ugly in the TOC. Ultimately there should only be two symbols in the TOC; one for old features (> than 5 years old) and one for new features (<= 5 years old).
Is it still possible to achieve this using a UniqueValueRenderer?
huh. The code I provided does exactly that for me --- it symbolizes the point layer with ONLY 2 specific symbols that is based upon the values found in "FlagType". So if FlagType = 'x', then the point symbols were size 4 and if FlagType = 'Y' then the point symbols were size 8 (of course that's just a generalization).
Dim queryFilter As IQueryFilter = New QueryFilter ' Dim needsExcerciseFilter As String = "LAST_EXERCISE_DATE < TO_DATE('" & DateTime.Now.AddYears(-5).ToString("yyyy-MM-dd HH:mm:ss") & "', 'YYYY-MM-DD HH24:MI:SS')" Dim okExcerciseFilter As String = "LAST_EXERCISE_DATE >= TO_DATE('" & DateTime.Now.AddYears(-5).ToString("yyyy-MM-dd HH:mm:ss") & "', 'YYYY-MM-DD HH24:MI:SS')" queryFilter.WhereClause = needsExcerciseFilter Dim featSelection As IFeatureSelection = featLayer featSelection.SelectFeatures(queryFilter, esriSelectionResultEnum.esriSelectionResultNew, False) featSelection.SelectionChanged() Dim selectionSet As ISelectionSet = featSelection.SelectionSet Dim featCursor As IFeatureCursor = Nothing selectionSet.Search(Nothing, True, featCursor) Dim symd As New SimpleMarkerSymbol symd.Style = esriSimpleMarkerStyle.esriSMSCross symd.Size = 4 Dim uvRenderer As IUniqueValueRenderer = New UniqueValueRenderer uvRenderer.FieldCount = 1 uvRenderer.Field(0) = "LAST_EXERCISE_DATE" uvRenderer.DefaultSymbol = symd Dim sym As ISimpleMarkerSymbol = Nothing Dim col1, col2 As IRgbColor col1 = New RgbColor col1.Red = 255 col1.Green = 0 col1.Blue = 0 col2 = New RgbColor col2.Red = 0 col2.Green = 255 col2.Blue = 0 feature = featCursor.NextFeature Do Until feature Is Nothing sym = New SimpleMarkerSymbol sym.Style = esriSimpleMarkerStyle.esriSMSDiamond sym.Size = 4 sym.Outline = True sym.Color = col1 uvRenderer.AddValue(feature.Value(feature.Fields.FindField("LAST_EXERCISE_DATE")), "", sym) feature = featCursor.NextFeature() Loop queryFilter.WhereClause = okExcerciseFilter featSelection.SelectFeatures(queryFilter, esriSelectionResultEnum.esriSelectionResultNew, False) featSelection.SelectionChanged() selectionSet = featSelection.SelectionSet feature = Nothing featCursor = Nothing selectionSet.Search(Nothing, True, featCursor) feature = featCursor.NextFeature Do Until feature Is Nothing sym = New SimpleMarkerSymbol sym.Style = esriSimpleMarkerStyle.esriSMSSquare sym.Size = 4 sym.Outline = True sym.Color = col2 uvRenderer.AddValue(feature.Value(feature.Fields.FindField("LAST_EXERCISE_DATE")), "", sym) feature = featCursor.NextFeature Loop featSelection.Clear() featSelection.SelectionChanged() Dim geoFeatLayer As IGeoFeatureLayer = featLayer geoFeatLayer.Renderer = uvRenderer mapDoc.UpdateContents() mapDoc.ActiveView.Refresh()
One solution (just a first thought) is to add and populate another field (say you call it "Exercised") similar to the way I have implemented a "FlagType". Basically, you'd populate this field with values that can only be one of two things (strings): Exercised>5yrs, Exercised<5yrs
This would occur before any rendering would happen, so that when you do get to your rendering you could set your queryFilter to either of these strings and the renderer to this field as well:
Yeah I was thinking something like that as well. It would need to 'virtual' and populated by my code though because we don't want to add an extra (physical) column to our FeatureClass which would mean someone would need to update it periodically.
Is there a way using a DefinitionQuery or QueryDef to have some kind of an SQL CASE in the Fields property that returns a 'computed' column?