<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>idea Arcade: Snap point to polyline (mid-segment) in ArcGIS Pro Ideas</title>
    <link>https://community.esri.com/t5/arcgis-pro-ideas/arcade-snap-point-to-polyline-mid-segment/idi-p/1155459</link>
    <description>&lt;P&gt;&lt;BR /&gt;Could an Arcade function be added to do the following:&lt;/P&gt;&lt;P&gt;Snap a point to a polyline — but snap it mid-segment, not just to the closest vertex.&lt;/P&gt;&lt;P&gt;The function would return the snapped point — as well as return the ID of the polyline the point was snapped to.&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Bud_0-1647703571493.png" style="width: 999px;"&gt;&lt;img src="https://community.esri.com/t5/image/serverpage/image-id/36775i69CB468A1697A27E/image-size/large?v=v2&amp;amp;px=999" role="button" title="Bud_0-1647703571493.png" alt="Bud_0-1647703571493.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;Thanks.&lt;/P&gt;</description>
    <pubDate>Mon, 21 Mar 2022 10:44:13 GMT</pubDate>
    <dc:creator>Bud</dc:creator>
    <dc:date>2022-03-21T10:44:13Z</dc:date>
    <item>
      <title>Arcade: Snap point to polyline (mid-segment)</title>
      <link>https://community.esri.com/t5/arcgis-pro-ideas/arcade-snap-point-to-polyline-mid-segment/idi-p/1155459</link>
      <description>&lt;P&gt;&lt;BR /&gt;Could an Arcade function be added to do the following:&lt;/P&gt;&lt;P&gt;Snap a point to a polyline — but snap it mid-segment, not just to the closest vertex.&lt;/P&gt;&lt;P&gt;The function would return the snapped point — as well as return the ID of the polyline the point was snapped to.&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Bud_0-1647703571493.png" style="width: 999px;"&gt;&lt;img src="https://community.esri.com/t5/image/serverpage/image-id/36775i69CB468A1697A27E/image-size/large?v=v2&amp;amp;px=999" role="button" title="Bud_0-1647703571493.png" alt="Bud_0-1647703571493.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;Thanks.&lt;/P&gt;</description>
      <pubDate>Mon, 21 Mar 2022 10:44:13 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-pro-ideas/arcade-snap-point-to-polyline-mid-segment/idi-p/1155459</guid>
      <dc:creator>Bud</dc:creator>
      <dc:date>2022-03-21T10:44:13Z</dc:date>
    </item>
    <item>
      <title>Re: Arcade: Snap point to polyline (mid-segment)</title>
      <link>https://community.esri.com/t5/arcgis-pro-ideas/arcade-snap-point-to-polyline-mid-segment/idc-p/1155583#M19082</link>
      <description>&lt;P&gt;Yes, a snap function would be great.&lt;/P&gt;&lt;P&gt;In the meantime, you can do it yourself (this is in multiple of my Calculation Attribute Rules):&lt;/P&gt;&lt;LI-CODE lang="javascript"&gt;function closest_feature(test_feature, compare_feature_set) {
  // returns the feature of compare_feature_set that is closest to test_feature
  var min_distance = 9999999
  var closest_feature = null
  for(var f in compare_feature_set) {
    var d = Distance(test_feature, f)
    if(d &amp;lt; min_distance) {
      min_distance = d
      closest_feature = f
    }
  }
  return closest_feature
}

function project_orthogonally(point_geometry, line_geometry) {
  // returns a projection of the point_geometry onto the line_geometry
  // only start and end point of the line_geometry are considered!
  // https://de.wikipedia.org/wiki/Orthogonalprojektion
  // https://en.wikibooks.org/wiki/Linear_Algebra/Orthogonal_Projection_Onto_a_Line
  var p = point_geometry
  var r0 = line_geometry.paths[0][0]
  var r1 = line_geometry.paths[0][-1]
  var ux = r1.x - r0.x
  var uy = r1.y - r0.y
  var lambda = ((p.x-r0.x)*ux + (p.y-r0.y)*uy) / (ux*ux + uy*uy)
  var new_p = Point({"x": r0.x + lambda * ux, "y": r0.y + lambda * uy, "spatialReference": p.spatialReference})
  // if new_p is on the line defined by r0 and r1 but not on the actual line_geometry, snap it to the closest end point
  if(Disjoint(new_p, line_geometry)) {
    new_p = IIF(Distance(r0, p) &amp;lt; Distance(r1, p), r0, r1)
  }
  return new_p
}

function snap_point_to_polyline(point_geometry, polyline_geometry) {
  // returns a point that is snapped to the polyline_geometry
  
  // create feature set of the polyline's segments
  var sr = point_geometry.spatialReference
  var vertices = polyline_geometry.paths[0]
  var fs_segments = {"fields": [], "spatialReference": sr, "geometryType": "esriGeometryPolyline", "features": []}
  for(var s=0; s&amp;lt;Count(vertices)-1; s++) {
    var p0 = vertices[s]
    var p1 = vertices[s+1]
    Push(fs_segments.features, {"geometry": {"paths": [[ [p0.x, p0.y], [p1.x, p1.y] ]], "spatialReference": sr}})
  }
  fs_segments = FeatureSet(Text(fs_segments))
  // project point_geometry onto the closest segment
  var closest_segment_geo = Geometry(closest_feature(point_geometry, fs_segments))
  return project_orthogonally(point_geometry, closest_segment_geo ) 
}


