<?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>topic [Arcade] Get z-Value from intersecting feature in Attribute Rules Questions</title>
    <link>https://community.esri.com/t5/attribute-rules-questions/arcade-get-z-value-from-intersecting-feature/m-p/1230814#M651</link>
    <description>&lt;P&gt;Hi there,&lt;/P&gt;&lt;P&gt;I am yet again standing infront of a problem :') I am currently trying to edit the geometry of $feature by giving it the z-value of an intersecting feature. For this to work I created this code snippet:&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;var lines = FeatureSetByName($map, "linefeature", ["globalId"], false)&lt;/P&gt;&lt;P&gt;var intersectingLines = Intersects(lines, $feature)&lt;BR /&gt;var lines = count(intersectingLines)&lt;BR /&gt;&lt;BR /&gt;if(lines == 1){&lt;BR /&gt;var intersectingLine = First(intersectingLines)&lt;BR /&gt;var newGeo = Point({&lt;BR /&gt;"x": Geometry($feature).x,&lt;BR /&gt;"y": Geometry($feature).y,&lt;BR /&gt;"z": Geometry(intersectingLine).z,&lt;BR /&gt;"spatialReference": Geometry($feature).spatialReference&lt;BR /&gt;})&lt;BR /&gt;SetGeometry($feature, newGeo)&lt;BR /&gt;return true&lt;BR /&gt;} else {&lt;BR /&gt;return true&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;So far so good, but somehow it won't work. Any Ideas what could be the problem?&lt;/P&gt;&lt;P&gt;Thanks!&lt;/P&gt;&lt;P&gt;Stefan&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Fri, 11 Nov 2022 09:38:43 GMT</pubDate>
    <dc:creator>StefanAngerer</dc:creator>
    <dc:date>2022-11-11T09:38:43Z</dc:date>
    <item>
      <title>[Arcade] Get z-Value from intersecting feature</title>
      <link>https://community.esri.com/t5/attribute-rules-questions/arcade-get-z-value-from-intersecting-feature/m-p/1230814#M651</link>
      <description>&lt;P&gt;Hi there,&lt;/P&gt;&lt;P&gt;I am yet again standing infront of a problem :') I am currently trying to edit the geometry of $feature by giving it the z-value of an intersecting feature. For this to work I created this code snippet:&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;var lines = FeatureSetByName($map, "linefeature", ["globalId"], false)&lt;/P&gt;&lt;P&gt;var intersectingLines = Intersects(lines, $feature)&lt;BR /&gt;var lines = count(intersectingLines)&lt;BR /&gt;&lt;BR /&gt;if(lines == 1){&lt;BR /&gt;var intersectingLine = First(intersectingLines)&lt;BR /&gt;var newGeo = Point({&lt;BR /&gt;"x": Geometry($feature).x,&lt;BR /&gt;"y": Geometry($feature).y,&lt;BR /&gt;"z": Geometry(intersectingLine).z,&lt;BR /&gt;"spatialReference": Geometry($feature).spatialReference&lt;BR /&gt;})&lt;BR /&gt;SetGeometry($feature, newGeo)&lt;BR /&gt;return true&lt;BR /&gt;} else {&lt;BR /&gt;return true&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;So far so good, but somehow it won't work. Any Ideas what could be the problem?&lt;/P&gt;&lt;P&gt;Thanks!&lt;/P&gt;&lt;P&gt;Stefan&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 11 Nov 2022 09:38:43 GMT</pubDate>
      <guid>https://community.esri.com/t5/attribute-rules-questions/arcade-get-z-value-from-intersecting-feature/m-p/1230814#M651</guid>
      <dc:creator>StefanAngerer</dc:creator>
      <dc:date>2022-11-11T09:38:43Z</dc:date>
    </item>
    <item>
      <title>Re: [Arcade] Get z-Value from intersecting feature</title>
      <link>https://community.esri.com/t5/attribute-rules-questions/arcade-get-z-value-from-intersecting-feature/m-p/1230842#M652</link>
      <description>&lt;P&gt;I managed to slove it myself. It was a problem with the result statement. This is the snippet that worked for me:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;var lines = FeatureSetByName($map, "linefeature", ["globalId"], false)&lt;/P&gt;&lt;P&gt;var intersectingLines = Intersects(lines, $feature)&lt;BR /&gt;var lines = count(intersectingLines)&lt;/P&gt;&lt;P&gt;if(lines == 1){&lt;BR /&gt;var intersectingLine = First(intersectingLines)&lt;BR /&gt;var newGeo = Point({&lt;BR /&gt;"x": Geometry($feature).x,&lt;BR /&gt;"y": Geometry($feature).y,&lt;BR /&gt;"z": Geometry(intersectingLine).z,&lt;BR /&gt;"spatialReference": Geometry($feature).spatialReference&lt;BR /&gt;})&lt;BR /&gt;return { "result": { "geometry": newGeo } };&lt;BR /&gt;} else {&lt;BR /&gt;return true&lt;BR /&gt;}&lt;/P&gt;</description>
      <pubDate>Fri, 11 Nov 2022 10:58:35 GMT</pubDate>
      <guid>https://community.esri.com/t5/attribute-rules-questions/arcade-get-z-value-from-intersecting-feature/m-p/1230842#M652</guid>
      <dc:creator>StefanAngerer</dc:creator>
      <dc:date>2022-11-11T10:58:35Z</dc:date>
    </item>
    <item>
      <title>Re: [Arcade] Get z-Value from intersecting feature</title>
      <link>https://community.esri.com/t5/attribute-rules-questions/arcade-get-z-value-from-intersecting-feature/m-p/1230845#M653</link>
      <description>&lt;P&gt;It is fairly more complex than that.&amp;nbsp; I have not tested this at all, but this should get you started.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="javascript"&gt;// How man decimals to round coordinates to check if identical
