Polygon intersection selects unselected graphics on user drawn polygon.

4697
14
Jump to solution
04-26-2012 06:03 AM
by Anonymous User
Not applicable
Original User: e_saurabh

Hi
   I have a small problem. i have some graphics on my base map. Now I do a Intersect for the graphics using polygon.Extent.Intersects(graphic.Geometry.Extent). This selects the different shapes on the map on which the polygon is drawn. But this also selects the graphics nearby with that comes around that selected graphic features which is not selected. I need to avoid this. Can anybody provide some light on it. I am using

VS 2010.
Silverlight 4.

I am using the code

GraphicsLayer graphicLayer = edmsMap.Layers[selectedProgramTypeName] as GraphicsLayer;
GraphicCollection graphicCollection = new GraphicCollection();
graphicCollection = graphicLayer.Graphics;
foreach (Graphic graphic in graphicCollection)
  { 
     if (polygon.Extent.Intersects(graphic.Geometry.Extent))
    {
         ESRI.ArcGIS.Client.Symbols.SimpleFillSymbol FillSymbol;
        FillSymbol = (ESRI.ArcGIS.Client.Symbols.SimpleFillSymbol)(LayoutRoot.Resources        ["PolygonSelectSymbol"]);
     graphic.Symbol = (ESRI.ArcGIS.Client.Symbols.SimpleFillSymbol)FillSymbol;
}
}
My xaml code is

<esriSymbols:SimpleFillSymbol x:Key="PolygonSelectSymbol" Fill="#66BB0000" BorderBrush="#88CC0000" BorderThickness="2"  />

Any code snippet will be good
Please find the attached screen shot along with.

Regards,
Saurabh.
0 Kudos
1 Solution

Accepted Solutions
by Anonymous User
Not applicable
Original User: jenniferdnery

Oh I see. If your GraphicsLayer contain features from a service, you can do a spatial query by setting Query.Geometry: http://help.arcgis.com/en/webapi/silverlight/samples/start.htm#SpatialQuery. If your GraphicsLayer contain features that only reside in the client, you can use FindGraphicsInHostCoordinates() but this only accepts either Point or Rect. You can also tweak this SDK sample: http://help.arcgis.com/en/webapi/silverlight/samples/start.htm#Intersect. You can skip the QueryTask section where it adds the results to the GraphicsLayer, since your features are drawn and not retrieved from service.

View solution in original post

0 Kudos
14 Replies
DeminHu
New Contributor
I might not  understand your case well,  but I think you  could look  GeometryService such as  relation or intersect.
0 Kudos
by Anonymous User
Not applicable
Original User: SharpGIS

What you are doing is intersecting envelopes with each other. You are not intersecting polygons with an envelope (but the extent of the envelope), so naturally you are going to get a lot of false positives.
Envelope/Envelope intersection is very fast and a good way to remove a lot of candidates, but you will have to do a full on intersection test, and unfortunately the API doesn't come with this out of the box, but you can use the geometry service for this, or google for an algorithm that will do the trick.
If the polygons you want to intersect against are visible on the screen, you can use hit testing to accomplish the same thing (and this is btw extremely fast too). See GraphicsLayer.FindGraphicsInHostCoordinates(Rectangle);
0 Kudos
SaurabhDasgupta
New Contributor II
Hi Mortein,
             Thanks for your answer. I finally managed to use the geometry service to perform the intersection query. Now I am able to select the graphics on the map and it gets selected but still have one step to go as this selects all the graphics on the map. Can you just tell me the way to select the selected graphics at a time. Below is my new code.

void spatialQueryPolygon(Object sender, DrawEventArgs e)
       {

           GraphicsLayer graphicLayer1 = edmsMap.Layers[selectedProgramTypeName] as GraphicsLayer;
           GraphicsLayer graphicLayer = edmsMap.Layers["graphicsLayer"] as GraphicsLayer;
           //GraphicCollection _theGraphicsCollection = graphicLayer.Graphics;
           geometryService.RelationCompleted += new EventHandler<RelationEventArgs>(geometryService_RelationCompleted);

           string sclRelationship = "dim(g1.interior, g2) != null";
           geometryService.RelationAsync(graphicLayer1.Graphics.ToList(), graphicLayer1.Graphics.ToList(),
               GeometryRelation.esriGeometryRelationRelation, sclRelationship);
       }

       void geometryService_RelationCompleted(object sender, RelationEventArgs e)
       {
           string results = "";
           for (int i = 0; i < e.Results.Count; i++)
           {
               results += string.Format("Point {0} is within polygon {1}.\n", e.Results.Graphic1Index,
                   e.Results.Graphic2Index);
               GraphicsLayer graphicLayer1 = edmsMap.Layers[selectedProgramTypeName] as GraphicsLayer;
               GraphicCollection graphicCollection = graphicLayer1.Graphics;
              
               foreach (Graphic graphic in graphicCollection)
               {
                   ESRI.ArcGIS.Client.Symbols.SimpleLineSymbol SimpleLineSymbol;
                   SimpleLineSymbol = (ESRI.ArcGIS.Client.Symbols.SimpleLineSymbol)(LayoutRoot.Resources["DefaultLineSymbol"]);
                   graphic.Symbol = (ESRI.ArcGIS.Client.Symbols.SimpleLineSymbol)SimpleLineSymbol;                  
               }
           }
       }



