ThinkGeo.com    |     Documentation    |     Premium Support

ExtentHelper.ToWorldCoordinate ScreenWidth and Height

ToWorldCoordinate and GetWorldDistanceBetweenTwoScreenPoints has a parameters called ScreenWidth and ScreenHeight that acording to my tests refers to WpfMap.ActualWidth and height instead of the real screen resolution. Is that OK?


I’m finding some troubles on showing a PopupOverlay on mouse click in a Feature



 Correct. You need to pass wpfMap.ActualWidth for ScreenWidth and wpfMap.ActualHeight for ScreenHeight in the ExtentHelper.GetWorldDistanceBetweenTwoScreenPoints function.


 Regarding your troubles for showing a PopupOverlay on Mouse Click on a Feature, I suggest you check out the Code Community sample, PopupOverlay. It shows how to implement that. wiki.thinkgeo.com/wiki/Map_Suite_Wp...es_Samples



Hi Val, 



I know the code example, I successfully shown a popup based on it when I was placing each LineShape on a different InMemoryFeatureLayer, but when I decided to plot all in the same Layer I start getting unacurate results:


 



 If I plot less LineShapes it seems to work again:




 I think that you need to look at the Code Community sample Get Feaures Clicked On wiki.thinkgeo.com/wiki/Map_Suite_Wp...Desktop.29. It is a desktop app but the logic that you will find for finding features within tolerance in screen coordinates can be applied to Wpf. Look at the code in the MapClick event handler, you will see how to get the nearest features from where the user clicked.



