I'm trying to use a pulldata javascript function in S123Connect to calculate a polygon from a point or line geometry provided by the user.
I have a survey with 1 geom_type field (select_one geom_types with values "polygon","polyline","point") and 3 geometry fields:
- pol -> geoshape, will be stored in the feature service, with a calculation
if(selected(${geom_type},'polyline'),
pulldata("@javascript","functions.js","to_polygon",string(${ply}),
if(selected(${geom_type},'point'),pulldata("@javascript","functions.js","to_polygon",string(${pnt}),
null)
- ply -> geotrace, will not be stored in the feature service (esriFieldType null), relevant if: selected(${geom_type},'polyline')
- pnt -> geopoint, will not be stored in the feature service (esriFieldType null), relevant if selected(${geom_type},'point')
I have a javascript function to_polygon(location) that will take location from ${ply} or ${pnt} and return a polygon:
- from ${pnt}: project the point using ArcGIS Online geometry service to a point in Web Mercator, then use an offset to calculate the polygon as a square, reproject the square to EPSG: 4326 and return coordinates as a string
- from ${ply}: project the polyline using ArcGIS Online geometry services to a polyline in Web Mercator, then calculate a polyline at an offset, add coordinates from both lines (coordinates from the offset line in reverse order) and close with starting point from polyline to create the polygon. Reproject the polygon back to EPSG:4326, return coordinate list as a string
Before implementing the whole function I created a small prototype function to test if the mechanism would actually work with a simple point, not yet implementing the projection stuff:
function to_polygon(location) {
if (location ==="") {return "Location is empty"}
var geom = "";
if (location.includes("rings")) {
geom = jSON.stringify(location);
} else if (location.includes("paths")){
geom = jSON.stringify(location);
} else {
var pt_0 = {"x":location.split(" ")[0],"y":location.split(" ")[1],"spatialReference": {"wkid": 4326}};
geom = geom + (parseFloat(pt_0["x"]) - 0.00001).toString() + " " + (parseFloat(pt_0["y"]) - 0.00001).toString() + ";";
geom = geom + (parseFloat(pt_0["x"]) + 0.00001).toString() + " " + (parseFloat(pt_0["y"]) - 0.00001).toString() + ";";
geom = geom + (parseFloat(pt_0["x"]) + 0.00001).toString() + " " + (parseFloat(pt_0["y"]) + 0.00001).toString() + ";";
geom = geom + (parseFloat(pt_0["x"]) - 0.00001).toString() + " " + (parseFloat(pt_0["y"]) + 0.00001).toString() + ";";
geom = geom + (parseFloat(pt_0["x"]) - 0.00001).toString() + " " + (parseFloat(pt_0["y"]) - 0.00001).toString() + ";";
}
return "\""+ geom + "\"";
}
If I test my function and store the function result in a text field, it works, see screenshot below. However, if I try to refer to the outcome in a calculation for the geoshape field, I receive the following error: ODK Validate Errors: Sometthing broke the parser. See above for a hint. Error evaluating field 'pol': For input string: "@javascript" caused by: java,lang.NumberFormatException: For input string: "@javascript" ... 10 more Result: Invalid.
If I copy the function result
"51.87814892676192 5.15626525895422;51.87816892676192 5.15626525895422;51.87816892676192 5.156285258954219;51.87814892676192 5.156285258954219;51.87814892676192 5.15626525895422;"
in the calculation for pol, I get the expected polygon for the pol.
So the problem doesn't seem to be in the function result itself but in the parsing of the function and calculation expression.

Any ideas How I could solve this issue (other than convincing the user that he shouldn't want this flexibility in drawing geometries😀?)