var fs_lines = FeatureSetByName($datastore, "Lines")
// optionally, buffer
fs_lines = Intersects(fs_lines, Buffer($feature, 100))

var closest_line_geometry = Geometry(closest_feature($feature, fs_lines))
return snap_point_to_polyline(Geometry($feature), closest_line_geometry)&lt;/LI-CODE&gt;</description>
      <pubDate>Mon, 21 Mar 2022 06:46:32 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-pro-ideas/arcade-snap-point-to-polyline-mid-segment/idc-p/1155583#M19082</guid>
      <dc:creator>JohannesLindner</dc:creator>
      <dc:date>2022-03-21T06:46:32Z</dc:date>
    </item>
    <item>
      <title>Re: Arcade: Snap point to polyline (mid-segment)</title>
      <link>https://community.esri.com/t5/arcgis-pro-ideas/arcade-snap-point-to-polyline-mid-segment/idc-p/1159509#M19203</link>
      <description>&lt;P&gt;Related:&amp;nbsp;&lt;/P&gt;&lt;P&gt;Attribute Rules Blog:&amp;nbsp;&lt;A href="https://community.esri.com/t5/attribute-rules-blog/auto-snapping-with-attribute-rules-during-editing/bc-p/1159508" target="_self"&gt;Auto Snapping with Attribute rules during Editing&lt;/A&gt;&lt;/P&gt;</description>
      <pubDate>Wed, 30 Mar 2022 16:54:25 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-pro-ideas/arcade-snap-point-to-polyline-mid-segment/idc-p/1159509#M19203</guid>
      <dc:creator>Bud</dc:creator>
      <dc:date>2022-03-30T16:54:25Z</dc:date>
    </item>
    <item>
      <title>Re: Arcade: Snap point to polyline (mid-segment)</title>
      <link>https://community.esri.com/t5/arcgis-pro-ideas/arcade-snap-point-to-polyline-mid-segment/idc-p/1307004#M25630</link>
      <description>&lt;P&gt;Related:&lt;/P&gt;&lt;P&gt;&lt;A href="https://www.esri.com/arcgis-blog/products/arcgis-online/mapping/arcgis-arcade-123-release/" target="_self"&gt;New Arcade functions&lt;/A&gt; in Arcade v1.23:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;&lt;A href="https://developers.arcgis.com/arcade/function-reference/geometry_functions/#nearestcoordinate" target="_self"&gt;NearestCoordinate&lt;/A&gt;&lt;/LI&gt;&lt;LI&gt;&lt;A href="https://developers.arcgis.com/arcade/function-reference/geometry_functions/#nearestvertex" target="_self"&gt;NearestVertex&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;Although, I don't think those functions help with "snapping mid-segment".&lt;/P&gt;</description>
      <pubDate>Mon, 10 Jul 2023 17:32:32 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-pro-ideas/arcade-snap-point-to-polyline-mid-segment/idc-p/1307004#M25630</guid>
      <dc:creator>Bud</dc:creator>
      <dc:date>2023-07-10T17:32:32Z</dc:date>
    </item>
    <item>
      <title>Re: Arcade: Snap point to polyline (mid-segment)</title>
      <link>https://community.esri.com/t5/arcgis-pro-ideas/arcade-snap-point-to-polyline-mid-segment/idc-p/1307377#M25642</link>
      <description>&lt;P&gt;Ooh, I missed that update, thanks for the link!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;It actually does solve your problem.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="javascript"&gt;function closest_feature(test_feature, compare_feature_set) {
    // ...
}
function project_orthogonally(point_geometry, line_geometry) {
    // ...
}
function snap_point_to_polyline(point_geometry, polyline_geometry) {
    // ...
}


var line = Polyline({
  paths: [[  [0, 0],  [1, 1],  [1, 5], ]],
    spatialReference: {wkid: 3857}
})
var p = Point({x: 2, y: 2, spatialReference: {wkid: 3857}})

var sp1 = snap_point_to_polyline(p, line)
var sp2 = NearestCoordinate(line, p).coordinate

Console("With 3 custom functions: " + sp1)
Console("With NearestCoordinate: " + sp2)&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;With 3 custom functions: {"spatialReference":{"wkid":3857},"x":1,"y":2}
With NearestCoordinate: {"spatialReference":{"wkid":3857},"x":1,"y":2}&lt;/PRE&gt;</description>
      <pubDate>Tue, 11 Jul 2023 17:52:26 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-pro-ideas/arcade-snap-point-to-polyline-mid-segment/idc-p/1307377#M25642</guid>
      <dc:creator>JohannesLindner</dc:creator>
      <dc:date>2023-07-11T17:52:26Z</dc:date>
    </item>
  </channel>
</rss>

