2

There are two points: A and B. I need to snap any points within a 65 m search radius (blue buffer) of point A. However, the snap distance of B needs to be exactly 5m apart from A (i.e. located anywhere on the red buffer). I know the Snap or Integrate tools can perform the snapping, however, I need to find a programmatic solution to set the minimum snap distance. How can I set a minimum snap distance for this type of analysis? I will need to eventually scale this up to accommodate thousands of points.

enter image description here

Desired Outcome (below)

enter image description here

3
  • Does B need to remain at the same angle from A, when moved to the 5m position?
    – klewis
    Jul 5, 2014 at 15:19
  • No, B can be anywhere within the red buffer.
    – Aaron
    Jul 5, 2014 at 17:06
  • Ah, then this greatly simplifies the problem, good question klewis. Aaron, I'm assuming you mean anywhere actually on the red buffer boundary line itself i.e. 5 meters exactly as originally stated, not 'within'. Jul 6, 2014 at 0:34

4 Answers 4

3

For the Points that fall within the 65 meter radius, can't you just subtract 5 meters from A's Y coordinate and use A's X coordinate to find a Point at the 5 meter position? You can use the DA cursor to update these Point's Geometry to the 5m position.

1

How about this for an idea.

If B is within the specified distance of A then create a polyline between A and B. You can then create a point any distance along that polyline.

Polyline object has a method positionalongline.

0

If you're not limiting yourself to an arcpy solution, what you're describing sounds like fairly common practice with ArcObjects - there is a 'Buffer Snap Agent' sample here:

Buffer snap agent http://resources.arcgis.com/en/help/arcobjects-net/conceptualhelp/index.html#/d/000100000334000000.htm

I haven't tested it but was interested in the VB.NET logic - that logic setting your min/max search distance (your outer buffer) and snap to distance (your inner buffer) is in the function, snippet copied from the published sample below. In this sample the distances are hard-coded, as you can see... (http://resources.arcgis.com/en/help/arcobjects-net/conceptualhelp/index.html#//000100000886000000)

Public Function Snap(ByVal geom As IGeometry, ByVal point As IPoint, ByVal tolerance As Double) As Boolean Implements IEngineSnapAgent.Snap
      GetFeatureClass()

      Dim b_setNewFeatureCache As Boolean = False

      If m_featureClass Is Nothing Or m_editor Is Nothing Then
        Return False
      End If

      If m_featureClass.ShapeType <> esriGeometryType.esriGeometryPoint Then
        Return False
      End If

      'Check if a feature cache has been created.
      If Not b_setNewFeatureCache Then
        m_featureCache = New FeatureCache()
        b_setNewFeatureCache = True
      End If

      'Fill the New Cache with the geometries.
      'It is up to the developer to choose an appropriate value
      'given the map units and the scale at which editing will be undertaken.
      FillCache(m_featureClass, point, 10000)

      Dim proximityOp As IProximityOperator = DirectCast(point, IProximityOperator)
      Dim minDist As Double = tolerance
      Dim cachePt As IPoint = New PointClass()
      Dim snapPt As IPoint = New PointClass()
      Dim outPoly As IPolygon = New PolygonClass()
      Dim topoOp As ITopologicalOperator

      Dim feature As IFeature
      Dim Index As Integer = 0
      Dim Count As Integer
      For Count = 0 To m_featureCache.Count - 1 Step Count + 1
        feature = m_featureCache.Feature(Count)
        cachePt = feature.Shape
        topoOp = cachePt

        'Set the buffer distance to an appropriate value
        'given the map units and data being edited
        outPoly = topoOp.Buffer(1000)

        Dim Dist As Double = proximityOp.ReturnDistance(outPoly)
        If Dist < minDist Then
          Index = Count
          minDist = Dist
        End If
      Next

      'Make sure minDist is within the search tolerance.
      If minDist >= tolerance Then
        Return False
      End If

      'Retrieve the feature and its part again.
      feature = m_featureCache.Feature(Index)
      cachePt = feature.Shape
      topoOp = cachePt

      'Set the buffer distance to an appropriate value
      'given the map units and data being edited
      outPoly = topoOp.Buffer(1000)
      proximityOp = outPoly
      snapPt = proximityOp.ReturnNearestPoint(point, esriSegmentExtension.esriNoExtension)

      'Since point was passed in ByValue, we have to modify its values instead.
      'of giving it a new address.
      point.PutCoords(snapPt.X, snapPt.Y)

      Return True

End Function
0

if you are snapping the B towards the A, you could create 5 m buffers around each A's, then you use snap with a tolerance of 60 meters.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.