ThinkGeo.com    |     Documentation    |     Premium Support

v2.x to v3.x SpatialQuery and DistanceQuery

Hello, all


I'd like to input lon/lat and search information about county and road.

In v2.x, I used spatialQuery and QueryByDistance to search where lon/lat in.

But, in v3.x RC2, it is many different. 

could someone help me?


In v3.x :

value = instance.SpatialQuery(targetShape, queryType, returningColumnNamesType)

    

instance is a feacureSource...I don't know what's it mean. How could I use it?

the follows code is error:


  Dim county_layer As ShapeFileFeatureLayer = DirectCast(WinformsMap1.FindFeatureLayer("county"), ShapeFileFeatureLayer)

  results = town_layer.QueryTools.GetFeaturesWithin(testpoint, ReturningColumnsType.AllColumns)

  

in v2.x, I write as belows:


'(county search)

Dim testpoint = New PointShape(longitude, latitude)

intRecID = Map1.Layers(2).SpatialQuery(testpoint, SpatialQueryContainment.Contained) 'county

If intRecID.Length > 0 Then

    str_county = Map1.Layers(2).DataQuery(intRecID(0), "COUNTYNAME")

End If

 

'(road search)

        intRecID2 = Map1.Layers(13).QueryByDistance(testpoint, 10, MapLengthUnits.metres, Map1.MapUnit) 'road

        Dim mPointShape = New PointShape(longitude, latitude)

        Dim items As New Dictionary(Of Integer, Double)()

        Dim distances As New List(Of Double)()

        Dim diss(intRecID2.Length - 1) As Double


        If intRecID2.Length > 0 Then

            For j As Integer = 0 To intRecID2.Length - 1

                diss(j) = mPointShape.DistanceTo(Map1.Layers(13).GetShape(intRecID2(j)), Map1.MapUnit, MapLengthUnits.miles, DistanceTypes.Shortest)

                items.Add(intRecID2(j), diss(j))

                distances.Add(diss(j))

            Next

        End If


        Dim firstRecord As Integer = 0

        Dim firstvalue As Double


        If (intRecID2.Length > 0) Then

            distances.Sort()

            firstvalue = distances(0)

            For j As Integer = 0 To intRecID2.Length - 1

                If items(intRecID2(j)) = firstvalue Then

                    firstRecord = intRecID2(j)

                End If

            Next


            str_road = Map1.Layers(13).DataQuery(firstRecord, "roadname")

                                

        End If



Carol, 
  
 FeatureSource is an abstract class in MapSuite3.0, I guess you’re working on .shp file, so you can define a concrete class ShapeFileFeatureSource as instance. 
 Dim instance as ShapeFileFeatureSource = New ShapeFileFeatureSource(shapePathFilename) 
  
 About the error, can you tell me the detail for the error? And I feel your code is not completely, because at the first line, you define a county_layer and assign value, but at the second line, you use another variable town_layer. I know you know this code can not work.  
  
 We have a sample for demonstrating how to use Spatial Query in HowDoI samples. You can find it at “Querying Feature Layers” catalog and the second sample called SpatialQueryAFeatureLayer, hope this is going to be help you. 
  
 Please let me know if you have more questions. 
  
 Thanks. 
  
 James  


Thanks for your reply, James 
  
 Sorry, I copy wrong code. But, code still wrong as belows.:( 
  
 Q1. What is difference between SpatialQuery and GetFeaturesWithin?  
 Spatial Query in HowDoI samples is use GetFeaturesWithin to query data, but I still can’t understand why it doesn’t use SpatialQuery? 
 I’d like to get information about town name and road name and didn’t show which area contained. 
  
 'use SpatialQuery 
 Dim testpoint As New InMemoryFeatureLayer() 
 testpoint.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20 
 testpoint.InternalFeatures.Add(“Point”, New Feature(New PointShape(longitude, latitude))) 
 Dim spatialQueryResultOverlay As New LayerOverlay() 
 spatialQueryResultOverlay.Layers.Add(“Point”, testpoint) 
 Dim pointQuery As InMemoryFeatureLayer = DirectCast(WinformsMap1.FindFeatureLayer(“Point”), InMemoryFeatureLayer) 
 Dim spatialQueryResults As Collection(Of Feature) 
 Dim town_layer As ShapeFileFeatureSource = New ShapeFileFeatureSource(“D:\GIS\town.shp”) 
 spatialQueryResults = town_layer.SpatialQuery(pointQuery, QueryType.Contains, ReturningColumnsType.AllColumns) 
  
 'use QueryTools.GetFeaturesWithin 
 Dim testpoint As New InMemoryFeatureLayer() 
 testpoint.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20 
 testpoint.InternalFeatures.Add(“Point”, New Feature(New PointShape(longitude, latitude))) 
 Dim spatialQueryResultOverlay As New LayerOverlay() 
 spatialQueryResultOverlay.Layers.Add(“Point”, testpoint) 
 Dim pointQuery As InMemoryFeatureLayer = DirectCast(WinformsMap1.FindFeatureLayer(“Point”), InMemoryFeatureLayer) 
 Dim spatialQueryResults As Collection(Of Feature) 
 Dim town_layer As ShapeFileFeatureLayer = DirectCast(WinformsMap1.FindFeatureLayer(“all_town”), ShapeFileFeatureLayer) 
 spatialQueryResults = town_layer.QueryTools.GetFeaturesWithin(pointQuery, ReturningColumnsType.AllColumns) 
  


Carol, 
  
 QueryTools is a wrapper class for SpatialQuery, it supplies many methods, such as GetFeaturesWithin, it’s the same as SpatialQuery and pass in the enumeration QueryType.Within. 
   
  
 Each QueryType of SpatialQuery can find the corresponding method in QueryTools. 
  
 I think you may use the wrong QueryType, you can try another items, like Intersects. Do you try to use all of them? If the answer is yes, I guess your data maybe not right. 
  
 If you still can not solve your problem, you can send us your data and I can test it. 
  
 Thanks. 
  
 James 


Thanks for your help, James


I use QueryTools to search lon/lat information in the map.


But, I have a problem.


If I input lon/lat twice, the code has error.


I attach my code as belows.


And, how could I get it data? I just get feature id and I don't know how to use it.


 



1406-Form1.vb (3.49 KB)

We’re always welcome, Carol. 
  
 Your code is very helpful, and I found the reason you get the error when you input long/lat twice, it’s because that you add the overlay with the same key at the second time when you call spatial query method. I have modified a little code and added a check if the key “SpatialQueryResultOverlay” is exist or not. 
  
 If your problem is not like this, you must send your data to us, you can contact support@thinkgeo.com. And is your email address is the one you use for register this discussion forum? I will send a email to confirm with you, and then you can send your data directly to me if the support@thinkgeo.com is not response quickly. 
  
 Thanks. 
 James 


Thanks for your help, James 
  
 Add the follows code, it runs great. :) 
  
        If WinformsMap1.Overlays.Contains("SpatialQueryResultOverlay") Then 
             WinformsMap1.Overlays.Remove("SpatialQueryResultOverlay") 
         End If 
         WinformsMap1.Overlays.Add("SpatialQueryResultOverlay", spatialQueryResultOverlay) 
  
  


