diff --git a/modules/core/locations.js b/modules/core/locations.js index dd8240709..39a7184e8 100644 --- a/modules/core/locations.js +++ b/modules/core/locations.js @@ -185,7 +185,7 @@ export function coreLocations() { _this.query = (loc, multi) => _wp(loc, multi); // - // `locationsHere` + // `locationsAt` // Convenience method to find all the locationSets valid at the given location. // Arguments // `loc`: the [lon,lat] location to query diff --git a/modules/presets/collection.js b/modules/presets/collection.js index 836e3e044..5ea1bff35 100644 --- a/modules/presets/collection.js +++ b/modules/presets/collection.js @@ -1,4 +1,5 @@ -import { utilArrayIntersection, utilArrayUniq } from '../util/array'; +import { locationManager } from '../core/locations'; +import { utilArrayUniq } from '../util/array'; import { utilEditDistance } from '../util'; @@ -46,7 +47,7 @@ export function presetCollection(collection) { return _this.item(id); }; - _this.search = (value, geometry, countryCodes) => { + _this.search = (value, geometry, loc) => { if (!value) return _this; // don't remove diacritical characters since we're assuming the user is being intentional @@ -87,18 +88,11 @@ export function presetCollection(collection) { } let pool = _this.collection; - if (countryCodes) { - if (typeof countryCodes === 'string') countryCodes = [countryCodes]; - countryCodes = countryCodes.map(code => code.toLowerCase()); - - pool = pool.filter(a => { - if (a.locationSet) { - if (a.locationSet.include && !utilArrayIntersection(a.locationSet.include, countryCodes).length) return false; - if (a.locationSet.exclude && utilArrayIntersection(a.locationSet.exclude, countryCodes).length) return false; - } - return true; - }); + if (Array.isArray(loc)) { + const validLocations = locationManager.locationsAt(loc); + pool = pool.filter(a => validLocations[a.locationSetID]); } + const searchable = pool.filter(a => a.searchable !== false && a.suggestion !== true); const suggestions = pool.filter(a => a.suggestion === true); diff --git a/modules/presets/index.js b/modules/presets/index.js index 9a86c085d..04630598e 100644 --- a/modules/presets/index.js +++ b/modules/presets/index.js @@ -362,11 +362,12 @@ export function presetIndex() { _this.universal = () => _universal; - _this.defaults = (geometry, n, startWithRecents) => { + _this.defaults = (geometry, n, startWithRecents, loc) => { let recents = []; if (startWithRecents) { recents = _this.recent().matchGeometry(geometry).collection.slice(0, 4); } + let defaults; if (_addablePresetIDs) { defaults = Array.from(_addablePresetIDs).map(function(id) { @@ -378,9 +379,16 @@ export function presetIndex() { defaults = _defaults[geometry].collection.concat(_this.fallback(geometry)); } - return presetCollection( + let result = presetCollection( utilArrayUniq(recents.concat(defaults)).slice(0, n - 1) ); + + if (Array.isArray(loc)) { + const validLocations = locationManager.locationsAt(loc); + result.collection = result.collection.filter(a => validLocations[a.locationSetID]); + } + + return result; }; // pass a Set of addable preset ids diff --git a/modules/ui/field.js b/modules/ui/field.js index 96718a7e4..43aac7591 100644 --- a/modules/ui/field.js +++ b/modules/ui/field.js @@ -1,15 +1,14 @@ -import * as countryCoder from '@ideditor/country-coder'; import { dispatch as d3_dispatch } from 'd3-dispatch'; import { select as d3_select } from 'd3-selection'; import { t, localizer } from '../core/localizer'; +import { locationManager } from '../core/locations'; import { svgIcon } from '../svg/icon'; import { uiTooltip } from './tooltip'; import { geoExtent } from '../geo/extent'; import { uiFieldHelp } from './field_help'; import { uiFields } from './fields'; import { uiTagReference } from './tag_reference'; -import { utilArrayIntersection } from '../util/array'; import { utilRebind, utilUniqueDomId } from '../util'; @@ -29,6 +28,14 @@ export function uiField(context, presetField, entityIDs, options) { var _state = ''; var _tags = {}; + var _entityExtent; + if (entityIDs && entityIDs.length) { + _entityExtent = entityIDs.reduce(function(extent, entityID) { + var entity = context.graph().entity(entityID); + return extent.extend(entity.extent(context.graph())); + }, geoExtent()); + } + var _locked = false; var _lockedTip = uiTooltip() .title(t.html('inspector.lock.suggestion', { label: field.label })) @@ -302,21 +309,9 @@ export function uiField(context, presetField, entityIDs, options) { return field.matchGeometry(context.graph().geometry(entityID)); })) return false; - if (field.locationSet) { - var extent = combinedEntityExtent(); - if (!extent) return true; - - var center = extent.center(); - var codes = countryCoder.iso1A2Codes(center).map(function(code) { - return code.toLowerCase(); - }); - - if (field.locationSet.include && !utilArrayIntersection(codes, field.locationSet.include).length) { - return false; - } - if (field.locationSet.exclude && utilArrayIntersection(codes, field.locationSet.exclude).length) { - return false; - } + if (entityIDs && _entityExtent && field.locationSetID) { // is field allowed in this location? + var validLocations = locationManager.locationsAt(_entityExtent.center()); + if (!validLocations[field.locationSetID]) return false; } var prerequisiteTag = field.prerequisiteTag; @@ -355,13 +350,5 @@ export function uiField(context, presetField, entityIDs, options) { }; - function combinedEntityExtent() { - return entityIDs && entityIDs.length && entityIDs.reduce(function(extent, entityID) { - var entity = context.graph().entity(entityID); - return extent.extend(entity.extent(context.graph())); - }, geoExtent()); - } - - return utilRebind(field, dispatch, 'on'); } diff --git a/modules/ui/preset_list.js b/modules/ui/preset_list.js index aa92d508e..38468c53d 100644 --- a/modules/ui/preset_list.js +++ b/modules/ui/preset_list.js @@ -1,9 +1,5 @@ import { dispatch as d3_dispatch } from 'd3-dispatch'; -import * as countryCoder from '@ideditor/country-coder'; - -import { - select as d3_select -} from 'd3-selection'; +import { select as d3_select } from 'd3-selection'; import { presetManager } from '../presets'; import { t, localizer } from '../core/localizer'; @@ -20,6 +16,7 @@ import { utilKeybinding, utilNoAuto, utilRebind } from '../util'; export function uiPresetList(context) { var dispatch = d3_dispatch('cancel', 'choose'); var _entityIDs; + var _currLoc; var _currentPresets; var _autofocus = false; @@ -94,19 +91,16 @@ export function uiPresetList(context) { function inputevent() { var value = search.property('value'); list.classed('filtered', value.length); - var extent = combinedEntityExtent(); - var results, messageText; - if (value.length && extent) { - var center = extent.center(); - var countryCodes = countryCoder.iso1A2Codes(center); - results = presets.search(value, entityGeometries()[0], countryCodes); + var results, messageText; + if (value.length) { + results = presets.search(value, entityGeometries()[0], _currLoc); messageText = t('inspector.results', { n: results.collection.length, search: value }); } else { - results = presetManager.defaults(entityGeometries()[0], 36, !context.inIntro()); + results = presetManager.defaults(entityGeometries()[0], 36, !context.inIntro(), _currLoc); messageText = t('inspector.choose'); } list.call(drawList, results); @@ -147,7 +141,7 @@ export function uiPresetList(context) { var list = listWrap .append('div') .attr('class', 'preset-list') - .call(drawList, presetManager.defaults(entityGeometries()[0], 36, !context.inIntro())); + .call(drawList, presetManager.defaults(entityGeometries()[0], 36, !context.inIntro(), _currLoc)); context.features().on('change.preset-list', updateForFeatureHiddenState); } @@ -483,13 +477,25 @@ export function uiPresetList(context) { presetList.entityIDs = function(val) { if (!arguments.length) return _entityIDs; + _entityIDs = val; + _currLoc = null; + if (_entityIDs && _entityIDs.length) { + // calculate current location + const extent = _entityIDs.reduce(function(extent, entityID) { + var entity = context.graph().entity(entityID); + return extent.extend(entity.extent(context.graph())); + }, geoExtent()); + _currLoc = extent.center(); + + // match presets var presets = _entityIDs.map(function(entityID) { return presetManager.match(context.entity(entityID), context.graph()); }); presetList.presets(presets); } + return presetList; }; @@ -522,12 +528,5 @@ export function uiPresetList(context) { }); } - function combinedEntityExtent() { - return _entityIDs.reduce(function(extent, entityID) { - var entity = context.graph().entity(entityID); - return extent.extend(entity.extent(context.graph())); - }, geoExtent()); - } - return utilRebind(presetList, dispatch, 'on'); }