Spec proposal: expose xforms-value-changed event with odk:setgeopoint action in XLSForm

or, "programmatically set a geopoint when the user changes the value of a control/question" :slight_smile:

What high-level problem are you trying to solve?

This is a proposal to expose the odk:setgeopoint action functionality that currently exists in both Collect and Enketo, which can be triggered in response to an xforms-value-changed event; that is, programmatically set a geopoint when the user changes the value of a control/question. This functionality already works today - in XForms - but is not yet exposed in XLSForm, so currently the only way to add this functionality into your form is by manually editing the XForm XML file.

[please skip to the summary at end if you are less interested in understanding the thought process that got there... :upside_down_face:]

Background

Currently there is existing functionality in both Collect and Enketo to programmatically capture the current GPS location, instead of requiring user input via an explicit geopoint question. This is accomplished via the odk:setgeopoint action. This action, along with the setvalue action, are the two ODK supported XForm actions. Both of these actions can be invoked in response to events; specifically, the odk-instance-first-load, xforms-value-changed, and odk-new-repeat events.

The odk:setgeopoint action permits a form designer to programmatically capture the current GPS location when the form is first started (odk-instance-first-load event), or whenever the user answers or changes a specific question (xforms-value-changed event), or when the user adds a new repeat group (odk-new-repeat event). There are examples of all three cases in the ODK XForms spec. The specific XForm case we want exposed via XLSForm is this:

<bind nodeset="/data/my_text" type="string" />
<bind nodeset="/data/my_text_changed" type="string" />
<bind nodeset="/data/my_current_location" type="string" />
...
<input ref="/data/my_text">
    <setvalue event="xforms-value-changed" ref="/data/my_text_changed">Value changed!</setvalue>
    <odk:setgeopoint event="xforms-value-changed" ref="/data/my_current_location" />       <======= MISSING IN XLSFORM!
</input>

However, presently only the odk-instance-first-load invoked GPS capture is exposed in XLSForm, as the XLSForm start-geopoint question. [aside: start-geopoint is predominantly used to 'warm-up' the GPS sensor for subsequent geo-questions in the form, but what it is actually doing is capturing the current GPS location - via the odk:setgeopoint action - upon initializing a new form, thereby warming up the GPS for later use].

Related to this discussion is the xforms-value-changed event which, in effect, is presently exposed in XLSForm as the trigger column. Basically, what happens in XLSForm is that when a question row (the 'dependent') has a trigger associated with it, the trigger field identifies the triggering control question (the 'antecedent'), which when its value changes will cause, or 'trigger', the dependent question's calculation to be executed and thus assign it a new value. This triggering behavior is now an established pattern that makes sense to XLSForm builders, although what is really happening under-the-covers in the XForm itself is that the triggered calculation is actually defined against with the antecedent control (!), telling it to perform said calculation whenever that control's value changes, and then update the specified target instance element with the result. So although the trigger (aka antecedent) and calculation appears to be associated with the desired target row (aka dependent) in XLSForm, in the actual XForm definition the location in the form definition where this is actually defined is somewhat reversed. To give a more concrete example, the following XLSForm

Screenshot 2024-08-09 at 4.30.26 PM

translates to this XForm:

<?xml version="1.0"?>
<h:html
    xmlns="http://www.w3.org/2002/xforms"
    xmlns:h="http://www.w3.org/1999/xhtml"
    xmlns:ev="http://www.w3.org/2001/xml-events"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:jr="http://openrosa.org/javarosa"
    xmlns:orx="http://openrosa.org/xforms"
    xmlns:odk="http://www.opendatakit.org/xforms">
    <h:head>
        <h:title>Simple Trigger</h:title>
        <model odk:xforms-version="1.0.0">
            <instance>
                <data id="SimpleTrigger" version="1">
                    <temp/>
                    <temp_ts/>
                    <meta>
                        <instanceID/>
                    </meta>
                </data>
            </instance>
            <bind nodeset="/data/temp" type="int"/>
            <bind nodeset="/data/temp_ts" type="dateTime"/>
            <bind nodeset="/data/meta/instanceID" type="string" readonly="true()" jr:preload="uid"/>
        </model>
    </h:head>
    <h:body>
        <input ref="/data/temp">
            <label>Enter the current temperature</label>
            <setvalue ref="/data/temp_ts" event="xforms-value-changed" value="now()"/>
        </input>
    </h:body>
