I have been getting a System.InvalidOperationException seemingly randomly while I am running my program. The additional information says: The FeatureSource is not open. Please call the Open Method before calling this method.
I am including my code below. It should be comprehensive enough to give you an idea of what I am doing or at least trying to do. Basically, I have a point layer displayed on the map, and I am drawing in a polygon layer. When the polygon layer finishes drawing, it looks for the nearest point and creates a highlight layer for it (inmemoryfeaturelayer). I am pulling attribute data from the point and joining it to the polygon. I am letting the user see which point is closest to their polygon shape by using the highlight layer. The highlight layer copies the point layer’s closest feature, and it creates a larger different color symbol to place over top of the closest feature. This part is done automatically.
I am trying to let me user select a different point if they decide they want to use a different feature. So, I have it set so they click on the visible dialog to change things around. I remove the normal map_click event that I had been using and add another one to route to my code below. I have been playing around with this and could not get it to crash the same way twice. I keep getting that exception; sometimes at 2 clicks on new features, other times at 30.
I saw something on your web application forms about a concurrency issue, but I would not know how to tackle that with WPF. Especially since I denote open and close methods anytime I am accessing a layer. I have been trying to trace it down using console messages, but it does not seem consistent when crashing. The one thing I did notice happens frequently even though I am not refreshing the map is Map Suite Trace: GoogleMapsLayer Request Image Count: * appearing in my console messages.
Any advice would be great. I am trying to provide you enough information without overwhelming you in my process here. I left most of it tact so it might have some other functions that either return shapefile names or something else. Those have been working for the most part. I am just confused on what is causing the exception since I haven’t been able to track it down. Thanks in advance!
001.
Private
Sub
ReselectJoinFeature(
ByVal
sender
As
Object
,
ByVal
e
As
ThinkGeo.MapSuite.WpfDesktopEdition.MapClickWpfMapEventArgs)
002.
Dim
newJoinFeature
As
Feature
003.
newJoinFeature =
New
Feature
004.
Dim
transferResults()
As
Object
005.
006.
'select the new feature, change the highlight layer
007.
newJoinFeature = SetNewJoinFeatureValue(e)
008.
009.
If
newJoinFeature IsNot
Nothing
Then
010.
'this next function just queries a database looking for fields/layer names that need to move attribute data
011.
'to/from
012.
transferResults = CheckForTransferValues(activeLayer.Name, valueTransferCollection(0).Name, newJoinFeature)
013.
014.
If
transferResults(4) <>
“”
Then
015.
valueTransferResult = transferResults(4)
016.
Else
017.
valueTransferResult =
""
018.
End
If
019.
Else
020.
Console.WriteLine(
“reselectjoinfeature is nothing”
)
021.
End
If
022.
End
Sub
023.
024.
025.
Private
Function
SetNewJoinFeatureValue(
ByVal
e
As
ThinkGeo.MapSuite.WpfDesktopEdition.MapClickWpfMapEventArgs)
As
Feature
026.
'I remove the original map click handler and add in a handler for this one. At this point, there is
027.
'already a point feature in the highlightoverlay that is shown on screen
028.
'the idea behind this is to click another point on the map to change the selection and also
029.
'change which feature is 'highlighted’
030.
'I am just overlapping the original feature with the highlightoverlay
031.
Dim
featureCollection
As
Collection(Of Feature)
032.
Dim
joiningLayerName
As
String
033.
Dim
tempAttributeLayer()
As
String
034.
Dim
newFeature
As
Feature
035.
Dim
joinLayer
As
ShapeFileFeatureLayer
036.
Dim
shapeType
As
ShapeFileType
037.
038.
'these next four lines are just there to grab a name for the target shapefile for the highlight overlay
039.
'they run into some functions that just adjust what name we are referring to from our database
040.
tempAttributeLayer = Split(txtSpJoinLayer.Text,
“:”
)
041.
joiningLayerName = tempAttributeLayer(1).Trim
042.
joiningLayerName = ReturnInternalNameFromUserName(joiningLayerName)
043.
joinLayer = ReturnShapefileFromLayerName(joiningLayerName)
044.
045.
joinLayer.Open()
046.
joinLayer.FeatureSource.Open()
047.
048.
shapeType = joinLayer.GetShapeFileType
049.
050.
joinLayer.FeatureSource.Close()
051.
joinLayer.Close()
052.
053.
'this function should return a collection (of 1 feature)
054.
'pass in the mouse click location and the name of the layer we are looking for
055.
featureCollection = SelectFeatures(e, joiningLayerName)
056.
057.
''assign the feature to a feature variable
058.
If
featureCollection IsNot
Nothing
Then
059.
If
featureCollection.Count > 0
Then
060.
newFeature =
New
Feature
061.
newFeature = featureCollection.Item(0)
062.
'if we were able to select a feature, it will be passed into the sub to add it to the highlight overlay
063.
CreateHighlightFeature(shapeType, newFeature)
064.
065.
'select and return something
066.
Return
newFeature
067.
End
If
068.
End
If
069.
Return
Nothing
070.
071.
End
Function
072.
073.
074.
Private
Function
SelectFeatures(
ByVal
e
As
ThinkGeo.MapSuite.WpfDesktopEdition.MapClickWpfMapEventArgs,
Optional
ByVal
targetLayer
As
String
=
Nothing
)
As
Collection(Of Feature)
075.
076.
Dim
selectedfeatures
As
Collection(Of Feature)
077.
Dim
box
As
RectangleShape
078.
Dim
xAdjust
As
Double
079.
Dim
xOverlay
As
New
LayerOverlay()
080.
Dim
xFeature1
As
New
Feature
081.
082.
xlayer = ReturnShapefileFromLayerName(targetLayer)
083.
084.
'we are using a function here to try to ascertain the current zoom level in order to make a size appropriate
085.
'box to grab a feature
086.
Select
Case
GetZoomLevel(WpfMap_Main)
087.
Case
1
To
5
088.
xAdjust = 10000
089.
Case
6
To
7
090.
xAdjust = 5000
091.
Case
8
092.
xAdjust = 4000
093.
Case
9
094.
xAdjust = 3000
095.
Case
10
096.
xAdjust = 2000
097.
Case
11
098.
xAdjust = 450
099.
Case
12
100.
xAdjust = 300
101.
Case
13
102.
xAdjust = 100
103.
Case
14
104.
xAdjust = 60
105.
Case
15
106.
xAdjust = 30
107.
Case
16
108.
xAdjust = 20
109.
Case
17
110.
xAdjust = 10
111.
Case
18
112.
xAdjust = 5
113.
Case
19
114.
xAdjust = 2
115.
Case
20
116.
xAdjust = 1
117.
End
Select
118.
119.
'here we create that box
120.
box =
New
RectangleShape(e.WorldX - xAdjust, e.WorldY + xAdjust, e.WorldX + xAdjust, e.WorldY - xAdjust)
121.
122.
xlayer.Open()
123.
xlayer.FeatureSource.Open()
124.
If
xlayer.GetShapeFileType = ShapeFileType.Point
Then
125.
selectedfeatures = xlayer.QueryTools.GetFeaturesWithin(box, ReturningColumnsType.AllColumns)
126.
Else
'xlayer.GetShapeFileType = ShapeFileType.Polygon in this case - need to add functionality for lines, etc depending on what kind of selection method we want
127.
selectedfeatures = xlayer.QueryTools.GetFeaturesIntersecting(box, ReturningColumnsType.AllColumns)
128.
End
If
129.
xlayer.FeatureSource.Close()
130.
xlayer.Close()
131.
132.
If
selectedfeatures.Count > 0
Then
133.
Return
selectedfeatures
134.
Else
135.
Return
Nothing
136.
End
If
137.
138.
139.
140.
End
Function
141.
142.
Private
Sub
CreateHighlightFeature(
ByVal
shapeType
As
ShapeFileType,
ByVal
newFeature
As
Feature)
143.
144.
'since I am running this sub repeatedly and I only want one feature shown in the highlight overlay
145.
'I first check the overlay’s featurelayer (highlightfeaturelayer) for content and clear it
146.
'remove inmemoryfeaturelayer features
147.
highlightFeatureLayer.Open()
148.
highlightFeatureLayer.FeatureSource.Open()
149.
150.
If
highlightFeatureLayer.InternalFeatures.Count > 0
Then
151.
highlightFeatureLayer.InternalFeatures.Clear()
152.
End
If
153.
154.
highlightFeatureLayer.FeatureSource.Close()
155.
highlightFeatureLayer.Close()
156.
157.
'here I take the shapetype that was passed in from newFeature’s shapefile to determine symbology
158.
Select
Case
(shapeType)
159.
Case
ShapeFileType.Point
160.
highlightFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = PointStyles.CreateSimpleCircleStyle(GeoColor.StandardColors.GhostWhite, 8, GeoColor.StandardColors.Black)
161.
Case
ShapeFileType.Polygon
162.
highlightFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.CreateSimpleAreaStyle(GeoColor.StandardColors.GhostWhite, GeoColor.StandardColors.Black, 3)
163.
Case
ShapeFileType.Polyline
164.
highlightFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = LineStyles.CreateSimpleLineStyle(GeoColor.StandardColors.GhostWhite, 3,
True
)
165.
166.
End
Select
167.
168.
'the rest of this should be generic enough to have here instead of in the select case
169.
highlightFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20
170.
highlightFeatureLayer.Open()
171.
highlightFeatureLayer.FeatureSource.Open()
172.
highlightFeatureLayer.FeatureSource.BeginTransaction()
173.
highlightFeatureLayer.FeatureSource.AddFeature(newFeature)
174.
highlightFeatureLayer.FeatureSource.CommitTransaction()
175.
highlightFeatureLayer.FeatureSource.Close()
176.
highlightFeatureLayer.Close()
177.
178.
highlightOverlay.Layers.Add(highlightFeatureLayer)
179.
180.
'the highlightOverlay was added to the map during initialization so I am only adjusting its contents
181.
'with this sub
182.
183.
WpfMap_Main.Refresh()
184.
185.
originalTransferValueFeature(2) = shapeType
186.
187.
End
Sub
188.
189.
Private
Function
ReturnShapefileFromLayerName(
ByVal
layerName
As
String
)
As
ShapeFileFeatureLayer
190.
If
layerName <>
“”
Then
191.
192.
193.
Dim
overlayCollection
As
New
Collection(Of LayerOverlay)
194.
Dim
layerCollection
As
New
Collection(Of ShapeFileFeatureLayer)
195.
196.
overlayCollection.Clear()
197.
layerCollection.Clear()
198.
199.
'need to build a collection of work layers and basemap layers
200.
201.
For
i
As
Integer
= 0
To
WpfMap_Main.Overlays.Count - 1
Step
1
202.
'Console.WriteLine(WpfMap_Main.Overlays.Item(i).ToString)
203.
If
WpfMap_Main.Overlays(i).
GetType
.ToString =
“ThinkGeo.MapSuite.WpfDesktopEdition.LayerOverlay”
Then
204.
205.
overlayCollection.Add(WpfMap_Main.Overlays(i))
206.
207.
End
If
208.
Next
209.
210.
For
i
As
Integer
= 0
To
overlayCollection.Count - 1
Step
1
211.
212.
For
j
As
Integer
= 0
To
overlayCollection.Item(i).Layers.Count - 1
Step
1
213.
214.
'Console.WriteLine(overlayCollection.Item(i).Layers(j).GetType().ToString)
215.
overlayCollection.Item(i).Layers(j).Open()
216.
If
overlayCollection.Item(i).Layers(j).
GetType
.ToString =
“ThinkGeo.MapSuite.Core.ShapeFileFeatureLayer”
Then
217.
overlayCollection.Item(i).Layers(j).Close()
218.
layerCollection.Add(overlayCollection.Item(i).Layers(j))
219.
End
If
220.
Next
221.
222.
Next
223.
224.
For
i
As
Integer
= 0
To
layerCollection.Count - 1
Step
1
225.
If
layerCollection.Item(i).Name = layerName
Then
226.
Return
layerCollection.Item(i)
227.
228.
End
If
229.
230.
Next
231.
Return
Nothing
232.
233.
Else
234.
Return
Nothing
235.
End
If
236.
End
Function