Can't pass attributes of a line from Collector to S123

3521
12
03-30-2020 10:05 AM
CesarAvila
New Contributor II

Hi. 

Basically here is the worflow:

From collector app, select one of the lines (see 1st screenshot). In the pop out window from collector there is a link that will open a survey in S123. Once the app is open, in the survey there are attributes passed from Collector but doesn't fill out the "Polyline" (see 2nd screenshot). It's possible to "pass" the line attribute from Collector to the "Polyline" in S123? I just put it like a "geotrace", but basically what I want is to "draw" that geotrace line from collector to s123.

collectorSurvey123 for

 

Thanks!

Tags (1)
12 Replies
BrettStokes
Esri Contributor

Hi Cesar,

This is certainly possible using an Arcade expression. Here are some detailed instructions on setting this up (the example is using a polygon but the steps are the same). This hasn't quite made it into a blog yet..

Brett

Pre-populate a Survey123 form with Existing Feature Layer Line/Polygon geometry via Custom URL

With Survey123 version 3.6+, line and polygon geometry capture is available via the `geotrace` and `geoshape` question types. You may be familiar with calculating geopoint questions which requires a set of text in the format `<LAT> <LON>`. Geotrace and Geoshape questions both extend this format to support a sequence of points; the format is `<LAT1> <LON1>;<LAT2> <LON2>;<LAT3> <LON3>;...`.  A polygon will automatically close (create a segment from the last point to the first point).  We can create an Arcade expression to calculate this sequence from the geometry of a line/polygon feature:

 

Line

var geom = Geometry($feature);

var outparts = [];

var counter = 0;

for (var p in geom.paths){

    var thispath = geom.paths

;

    for (var pt in thispath){

        var ptstr = Concatenate(thispath[pt].y, " ", thispath[pt].x);

        outparts[counter]= ptstr;

        counter = counter + 1;

    }  

}

Return Concatenate(outparts, ";")

Polygon

var geom = Geometry($feature);

var firstpart = geom.rings[0];

var outparts = [];

var counter = 0;

for (var pt in firstpart){

    var ptstr = Concatenate(firstpart[pt].y, " ", firstpart[pt].x);

    outparts[counter]= ptstr;

    counter = counter + 1;   

}

return Concatenate(outparts, ";")

 

This allows us to pass the geometry into Survey123 to pre-populate the geotrace/geoshape question via a custom URL.

 

Steps

1) Open your web map to configure the pop-up for your polygon layer. *Note that for Survey123 to read the coordinates properly, the map must be in WGS84 (SRID 4326) projection.

2) Add a new Attribute Expression.

3) Copy/paste the Arcade expression (blue text above) into the Expression dialog and click OK (I'm using the polygon expression in this example):

 

 4) You should now see your attribute expression in the list (I renamed mine to ‘Shape as Text’):

 

 5) Construct your custom URL (to add as a link in the pop-up) using the 'field:<question_name>={field_name}' syntax to set the value of the geoshape question.

 

See the Understanding Survey123's custom URL Scheme blog post for more details on where to find your itemID etc.

 

Here is an example URL that passes values for 5 attribute fields plus the geometry field (also the geoshape question name highlighted in yellow):

 

 

arcgis-survey123://?itemID=7bf73e2a957a4d1c8ce899771af0db3e&field:PARCEL_PFI={PARCEL_PFI}&field:PARCEL_SPI={PARCEL_SPI}&field:PC_PLANNO={PC_PLANNO}&field:PC_LOTNO={PC_LOTNO}&field:extra_comments={extra_comments}&field:Parcel_polygon={expression/expr0}

 6) Change your ‘Pop-up Contents’ to display a custom attribute, then click ‘Configure’:

 

7) Add some text (eg ‘Launch Survey’) to use as your link and copy / paste in your custom URL:

😎 Click OK to close the ‘Configure Pop-up’ and save your webmap.

 

You should now be able to click on a polygon to see the pop-up and then follow the link to launch the survey. The survey form will pre-populate with the geometry and attribute values you included in your URL:

    

 

    

Limitations

1) Note that for Survey123 to read the coordinates properly, the map must be in WGS84 (SRID 4326) projection. Esri offers a number of basemaps in this projection.

2) The line script assembles multiple parts into a single-part geometry.

3) The polygon arcade expression only uses the first part of the shape; this will not include 'donut holes' in polygons, multipart etc.