Regards,
Saurabh.
0 Kudos
by Anonymous User
Not applicable
Original User: e_saurabh

Hi Mortein,
             Thanks for your answer. I finally managed to use the geometry service to perform the intersection query. Now I am able to select the graphics on the map and it gets selected but still have one step to go as this selects all the graphics on the map. Can you just tell me the way to select the selected graphics at a time. Below is my new code.

void spatialQueryPolygon(Object sender, DrawEventArgs e)
       {

           GraphicsLayer graphicLayer1 = edmsMap.Layers[selectedProgramTypeName] as GraphicsLayer;
           GraphicsLayer graphicLayer = edmsMap.Layers["graphicsLayer"] as GraphicsLayer;
           //GraphicCollection _theGraphicsCollection = graphicLayer.Graphics;
           geometryService.RelationCompleted += new EventHandler<RelationEventArgs>(geometryService_RelationCompleted);

           string sclRelationship = "dim(g1.interior, g2) != null";
           geometryService.RelationAsync(graphicLayer1.Graphics.ToList(), graphicLayer1.Graphics.ToList(),
               GeometryRelation.esriGeometryRelationRelation, sclRelationship);
       }

       void geometryService_RelationCompleted(object sender, RelationEventArgs e)
       {
           string results = "";
           for (int i = 0; i < e.Results.Count; i++)
           {
               results += string.Format("Point {0} is within polygon {1}.\n", e.Results.Graphic1Index,
                   e.Results.Graphic2Index);
               GraphicsLayer graphicLayer1 = edmsMap.Layers[selectedProgramTypeName] as GraphicsLayer;
               GraphicCollection graphicCollection = graphicLayer1.Graphics;
              
               foreach (Graphic graphic in graphicCollection)
               {
                   ESRI.ArcGIS.Client.Symbols.SimpleLineSymbol SimpleLineSymbol;
                   SimpleLineSymbol = (ESRI.ArcGIS.Client.Symbols.SimpleLineSymbol)(LayoutRoot.Resources["DefaultLineSymbol"]);
                   graphic.Symbol = (ESRI.ArcGIS.Client.Symbols.SimpleLineSymbol)SimpleLineSymbol;                  
               }
           }
       }



Regards,
Saurabh.


Can anybody provide me some help on this..
0 Kudos
by Anonymous User
Not applicable
Original User: SharpGIS

Are you saying you don't want to select all the graphics? Because your code loops through ALL the graphics in your layer and selects them one by one. Not sure why you do that, if you don't want to do that.
0 Kudos
SaurabhDasgupta
New Contributor II
Are you saying you don't want to select all the graphics? Because your code loops through ALL the graphics in your layer and selects them one by one. Not sure why you do that, if you don't want to do that.


Yes Morten.. That exactly what I want... I dont want to select all the graphics, just want to select the selected graphics for the user drawn polygon; but not finding a proper way to do the loop for selecting the single graphics.May be my loop is wrongly typed. Can u provide me a better way..

Regards,
saurabh.
0 Kudos
SaurabhDasgupta
New Contributor II
Yes Morten.. That exactly what I want... I dont want to select all the graphics, just want to select the selected graphics for the user drawn polygon; but not finding a proper way to do the loop for selecting the single graphics.May be my loop is wrongly typed. Can u provide me a better way..

Regards,
saurabh.


Hi Mortein,
              Finally I am able to select the graphics as required graphics from the user drawn polygon. But still this selects unwanted graphics and most importantly in my case this selects only the line graphics even if I draw to select polygon or point. Below is my code which I am performing using geometry service.

