mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 20:21:09 +02:00
Pelias hides the 'category' field from API responses unless the caller filters by categories=... explicitly — a default intended for keyword search that strips category metadata from address queries. Patch the Pelias API's geojsonify_place_details.js so the category array is returned on every feature (food, retail, transport, …), mounted into the container as a read-only volume override. Rewrite category-map.ts to map Pelias' OSM taxonomy to our 7 PlaceCategories using a priority-ordered list so a restaurant tagged ['food','retail','nightlife'] resolves to 'food' (the most specific), not 'shopping'. Verified with Konstanz test queries: Konzil Restaurant → food Bahnhof Konstanz → transit Physiotherapie-Schule → work MX-Park → leisure Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
123 lines
4 KiB
JavaScript
123 lines
4 KiB
JavaScript
const _ = require('lodash');
|
|
const field = require('./fieldValue');
|
|
|
|
// Properties to be copied
|
|
// If a property is identified as a single string, assume it should be presented as a string in response
|
|
// If something other than string is desired, use the following structure: { name: 'category', type: 'array' }
|
|
const DETAILS_PROPS = [
|
|
{ name: 'unit', type: 'string' },
|
|
{ name: 'housenumber', type: 'string' },
|
|
{ name: 'street', type: 'string' },
|
|
{ name: 'postalcode', type: 'string' },
|
|
{ name: 'postalcode_gid', type: 'string' },
|
|
{ name: 'confidence', type: 'default' },
|
|
{ name: 'match_type', type: 'string' },
|
|
{ name: 'distance', type: 'default' },
|
|
{ name: 'accuracy', type: 'string' },
|
|
{ name: 'country', type: 'string' },
|
|
{ name: 'country_gid', type: 'string' },
|
|
{ name: 'country_a', type: 'string' },
|
|
{ name: 'dependency', type: 'string' },
|
|
{ name: 'dependency_gid', type: 'string' },
|
|
{ name: 'dependency_a', type: 'string' },
|
|
{ name: 'macroregion', type: 'string' },
|
|
{ name: 'macroregion_gid', type: 'string' },
|
|
{ name: 'macroregion_a', type: 'string' },
|
|
{ name: 'region', type: 'string' },
|
|
{ name: 'region_gid', type: 'string' },
|
|
{ name: 'region_a', type: 'string' },
|
|
{ name: 'macrocounty', type: 'string' },
|
|
{ name: 'macrocounty_gid', type: 'string' },
|
|
{ name: 'macrocounty_a', type: 'string' },
|
|
{ name: 'county', type: 'string' },
|
|
{ name: 'county_gid', type: 'string' },
|
|
{ name: 'county_a', type: 'string' },
|
|
{ name: 'localadmin', type: 'string' },
|
|
{ name: 'localadmin_gid', type: 'string' },
|
|
{ name: 'localadmin_a', type: 'string' },
|
|
{ name: 'locality', type: 'string' },
|
|
{ name: 'locality_gid', type: 'string' },
|
|
{ name: 'locality_a', type: 'string' },
|
|
{ name: 'borough', type: 'string' },
|
|
{ name: 'borough_gid', type: 'string' },
|
|
{ name: 'borough_a', type: 'string' },
|
|
{ name: 'neighbourhood', type: 'string' },
|
|
{ name: 'neighbourhood_gid', type: 'string' },
|
|
{ name: 'continent', type: 'string' },
|
|
{ name: 'continent_gid', type: 'string' },
|
|
{ name: 'continent_a', type: 'string' },
|
|
{ name: 'empire', type: 'string', condition: _.negate(hasCountry) },
|
|
{ name: 'empire_gid', type: 'string', condition: _.negate(hasCountry) },
|
|
{ name: 'empire_a', type: 'string', condition: _.negate(hasCountry) },
|
|
{ name: 'ocean', type: 'string' },
|
|
{ name: 'ocean_gid', type: 'string' },
|
|
{ name: 'ocean_a', type: 'string' },
|
|
{ name: 'marinearea', type: 'string' },
|
|
{ name: 'marinearea_gid', type: 'string' },
|
|
{ name: 'marinearea_a', type: 'string' },
|
|
{ name: 'bounding_box', type: 'default' },
|
|
{ name: 'label', type: 'string' },
|
|
{ name: 'category', type: 'array', condition: () => true },
|
|
];
|
|
|
|
const EXTENDED_PROPS = DETAILS_PROPS.concat([
|
|
{ name: 'population', type: 'default' },
|
|
{ name: 'popularity', type: 'default' },
|
|
]);
|
|
|
|
// returns true IFF source a country_gid property
|
|
function hasCountry(params, source) {
|
|
return source.hasOwnProperty('country_gid');
|
|
}
|
|
|
|
function checkCategoryParam(params) {
|
|
return _.isObject(params) && params.hasOwnProperty('categories');
|
|
}
|
|
|
|
/**
|
|
* Collect the specified properties from source into an object and return it
|
|
* Ignore missing properties.
|
|
*
|
|
* @param {object} params clean query params
|
|
* @param {object} source
|
|
* @param {object} dst
|
|
*/
|
|
function collectProperties(params, source) {
|
|
let props = DETAILS_PROPS;
|
|
|
|
// extended properties when debugging mode is enabled
|
|
if (params.enableDebug === true) {
|
|
props = EXTENDED_PROPS;
|
|
}
|
|
|
|
return props.reduce((result, prop) => {
|
|
// if condition isn't met, don't set the property
|
|
if (_.isFunction(prop.condition) && !prop.condition(params, source)) {
|
|
return result;
|
|
}
|
|
|
|
if (source.hasOwnProperty(prop.name)) {
|
|
let value = null;
|
|
|
|
switch (prop.type) {
|
|
case 'string':
|
|
value = field.getStringValue(source[prop.name]);
|
|
break;
|
|
case 'array':
|
|
value = field.getArrayValue(source[prop.name]);
|
|
break;
|
|
// default behavior is to copy property exactly as is
|
|
default:
|
|
value = source[prop.name];
|
|
}
|
|
|
|
if (_.isNumber(value) || (value && !_.isEmpty(value))) {
|
|
result[prop.name] = value;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}, {});
|
|
}
|
|
|
|
module.exports = collectProperties;
|