Can someone please help me find out how to get the midpoint (x.y) of a line segment in Arcade (ArcGIS Online) ?
I have a road layer with many segmented lines, I want to create a pop up link using the mid point x,y info.
Thank you so much !!
Hi KhattabK ,
Not entirely sure if this works, but could you try it?
Function <SPAN class="token function">dist</SPAN><SPAN class="punctuation token">(</SPAN>x1<SPAN class="punctuation token">,</SPAN> y1<SPAN class="punctuation token">,</SPAN> x2<SPAN class="punctuation token">,</SPAN> y2<SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">{</SPAN> <SPAN class="keyword token">return</SPAN> <SPAN class="token function">Sqrt</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="token function">Pow</SPAN><SPAN class="punctuation token">(</SPAN>x2<SPAN class="operator token">-</SPAN>x1<SPAN class="punctuation token">,</SPAN> <SPAN class="number token">2</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="operator token">+</SPAN> <SPAN class="token function">Pow</SPAN><SPAN class="punctuation token">(</SPAN>y2<SPAN class="operator token">-</SPAN>y1<SPAN class="punctuation token">,</SPAN> <SPAN class="number token">2</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="punctuation token">}</SPAN> <SPAN class="comment token">// get the geometry</SPAN> <SPAN class="keyword token">var</SPAN> segment <SPAN class="operator token">=</SPAN> <SPAN class="token function">Geometry</SPAN><SPAN class="punctuation token">(</SPAN>$feature<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="string token">"paths"</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="number token">0</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="comment token">// determine length halfway</SPAN> <SPAN class="keyword token">var</SPAN> halflen <SPAN class="operator token">=</SPAN> <SPAN class="token function">Length</SPAN><SPAN class="punctuation token">(</SPAN>$feature<SPAN class="punctuation token">)</SPAN> <SPAN class="operator token">/</SPAN> <SPAN class="number token">2</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="comment token">// initialize vars</SPAN> <SPAN class="keyword token">var</SPAN> xcrd <SPAN class="operator token">=</SPAN> Null<SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">var</SPAN> ycrd <SPAN class="operator token">=</SPAN> Null<SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">var</SPAN> cumlen <SPAN class="operator token">=</SPAN> <SPAN class="number token">0</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="comment token">// loop through coordinate pairs in segment</SPAN> <SPAN class="keyword token">for</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="keyword token">var</SPAN> i <SPAN class="keyword token">in</SPAN> segment<SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">{</SPAN> <SPAN class="keyword token">if</SPAN> <SPAN class="punctuation token">(</SPAN>i <SPAN class="operator token">></SPAN> <SPAN class="number token">0</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">{</SPAN> <SPAN class="comment token">// second coordinate pair, start calculating distance</SPAN> <SPAN class="keyword token">var</SPAN> xprev <SPAN class="operator token">=</SPAN> segment<SPAN class="punctuation token">[</SPAN>i<SPAN class="number token">-1</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="string token">"x"</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">var</SPAN> yprev <SPAN class="operator token">=</SPAN> segment<SPAN class="punctuation token">[</SPAN>i<SPAN class="number token">-1</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="string token">"y"</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">var</SPAN> xcurr <SPAN class="operator token">=</SPAN> segment<SPAN class="punctuation token">[</SPAN>i<SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="string token">"x"</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">var</SPAN> ycurr <SPAN class="operator token">=</SPAN> segment<SPAN class="punctuation token">[</SPAN>i<SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="string token">"y"</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">var</SPAN> len <SPAN class="operator token">=</SPAN> <SPAN class="token function">dist</SPAN><SPAN class="punctuation token">(</SPAN>xprev<SPAN class="punctuation token">,</SPAN> yprev<SPAN class="punctuation token">,</SPAN> xcurr<SPAN class="punctuation token">,</SPAN> ycurr<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">var</SPAN> prevcum <SPAN class="operator token">=</SPAN> cumlen<SPAN class="punctuation token">;</SPAN> cumlen <SPAN class="operator token">+</SPAN><SPAN class="operator token">=</SPAN> len<SPAN class="punctuation token">;</SPAN> <SPAN class="comment token">// if past halfway on line</SPAN> <SPAN class="keyword token">if</SPAN> <SPAN class="punctuation token">(</SPAN>cumlen <SPAN class="operator token">></SPAN> halflen<SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">{</SPAN> <SPAN class="comment token">// calculate midpoint</SPAN> <SPAN class="keyword token">var</SPAN> restlen <SPAN class="operator token">=</SPAN> halflen <SPAN class="operator token">-</SPAN> prevcum<SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">var</SPAN> frac <SPAN class="operator token">=</SPAN> restlen <SPAN class="operator token">/</SPAN> len<SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">var</SPAN> xmid <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">(</SPAN>xcurr <SPAN class="operator token">-</SPAN> xprev<SPAN class="punctuation token">)</SPAN> <SPAN class="operator token">*</SPAN> frac <SPAN class="operator token">+</SPAN> xprev<SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">var</SPAN> ymid <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">(</SPAN>ycurr <SPAN class="operator token">-</SPAN> yprev<SPAN class="punctuation token">)</SPAN> <SPAN class="operator token">*</SPAN> frac <SPAN class="operator token">+</SPAN> yprev<SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">return</SPAN> <SPAN class="string token">"("</SPAN> <SPAN class="operator token">+</SPAN> <SPAN class="token function">Round</SPAN><SPAN class="punctuation token">(</SPAN>xmid<SPAN class="punctuation token">,</SPAN> <SPAN class="number token">2</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="operator token">+</SPAN> <SPAN class="string token">", "</SPAN> <SPAN class="operator token">+</SPAN> <SPAN class="token function">Round</SPAN><SPAN class="punctuation token">(</SPAN>ymid<SPAN class="punctuation token">,</SPAN> <SPAN class="number token">2</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="operator token">+</SPAN> <SPAN class="string token">")"</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="punctuation token">}</SPAN> <SPAN class="punctuation token">}</SPAN> <SPAN class="keyword token">else</SPAN> <SPAN class="punctuation token">{</SPAN> <SPAN class="comment token">// first coordinate pair</SPAN> <SPAN class="keyword token">var</SPAN> xcrd <SPAN class="operator token">=</SPAN> segment<SPAN class="punctuation token">[</SPAN>i<SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="string token">"x"</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">var</SPAN> ycrd <SPAN class="operator token">=</SPAN> segment<SPAN class="punctuation token">[</SPAN>i<SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="string token">"y"</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="punctuation token">}</SPAN> <SPAN class="punctuation token">}</SPAN> <SPAN class="keyword token">return</SPAN> <SPAN class="string token">"Error"</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
Hi Xander Bakker !
Thank you so much for getting back to me so quickly ! I really appreciate your help.
This worked like a champ ! I had to add the Meters to Lat Long Function & concatenation to get what I wanted. I will share the source link here for the benefit. Lat/Long unit conversion with Arcade
I was wondering if you know if this is possible in Arcade :
The ability to grab the x,y of the user's mouse click and put it in Arcade for String Concatenation. (please see snip below)
Thank you so much Xander Bakker!!!!!
Unfortunately, it is not possible to access the exact location where the user clicked. It would be great to be able to do this. Currently for a pop-up you will have access (initially) to the feature geometry where the user clicked, but not the exact location. No problem for point data, but it will be for polylines and polygons.
Thank you so much for the clarification!!
If for some reason that midpoint expression doesn't work, this might be an option:
Buffer the line and get the centroid of the resulting polygon. It's kind of like a "poor man's midpoint".
If I recall, that works ok. But I think I remember the point not being the exact midpoint of the line. I forget what the specific issue was. It's probably good enough for most use cases though...
Are you a wizard?
In Desktop in Toolbox you can use the Data Management > Features > Add Geometry Attributes.
Add the line you're wanting to determine the midpoint for as the Input Feature and check the box next to Line_Start_Mid_End. This will add columns in the line's attribute table showing the coordinates for the Start X and Y, Mid X and Y, End X and Y in the same coordinate system as the line. It doesn't actually create a point but you could then create a feature using these coordinates.
That's an interesting idea.
If I understand correctly, I think you're saying we could:
...reference those "Geometry Attributes" (fields in the attribute table but not in the underlying db table) right in Arcade. I think I've done the same sort of thing with the $feature.shape_length: https://community.esri.com/t5/arcgis-pro-ideas/hascurve-arcade-geometry-property/idc-p/1149449/highlight/true#M18873
Is that what you were thinking?
Never mind. Those "Geometry Attribute" fields aren't dynamic.
Add Geometry Attributes (Data Management)The values in these fields are not automatically recalculated after edits. If you edit the features, you'll need to run this tool again to update the field values.
Add Geometry Attributes (Data Management)
The values in these fields are not automatically recalculated after edits. If you edit the features, you'll need to run this tool again to update the field values.
I meant use that function to obtain the midpoint and then create a point (Editor > Create Feature with Absolute X, Y) in ArcMap.
As I am a novice with Arcade, I am loving this post. Xander Bakker's post works great, but I am like you and need the Lat/Long. You have the code link for that, but I am not sure how to add it to the original function. Can you give me some advice as to where to insert it?
Thank You in advance!
I want to add to the discussion (and possibly be corrected if I'm wrong). This gets the more precise midpoint of the feature, but doesn't always return a point on the line if the line is not straight. If you don't need a precise midpoint and you want the coordinates to be on the line, I've found the easier option is to get the number of a paths in the geometry object, and get coordinates from one of those paths closest to the middle. If there are 11 paths in the segment, get the 5 or 6th and use those coordinates. then it's always on the line, and the code is simpler.
Membros conectados podem postar, seguir atualizações e mais. Novo aqui? Registre uma conta gratuita.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.