</h:html>

As you can see, all the actual triggering stuff - the xforms-value-changed event, the setvalue action, and the calculation definition - actually reside under the antecedent triggering question's XForm definition. Whereas the dependent question - ie the entire temp_ts row - is merely the target of the setvalue action's ref.

More background: Current XLSForm trigger behavior

As described above, IMO the existing trigger column in XLSForm basically represents the xforms-value-changed event; that is, when the specified triggering question's value changes (the antecedent), perform some action against the control for that row (ie the target, or dependent). Presently, this action is always a setvalue action, which either (a) evaluates the associated calculation and store the result in the specified target's element, or (b) if the calculation is empty then clear the target element's value. From https://xlsform.org/en/#trigger:

...An important and powerful difference with regular calculations is that the calculation value with a trigger may also be empty, which serves to clear a value from the form.

This last point is quite important, because it stipulates that irrespective of whether the triggered calculation contains something or is empty, you will always perform a setvalue action against the target element whenever the triggering element's value changes!

Whereas, what is desired here - and what is already possible to define in the raw XForm... - is to instead perform a odk:setgeopoint action when the triggering element's value changes. That is, if we consider the XLSForm trigger column does effectively just represent the xforms-value-changed event, then it rather needs to be 'decoupled' somewhat from the otherwise always-implied setvalue action; there are other valid actions you can associate with xforms-value-changed event.

Requirement

To reiterate, the desired xforms-value-changed event-triggered odk:setgeopoint action already works; what is needed is just to appropriately expose this in XLSForm; specifically, in a manner that remains consistent with and sympathetic to the existing behavior of XLSForm triggers (which are all currently setvalue-only).

A trigger-based XLSForm which updates a geopoint, in response to answering or changing the value of a form question, I think would most intuitively appear in an XLSForm something along the lines of:

Screenshot 2024-08-09 at 4.52.43 PM

This is consistent with existing trigger functionality, which can be applied to arbitrary data types; eg dateTime, text, calculations, etc. From XLSForm trigger spec:

Screenshot 2024-08-09 at 4.55.36 PM

So you might expect the same could be applied to trigger programmatically setting a geopoint. But now instead of, say, setting a dateTime to now() when the trigger ${temp} is fired, we instead want to set a geopoint value using odk:setgeopoint.