Hi Val, 
  
  I based my code example in this Code Community sample, please take a quick look to the code I posted, is the same (measure on screen distance for creating a buffer of x pixels and them GetFeaturesNearestTo. The thing works well with few Features on the Layer, but it fails when 80 Features are loaded. Please check it (you have a comment on the code I uploaded to load few or many Features and see the diference. See the pictures above to see that shows) 
  By the way, if I load one Feature in one different InMemoryFeatureLayer it works well (but has performance hit when loading 1000 Layers) 
  
 Carlos.

Hi Val, 



I based my code example in this Code Community sample, please take a quick look to the code I posted, is the same (measure on screen distance for creating a buffer of x pixels and them GetFeaturesNearestTo). The thing works well with few Features on the Layer, but it fails when 80 Features are loaded. Please check it, you have a comment on the code I uploaded to load few or all Features and see the diference. See the pictures above to see what it shows




By the way, if I load each Feature in one different InMemoryFeatureLayer it works well (but has performance hit when loading 1000 Layers) 



Carlos.



Hi Carlos, 



I checked our core assembly and found it is actually a bug for the method "GetFeaturesNearestTo". In the method, if the found feature in the buffer area is less than the limited count, we return the nearest features without the limited distance. This also explains why it works if you add all features into one InMemoryFeatureLayer. I have reported this issue to the core team. Please try the latest build tomorrow. 


Also, I modified one of your method like following, and it works fine too.


Private Function GetFeaturesOnScreenPos(ByVal ScreenPos As ScreenPointF) As Collection(Of Feature)
        Dim ScreenBufferSize As Integer = 5
        Dim selectedFeatures As New Collection(Of Feature)

        Try
            'Logic for converting screen coordinate values to world coordinate for the spatial query. Notice that the distance buffer for the spatial query
            'will change according to the zoom level while it remains the same for the screen buffer distance.
            Dim WorldPos As PointShape = ExtentHelper.ToWorldCoordinate(WpfMap1.CurrentExtent, ScreenPos.X, ScreenPos.Y, WpfMap1.ActualWidth, WpfMap1.ActualHeight)
            Dim bufferPointF As ScreenPointF = New ScreenPointF(ScreenPos.X + ScreenBufferSize, ScreenPos.Y)
            Dim distanceBuffer As Double = ExtentHelper.GetWorldDistanceBetweenTwoScreenPoints(WpfMap1.CurrentExtent, ScreenPos, bufferPointF, WpfMap1.ActualWidth, WpfMap1.ActualHeight, WpfMap1.MapUnit, DistanceUnit.Meter)
            Dim BufferedShape As MultipolygonShape = WorldPos.Buffer(distanceBuffer, WpfMap1.MapUnit, DistanceUnit.Meter)

            'Gets the track overlay
            Dim TracksOverlay As LayerOverlay = DirectCast(WpfMap1.Overlays("TracksOverlay"), LayerOverlay)
            Dim columnNames As Collection(Of String) = New Collection(Of String)
            columnNames.Add("ID")

            'Search in all the layers the features within the distance range
            For Each tmpFeatureLayer As FeatureLayer In TracksOverlay.Layers
                tmpFeatureLayer.Open()
                'Dim Features As Collection(Of Feature) = tmpFeatureLayer.FeatureSource.GetFeaturesNearestTo(WorldPos, WpfMap1.MapUnit, 5, columnNames, distanceBuffer, DistanceUnit.Meter)
                Dim Features As Collection(Of Feature) = tmpFeatureLayer.QueryTools.GetFeaturesIntersecting(BufferedShape.GetBoundingBox(), columnNames)
                For Each tmpFeature As Feature In Features
                    selectedFeatures.Add(tmpFeature)
                Next
                tmpFeatureLayer.Close()
            Next
        Catch
        End Try

        Return selectedFeatures
    End Function



Thanks for reporting. 

Howard



Thanks a lot for your prompt reply Howard. 



I still don't understand why it doesn't fail then only tracks 62,63,32,72 and 50 was added. They are in the same place than when all the tracks are added, but in this case they do not appear in the GetFeaturesNearestTo while when adding all the tracks they do.



Once the bug will be fixed, do you recommend me better to use this method again or is it GetFeaturesIntersercting more efective? 



Klaus:  



Posted By Klaus on 11-19-2010 10:28 AM  

Just some more notes on dynamically creating maptips, I see you are using GetFeaturesNearestTo. Sounds like you have success with this query method. For some strange reason, I could not get this to work reliably for me, so I ended up using Intersects, which posed its own challenges, some of them solved using predefined search tolerance levels based on map scale. As for mouse move, make sure you are using a Timer and not handling every single mouse move otherwise map performance will be compromised. This probably explains why your panning is taking that long.  



Your are a visioneer ;)  You said this method had its own challenges. Could you please share them with me?



Hi Howard, 
  
  I tested your method and works like a charm. Thanks a million. 
  
 Carlos.

Hi Carlos, 
  
 You are welcome. Just feel free to let us know if you have more queries. 
  
 Thanks, 
 Howard

Hi Howard, 



I still don't understand why it doesn't fail then only tracks 62,63,32,72 and 50 was added. They are in the same place than when all the tracks are added, but in this case they do not appear in the GetFeaturesNearestTo while when adding all the tracks they do. So it seems there is something more wrong in the function. 



Once the bug will be fixed, do you recommend me better to use this method again or is it GetFeaturesIntersercting more efective?



Hey Carlos,


Your idea of using GetFeaturesNearestTo is more robust for this particular scenario if you limit your result to 1. The challenge I faced with GetFeaturesIntersecting is that if more than one feature is returned, first item in list is not necessarily feature user clicked on.  I tried to solve this one by ordering features based on distance to buffer  but it did not quite work.  Also, I found GetFeaturesIntersecting  to be very sensitive to tolenance used to create buffered shape.


So, GetFeaturesNearestTo is what I am using now.  Thanks for the tip.


 


 



Hi Klaus, 
  
  Thanks to you for sharing your experience. 


