Help with finding intersecting layer

1291
12
Jump to solution
08-21-2020 08:10 AM
BrianBulla
Occasional Contributor III

Hi.  I'm creating a series of MapTools to sketch a line on the map that will represent a new feature.  A criteria of the sketch is that the first node of the sketch must intersect a line feature.  So for example, to create a hydrant lateral the first click must intersect a watermain....the second click will represent the hydrant valve and the last the hydrant.

I have created a routine for checking for the intersection of the first click to a given layer, but I am getting mixed results.  With certain layers it works (ie.  my sewer layer for my sewer connection tool), but other layers (ie. my watermain layer for my hydrant tool).  Here is the code:

public static bool IntersectsLayer(MapPoint point, FeatureLayer layer)
        {
            try
            {
                SpatialQueryFilter spatialFilter = new SpatialQueryFilter();
                spatialFilter.FilterGeometry = point;
                spatialFilter.SpatialRelationship = SpatialRelationship.Intersects;

                RowCursor theCursor = layer.Search(spatialFilter);
                Feature feature;
                while (theCursor.MoveNext())
                {
                    using (feature = (Feature)theCursor.Current)
                    {
                        return true;
                    }
                }
            }
            catch (Exception ex)
            {
                ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(ex.ToString());
            }

            return false;
        }‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

And here is the code that calls it:

protected override Task<bool> OnSketchCompleteAsync(Geometry geometry)
        {
            //use the sketch geometry to create the connectionPoint, valve and hydrant
            var pointCollection = ((Multipart)geometry).Points;
            MapPoint connectionPoint = pointCollection[0];
            MapPoint hydrantPoint = pointCollection[pointCollection.Count - 1];
            MapPoint valvePoint = pointCollection[1];

            //start creating the features
            QueuedTask.Run(() =>
            {
                if (Global.IntersectsLayer(connectionPoint, waterMainLayer) == false)
                {
                    ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(connectionPoint.X.ToString() + ", " + connectionPoint.Y.ToString(), "Error");
                    ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show("The starting point must intersect the WaterMain or Water Service layer.", "Error");
                    return;
                }

         .......‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Can anyone see anything wrong in the code?  For some reason it always returns false when using the watermain layer.  I have snapping turned on, and it always works when using my similarly coded sewer connection tool.

Any ideas are appreciated.

0 Kudos
1 Solution

Accepted Solutions
Wolf
by Esri Regular Contributor
Esri Regular Contributor

You are using indexof to find the layer by name.  Did you validate the returned feature layer?  indexof can return > 0 for any name that starts with 

"GISWRKS1.WORKS.WaterMain"

View solution in original post

12 Replies
Wolf
by Esri Regular Contributor
Esri Regular Contributor

Hi Brian,

 I made a small sample add-in that includes your method and was not able to duplicate your problem.  I attached the sample (please make sure to run the "pro fix references" tool to fix the Pro assembly references before you build).  When I run the sample with UseSnapping set to true, I can't get IntersectsLayer to fail.  With snapping off, I can see IntersectsLayer return false which is expected.  I am using overlay graphics to allow zooming in closely into the start point area to see if the watermain line and start point intersect:

The sample requires a TestLines feature class since i used the C:\Data\FeatureTest sample data from community samples.

0 Kudos
BrianBulla
Occasional Contributor III

Hi Wolfgang Kaiser‌.  Thanks for creatign that.

After running your tool, it is working with all of my layers.  Did you do something different in yours??  I still don't understand why the exact same code is returning false when I run it.

I renamed the layer causing problems to TestLines, and it worked with yours.

0 Kudos
Wolf
by Esri Regular Contributor
Esri Regular Contributor

Hi Brian,

 I would take a look at the 'snapping' settings in your add-in.  You should see snapping enabled when you activate the tool - so with my sample I see this under the crosshair cursor:

 If you can't see the 'snapping' indicator, look at all 'snapping' settings in my add-in sample code.  Actually I think Vertex and Intersection snapping are not really needed (this was copy/paste inheritance).

public SnapPointsToLine()
{
  IsSketchTool = true;
  UseSnapping = true;
  SketchType = SketchGeometryType.Line;
  SketchOutputMode = SketchOutputMode.Map;
}

protected override Task OnToolActivateAsync(bool active)
{
  var lineLayerName = "TestLines";
  var lineLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().Where(fl => fl.Name.Equals(lineLayerName, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
  if (lineLayer != null)
  {
    Snapping.IsEnabled = true;
    Snapping.SetLayerSnapModes(lineLayer, SnapMode.Vertex, true);
    Snapping.SetLayerSnapModes(lineLayer, SnapMode.Edge, true);
    Snapping.SetLayerSnapModes(lineLayer, SnapMode.Intersection, true);
  }
  return base.OnToolActivateAsync(active);
}
0 Kudos
BrianBulla
Occasional Contributor III

Hi Wolfgang Kaiser‌,

Yes, within OnToolActivateAsync I have the tool turn it on, just in case the user doesn't.  And in my testing it is definitely turned on.  

//turn on snapping in case the user does not have it set in their map
Snapping.IsEnabled = true;
Snapping.SetSnapMode(SnapMode.Edge, true);
Snapping.SetSnapMode(SnapMode.End, true);
0 Kudos
Wolf
by Esri Regular Contributor
Esri Regular Contributor

And the tool has snapping turned on too:

UseSnapping = true;
0 Kudos
BrianBulla
Occasional Contributor III

Yes, the tool has it turned on too.

public HydrantTool()
        {
            IsSketchTool = true;
            SketchType = SketchGeometryType.Line;
            SketchOutputMode = SketchOutputMode.Map;
            UseSnapping = true;
        }

Also, this is how I am getting the watermain layer, but I don't see any issues here either:

FeatureLayer waterMainLayer;

waterMainLayer = map.GetLayersAsFlattenedList().OfType<FeatureLayer>().Where(l => l.Name.IndexOf("GISWRKS1.WORKS.WaterMain", StringComparison.CurrentCultureIgnoreCase) >= 0).FirstOrDefault();
0 Kudos
Wolf
by Esri Regular Contributor
Esri Regular Contributor

You are using indexof to find the layer by name.  Did you validate the returned feature layer?  indexof can return > 0 for any name that starts with 

"GISWRKS1.WORKS.WaterMain"
BrianBulla
Occasional Contributor III

Ah....your a genius Wolfgang!!  I had a layer in the TOC called GISWRKS1.WORKS.Watermain_Breaks that was causing the problem.

So, is there a way to look for a layer name with an EXACT match??

0 Kudos
Wolf
by Esri Regular Contributor
Esri Regular Contributor

I think the snippet in my sample did it.

var lineLayerName = "TestLines";
  var lineLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().Where(fl => fl.Name.Equals(lineLayerName, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
 
0 Kudos