diff --git a/packages/xpath/src/functions/xforms/geo.ts b/packages/xpath/src/functions/xforms/geo.ts index 37e59556..27c9337b 100644 --- a/packages/xpath/src/functions/xforms/geo.ts +++ b/packages/xpath/src/functions/xforms/geo.ts @@ -82,11 +82,22 @@ const INVALID_LINE: Line = { end: INVALID_POINT, }; +/** + * Takes an {@link pointsArg} representing a serialized sequence of geopoints, + * producing an array of {@link Line}s. + * + * Corresponds to the semantics of _a single argument_ from either of the + * following functions, specified by ODK XForms: + * + * - {@link https://getodk.github.io/xforms-spec/#fn:area | area} + * - {@link https://getodk.github.io/xforms-spec/#fn:distance | distance} + */ const evaluateLines = ( context: EvaluationContext, - expression: readonly EvaluableArgument[] + pointsArg: EvaluableArgument ): Line[] => { - const points = expression.flatMap((el) => evaluatePoints(context, el)); + const points = evaluatePoints(context, pointsArg); + if (points.length < 2) { return [INVALID_LINE]; } @@ -170,8 +181,8 @@ const geodesicArea = (lines: readonly Line[]): number => { export const area = new NumberFunction( 'area', [{ arityType: 'required' }], - (context, [expression]) => { - const lines = evaluateLines(context, [expression!]); + (context, [pointsArg]) => { + const lines = evaluateLines(context, pointsArg!); if (lines.some(isInvalidLine)) { return NaN; @@ -209,8 +220,10 @@ const sum = (values: readonly number[]) => { export const distance = new NumberFunction( 'distance', [{ arityType: 'required' }, { arityType: 'variadic' }], - (context, args) => { - const lines = evaluateLines(context, args); + (context, pointsArgs) => { + const lines = pointsArgs.flatMap((pointsArg) => { + return evaluateLines(context, pointsArg); + }); if (lines.some(isInvalidLine)) { return NaN;