AprilChipman
Occasional Contributor III

This post was so very helpful! Thank you!!  I am still having problems getting my survey points to center on points from existing layers. They keep showing up on the west coast of Africa!

Is there something wrong with my URL or attribute expression?

arcgis-survey123://?itemID=xxxxxxx&field:comments={wmMapName}&field:stormpoint={expression/expr0},{expression/expr1}

(This one put the point where I was standing, not over the existing feature.)

arcgis-survey123://?itemID=xxxxxxx&field:comments={wmMapName}&center={expression/expr0},{expression/expr1}

(This one put the point off the west coast of Africa.)

'Attribute Expression for Longitude (expr0)

var originShift = 2.0 * PI * 6378137.0 / 2.0;

var lon = (Geometry($feature).x / originShift) * 180.0;
var lat = (Geometry($feature).y / originShift) * 180.0;

lat = 180.0 / PI * (2.0 * Atan( Exp( lat * PI / 180.0)) - PI / 2.0);
return lon;


'Attribute Expression for Latitude (expr1)

var originShift = 2.0 * PI * 6378137.0 / 2.0;

var lon = (Geometry($feature).x / originShift) * 180.0;
var lat = (Geometry($feature).y / originShift) * 180.0;

lat = 180.0 / PI * (2.0 * Atan( Exp( lat * PI / 180.0)) - PI / 2.0);
return lat;

I tested the points and lines on the same webmap with layers from the same existing feature service. Obviously, I used two different surveys.

0 Kudos
CesarAvila
New Contributor II

Use this arcade expression for the points:

function LatLon(x, y) {

var lon = (Geometry($feature).x);
var lat = (Geometry($feature).y);

return [lat, lon];
}
function CreateURLSurvey(lat, lon) {
var url = lat + "," + lon;// This is the line that defines the location
Console(url);
return url;
}

var latlon = LatLon(Geometry($feature).X, Geometry($feature).Y);
var url = CreateURLSurvey(latlon[0], latlon[1]);
return url;

After that, your URL need to have "&center=" followed by the expression name.

example: arcgis-survey123://?itemID=d6b57a44f78d4c5388f4a82a6d208c89&center={expression/expr0}

0 Kudos
AprilChipman
Occasional Contributor III

Thank you, Cesar!

This appears to have worked in my testing maps and layers - now to put it into the in-use versions! 

Do you have a solution or any further news on being able to use a script like this on a layer inside a feature service with many layers? When I try to add the Attribute Expression, I get "Runtime Error: Cannot call member method on null." My workaround is to individually add all the layers that I need to use with Survey123, but that certainly gets cumbersome for both administrators and end-users.

I've also got some use cases for the lines and polygons being populated from existing features. I'm adding those to my 'To Do' list now!

Thanks again!

0 Kudos
by Anonymous User
Not applicable

Thanks for posting this Brett. I'm getting an error when testing the "Lines" code:

Execution Error:Runtime Error: Cannot call member property on object of this type. y

Any idea on why this would be and how to fix? Thanks.

ToddHelt
New Contributor III

Matt, did you every get a solution for the "Execution Error:Runtime Error: Cannot call member property on object of this type. y"? I am encountering the same issue with the passing polyline geometry to a Survey123 survey.  Thanks!

Todd

0 Kudos
by Anonymous User
Not applicable

Yes. Here is the Arcade expression I am using.

 

var paths = Geometry($feature).paths;
var originShift = 2.0 * PI * 6378137.0 / 2.0;
var outparts = [];
var counter = 0;
var thispath = paths[0];
    for (var pt in thispath){
        var lat = (thispath[pt].y / originShift) * 180.0;
        lat = 180.0 / PI * (2.0 * Atan( Exp( lat * PI / 180.0)) - PI / 2.0);
        var lon = (thispath[pt].x / originShift) * 180.0;
        var ptstr = Concatenate(lat, " ", lon);
        outparts[counter]= ptstr;
        counter = counter + 1;
    }  
Return Concatenate(outparts, ";")

arcgis-survey123://?itemID=YOURITEMID&field:LINE={expression/expr0} 

ToddHelt
New Contributor III

Awesome Matt, that worked like a charm, thanks so much for sharing!

Todd

0 Kudos
JamieLambert
Occasional Contributor III

This one worked for me - thanks for sharing Matt!