mirror of
https://github.com/FoggedLens/iD.git
synced 2026-02-12 16:52:50 +00:00
implement special address field for addr:street/addr:place
This commit is contained in:
@@ -2100,6 +2100,22 @@ input.date-selector {
|
||||
.ideditor[dir='rtl'] .addr-row:last-of-type input:last-of-type {
|
||||
border-radius: 0 0 0 4px;
|
||||
}
|
||||
.combobox-address-street-place .combobox-option.address-street,
|
||||
.combobox-address-street-place .combobox-option.address-place {
|
||||
padding-right: 20px;
|
||||
}
|
||||
.combobox-address-street-place .combobox-option.address-street::after,
|
||||
.combobox-address-street-place .combobox-option.address-place::after {
|
||||
position: absolute;
|
||||
right: 2px;
|
||||
opacity: 0.4;
|
||||
}
|
||||
.combobox-address-street-place .combobox-option.address-street::after {
|
||||
content: url(data:image/svg+xml;charset=utf-8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMCIgeT0iMCIgd2lkdGg9IjIwIiBoZWlnaHQ9IjIwIiB2aWV3Qm94PSIwIDAgMjAgMjAiPg0KICAgIDxwYXRoIGQ9Ik0xNC41NTgsMyBDMTMuMjEsMyAxMi4xMTYsNC4wOTMgMTIuMTE2LDUuNDQyIEMxMi4xMTYsNS42ODggMTIuMTYxLDUuOTIgMTIuMjI4LDYuMTQ0IEw2LjE0NCwxMi4yMjggQzUuOTIsMTIuMTYxIDUuNjg4LDEyLjExNiA1LjQ0MiwxMi4xMTYgQzQuMDkzLDEyLjExNiAzLDEzLjIxIDMsMTQuNTU4IEMzLDE1LjkwNyA0LjA5MywxNyA1LjQ0MiwxNyBDNi43OSwxNyA3Ljg4NCwxNS45MDcgNy44ODQsMTQuNTU4IEM3Ljg4NCwxNC4zMTIgNy44MzksMTQuMDggNy43NzIsMTMuODU2IEwxMy44NTYsNy43NzIgQzE0LjA4LDcuODM5IDE0LjMxMiw3Ljg4NCAxNC41NTgsNy44ODQgQzE1LjkwNyw3Ljg4NCAxNyw2Ljc5IDE3LDUuNDQyIEMxNyw0LjA5MyAxNS45MDcsMyAxNC41NTgsMyB6IE0xNC41NTgsNC40NjUgQzE1LjA5OCw0LjQ2NSAxNS41MzUsNC45MDIgMTUuNTM1LDUuNDQyIEMxNS41MzUsNS45ODEgMTUuMDk4LDYuNDE5IDE0LjU1OCw2LjQxOSBDMTQuMDE5LDYuNDE5IDEzLjU4MSw1Ljk4MSAxMy41ODEsNS40NDIgQzEzLjU4MSw0LjkwMiAxNC4wMTksNC40NjUgMTQuNTU4LDQuNDY1IHogTTUuNDQyLDEzLjU4MSBDNS45ODEsMTMuNTgxIDYuNDE5LDE0LjAxOSA2LjQxOSwxNC41NTggQzYuNDE5LDE1LjA5OCA1Ljk4MSwxNS41MzUgNS40NDIsMTUuNTM1IEM0LjkwMiwxNS41MzUgNC40NjUsMTUuMDk4IDQuNDY1LDE0LjU1OCBDNC40NjUsMTQuMDE5IDQuOTAyLDEzLjU4MSA1LjQ0MiwxMy41ODEgeiIgZmlsbD0iY3VycmVudENvbG9yIi8+DQo8L3N2Zz4=);
|
||||
}
|
||||
.combobox-address-street-place .combobox-option.address-place::after {
|
||||
content: url(data:image/svg+xml;charset=utf-8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMCIgeT0iMCIgd2lkdGg9IjIwIiBoZWlnaHQ9IjIwIiB2aWV3Qm94PSIwIDAgMjAgMjAiPg0KICAgIDxwYXRoIGQ9Ik0xMCwzIEM2LjY4NiwzIDQsNS42MTIgNCw4LjgzMyBDNCwxMi4wNTUgMTAsMTcgMTAsMTcgQzEwLDE3IDE2LDEyLjA1NSAxNiw4LjgzMyBDMTYsNS42MTIgMTMuMzE0LDMgMTAsMyB6IE0xMC4xODcsNi41IEMxMS41MTMsNi41IDEyLjU4Nyw3LjU0NSAxMi41ODcsOC44MzMgQzEyLjU4NywxMC4xMjIgMTEuNTEzLDExLjE2NyAxMC4xODcsMTEuMTY3IEM4Ljg2MiwxMS4xNjcgNy43ODcsMTAuMTIyIDcuNzg3LDguODMzIEM3Ljc4Nyw3LjU0NSA4Ljg2Miw2LjUgMTAuMTg3LDYuNSB6IiBmaWxsPSJjdXJyZW50Q29sb3IiLz4NCjwvc3ZnPg==);
|
||||
}
|
||||
|
||||
|
||||
/* Field - Wikipedia
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
{
|
||||
"countryCodes": ["at", "bg", "ch", "de", "si", "pl"],
|
||||
"format": [
|
||||
["street", "housenumber"],
|
||||
["street+place", "housenumber"],
|
||||
["postcode", "city"]
|
||||
]
|
||||
},
|
||||
@@ -42,7 +42,7 @@
|
||||
"it", "li", "nl", "no", "pt", "se", "sk", "sm", "va"
|
||||
],
|
||||
"format": [
|
||||
["street", "housenumber", "unit"],
|
||||
["street+place", "housenumber", "unit"],
|
||||
["postcode", "city"]
|
||||
]
|
||||
},
|
||||
@@ -186,5 +186,12 @@
|
||||
["city", "postcode"],
|
||||
["district"]
|
||||
]
|
||||
},
|
||||
{
|
||||
"countryCodes": ["ru"],
|
||||
"format": [
|
||||
["housenumber", "street+place"],
|
||||
["city", "postcode"]
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -852,7 +852,7 @@ export default {
|
||||
bubbleIdQuadKey = '0' + bubbleIdQuadKey;
|
||||
}
|
||||
const imgUrlPrefix = streetsideImagesApi + 'hs' + bubbleIdQuadKey;
|
||||
const imgUrlSuffix = '.jpg?g=13305&n=z';
|
||||
const imgUrlSuffix = '.jpg?g=13515&n=z';
|
||||
|
||||
// Cubemap face code order matters here: front=01, right=02, back=03, left=10, up=11, down=12
|
||||
const faceKeys = ['01','02','03','10','11','12'];
|
||||
|
||||
@@ -36,7 +36,7 @@ export function uiFieldAddress(field, context) {
|
||||
.catch(function() { /* ignore */ });
|
||||
|
||||
|
||||
function getNear(isAddressable, searchRadius, resultProp) {
|
||||
function getNear(isAddressable, type, searchRadius, resultProp) {
|
||||
var extent = combinedEntityExtent();
|
||||
var l = extent.center();
|
||||
var box = geoExtent(l).padByMeters(searchRadius);
|
||||
@@ -55,11 +55,19 @@ export function uiFieldAddress(field, context) {
|
||||
dist = Math.min(dist, choice.distance);
|
||||
}
|
||||
|
||||
let value = resultProp && d.tags[resultProp] ? d.tags[resultProp] : d.tags.name;
|
||||
const value = resultProp && d.tags[resultProp] ? d.tags[resultProp] : d.tags.name;
|
||||
let title = value;
|
||||
if (type === 'street') {
|
||||
title = `${addrField.t('placeholders.street')}: ${title}`;
|
||||
} else if (type === 'place') {
|
||||
title = `${addrField.t('placeholders.place')}: ${title}`;
|
||||
}
|
||||
return {
|
||||
title: value,
|
||||
title,
|
||||
value,
|
||||
dist
|
||||
dist,
|
||||
type,
|
||||
klass: `address-${type}`
|
||||
};
|
||||
})
|
||||
.sort(function(a, b) {
|
||||
@@ -74,7 +82,16 @@ export function uiFieldAddress(field, context) {
|
||||
return d.tags.highway && d.tags.name && d.type === 'way';
|
||||
}
|
||||
|
||||
return getNear(isAddressable, 200);
|
||||
return getNear(isAddressable, 'street', 200);
|
||||
}
|
||||
|
||||
function getNearPlaces() {
|
||||
function isAddressable(d) {
|
||||
return d.tags.name && d.tags.place ||
|
||||
d.tags.boundary === 'administrative' && d.tags.admin_level >= 8;
|
||||
}
|
||||
|
||||
return getNear(isAddressable, 'place', 200);
|
||||
}
|
||||
|
||||
function getNearCities() {
|
||||
@@ -85,20 +102,28 @@ export function uiFieldAddress(field, context) {
|
||||
if (d.tags.place === 'city' || d.tags.place === 'town' || d.tags.place === 'village') return true;
|
||||
}
|
||||
|
||||
if (d.tags['addr:city']) return true;
|
||||
if (d.tags[`${field.key}:city`]) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return getNear(isAddressable, 200, 'addr:city');
|
||||
return getNear(isAddressable, 'city', 200, `${field.key}:city`);
|
||||
}
|
||||
|
||||
function getNearPostcodes() {
|
||||
return [... new Set([]
|
||||
.concat(getNearValues('postcode')))
|
||||
.concat(getNear(d => d.tags.postal_code, 'postcode', 200, 'postal_code'))];
|
||||
}
|
||||
|
||||
function getNearValues(key) {
|
||||
const tagKey = `${field.key}:${key}`;
|
||||
|
||||
function hasTag(d) {
|
||||
return _entityIDs.indexOf(d.id) === -1 && d.tags[key];
|
||||
return _entityIDs.indexOf(d.id) === -1 && d.tags[tagKey];
|
||||
}
|
||||
|
||||
return getNear(hasTag, 200, key);
|
||||
return getNear(hasTag, key, 200, tagKey);
|
||||
}
|
||||
|
||||
|
||||
@@ -120,11 +145,11 @@ export function uiFieldAddress(field, context) {
|
||||
var dropdowns = addressFormat.dropdowns || [
|
||||
'city', 'county', 'country', 'district', 'hamlet',
|
||||
'neighbourhood', 'place', 'postcode', 'province',
|
||||
'quarter', 'state', 'street', 'subdistrict', 'suburb'
|
||||
'quarter', 'state', 'street', 'street+place', 'subdistrict', 'suburb'
|
||||
];
|
||||
|
||||
var widths = addressFormat.widths || {
|
||||
housenumber: 1/3, street: 2/3,
|
||||
housenumber: 1/5, unit: 1/5, street: 1/2, place: 1/2,
|
||||
city: 2/3, state: 1/4, postcode: 1/3
|
||||
};
|
||||
|
||||
@@ -169,19 +194,46 @@ export function uiFieldAddress(field, context) {
|
||||
function addDropdown(d) {
|
||||
if (dropdowns.indexOf(d.id) === -1) return; // not a dropdown
|
||||
|
||||
var nearValues = (d.id === 'street') ? getNearStreets
|
||||
: (d.id === 'city') ? getNearCities
|
||||
: getNearValues;
|
||||
var nearValues;
|
||||
switch (d.id) {
|
||||
case 'street':
|
||||
nearValues = getNearStreets;
|
||||
break;
|
||||
case 'place':
|
||||
nearValues = getNearPlaces;
|
||||
break;
|
||||
case 'street+place':
|
||||
nearValues = () => []
|
||||
.concat(getNearStreets())
|
||||
.concat(getNearPlaces());
|
||||
d.isAutoStreetPlace = true;
|
||||
d.id = _tags[`${field.key}:place`] ? 'place' : 'street';
|
||||
break;
|
||||
case 'city':
|
||||
nearValues = getNearCities;
|
||||
break;
|
||||
case 'postcode':
|
||||
nearValues = getNearPostcodes;
|
||||
break;
|
||||
default:
|
||||
nearValues = getNearValues;
|
||||
}
|
||||
|
||||
d3_select(this)
|
||||
.call(uiCombobox(context, 'address-' + d.id)
|
||||
.call(uiCombobox(context, `address-${d.isAutoStreetPlace ? 'street-place' : d.id}`)
|
||||
.minItems(1)
|
||||
.caseSensitive(true)
|
||||
.fetcher(function(typedValue, callback) {
|
||||
typedValue = typedValue.toLowerCase();
|
||||
callback(nearValues('addr:' + d.id)
|
||||
callback(nearValues(d.id)
|
||||
.filter(v => v.value.toLowerCase().indexOf(typedValue) !== -1));
|
||||
})
|
||||
.on('accept', function(selected) {
|
||||
if (d.isAutoStreetPlace) {
|
||||
// set subtag depending on selected entry
|
||||
d.id = selected ? selected.type : 'street';
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@@ -228,42 +280,67 @@ export function uiFieldAddress(field, context) {
|
||||
|
||||
function change(onInput) {
|
||||
return function() {
|
||||
var tags = {};
|
||||
setTimeout(() => {
|
||||
var tags = {};
|
||||
|
||||
_wrap.selectAll('input')
|
||||
.each(function (subfield) {
|
||||
var key = field.key + ':' + subfield.id;
|
||||
_wrap.selectAll('input')
|
||||
.each(function (subfield) {
|
||||
var key = field.key + ':' + subfield.id;
|
||||
|
||||
var value = this.value;
|
||||
if (!onInput) value = context.cleanTagValue(value);
|
||||
var value = this.value;
|
||||
if (!onInput) value = context.cleanTagValue(value);
|
||||
|
||||
// don't override multiple values with blank string
|
||||
if (Array.isArray(_tags[key]) && !value) return;
|
||||
// don't override multiple values with blank string
|
||||
if (Array.isArray(_tags[key]) && !value) return;
|
||||
|
||||
tags[key] = value || undefined;
|
||||
});
|
||||
if (subfield.isAutoStreetPlace) {
|
||||
if (key === `${field.key}:street`) {
|
||||
tags[`${field.key}:place`] = undefined;
|
||||
} else if (key === `${field.key}:place`) {
|
||||
tags[`${field.key}:street`] = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
dispatch.call('change', this, tags, onInput);
|
||||
tags[key] = value || undefined;
|
||||
});
|
||||
|
||||
dispatch.call('change', this, tags, onInput);
|
||||
}, 0);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function updatePlaceholder(inputSelection) {
|
||||
return inputSelection.attr('placeholder', function(subfield) {
|
||||
if (_tags && Array.isArray(_tags[field.key + ':' + subfield.id])) {
|
||||
return t('inspector.multiple_values');
|
||||
}
|
||||
if (_countryCode) {
|
||||
var localkey = subfield.id + '!' + _countryCode;
|
||||
var tkey = addrField.hasTextForStringId('placeholders.' + localkey) ? localkey : subfield.id;
|
||||
return addrField.t('placeholders.' + tkey);
|
||||
if (subfield.isAutoStreetPlace) {
|
||||
return `${getLocalPlaceholder('street')} / ${getLocalPlaceholder('place')}`;
|
||||
}
|
||||
return getLocalPlaceholder(subfield.id);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function getLocalPlaceholder(key) {
|
||||
if (_countryCode) {
|
||||
var localkey = key + '!' + _countryCode;
|
||||
var tkey = addrField.hasTextForStringId('placeholders.' + localkey) ? localkey : key;
|
||||
return addrField.t('placeholders.' + tkey);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function updateTags(tags) {
|
||||
utilGetSetValue(_wrap.selectAll('input'), function (subfield) {
|
||||
var val = tags[field.key + ':' + subfield.id];
|
||||
utilGetSetValue(_wrap.selectAll('input'), subfield => {
|
||||
var val;
|
||||
if (subfield.isAutoStreetPlace) {
|
||||
val = tags[`${field.key}:place`] || tags[`${field.key}:street`];
|
||||
subfield.id = _tags[`${field.key}:place`] ? 'place' : 'street';
|
||||
} else {
|
||||
val = tags[`${field.key}:${subfield.id}`];
|
||||
}
|
||||
return typeof val === 'string' ? val : '';
|
||||
})
|
||||
.attr('title', function(subfield) {
|
||||
|
||||
Reference in New Issue
Block a user