I've attempted to build a Survey123 form that calculates an estimated transmitter location using triangulation based on azimuths and GPS points from 3–5 observer positions. Each observer records:
A geopoint (their current location)
An azimuth (direction of strongest signal via radio telemetry)
The goal was to estimate:
Latitude & longitude of the signal source
Error radius based on variance between intersections
In the XLSForm, I used a repeat group to collect observer location + azimuth, then constructed a triplet_string like lat,long,az | lat,long,az| ... This string was passed to a JavaScript function using:
pulldata("@javascript", "triangulate.js", "triangulateFromRepeat", ${triplet_string}, 0)
The trinagulate.js script included:
parent.triangulateFromRepeat = function(inputString) {
return [estimatedLat, estimatedLon, errorRadius];
};
I tried defining test functions with static return values and packaged a minimal test form which confirmed that Survey123 could see the script but not invoke any function inside it.
Despite following Esri's documented pattern (parent.functionName = ...), Survey123 Connect (v3.22.49) consistently returned:
@javascript error: TypeError: Property 'functionName' of object [object Object] is not a function
This occurred with multiple valid JS definitions, a stripped-down test form, and with clean scripts with no syntax errors.
Are functions defined with parent.functionName = ... not accessible?
Any thoughts on how to estimate a location using triangulation using multiple points and azimuths inside of Survey123?
I figured this out and am posting it here for anyone else who might be attempting to get Survey123 to estimate a location based on triangulation. This is a fairly common thing to do in wildlife radiotelemetry surveys. Note, as this requires JavaScript, this can only be implemented by a user that is signed in to the same organization as where the form originated. (An ESRI imposed security limitation.)
Using `pulldata('@javascript', 'triangulate.js', 'triangulate', ${location1}, ${azimuth1}, ...)` does not work. This approach assumes positional arguments in JavaScript but Survey123 passes only one JSON object. The key step was using a calculate field named 'json_input' with bind::type=string to concat the latitudes, longitudes, and azimuths that are used by the script to estimate the actual location.
I'm attaching both the xlsform and the javascript file (zipped). Certainly interested in any feedback on this approach! Thanks. -- Greg