ThinkGeo.com    |     Documentation    |     Premium Support

Spacial query returns no results

I'm attempting to load some road data from a shapefile, drawing them onscreen in different colours depending upon classification.  Later I attempt to run a spacial query on the underlying data.  I've attempted to knock up a working query using the examples in the API, however the code never returns any matching results.


The loading code is as follows:



protected void LoadRoads()
{
   // Loads the shape files which render positions of network roads

   // Load the 1-3 shape files, rebuilding indexes if not valid
   String roadsShapefile = "C:\shapefiles\Roads.shp";
   ShapeFileFeatureLayer.BuildIndexFile(roadsShapefile, BuildIndexMode.DoNotRebuild);

   // Create a new value style which will draw line a single pixel line in the relevant colour between levels 1 and 10
   ValueStyle roadNetworkValueStyle = new ValueStyle();
   roadNetworkValueStyle.ColumnName = "ROAD_TYPE";
   roadNetworkValueStyle.ValueItems.Add(new ValueItem("Motorway", new LineStyle(new GeoPen(GeoColor.FromArgb(255, 107, 178, 247), 1))));
   roadNetworkValueStyle.ValueItems.Add(new ValueItem("Other", new LineStyle(new GeoPen(GeoColor.FromArgb(255, 132, 178, 140), 1))));

   // Create a new value style which will draw line a double pixel line in the relevant colour between levels 11 and 20
   ValueStyle roadNetworkValueStyle2 = new ValueStyle();
   roadNetworkValueStyle2.ColumnName = "ROAD_TYPE";
   roadNetworkValueStyle2.ValueItems.Add(new ValueItem("Motorway", new LineStyle(new GeoPen(GeoColor.FromArgb(255, 107, 178, 247), 2))));
   roadNetworkValueStyle2.ValueItems.Add(new ValueItem("Other", new LineStyle(new GeoPen(GeoColor.FromArgb(255, 132, 178, 140), 3))));

   // Create a feature layer to hold the shape file, then apply the value styles to the relevant levels
   ShapeFileFeatureLayer shapeFileFeatureLayer = new ShapeFileFeatureLayer(roadsShapefile);
   shapeFileFeatureLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(roadNetworkValueStyle);
   shapeFileFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level10;
   shapeFileFeatureLayer.ZoomLevelSet.ZoomLevel11.CustomStyles.Add(roadNetworkValueStyle2);
   shapeFileFeatureLayer.ZoomLevelSet.ZoomLevel11.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

   // Define a shape overlay for the road layer.
   LayerOverlay shapeOverlay = new LayerOverlay("Roads", false, TileType.SingleTile);
   shapeOverlay.Layers.Add("Roads", shapeFileFeatureLayer);
   shapeOverlay.TransitionEffect = TransitionEffect.Stretching;

   myAreasMap.CustomOverlays.Add(shapeOverlay);
}

And here is the code which attempts to run the query:



protected void QueryTest()
{
   // Begin by drawing a rectangle over the map

   InMemoryFeatureLayer rectangleLayer = new InMemoryFeatureLayer();
   rectangleLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = new AreaStyle(new GeoSolidBrush(new GeoColor(50, 100, 100, 200)));
   rectangleLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle.OutlinePen.Color = GeoColor.StandardColors.DarkBlue;
   rectangleLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

   BaseShape baseShape = BaseShape.CreateShapeFromWellKnownData("POLYGON((150000 100000, 150000 500000, 675000 500000, 675000 100000, 150000 100000))");
   rectangleLayer.InternalFeatures.Add("Rectangle", new Feature(baseShape));
   rectangleLayer.BuildIndex();

   // Define a shape overlay, add the layer and place it on the map
   LayerOverlay rectangleOverlay = new LayerOverlay("Rectangle", false, TileType.SingleTile);
   rectangleOverlay.Layers.Add("Rectangle", rectangleLayer);
   rectangleOverlay.TransitionEffect = TransitionEffect.Stretching;
   myAreasMap.CustomOverlays.Add(rectangleOverlay);

   InMemoryFeatureLayer spatialQueryResultLayer = new InMemoryFeatureLayer();
   spatialQueryResultLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = new AreaStyle(new GeoSolidBrush(GeoColor.FromArgb(200, GeoColor.SimpleColors.PastelRed)));
   spatialQueryResultLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle.OutlinePen.Color = GeoColor.StandardColors.Red;
   spatialQueryResultLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

   LayerOverlay resultsOverlay = new LayerOverlay("Results", false, TileType.SingleTile);
   resultsOverlay.Layers.Add("Results", spatialQueryResultLayer);
   resultsOverlay.TransitionEffect = TransitionEffect.Stretching;
   myAreasMap.CustomOverlays.Add(resultsOverlay);

   LayerOverlay roadsOverlay = (LayerOverlay)myAreasMap.CustomOverlays["Roads"];
   ShapeFileFeatureLayer roadsLayer = (ShapeFileFeatureLayer)roadsOverlay.Layers["Roads"];

   Feature rectangleFeature = rectangleLayer.InternalFeatures["Rectangle"];
   roadsLayer.Open();
   Collection<feature> spatialQueryResults = roadsLayer.QueryTools.GetFeaturesContaining(rectangleFeature, new string[0]);
   roadsLayer.Close();

   spatialQueryResultLayer.InternalFeatures.Clear();
   spatialQueryResultLayer.Open();
   foreach (Feature feature in spatialQueryResults)
   {
   spatialQueryResultLayer.InternalFeatures.Add(feature.Id, feature);
   }
   spatialQueryResultLayer.Close();
   resultsOverlay.Redraw();
}

While I appreciate that this is probably not the best way to do things, I'm simply trying to get a working example first.  The code runs fine, and the roads render fine when displayed onscreen, however when I run the query code the spacialQueryResults structure is always empty despite the rectangle being correctly drawn in a layer over the relevant section of roads.



 You are using the wrong type of Spatial Query. By using GetFeaturesContaining, you are asking to get the streets that contain the Polygon ("POLYGON((150000 100000, 150000 500000, 675000 500000, 675000 100000, 150000 100000))").


 That does not make sense because a street that is of line type cannot contain a Polygon that is of area type. What you should use instead are the Spatial query functions GetFeaturesIntersecting or GetFeaturesWithin depending if you want the features to be fully within the Polygon or not. See the illustrations below:


Using GetFeaturesIntersecting:



 


Using GetFeaturesWithin:



 


 



Ah, I can’t believe it was something so simple.  Thanks, I’m now getting matching records using GetFeaturesWithin.  The drawing still isn’t working, however at least I’m now a step closer.

Hi, Iain


The drawing still isn't working is caused by that you don't set the default line style for spatialQueryResultLayer, so even though you have got matching records using GetFeaturesWithin; features still will not be drawn. So please add the code below to spatialQueryResultLayer, it will works well. 




spatialQueryResultLayer.ZoomLevelSet.ZoomLevel10.DefaultLineStyle = LineStyles.LocalRoad3;


Thanks,


Johnny



hi all…how can i use the data stored in SQL server to build my map…can any one help me plz?

Stetsh, 
  
   The question asked is distinct from the topic of this post. Could you create a new post for your question on SQL server? Also, I think, it would help a lot the people responding to the forum if you could elaborate a little more in the explanation of what you are trying to accomplish. Thank you.