Skip to content
This repository has been archived by the owner on Jun 3, 2024. It is now read-only.

QMAPS-2088 Use ?q= intention bbox as initial map position #1066

Merged
merged 13 commits into from
Apr 27, 2021
3 changes: 2 additions & 1 deletion bin/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,11 @@ function App(config) {
});

const redirectUnsupported = new require('./middlewares/unsupported_browser')(config);
const fullTextQuery = new require('./middlewares/fullText_query')(config);
const preFetchPoi = new require('./middlewares/prefetch_poi')(config);
const ogMeta = new require('./middlewares/og_meta')(config);

router.get('/*', redirectUnsupported, preFetchPoi, ogMeta, (req, res) => {
router.get('/*', redirectUnsupported, fullTextQuery, preFetchPoi, ogMeta, (req, res) => {
const userAgent = req.headers['user-agent'];
const disableMenuRule = config.server.disableBurgerMenu.userAgentRule;
let appConfig = config;
Expand Down
73 changes: 73 additions & 0 deletions bin/middlewares/fullText_query.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
const axios = require('axios');
const yaml = require('node-yaml');

module.exports = function (config) {
const idunnTimeout = Number(config.server.services.idunn.timeout);
if (isNaN(idunnTimeout)) {
throw new Error(
`Invalid config: idunn timeout is set to "${config.server.services.idunn.timeout}"`
);
}

const idunnBaseUrl = config.server.services.idunn.url || config.services.idunn.url;
const geocoderUrl = idunnBaseUrl + '/v1/autocomplete';
const useNlu = config.services.geocoder.useNlu;

const categories = yaml.readSync('../../config/categories.yml');
const isCategoryValid = type => categories.find(category => category.name === type);

// @TODO: import it from client lib src/libs/url_utils.js when possible
const removeNullEntries = obj =>
bbecquet marked this conversation as resolved.
Show resolved Hide resolved
Object.entries(obj)
.filter(([_key, value]) => value !== null && value !== undefined)
.reduce((result, [key, value]) => ({ ...result, [key]: value }), {});

async function getRedirectUrl(query, res) {
const response = await axios.get(geocoderUrl, {
params: {
lang: res.locals.language.code,
nlu: useNlu ? 'true' : undefined,
q: query,
},
timeout: idunnTimeout,
});
const intention = (response.data.intentions || [])[0];
if (intention && intention.filter) {
const { q, bbox, category } = intention.filter;
const params = new URLSearchParams(
removeNullEntries({
q,
bbox: bbox && bbox.join(','),
type: isCategoryValid(category) ? category : null,
})
);

return `${config.system.baseUrl}places/?${params.toString()}`;
}

const encodedQuery = encodeURIComponent(query);
const firstPoi = (response.data.features || [])[0];
if (firstPoi) {
return `${config.system.baseUrl}place/${firstPoi.properties.geocoding.id}?q=${encodedQuery}`;
}

return `${config.system.baseUrl}noresult?q=${encodedQuery}`;
}

return function (req, res, next) {
// interpret only requests matching `/?q=<full_text_query>`
if (req.path !== '/' || !req.query.q) {
next();
return;
}

getRedirectUrl(req.query.q, res)
.then(redirectUrl => {
res.redirect(307, redirectUrl);
})
.catch(error => {
req.logger.error({ err: error });
next();
});
};
};
4 changes: 2 additions & 2 deletions src/adapters/scene.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ Scene.prototype.getMapInitOptions = function ({ locationHash, bbox }) {
};
};

Scene.prototype.initMapBox = async function ({ locationHash, bbox }) {
Scene.prototype.initMapBox = function ({ locationHash, bbox }) {
window.times.initMapBox = Date.now();

setRTLTextPlugin(
Expand All @@ -94,7 +94,7 @@ Scene.prototype.initMapBox = async function ({ locationHash, bbox }) {
hash: false,
maxZoom: 20,
locale,
...(await this.getMapInitOptions({ locationHash, bbox })),
...this.getMapInitOptions({ locationHash, bbox }),
});
// @MAPBOX: This method isn't implemented by the Mapbox-GL mock
this.mb.setPadding = this.mb.setPadding || (() => {});
Expand Down