// GCS should use a large value, such as 9
// PCS should use a value such as 4
var compare_coordinate_round_value = 2;

// When walking the line to split, a line is created between pairs of vertex
// this value is the distance ito determine if the created point is on that line
// GCS should use a small value, such as 0.0001
// PCS should use a larger value, such as 0.1
var point_on_line_tol = 0.1;

function get_z_at_location(line_geometry, point_geometry) {
    var point_coord = null;
    if (TypeOf(line_geometry) == 'Dictionary') {
        line_shape = line_geometry;
    } else {
        line_shape = Dictionary(Text(line_geometry));
    }

    point_coord = [point_geometry.X, point_geometry.Y];

    var line_path = line_shape['paths'];
    // If the point is at the start or end
    if (compare_coordinate(point_coord[0],point_coord[1], line_path[0][0][0], line_path[0][0][1]))
    {
        return line_path[0][0][2];
    }
    if (compare_coordinate(point_coord[0],point_coord[1], line_path[-1][-1][0],line_path[-1][1])) {
        return line_path[-1][-1][2];
    }

    var min_distance = point_on_line_tol * 2;
    var z_value = null;


    for (var i in line_path) {
        var current_path = line_path[i];
        // Loop over vertex, exit when at last vertex
        for (var j = 0 ; j &amp;lt; Count(current_path) - 1 ; j++) {
            var from_coord = current_path[j];
            var to_coord = current_path[j + 1];
            var shortest = pDistance(point_coord[0], point_coord[1], from_coord[0], from_coord[1], to_coord[0],to_coord[1]);
            var distance =  shortest[0];
	        var coordinates = shortest[1];
	        var isVertex =  shortest[2];
            if (distance &amp;lt;= min_distance) {
                // set the min distance of the current item
                min_distance = distance;
                var to_z = to_coord[2];
                var from_z = from_coord[2];
                // If the Z's are equal, no need to interpolate or check anything else
                if (to_z == from_z){
                    z_value = to_z;
                    continue;
                }
                if (isVertex){
                    if (compare_coordinate(from_coord[0], from_coord[1],coordinates[0],coordinates[1])){
                        z_value = from_z;
                        continue;
                    }
                    else if (compare_coordinate(to_coord[0], to_coord[1],coordinates[0],coordinates[1])){
                        z_value = to_z;
                        continue;
                    }
                }

                // Since the Zs are not equal and we are not at a vertex, we need to interpolate the z at the location
                var dist_to_point = Sqrt( (coordinates[0] - from_coord[0]) * Exp(2) + (coordinates[1] - from_coord[0])* Exp(2))
                var dist_of_seg = Sqrt( (to_coord[0] - from_coord[0]) * Exp(2) + (to_coord[1] - from_coord[0])* Exp(2))
                var percent_along = (dist_to_point/ dist_of_seg)
                var z_dif = Abs(to_z - from_z)
                z_value = z_dif * percent_along
            }
        }
    }
    return z_value
}

function compare_coordinate(x, y, x1, y1) {

    // TODO, probably move to Equals and compare the geometry
    if ((Round(x1, compare_coordinate_round_value) != Round(x, compare_coordinate_round_value)) ||
        (Round(y1, compare_coordinate_round_value) != Round(y, compare_coordinate_round_value)) ){
        return false;
    }
    return true;
    // TODO - Figure out Z
    if (Count(coordinate &amp;gt; 2) &amp;amp;&amp;amp; IsEmpty(source_geo.Z) == false) {
        if (Round(coordinate[2], 2) != Round(source_geo.Z, 2)) {
            return false;
        }
    }
    return true;
}

