<?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 Re: Create ServiceLines automatically? in ArcGIS Utility Network Questions</title>
    <link>https://community.esri.com/t5/arcgis-utility-network-questions/create-servicelines-automatically/m-p/1159803#M1673</link>
    <description>&lt;P&gt;We have played around doing this in Arcade and an attribute rule.&lt;/P&gt;&lt;P&gt;Here is the code if you want to try it out.&lt;/P&gt;&lt;LI-CODE lang="javascript"&gt;function find_closest_line() {
   var line_class = FeatureSetByName($datastore, "line", ["objectid"], true);
   //var candidates = Intersects(line_class, Buffer($feature, 500, "miles"));
   var candidates = line_class;

   var shortest = [1e10, null];
   for (var line in candidates) {
      var d = Distance($feature, line)
      if (d &amp;lt; shortest[0]) shortest = [d, line]
   }

   return shortest[-1]
}

function point_and_distance(point_feature, other_feature) {
	/*
		finds the closest point from point_feature to other_feature

		Args:
			point_feature: Point Geometry
			other_feature: Point/Line/Polygon Geometry

		Returns: dictionary
			{distance: number,               // distance from point_feature to closest point
			 point: geometry,  // the coordinate pair of the closest point
			 isVertex: bool}                 // if the closest point is a vertex of other_feature

	*/

	var point_feature = Geometry(point_feature);
	var other_feature = Geometry(other_feature);

	var shape = TypeOf(other_feature);
	var vertices;
	if (shape == 'Point') {
		return {"distance": Distance(point_feature, other_feature),
		        "coordinates": [other_feature["x"], other_feature["y"]],
				"isVertex": true}
	}

	else if (shape == 'Multipoint') {
	    var points = other_feature["points"];
	    var shortest = [1e10, null];
	    for (var i in points) {
	       var p = points[i]
	       var dist = Distance(point_feature, p);
	       if (dist &amp;lt; shortest[0]) shortest = [dist, [p["x"], p["y"]]]
	    }
	    return {"distance": shortest[0],
		        "coordinates": shortest[1],
				"isVertex": true}
	}

    else if (shape == 'Polyline') vertices = other_feature["paths"]
	else if (shape == 'Polygon') vertices = other_feature["rings"]
	else return null

	var x = point_feature["x"];
	var y = point_feature["y"];

	// Loop through each part of the geometry and each segment, tracking the shortest distance
	var shortest = [1e10];
	for (var i in vertices) {
	    var part = vertices[i];
	    var previous = part[0];
	    for (var j = 1; j &amp;lt; Count(part); j++) {
	        var current = part[j];
	        var result = pDistance(x, y, previous["x"], previous["y"], current["x"], current["y"]);
	        if (result[0] &amp;lt; shortest[0]) shortest = result
	        previous = current;
	    }

	}

	// Couldn't find anything
	if (Count(shortest) == 1) return null

	return {"distance": shortest[0],
	        "coordinates": shortest[1],
	        "isVertex": shortest[2]}

}

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 = true;
  if (param &amp;lt; 0) {
    xx = x1;
    yy = y1;
  }
  else if (param &amp;gt; 1) {
    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];
}

function create_line(start, end_coordinates) {
    var geo = Geometry(start);
    return Polyline({"paths": [[[geo["x"], geo["y"]], end_coordinates]], "spatialReference": geo["spatialReference"]})

}


var closest = find_closest_line();
if (closest == null) return null

var data = point_and_distance($feature, closest);
if (data == null) return null

var lateral = create_line($feature, data["coordinates"]);

return {"result": null,
        "edit": [{
            "className": "lateral", "adds": [{"geometry": lateral}]
        }
        ]
}&lt;/LI-CODE&gt;</description>
    <pubDate>Thu, 31 Mar 2022 10:06:43 GMT</pubDate>
    <dc:creator>MikeMillerGIS</dc:creator>
    <dc:date>2022-03-31T10:06:43Z</dc:date>
    <item>
      <title>Create ServiceLines automatically?</title>
      <link>https://community.esri.com/t5/arcgis-utility-network-questions/create-servicelines-automatically/m-p/1159395#M1668</link>
      <description>&lt;P&gt;Hi everybody,&lt;/P&gt;&lt;P&gt;I just wonder if there is any way or any tool which helps me to create ServiceLines (Laterals) automatically within my UtilityNetwork. As fas as I remember, there was such a Tool in the previous Geometric Network fo ArcMap.&lt;BR /&gt;&lt;BR /&gt;Some ideas about how to do it?&lt;BR /&gt;&lt;BR /&gt;Thanks in advance!&lt;/P&gt;</description>
      <pubDate>Wed, 30 Mar 2022 14:12:01 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-utility-network-questions/create-servicelines-automatically/m-p/1159395#M1668</guid>
      <dc:creator>SergioOrdás</dc:creator>
      <dc:date>2022-03-30T14:12:01Z</dc:date>
    </item>
    <item>
      <title>Re: Create ServiceLines automatically?</title>
      <link>https://community.esri.com/t5/arcgis-utility-network-questions/create-servicelines-automatically/m-p/1159803#M1673</link>
      <description>&lt;P&gt;We have played around doing this in Arcade and an attribute rule.&lt;/P&gt;&lt;P&gt;Here is the code if you want to try it out.&lt;/P&gt;&lt;LI-CODE lang="javascript"&gt;function find_closest_line() {
   var line_class = FeatureSetByName($datastore, "line", ["objectid"], true);
   //var candidates = Intersects(line_class, Buffer($feature, 500, "miles"));
   var candidates = line_class;

   var shortest = [1e10, null];
   for (var line in candidates) {
      var d = Distance($feature, line)
      if (d &amp;lt; shortest[0]) shortest = [d, line]
   }

   return shortest[-1]
}

