Get route m-value at point-clicked using Arcade?

2421
8
Jump to solution
03-05-2020 07:42 AM
NickHarvey
Occasional Contributor II

Hi All - I see that it is possible to access x,y,z, & m values for a custom pop-up using Arcade. The code below appears to be working in ArcGIS Pro 2.5.0 per my route layer:

var line = Geometry($feature)
var paths = line.paths;
var startingpoint = paths[0][0];
return text(startingpoint)‍‍‍‍‍‍‍‍

However, I'm not yet understanding how to return the m-value for any point along the route that was clicked, rather than the centroid or endpoints.  The m-value I'm looking for appears in the pop-up panel at lower right in ArcGIS Pro 2.5.0 (see pic below). 

Any assistance appreciated!  

1 Solution

Accepted Solutions
XanderBakker
Esri Esteemed Contributor

Hi Nicholas Flett and nickharvey 

The limitation with Arcade is that you start off with the geometry you clicked on (you M-enabled line) and not the point location of where you clicked. Therefore, it is not possible to determine at which location of the line feature you clicked when using Arcade. The SDK should allow you to do this, although the complexity of the implementation will increase. 

View solution in original post

8 Replies
BenTurrell
Occasional Contributor III

Hey Nick Harvey‌,

Try this:

var line = Geometry($feature)
var paths = line.paths;
var startingpoint = paths[0][0]["x"];
return text(startingpoint)

Thanks,

Ben


If this answer has helpful please mark it as helpful. If this answer solved your question please mark it as the answer to help others who have the same question.

NickHarvey
Occasional Contributor II

Thanks for chiming in Ben - You're right...I can get to the m-value for the starting point of the route by replacing "x" with "m" for example...But I'm chasing the m-value for any point along the route, as it appears at the bottom of the pop-up panel at 2.5.0 where the route is clicked.  My idea was to build a calculation(expression) in the pop-up which uses this m-value as a variable.  The m-value is being populated at the bottom of the pop-up panel.  I'm not understanding how to reference it into the pop-up body though (?). 

0 Kudos
by Anonymous User
Not applicable

Hi Nick,
Did you make any progress with this?
I'm writing the same expression for start, end and current m values.

var line = Geometry($feature)
var paths = line.paths;
var firstpoint = paths[0][0]["m"];
var lastpoint = paths[0][Count(paths[0])-1]["m"];
var currentpoint = paths

  • ["m"]
    return text(currentpoint)
  • But have no idea what to put in place of the * shown above.
    Is this even the correct approach to using M-values in pop-ups?

    0 Kudos
    NickHarvey
    Occasional Contributor II

    Hey thanks for responding Nicholas - No progress sorry to say...Yeah, my guess is that it is not the right approach for retrieving m-values dynamically along the line because our Arcade expressions above each refer to a specific vertex (?).  As my picture above depicts - m-values do show up in the standard popup though (at bottom right)...I wonder about SDK (?)         

    0 Kudos
    XanderBakker
    Esri Esteemed Contributor

    Hi Nicholas Flett and nickharvey 

    The limitation with Arcade is that you start off with the geometry you clicked on (you M-enabled line) and not the point location of where you clicked. Therefore, it is not possible to determine at which location of the line feature you clicked when using Arcade. The SDK should allow you to do this, although the complexity of the implementation will increase. 

    DISIG
    by
    New Contributor III

    Hello Nick,

    Hello everybody. I am trying to do the same dynamically in Argis Online.(my point geometry change, my m value change in the map context windows)

    I want to use the cut function to get the left length of an intersecting (or nearest) line with M value in a field.

    I will write more after testing all that.

    i have got to 90° rotate the result of a clip between the buffer of my point and the line.

    not easy...

     

    it quite works...

    /*
    récupérer le cumul par intersection du point avec l'arc.
    */
    var CurDep = $feature.ROUTE
    var CurBuffGeom =Extent(Buffer($feature, 2, 'meters'))
    var CurArcGeom = Back(Filter(FeatureSetById($map, /* tests_arcade - Test li */ "17f27378b8d-layer-3"),'route=@CurDep'))
    var CUTTER = rotate(Clip(CurArcGeom,CurBuffGeom),90)
    return LengthGeodetic(first(Cut(CurArcGeom, CUTTER)))

     

    note : replaced first with back (when i flip the cutter, 90° the left part is the end part of the line.)

    0 Kudos
    BartvanderWolf
    New Contributor II

    Hi All,
    Working on the same sort of workflow. I guess what would be handy is a "$clickedlocation" profile variabele.  We could create the geometry object for that location and hopefully extract M and Z-values from "$feature"..

    I try to create a popup for route segments exposing some route statistics. Id also would like to show the progress (M) and elevation (Z) of the clicked location. Only way I can think of to achieve this, is to convert vertices to points and do the popup on that layer.

    DISIG
    by
    New Contributor III

    this final code work fine for me.

    i pre calculate the "M" value.

    // CALCUL DU CUMUL POUR UNE LIGNE
    // version 1.0 2023-03-16

     

    // variables utilisateur
    var CAS            = 0 ;//mettre 0 pour point de début et -1 point de fin
                        console("cas choisis : "+ CAS )
    var SearchingLayer = FeatureSetByName($map,"ROUTE");
    var TOLERANCE      = 20 ;// la variable TOLERANCE de capture fixée à 5 mètres peut être ajustée si nécessaire
                        console("tolérance choisie : "+TOLERANCE)

     

    // 1 - Extraction du point de calcul et recherche
    var myPoint   = Point({x: Geometry($feature)['paths'][CAS][CAS]['x'],y: Geometry($feature)['paths'][CAS][CAS]['y'],spatialReference: { wkid: 102100 }})
                  console("coordonnées de mon point : "+ myPoint)
    var buff      = Extent(bufferGeodetic(myPoint,TOLERANCE,'meters'));
    var myGeom    = myPoint;
    var MySearch = Intersects(BufferGeodetic(myGeom, TOLERANCE, "meters"),SearchingLayer);

     

    // le calcul renvoit -1 pour signifier absence de rd à proximité
    if(isempty(Mysearch)){return -1}
    // dans les autres cas on calcul pour le cas choisi.
    if(count(Mysearch)==1){
              console("cas une seule rd")
      var Arc = first(Mysearch)
    }
    else{
                     console("cas plusieurs rd")
      var EvDistance = Infinity;
      var MyNearest;
      for (var listing in MySearch){
          var DynDistance = Distance(listing,myGeom, "meters");
          if(DynDistance < EvDistance){
            EvDistance = DynDistance;
            MyNearest = listing;
            var Arc = MyNearest
          }
      }
    }
    var longueur  = 0;
    var p         = 0;
    var newLine   = Dictionary(text(Geometry(Arc)));
    var reste     = Round(LengthGeodetic(First(Cut(Arc,Rotate(clip(Arc,buff),90)))));
    var cutter    = Rotate(clip(Arc,buff),90);
    for (p in newLine.paths){
        var segment  = Polyline({paths: [newLine.paths[p]],spatialReference:{latestWkid:3857,wkid:102100}})
        var segLongueur = lengthGeodetic(segment,'meters')
        if (intersects(segment,cutter)==true)
            {return round(longueur+reste)}
        else
            {longueur += segLongueur;}
    0 Kudos