function pDistance(x, y, x1, y1, x2, y2) {
  // adopted from https://stackoverflow.com/a/6853926
  var A = x - x1;
  var B = y - y1;
  var C = x2 - x1;
  var D = y2 - y1;

  var dot = A * C + B * D;
  var len_sq = C * C + D * D;
  var param = -1;
  if (len_sq != 0) //in case of 0 length line
      param = dot / len_sq;

  var xx, yy;

  var is_vertex = false;
  if (compare_coordinate(x, y, x1, y1)) {
       is_vertex = true;
  }
  if (compare_coordinate(x, y, x2, y2)) {
       is_vertex = true;
  }

  if (param &amp;lt; 0) {
   // is_vertex = true;
    xx = x1;
    yy = y1;
  }
  else if (param &amp;gt; 1) {
 //  is_vertex = true;
    xx = x2;
    yy = y2;
  }
  else {
  //  is_vertex = false;
    xx = x1 + param * C;
    yy = y1 + param * D;
  }

  var dx = x - xx;
  var dy = y - yy;
  return [Sqrt(dx * dx + dy * dy), [xx, yy], is_vertex];
}

// Used to check different empty null states, override of core IsEmpty
function IsEmptyButBetter(data) {
    if (IsEmpty(data)) return true;
    for (var x in data) return false;
    return true;
}
var feat_geo = Geometry($feature);
var lines = FeatureSetByName($map, "linefeature", ["globalId"], false)

var intersected_line = First(Intersects(lines, $feature));
if (intersected_line == null ){
    
    return Geometry($feature);
}
var new_z = get_z_at_location(Geometry(intersected_line),feat_geo)
// NOTE: It would be much better to not assign this rule to the Geometry field and leave the field assignment null
// then use the return edits dictionary to only update the geometry when the Z changes.  This save the edit event in
// an update event scenario.  I just did nto have the time to look up the return edit syntax, exercise is left to the 
// reader
var new_point = Point({
    "x": feat_geo.x,
    "y":feat_geo.y,
    "z": new_z,
    "spatialReference": feat_geo.spatialReference
});
return new_point&lt;/LI-CODE&gt;</description>
      <pubDate>Fri, 11 Nov 2022 11:15:23 GMT</pubDate>
      <guid>https://community.esri.com/t5/attribute-rules-questions/arcade-get-z-value-from-intersecting-feature/m-p/1230845#M653</guid>
      <dc:creator>MikeMillerGIS</dc:creator>
      <dc:date>2022-11-11T11:15:23Z</dc:date>
    </item>
    <item>
      <title>Re: [Arcade] Get z-Value from intersecting feature</title>
      <link>https://community.esri.com/t5/attribute-rules-questions/arcade-get-z-value-from-intersecting-feature/m-p/1230850#M654</link>
      <description>&lt;P&gt;Hmm, strange. Maybe I have the luck that the line features I am intersecting are all on the same hight? Because I actually managed to get my desired results with the simple code from above. Obiously this approach would fail if there where more vertices with different hight properties. Definitly something I have to consider.&lt;/P&gt;</description>
      <pubDate>Fri, 11 Nov 2022 11:57:00 GMT</pubDate>
      <guid>https://community.esri.com/t5/attribute-rules-questions/arcade-get-z-value-from-intersecting-feature/m-p/1230850#M654</guid>
      <dc:creator>StefanAngerer</dc:creator>
      <dc:date>2022-11-11T11:57:00Z</dc:date>
    </item>
    <item>
      <title>Re: [Arcade] Get z-Value from intersecting feature</title>
      <link>https://community.esri.com/t5/attribute-rules-questions/arcade-get-z-value-from-intersecting-feature/m-p/1230851#M655</link>
      <description>&lt;P&gt;Correct, if the line has all the same Z's, easypeasy.&amp;nbsp; But the reality is that a line may have different z's at every vertex.&lt;/P&gt;</description>
      <pubDate>Fri, 11 Nov 2022 11:59:48 GMT</pubDate>
      <guid>https://community.esri.com/t5/attribute-rules-questions/arcade-get-z-value-from-intersecting-feature/m-p/1230851#M655</guid>
      <dc:creator>MikeMillerGIS</dc:creator>
      <dc:date>2022-11-11T11:59:48Z</dc:date>
    </item>
    <item>
      <title>Re: [Arcade] Get z-Value from intersecting feature</title>
      <link>https://community.esri.com/t5/attribute-rules-questions/arcade-get-z-value-from-intersecting-feature/m-p/1230855#M656</link>
      <description>&lt;P&gt;Alright. In this case I will have a look on that as well, for a more functional solution. Thanks for the help!&lt;/P&gt;</description>
      <pubDate>Fri, 11 Nov 2022 12:08:14 GMT</pubDate>
      <guid>https://community.esri.com/t5/attribute-rules-questions/arcade-get-z-value-from-intersecting-feature/m-p/1230855#M656</guid>
      <dc:creator>StefanAngerer</dc:creator>
      <dc:date>2022-11-11T12:08:14Z</dc:date>
    </item>
  </channel>
</rss>