Hi Carlos, 
  
 The old method implementation was wrong if the found count is less than the limit count. In this case, all nearest feature no matter if the feature is in or out side of the limit distance will be returned. I’m not sure if you have tried the latest Dll. If it still has issue, please let us know. Using GetFeaturesIntersercting is just a method similar like the one you used; I recommend use GetFeaturesNearestTo because of the sensitive for the GetFeaturesIntersecting. 
  
 Please let us know if you have more queries. 
  
 Thanks, 
 Howard 
  


Hi Howard, 
  
  Latest build works fine thanks a lot for the fast bugfix!!! 
  
  I understand the previous behaivor, but still don’t know why for a given screen point with nothing arround it was returning no feaures when only few features was added to the layer, and 5 when there were many, it would expect it would be consistent in both cases returning 5 (out of the buffer) features. Now it’s corrected and return none for the same screen point. 
  
 Carlos.

Hi Carlos, 
  
 That’s great that it fixes your issue. I’m not quite understand the issue you mentioned with the previous version. But any way, please let me know if you have more queries or provide me more information for the issue so that I can explain to you clearly. 
  
 Thanks, 
 Howard

    As it's working fine now with your fix, it doen't really mater why it was failing with the previous version of the dll, was just curiosity, don't loose time with it unless the answer is really simple and I'm missing something obvious.


 
 The issue was that having 100 LineShapes loaded for a given point on the screen it was returning 5 Features outside the buffer:



 


 
 This I understand as fulfills exactly your explanation of the issue (the buffer zone was not being taken in consideration if it was non features within it's size, so numberOfItemsToFind was returned even if they was outside the buffer)
 
 The freak behavior is when only this supposed nearest features was loaded (Tracks 62, 67, 32, 73 and 50 in the above picture), as I would expect the same issue given the same screen point, when in this case it returns none:
 

 
 As there is no features within the buffer limit, it should have returned the 5 nearest (the only 5 existing in this case)
 
 This test was commented in my posted code example:
 

'Plot a few                 If tmpLineFields(0) = "Track-62" Then InMemoryTrackFeatureLayer.InternalFeatures.Add(New Feature(LS.GetWellKnownText, tmpLineFields(0)))                 If tmpLineFields(0) = "Track-67" Then InMemoryTrackFeatureLayer.InternalFeatures.Add(New Feature(LS.GetWellKnownText, tmpLineFields(0)))                 If tmpLineFields(0) = "Track-32" Then InMemoryTrackFeatureLayer.InternalFeatures.Add(New Feature(LS.GetWellKnownText, tmpLineFields(0)))                 If tmpLineFields(0) = "Track-73" Then InMemoryTrackFeatureLayer.InternalFeatures.Add(New Feature(LS.GetWellKnownText, tmpLineFields(0)))                 If tmpLineFields(0) = "Track-50" Then InMemoryTrackFeatureLayer.InternalFeatures.Add(New Feature(LS.GetWellKnownText, tmpLineFields(0)))                  'Plot All                 'InMemoryTrackFeatureLayer.InternalFeatures.Add(New Feature(LS.GetWellKnownText, tmpLineFields(0)))





Hi Carlos, 
  
 I see; that’s easy to answer. I double checked the old code and found if the found features count is zero, we will return an empty collection. In another word, it works fine if the features count is less or equal to the numberOfItemsToFind. While if the found features count is greater than the limit, it works incorrect. I also checked there are some other issues in these overloads and we have fixed them. 
  
 Hope it makes sense. 
  
 Thanks, 
 Howard

Hi Howard, 
  
  I’m happy my question was helpful for finding more bugs to fix. 
  
  It still doesn’t make sense, as the features count should be the same in my both examples (zero), and in one instance it was returning numberOfItemsToFind outside the buffer, but in the other it was returning none. Anyway I don’t want to waste your time anymore on this issue as the bug is fixed and working really nice. 
  
  Thanks, 
  
 Carlos.

Hi Carlos, 
  
 You are welcome and thanks for reporting us bugs. 
  
 Just feel free to let us know if you have any more queries. 
  
 Thanks, 
 Howard