Skip to content

Add support for reference geometry for geo questions #839

Closed

Activity

  1. added this to the Next milestone on Apr 22, 2026
  2. lindsay-stevens commented on Jun 9, 2026

    @lindsay-stevens
    Contributor

    The example XForm (posted here) does the following:

    <input ref="/data/from_repeat/geometry">
      <label>Capture geotrace</label>
      <itemset nodeset="../../from_repeat[geometry != '']">
      <value ref="geometry"/>
        <label ref="geometry"/>
      </itemset>
    </input>
    

    Which is not valid XForms 1.0 since the input element XSD says:

    <xsd:element name="input">
      <xsd:complexType>
        <xsd:sequence>
          <xsd:element ref="xforms:label"/>
          <xsd:group ref="xforms:UI.Common" minOccurs="0" maxOccurs="unbounded"/>
        </xsd:sequence>
        <xsd:attributeGroup ref="xforms:Common.Attributes"/>
        <xsd:attributeGroup ref="xforms:Single.Node.Binding.Attributes"/>
        <xsd:attribute name="inputmode" type="xsd:string" use="optional"/>
        <xsd:attributeGroup ref="xforms:UI.Common.Attrs"/>
        <xsd:attribute name="incremental" type="xsd:boolean" use="optional" default="false"/>
      </xsd:complexType>
    </xsd:element>
    

    But the itemset element is in List.UI.Common rather than UI.Common.

    <xsd:group name="List.UI.Common">
      <xsd:sequence>
        <xsd:choice>
          <xsd:element ref="xforms:item"/>
          <xsd:element ref="xforms:itemset"/>
          <xsd:element ref="xforms:choices"/>
        </xsd:choice>
      </xsd:sequence>
    </xsd:group>
    

    The range type has a similar definition to input and also does not accept List.UI.Common so the changes associated with getodk/xforms-spec#336 / #836 have the same issue:

    <xsd:element name="range">
      <xsd:complexType>
        <xsd:sequence>
          <xsd:element ref="xforms:label"/>
          <xsd:group ref="xforms:UI.Common" minOccurs="0" maxOccurs="unbounded"/>
        </xsd:sequence>
        <xsd:attributeGroup ref="xforms:Common.Attributes"/>
        <xsd:attributeGroup ref="xforms:Single.Node.Binding.Attributes"/>
        <xsd:attributeGroup ref="xforms:UI.Common.Attrs"/>
        <xsd:attribute name="start" type="xsd:string" use="optional"/>
        <xsd:attribute name="end" type="xsd:string" use="optional"/>
        <xsd:attribute name="step" type="xsd:string" use="optional"/>
        <xsd:attribute name="incremental" type="xsd:boolean" use="optional" default="false"/>
      </xsd:complexType>
    </xsd:element>
    

    From the pyxform perspective I think it's also confusing for questions to conditionally behave like selects depending on whether a parameter (tick-labelset or reference-geometry) is present.

    So I suggest creating control types for these in the odk namespace (e.g. odk:range, odk:geo or something) since they would not be valid XForms elements anymore. Or if there is a way to achieve the functionality with pulldata or similar (as mentioned in getodk/collect#7118) that might be simpler.

  3. lognaturel commented on Jun 9, 2026

    @lognaturel
    ContributorAuthor

    Which is not valid XForms 1.0

    That's ok. We use W3C XForms for inspiration but the ODK XForms spec is clearly separate now. We try not to dramatically change the meaning of existing constructs and here it feels to me like we're broadening an existing concept.

    We now have range forms with child itemsets so I don't think we should reconsider the general structure, for better or worse. The client implementations are also complete.

  4. moved this to ✏️ in progress in ODK Centralon Jun 15, 2026
  5. moved this from Backlog to In progress in Cross-cutting projectson Jun 17, 2026
  6. lindsay-stevens commented on Jun 18, 2026

    @lindsay-stevens
    Contributor

    As noted in this PR comment, about the meaning of the reference-geometry token:

    [in addition to CSV] It could also be XML or geojson sources -- any named secondary instance -- whether it's internal or external or what the file format is shouldn't matter.

    As noted in this commit message which addressed that clarification to allow any file type:

    there are also the possibilities of instances generated for
    pulldata calls and ${last-saved#q} references, but that parsing code
    and logic is in survey.py which would require a larger refactor so
    it is excluded from this commit.

    So I would like to clarify some things in relation to scope for this feature - should they be supported now, later, or never?

    pulldata

    Currently not supported. The problem for now would be that a user might have a pulldata call that triggers an auto-generated secondary csv instance, but the validation for reference-geometry won't allow using that instance (because pyxform doesn't know anything about pulldata until the output processing in survey.py), and also because secondary instance names must be unique the user could not work around it by adding a csv-external or similar.

    last-saved

    Currently not supported. It doesn't work because survey.py looks in specific places (default, choice_filter, anything that ends up in bind) for last-saved references in order to trigger an auto-generated secondary instance for it, and those places do not include the parameters. In other words the nodeset output will look OK but there won't be a matching secondary instance. A user might be able to work around this by including a last-saved reference somewhere that causes there to be a secondary instance.

    Question type aliases

    Currently not supported. The reference-geometry parameter is only enabled for the primary documented question type names for geo types "geopoint", "geoshape", and "geotrace". But per question_type_dictionary.py there are a few aliases (many of which have been there since the beginning) that currently get resolved in builder.py; and there are some more recent question types that map to geopoint:

    • for geopoint:
      • aliases: "location", "q location", "q geopoint", "gps", "add location prompt",
      • mapped: "start-geopoint", "background-geopoint"
    • for geoshape: alias "q geoshape"
    • for geotrace: alias "q geotrace"

    For "range" there are no aliases or mapped question types.

    Advanced expressions

    There is currently no parsing magic or escape hatch etc to allow advanced users to provide a custom nodeset XPath, for example to filter the repeats or secondary instance data.

  7. lognaturel commented on Jun 19, 2026

    @lognaturel
    ContributorAuthor

    Excluding csv attachments queried by search/pulldata, "fast external itemsets", last-saved and question type aliases all sound right to me.

    to filter the repeats or secondary instance data

    We'd discussed in the original forum thread using choice_filter for that and it looks like it's working as I would expect: https://github.com/XLSForm/pyxform/pull/847/changes#diff-dc5c2adf1e90fb5537c667d9b315109955dc03310e604c94745d6ec2516f2e5bR329

  8. moved this from ✏️ in progress to ✅ done in ODK Centralon Jun 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions