Filter combo field options by optionsLocationSet - #12657
Conversation
id-tagging-schema's field.json schema gained an optionsLocationSet property (openstreetmap/schema-builder#349): a per-option locationSet, letting a single combo option (e.g. surface=laterite, a tropical soil type essentially absent outside a specific belt of countries) be offered only in the regions where it's relevant, without touching the rest of the shared field's option list. This wires that data up on the iD side, reusing the exact mechanism already used to hide a whole field by region: - modules/presets/index.js: when merging a field with an optionsLocationSet, resolves each option's locationSet through locationManager.registerLocationSets() (same call already used for whole-field/preset/category locationSets) and stores the results in field.optionsLocationSetID, keyed by option value. - modules/ui/fields/combo.js: adds optionAllowedHere(value), checking the current entity's location against the option's locationSetID the same way modules/ui/field.js already does for whole fields. Applied in both suggestion paths: the static options list (getOptions()) and the live taginfo-backed suggestions, since taginfo doesn't know about this restriction and would otherwise surface a globally-popular value regardless of region. An option with no entry in optionsLocationSetID, or when the entity's location can't be determined, is offered everywhere, unchanged from today's behavior. Typing a value directly is still always possible (customValues), this only affects what's suggested.
|
We are still discussing what the new format should look like. Latest discussion on this topic is here openstreetmap/id-tagging-schema#2493 (comment) I don't think the idea at https://github.com/openstreetmap/schema-builder/pull/349/changes#diff-52dd1cfe1fba598e780b1576304786ad0f86bbbbcb7b0c505e75ba12563075c9R120 is better. |
|
Thanks for the pointer, hadn't seen #2493. Fair concern, This PR's Happy to wait for #2493 to settle before pushing on the schema side, or to help prototype the richer-field-metadata format there if that's useful. Let me know which is more helpful. |
k-yle
left a comment
There was a problem hiding this comment.
i agree, we should go with tobias' more flexible proposal from openstreetmap/id-tagging-schema#2493 (comment) - that would solve 3 different issues at once
This came out of a discussion on openstreetmap/id-tagging-schema#2332, where a maintainer asked whether a single
surfacecombo option (laterite, a tropical soil type essentially absent outside a specific belt of countries) could be scoped to only the regions where it's actually relevant, instead of appearing in the dropdown everywhere. Field-levellocationSetalready exists for hiding a whole field by region (modules/ui/field.js), but there's nothing equivalent for a single option inside a shared combo field likesurface, which is used across most highway presets globally.id-tagging-schema's schema gained an
optionsLocationSetproperty to carry this (companion PR: openstreetmap/schema-builder#349), a map from option value to alocationSetobject. This PR wires that data up on the iD side.What changed
modules/presets/index.js: when merging a field with anoptionsLocationSet, each option'slocationSetgets pushed throughlocationManager.registerLocationSets()(the same call already used for whole-field/preset/categorylocationSets), and the resultinglocationSetIDs land onfield.optionsLocationSetID, keyed by option value.modules/ui/fields/combo.js: addsoptionAllowedHere(value), which checks the current entity's location against the option'slocationSetIDthe same waymodules/ui/field.js'sisAllowed()already does for whole fields (samecombinedEntityExtent()/locationManager.locationSetsAt()pattern). Applied in both suggestion paths:getOptions())lateritecurrently has 700+ uses) regardless of where you're editingAn option with no entry in
optionsLocationSetID, or when the entity's location can't be determined (e.g. no entity yet), is offered everywhere, unchanged from today. Typing a value directly is still always possible (customValues), this only affects what gets suggested, matching how whole-fieldlocationSetfiltering already behaves (it hides the field, but doesn't retroactively invalidate already-tagged data).Testing
modules/presets/index.js: unit test confirmingoptionsLocationSetIDresolves correctly on merge, and that fields withoutoptionsLocationSetare unaffected.modules/ui/fields/combo.js: two end-to-end tests exercising the real DOM/combobox path (render the field, focus, simulate a↓keypress to open the dropdown, read the actual rendered.combobox-optionelements), confirming a region-restricted option is excluded whenlocationSetsAt()doesn't include its id, and included when it does.npm run lint,tsc,vitest run, 2367 passed).This is the iD half of a three-repo change; a follow-up id-tagging-schema PR will apply
optionsLocationSettolateriteonce this and the schema-builder PR both land. Happy to adjust the approach if you'd prefer something different.