Select to view content in your preferred language

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

3263
9
Jump to solution
03-05-2020 07:42 AM
NickHarvey
Frequent Contributor

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

9 Replies
BenTurrell
Frequent Contributor

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
Frequent Contributor

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
    Frequent Contributor

    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. 

    JosephJordan
    New Contributor

    This is FINALLY possible, with the addition of the $userInput profile variable!  Try this:

    var geom=Geometry($feature)
    var densegeom=Densify(geom, 1)
    var PTC=PointToCoordinate(densegeom, $userInput)
    var SegNum=PTC.segmentID
    var paths=densegeom.paths
    var POI = paths[0][SegNum];
    return round(POI.m,4)

    https://www.youtube.com/watch?v=dddZTpsOjY0

    For years I've wanted a way to click a line record in a Web App and extract the Log Mile clicked. (The same way you can in ArcGIS Pro). I've also always wanted to be able to perform dynamic segmentation within web applications. With the arcade geometry functions released this year, this is finally
    0 Kudos
    DISIG
    by
    Regular Contributor

    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
    Emerging Contributor

    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
    Regular Contributor

    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