function point_and_distance(point_feature, other_feature) {
	/*
		finds the closest point from point_feature to other_feature

		Args:
			point_feature: Point Geometry
			other_feature: Point/Line/Polygon Geometry

		Returns: dictionary
			{distance: number,               // distance from point_feature to closest point
			 point: geometry,  // the coordinate pair of the closest point
			 isVertex: bool}                 // if the closest point is a vertex of other_feature

	*/

	var point_feature = Geometry(point_feature);
	var other_feature = Geometry(other_feature);

	var shape = TypeOf(other_feature);
	var vertices;
	if (shape == 'Point') {
		return {"distance": Distance(point_feature, other_feature),
		        "coordinates": [other_feature["x"], other_feature["y"]],
				"isVertex": true}
	}

	else if (shape == 'Multipoint') {
	    var points = other_feature["points"];
	    var shortest = [1e10, null];
	    for (var i in points) {
	       var p = points[i]
	       var dist = Distance(point_feature, p);
	       if (dist &amp;lt; shortest[0]) shortest = [dist, [p["x"], p["y"]]]
	    }
	    return {"distance": shortest[0],
		        "coordinates": shortest[1],
				"isVertex": true}
	}

    else if (shape == 'Polyline') vertices = other_feature["paths"]
	else if (shape == 'Polygon') vertices = other_feature["rings"]
	else return null

	var x = point_feature["x"];
	var y = point_feature["y"];

	// Loop through each part of the geometry and each segment, tracking the shortest distance
	var shortest = [1e10];
	for (var i in vertices) {
	    var part = vertices[i];
	    var previous = part[0];
	    for (var j = 1; j &amp;lt; Count(part); j++) {
	        var current = part[j];
	        var result = pDistance(x, y, previous["x"], previous["y"], current["x"], current["y"]);
	        if (result[0] &amp;lt; shortest[0]) shortest = result
	        previous = current;
	    }

	}

	// Couldn't find anything
	if (Count(shortest) == 1) return null

	return {"distance": shortest[0],
	        "coordinates": shortest[1],
	        "isVertex": shortest[2]}

}

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 = true;
  if (param &amp;lt; 0) {
    xx = x1;
    yy = y1;
  }
  else if (param &amp;gt; 1) {
    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];
}

function create_line(start, end_coordinates) {
    var geo = Geometry(start);
    return Polyline({"paths": [[[geo["x"], geo["y"]], end_coordinates]], "spatialReference": geo["spatialReference"]})

}


var closest = find_closest_line();
if (closest == null) return null

var data = point_and_distance($feature, closest);
if (data == null) return null

var lateral = create_line($feature, data["coordinates"]);

return {"result": null,
        "edit": [{
            "className": "lateral", "adds": [{"geometry": lateral}]
        }
        ]
}&lt;/LI-CODE&gt;</description>
      <pubDate>Thu, 31 Mar 2022 10:06:43 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-utility-network-questions/create-servicelines-automatically/m-p/1159803#M1673</guid>
      <dc:creator>MikeMillerGIS</dc:creator>
      <dc:date>2022-03-31T10:06:43Z</dc:date>
    </item>
    <item>
      <title>Re: Create ServiceLines automatically?</title>
      <link>https://community.esri.com/t5/arcgis-utility-network-questions/create-servicelines-automatically/m-p/1159906#M1676</link>
      <description>&lt;P&gt;Thanks for the answer Mike, I would like to have a more firendly user tool within the UN (as in the previous Geometric Network) but I will have to try it this way if no other option then.&lt;BR /&gt;Thanks for the code and I will write a feedback if I finally have to use it&lt;/P&gt;</description>
      <pubDate>Thu, 31 Mar 2022 15:13:41 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-utility-network-questions/create-servicelines-automatically/m-p/1159906#M1676</guid>
      <dc:creator>SergioOrdás</dc:creator>
      <dc:date>2022-03-31T15:13:41Z</dc:date>
    </item>
    <item>
      <title>Re: Create ServiceLines automatically?</title>
      <link>https://community.esri.com/t5/arcgis-utility-network-questions/create-servicelines-automatically/m-p/1159982#M1678</link>
      <description>&lt;P&gt;I'll be trying that, I also really like those ArcMap tools Sergio mentions, thanks Mike.&lt;/P&gt;</description>
      <pubDate>Thu, 31 Mar 2022 18:05:48 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-utility-network-questions/create-servicelines-automatically/m-p/1159982#M1678</guid>
      <dc:creator>SSMIC3038</dc:creator>
      <dc:date>2022-03-31T18:05:48Z</dc:date>
    </item>
  </channel>
</rss>