Carol, 
  
 I have tested another problem which you mentioned by email in none english evnironment, but I can run code properly. 
  
 There is a little different from your machine is that I just can find a Chinese (Simplified) environment, I guess you use Chinese (Traditional). I don’t know is there any different with them. 
 The following code is what I am testing: 
  ShapeFileFeatureLayer layer = new ShapeFileFeatureLayer(@“C:\TWN_TOWN.shp”); 
  layer.Open(); 
  layer.QueryTools.GetColumns(); 
  layer.QueryTools.GetFeaturesIntersecting(rectangle, ReturningColumnsType.AllColumns); 
  layer.Close(); 
  
 I will work on this issue until it is going to be fixed.  
  
 Thanks. 
  
 James 


Thanks for your reply, James 
  
 But it still has the same wrong. 
 in follows code: 
 layer.QueryTools.GetColumns();  
  
 error message: 
 We only Supported Charactor©, Number(N), Logical(L), Date(D), Memo(M), Floating Point(F) now. You are using an UnSupported Format or your password is not right 


Carol, 
  
 From the test results, I think your shp file is not correct. Can you contact your data provider and let them check the files as the specification. 
 This problem is not caused by our MapSuite, and I can not recreate your error. 
  
 Thanks. 
 James 


Thanks a lot, James 
  
 I use ShapeFileFeatureLayer.Rebuild to fix it. 
  
 it seems can run correctly.  
  
 I will contact my data provider to check my files problem. 
  
 Carol 
  


Carol, 
  
 It’s good, wait for your good news. 
  
 James

Thanks for your reply, James 
  
 But I have a problem about DistanceQuery 
  
 I use follows code to get which road has shortest distance. 
 But I don’t know how to get correct information. 
  
  
  Dim DistanceQueryResults As Collection(Of Feature) 
         roadLayer.Open() 
         DistanceQueryResults = roadLayer.QueryTools.GetFeaturesWithinDistanceOf(lineFeature, GeographyUnit.DecimalDegree, DistanceUnit.Meter, 50, New String() {“ROADNAME”, “TNODE”, “FNODE”}) 
         roadLayer.Close() 
  
         Dim items As New Dictionary(Of Integer, Double)() 
         Dim distances As New List(Of Double)() 
         Dim diss(DistanceQueryResults.Count - 1) As Double 
         Dim mPointShape As New PointShape(longitude, latitude) 
         If DistanceQueryResults.Count > 0 Then 
  
             For j As Integer = 0 To DistanceQueryResults.Count - 1 
                 diss(j) = mPointShape.GetDistanceTo(DistanceQueryResults(j), GeographyUnit.DecimalDegree, DistanceUnit.Meter) 
                 items.Add(DistanceQueryResults.Item(j).Id, diss(j)) 
                 distances.Add(diss(j)) 
             Next 
         End If 
  
         Dim firstRecord As Integer = 0 
         Dim firstvalue As Double 
         If (DistanceQueryResults.Count > 0) Then 
             distances.Sort() 
             firstvalue = distances(0) 
             For j As Integer = 0 To DistanceQueryResults.Count - 1 
                 If items(DistanceQueryResults.Item(j).Id) = firstvalue Then 
                     firstRecord = DistanceQueryResults(j).Id 
                 End If 
             Next 
  
         End If 
  
 'this code is wrong, it will print the first record in DistanceQueryResults.  
 Dim str_road As String = MapEngine.LoadDataTable(DistanceQueryResults, New String() {“roadname”}).Rows(0).Item(“roadname”).ToString() 


I know the answer of this problem. 
 Thanks. :)

Carol, 
  
 I am happy that you solve your problem! 
 Just let me know if you have more questions. 
  
 James