public void spatialQueryPolygon(Object sender, DrawEventArgs e)
       {
           GeometryService geometryService =
                            new GeometryService("http://sgdc1w8ahva09/ArcGIS/rest/services/BaseMap1/GeometryServer");
           GraphicsLayer programTypeGraphicLayer = edmsMap.Layers[selectedProgramTypeName] as GraphicsLayer;
           GraphicCollection sourceGraphicCollection = programTypeGraphicLayer.Graphics;
           Graphic queryGraphic = new Graphic();
           // e.Geometry.SpatialReference = new SpatialReference(ArcConstants.SRID);
           queryGraphic.Geometry = e.Geometry;
           //queryGraphic.Geometry.SpatialReference = new SpatialReference(ArcConstants.SRID);
           GraphicCollection queryGraphicCollection = new GraphicCollection();
           queryGraphicCollection.Add(queryGraphic);
           geometryService.RelationCompleted += new EventHandler<RelationEventArgs>(geometryService_RelationCompleted);
           geometryService.RelationAsync(sourceGraphicCollection, queryGraphicCollection, GeometryRelation.esriGeometryRelationIntersection, null);
       }

       void geometryService_RelationCompleted(object sender, RelationEventArgs e)
       {
           GraphicsLayer sourceGraphicLayer = edmsMap.Layers[selectedProgramTypeName] as GraphicsLayer;
           GraphicCollection sourceGraphicCollection = sourceGraphicLayer.Graphics;
           GraphicCollection targetGraphicCollection = new GraphicCollection();
           List<GeometryRelationPair> geometryRelationPairList = new List<GeometryRelationPair>();
           List<string> collectionEventResultIdList = new List<string>();
           int datasetActivityID = layerIDs[layerNameslist.IndexOf(selectedProgramTypeName)];
           geometryRelationPairList = e.Results;

           foreach (GeometryRelationPair geometryRelationPair in geometryRelationPairList)
           {
               targetGraphicCollection.Add(sourceGraphicCollection[geometryRelationPair.Graphic1Index]);
           }

           foreach (Graphic graphic in targetGraphicCollection)
           {
               ESRI.ArcGIS.Client.Symbols.MarkerSymbol MarkerSymbol;
               MarkerSymbol = (ESRI.ArcGIS.Client.Symbols.MarkerSymbol)(LayoutRoot.Resources["DefaultMarkerSymbol"]);

               ESRI.ArcGIS.Client.Symbols.SimpleFillSymbol FillSymbol;
               FillSymbol = (ESRI.ArcGIS.Client.Symbols.SimpleFillSymbol)(LayoutRoot.Resources["PolygonSelectSymbol"]);

               ESRI.ArcGIS.Client.Symbols.SimpleLineSymbol SimpleLineSymbol;
               SimpleLineSymbol = (ESRI.ArcGIS.Client.Symbols.SimpleLineSymbol)(LayoutRoot.Resources["DefaultLineSymbol"]);

               string shape = graphic.Geometry.ToString();
               if (shape.Contains("Polygon"))
               {
                   graphic.Symbol = (ESRI.ArcGIS.Client.Symbols.SimpleFillSymbol)FillSymbol;
               }
               else if (shape.Contains("Polyline"))
               {
                   graphic.Symbol = (ESRI.ArcGIS.Client.Symbols.SimpleLineSymbol)SimpleLineSymbol;
               }
               else if (shape.Contains("Point"))
               {
                   graphic.Symbol = (ESRI.ArcGIS.Client.Symbols.SimpleMarkerSymbol)MarkerSymbol;
               }


Can u provide me a better way to select the desired graphics as wanted.

Regards,
Saurabh.
0 Kudos
by Anonymous User
Not applicable
Original User: jenniferdnery

Have you tried using Editor.Select? This SDK sample demonstrates how you can do this by simply having an Editor as your Button's DataContext and then using Select command as Button.Command property. Editor SelectionMode can be set to Polygon if you are working with FeatureLayers. You can include/exclude layers from your map by setting Editor.LayerIDs property.
0 Kudos
SaurabhDasgupta
New Contributor II
Have you tried using Editor.Select? This SDK sample demonstrates how you can do this by simply having an Editor as your Button's DataContext and then using Select command as Button.Command property. Editor SelectionMode can be set to Polygon if you are working with FeatureLayers. You can include/exclude layers from your map by setting Editor.LayerIDs property.


Hi Jennefer,
               Thanks for the reply. But when I searched through the silverlight api it clearly says that "The SelectionMode specifies whether the user selects using a point, polygon, polyline or rectangle. Only FeatureLayer supports polygon and polyline selection modes. If any of these modes are selected but no FeatureLayers are referenced by the editor, this command will be disabled.
"
http://help.arcgis.com/en/webapi/silverlight/apiref/ESRI.ArcGIS.Client~ESRI.ArcGIS.Client.Editor~Sel...
and in my caase I am usng graphics layer.

Can u let me know in case of graphics layer how I can achieve this.

Regards,
Saurabh.
0 Kudos