This immediately suggests a possibility of perhaps just introducing a new function, say setgeopoint(), with which to put in the calculation field to indicate setting the geopoint value with odk:setgeopoint instead. However, in all other contexts, the XLSForm calculation field is just that - it specifies the actual XPath expression to perform, and there is no actual valid 'setgeopoint()' function [indeed, it was deliberate decision not to make setgeopoint a function; see Spec addition proposal: location preload - #9 by martijnr].

Further, adding something into the existing calculation field for this could lead to form designers thinking they can use it in other calculations in other contexts, when it fact it is not and could only be used in conjunction with the specific xforms-value-changed event trigger. It is for these reasons that I'm not keen on adding what would basically be 'semantic sugar' to the existing XLSForm calculation field to accomplish this; it doesn't feel right.

Proposal

As stated earlier, I think it is natural to re-use the existing XLSForm trigger mechanism to expose an xforms-value-changed event triggered odk:setgeopoint action, because this is consistent with the existing usage of (event) triggers in XLSForm. Therefore, what is needed is a new means in XLSForm to override the current always-implied setvalue action. Unfortunately, as described above, it is not sufficient to use the lack of a calculation to perhaps identify when not to perform a setvalue because an empty calculation is already defined to mean simply blank the dependent value!

It is for this reason that I think it may be unavoidable to have to introduce a new column type to the XLSForm survey worksheet [as loath as I may be to add new columns...]; we legitimately want to re-use the trigger column, but we cant repurpose the calculation column, and none of the other existing survey worksheet columns seem to lend themselves to this purpose (eg the existing optional parameters column cannot be used, because this applies the parameters into the dependent question, whereas the trigger stuff actually resides under the antecedent question, as described earlier)

An additional XLS column in the survey worksheet to indicate performing a odk:setgeopoint for the (presumably specified) trigger could be a simple as a dedicated column with the value true. eg

Here, if a row has a trigger defined, and setgeopoint = true, then perform a odk:setgeopoint action storing a GPS location for that row. Otherwise (if setgeopoint is missing, or false) then perform the de facto a setvalue action and store whatever the calculation field says (or blank if empty). That is, the setgeopoint = true overrides the trigger's default setvalue behavior.

The main disadvantage I see with this solution is that it may not scale well should we want to introduce further new actions in the future (eg perhaps automatically take a picture?, or make an API call when a question is answered? etc). With this approach every new action type would require adding a new column. Further, some of these new actions might involve additional parameters (eg a URL for making an API call...), which may mean adding additional columns to specify action-specific parameters.

So instead I might propose adding a new fairly generic action column - called say "action" - which, when non-null, specifies what specific XForm action to take in response to the trigger, the default being a setvalue action (with its implied calculation...) should no action be specified, in order to maintain backward compatibility with how things work today. That is

(I dont see why not use the actual odk:setgeopoint XForm action name here)

I also see no need to complicate things further by permitting more than one action [each with potentially its own parameters...], although in principle this can certainly be supported in XForms. But an inability to express in XLSForm having multiple antecedent questions performing actions against the same target question is no worse than what already exists today. Although in XForms you may have multiple antecedent questions performing multiple setvalue (each with their own calculation...) against the same ref element [remember, the triggering stuff is actually defined against the triggering question, not the target!], there isnt any way to express this in XLSForm, because each row can only define at most one trigger. Which is to say, I think restricting it to a single action column where you can optionally specify a single action may suffice.

Other options

Another option, which is ostensibly equivalent to the above, is instead of having a separate action column containing the desire action override, instead put the action specifier alongside the triggering question identifier in the existing trigger column. eg

Given that the odk:setgeopint doesn't require any further parameters itself, this would be functionally identical to the proposed new explicit action column approach. My personal preference is however for an explicit 'action' column, because I think it could be useful going forward to be able to distinctly identify actions in an explicit manner in XLSForm, outside of the ostensibly xforms-value-changed only event-specific 'trigger' column. Indeed, XForm actions and XForm events are quite distinct from each other, so the ability to somewhat maintain a (extensible) clear separation may become more beneficial as ODK event-actions evolve and mature.

Summary

In summary, this is a proposal to expose existing the odk:setgeopoint action functionality which exists in both Collect and Enketo, in XLSForm when the user answers or changes a form control value; that is, in response to an xforms-value-changed event. This will permit programmatically capturing a geopoint when the user answers a question. This functionality already works but only in XForms; it is not yet exposed in XLSForm, so currently the only way to add this functionality into your form is by manually editing the XForm XML file. The proposal is to add a new 'action' column to XLSForm with which to specify performing a odk:setgeopoint action in response to the trigger instead of the default setvalue calculation.

Comments and suggestions of alternative or better solutions most welcome. We have an immediate need for this existing ODK functionality to be exposed in XLSForm, and given that the underlying functionality already works, in XForm, and doesnt actually require any changes to either Collect or Enketo to support, it would be nice to get something suitable defined for XLSForm soon and then proceed in making the necessary code changes in pyxform to consume it. Many thanks,

  • Gareth
3 Likes

Note, the above gives an example of what this would look like (in XLSForm) for programmatically setting an explicit geopoint question in your form; that is, overriding what location the user might enter.

But much like the existing trigger temperature examples in the spec, you could potentially trigger the setgeopoint action against an otherwise 'hidden' calculate, or perhaps readonly text question if you want to show the captured location but not permit the user to change it.

[I note that having a (hidden) calculate question with a blank calculation will currently throw a 'Missing calculation' pyxform error. This can either be relaxed to a warning, or at worst - because the proposed behavior will ignore the calculation column if an action is specified - you could put anything in here...]

1 Like

Bump...

As mentioned, we (KoboToolbox) have an immediate need to expose this existing Collect and Enketo functionality in XLSForms too. We (Kobo) also now have resources committed to implement the necessary changes to pyxform for the proposed spec changes. But obviously we want to make sure the proposed approach - as outlined above - is appropriate and aligns with existing XLSForm trigger usage and behavior.

Sorry if my proposal is a bit long-winded or esoteric, but I did want to thoroughly explain the rationale, and why I found it a bit tricky to add new action(s) to what is ostensibly the setvalue-only existing xforms-value-changed event behavior, as presently surfaced by XLSForm triggers.

I'd be happy to facilitate any discussions needed on how we might move this forward (@LN?). I do think surfacing this existing ODK XForm functionality finally in XLSForm would be a benefit to the broader ODK community.

I’m not sure whether this was surfaced in one of the original design threads for start-geopoint but I remember some discussion around introducing another similar type — something like bg-geopoint — for the value-changed and new-repeat events. The value-changed case would require a reference in the trigger column and the new-repeat case might be implied by being contained in a repeat. The nice thing about introducing an XLSForm type is that it makes the point source easy to see when skimming a form.

Automatically capturing location on new repeat creation can be pretty interesting for some kinds of walking/traveling surveys so it would be nice to have a path to that as well if possible.

I’ll try to give your proposed concept more thought early next week.

A new datatype would preclude being able to overwrite an existing geopoint question with a new location, when triggered obviously, something which current trigger behavior permits, right? But yes this approach may be simpler to understand and more immediately obvious in XLSForm [at perhaps limiting the full functionality that would be available in a custom XForm, but then we're already doing limiting this regular set-value triggers...). Nice idea. :+1:

So, basically, the type of the question (that has the trigger...) determines the XForm action to perform: if type=bg-geopoint then perform a xforms-value-event with the odk:setgeopoint action (and completely ignore whatever happens to be in the calculation?), whereas if it is any other type then perform a xforms-value-event with the set-value action, using whatever is in the calculation.

So presumaly this new bg-geopoint would always require a trigger?

So is it going to be necessary to resolve the odk-new-repeat event-driven odk:setgeopoint action - at least wrt XLSForm spec exposure - before we can proceed with the xforms-value-changed one? aka

<odk:setgeopoint event="odk-new-repeat" ref="/data/person/location" />

...and for that matter, what about the odk-new-repeat event-driven setvalue action too... [oh my! :face_with_spiral_eyes:]

<setvalue event="odk-new-repeat" ref="/data/person/age" value="../../my_age + 2" />

Obviously, I'd prefer to limit the scope to just the one aforementioned usecase for now.

We'd like to have a clear, coherent specification path to the odk-new-repeat case before any implementation begins. If you'd like to take on implementation of a subset of the spec we agree on, that would be fine.

I believe this case is already addressed by the default column in a repeat: if there's a dynamic expression in the column, pyxform generates a setvalue action.

Yes, after giving this some more thought, I still think this is our best bet out of the ideas considered so far. When we were first considering how to expose events and actions in XLSForm we discussed whether to expose the raw concepts or whether to try to expose something more related to users' end goals.

Like you mention, it's a tradeoff between ease of use and flexibility. We ultimately decided to try to capture the spirit of the specific problems an action is introduced to address. For example, setvalue is about setting defaults that users can override (we don't have things like user-specified buttons like W3C XForms and are unlikely to) and setgeopoint is about capturing locations in the background as a kind of metadata. If we introduce any other actions, we imagine they are likely to similarly have specific use cases that can be exposed as such.

That's how we ended up with start-geopoint and I continue to think bg-geopoint fits in nicely with that model.

Yes, I imagine bg-geopoint would require a reference in the trigger column and not allow values in any other column other than name. There would likely be an exception if we use bg-geopoint for the odk-new-repeat event case.

But what I wrote above about setvalue in repeats made me think that we could consider doing something similar for capturing background location at the start of a repeat. Instead of using the new bg-geopoint type, we could use the existing start-geopoint and say that if it's in a repeat, it captures the location when the repeat instance is created.

I think using bg-geopoint for this would also work -- if it's in a repeat, trigger would be optional. I don't currently have a strong preference between the two and feel satisfied that the general bg-geopoint approach would give us a path to the odk-new-repeat event case whenever that gets implemented.

@Lindsay_Stevens_Au I'd appreciate your sanity check on this thread! Maybe you see advantages to the action column that @Xiphware suggested that I'm missing? Or possible challenges with introducing a bg-geopoint type?

Whole lot of insights here. Something crosses my mind for bg-geopoint on repeat, I like this idea. but not sure whether it will make complete sense for my practice. Imagine if I walked from A to B, usually after I finish repeat A, I will 'Go to the next repeat' straight away, which is B before I even reach B destination. In other words, the geopoint recorded for B repeat is actually indicative of A repeat's location.

There are also data collector advancing to the next repeat only when they are at the new location. In this way, the geopoint will be indicative of B repeat's location. I think it require changes on practice in order to get accurate representation for geopoint question.

Having geopoint reset on trigger by changes on custom field (particularly text input /qr code) also makes a lot sense too, at least it will not be affected by the data collector's practices. The geopoint always can ties to id field and reset when id changed.

Good observation; thank you for raising in it!

FWIW I expect whatever 'backgroundy' stuff happens whenever an enumerator indicates to start a new repeat - be in a setvalue trigger or a background odk:setgeopoint - that all these actions will occur at the same instant; ie all ultimately tied to the underlying odk-new-repeat event.

So it may well be the case that additional training/best-practices may be required to ensure enumerators dont actually start new repeats, presumably for the purpose to acquiring a new set of data, until they are actually in the position - both spatially or temporally - to do so.

Having geopoint reset on trigger by changes on custom field

Note, this sounds basically like the proposed xforms-valued-changed background geopoint. It is probably worth noting that a new-repeat triggered geopoint wont (or shouldnt!) preclude also permitting such a 'regular' background setgeopoint question inside a repeat; that is, saving a geopoint when you first start the repeat, and also potentially saving further geopoints when you answer specific questions within it. These are entirely different events, in XForms, and need be to exposed as such in XLSForms too.

Yup, at this point we'd only be taking on the pyxform changes needed for an xforms-value-changed triggered odk:setgeopoint action

But I agree it's important this work be done in a manner that will be consistent spec-wise with how we'd anticipate this looking for odk-new-repeat.

Yes, I imagine bg-geopoint would require a reference in the trigger column and not allow values in any other column other than name. There would likely be an exception if we use bg-geopoint for the odk-new-repeat event case.

As I thought about this more, I'm now leaning more not trying to reuse this new bg-geopoint for new repeats; but, instead, actually reuse the existing start-geopoint (!). My rationale is that it's still quite possible that we might want to capture GPS locations when various questions inside a repeat change, in addition to capturing one when the repeat is first begun, or 'started'... But having a similar looking 'bg-geopoint' question for both in a repeat seems like it would be confusing. Instead, by re-purposing the existing start-geopoint question type within a repeat we can use its context - that of being inside a repeat - to identify that this should actually be mapped to an odk-new-repeat style setgeopoint. Whereas, a start-geopoint question at the 'root' level of the form (specifically, outside of any repeat) would identify that it should be mapped to an odk-instance-first-load style setgeopoint; that is, our existing start-geopoint behavior.

[which I think might be what you were saying too, @LN ? :thinking:]

This would have the added benefit of being able to universally state, in the XLSForm spec, that "bg-geopoint MUST always have a trigger" and "start-geopoint MUST never have a trigger", irrespective of their context.

Yes, that seems likely without a form update. A form could be changed to add a last question in repeats that gives instructions to navigate to the next repeat's location.

In general, I think these background point captures are most useful for sanity checks, auditing or opportunistic location capture. If you really want to know the precise location of a thing, I'd recommend using the geopoint questions that involve the end user.

I see capturing the location at the start of every repeat instance as most useful for lightweight auditing. You could view the shape described by all the points across the repeats to get a sense of where your data collector traveled. For this kind of usage, it doesn't matter too much whether the location is related to the current or previous repeat, you're just looking at the overall shape to make sure a data collector didn't just go sit under a tree and start fabricating data partway through the survey.

Yes, agreed that this will give the form designer more control in general. While I do agree that it will generally be better-suited for capturing the location of a thing, if that location is important data to capture, I would still recommend the user-controlled location capture.

Yes, exactly!

I like that clarity as well.

I'd still like @Lindsay_Stevens_Au's sanity check at some point. That could be in code review since this should be relatively straightforward to implement and not a huge deal if it needs to be modified.

2 Likes

OK. I'll go ahead and create a new github issue for pyxform to implement the proposed spec changes for this. There's a few other (mis?)behaviors that I have detected in the handling of both odk:setgeopoint, and for that matter existing setvalue, actions - in Enketo only - when used in conjunction within repeat groups which I want to fully document; there may need to be some additional documentation in the spec describing the correct behavior for these edge-cases.

I recommend taking a look through Enketo issues and especially https://github.com/enketo/enketo/issues/298#issuecomment-1830501583 and https://github.com/enketo/enketo/issues/298#issuecomment-1830501607

1 Like

So now for the really hard, tricky, technical question... what do we call this new XLSForm question type?! :slight_smile:

bg-geopoint
background-geopoint
save-geopoint
BFG (Background Friendly Geopoint)
...

[I'll propose the former for now, unless there are strong opinions otherwise...]

Whether it's a question type, new column, or parameter - the internal implementation will probably be not that different so I think it's more about what will be most obvious for users and most compatible with current and likely future use cases. From that point of view a new question type seems good to me. But I have questions!

Would this new question type accept the same parameters as geopoint i.e. capture-accuracy, et al? Or be like start-geopoint and have non-configurable behaviour to capture the "highest accuracy point within 20 seconds" (of it's trigger event)?

About the following use cases with groups - should pyxform reject (or warn about) any of these? Numbers 1 to 3 seem OK, 4 and 6 seem wrong, 5 might be useful to overwrite at each repeat (e.g. last location before completion).

  1. trigger in non-repeating group A, target in non-repeating group A
  2. trigger in non-repeating group A, target in non-repeating group B
  3. trigger in repeating group A, target in repeating group A
  4. trigger in repeating group A, target in repeating group B
  5. trigger in repeating group A, target in non-repeating group B
  6. trigger in non-repeating group A, target in repeating group B

Which event applies to each of the above cases - xforms-value-changed if trigger is non-repeating, odk-new-repeat if repeating, or only ever the former? And/or should the event be configurable?

As mentioned above, if the new question type has a calculate value it will be rejected because it conflicts with the objective of generating odk:setgeopoint. But is it possible that users may need to have a setvalue as well (i.e. allow a calculate)? Would that work in Collect/Enketo? Any other constraints/limitations on using this type?

In terms of documenting this feature, what would the XLSForm template and/or ODK docs say about it? It may seem premature, but it would be a useful exercise because if we can't devise a reasonably concise explanation of what it does and when to use it (and not use it?) then maybe the design is off. E.g. for the template:

Record a single point (a location) when the (required) trigger question changes.

4 Likes

Thanks for thinking through it and for the good questions, @Lindsay_Stevens_Au!

It would be like start-geopoint in all ways except for how it's triggered so yes, no configuration and the same idea of capturing the highest-accuracy point within 20 seconds of the triggering event.

I agree with you that 4 and 6 are problematic. I believe that in both cases clients would complain once there's more than one repeat instance which is a bit late. If pyxform can easily detect and error on those cases, that does seem preferable.

For the odk-new-repeat event, there wouldn't be a user-defined trigger. I'm liking what we've described above: using start-geopoint for that purpose when it's found in a repeat.

That means your 6 scenarios would be only related to xforms-value-changed because they involve a trigger other than a new repeat instance being created.

I can't think of a compelling use case for having setvalue and setgeopoint actions targeting the same field and it seems like it would be very likely to lead to unpredictable behavior. It feels best not to support it.

I'm not thinking of any more! Good call on some limitations around what trigger references are allowed.

Yes, I agree strongly! And I think your description works well so I'm continuing to feel good about it.

Naming-wise, I'm still liking bg-geopoint and am also ok with the more explicit background-geopoint.

2 Likes

Love this discussion! Thanks for thinking through all the nitty gritty cases @Lindsay_Stevens_Au @LN :heart:

I would suggest we go with background-geopoint as the more explicit option, in line with start-geopoint. Anyone without a CSS education might not understand why bg would refer to 'background'...

Yes, I had also considered these permutations - and others - during my analysis, especially as a result of the 'experimentation' performed in regards to Incorrect (setvalue) trigger behavior in Enketo when used inside repeat groups?

As you note, these permutations apply pretty much to any xform-value-changed event, not just the odk:setgeopoint described here; specifically what is the proscribed behavior when setvalue triggers and targets are at different levels of the XML hierarchy?

I think in regular non-repeating groups, I dont really see much issue or why either the trigger or target need to care, because the XML path to the correct one is wholly deterministic and unique. So I dont think anything special needs to be said for 1 & 2.

Permutation 3 - where the trigger and target are in the same repeat - is the interesting one, and the one I set out to explicitly confirm behavior of because it'll probably be the most common. In this situation I think the expected behavior is that the triggering behaving is kept wholly within the current repeat iteration; that is, that iteration's trigger only affects that iteration's target. This is the behavior I confirmed in Collect but doesnt appear to work in Enketo (see above).

Permutation 4 - where the trigger and target are in different (and non-emcompassing!) repeat is probably something to flag as an error; I have a hard time thinking how deterministic behavior here could be enforced without somehow strictly associating the specifc repeat iterations with each other (which at a minimum would require enforcing the same numer of iterations for each...)

Permutation 5 & 6 are the interesting ones IMO - what do you do when your control's trigger is outside of your repeat; eg does the trigger result in all the repeat interations getting recalculated? I could see potential usecases for both these permutation, although it does still feel somewhat of an edge case.

Note, the other permutation I considered, closely related to 5 & 6 would be a trigger and target within nested repeats of each other. Again, this is definitely and edge case but still something that can be defined nonetheless.

As a first pass, how about ensuring the trigger and target have the same XML parent? That probably handles the majority of the usecases. Then we can extend the scope to perhaps ensure they have a common ancestor and there are no intervening repeating groups?

Again, its worth noting this is not specific to exposing odk:setgeopoint in XLSForm per se, but rather how we should fully define XLSForm triggers/XForm xform-value-changed events in general; specifically, it equally affects our existing setvalue action triggers.

The proposal is this would be a new question type - eg background-geopoint - which would require a trigger and would exclude a calculation [or completely ignore one, depending on how today's start-geopoint behaves when other such columns are define on it...].

So I think in this regard it would look and behave - in XLSForm - very much like start-geopoint, other than requiring a trigger (plus checks on where this trigger resides, as described above)

This feels kinda similar to the case of having a single target being able to have multiple different triggers; you'd need to have multiple triggers for this situation because otherwise a single source trigger cant be trying to both explicitly set a (calculated) geopoint value at the same time wanting to acquire hardware based one...

Note it is already the case that we do not permit, in XLSForm at least [but you can do it in raw XForms...], to have a control with multiple triggers. So I think it is probably reasonable to strictly enforce that this new question type MUST have a trigger but MUST NOT have a calculation.