UNPKG

@opengis/bi

Version:

BI data visualization module

107 lines (87 loc) 4.78 kB
import descriptionList from "./descriptionList.js"; import metaFormat from "./metaFormat.js"; async function getDataByLatLng({ pg, layer, table, id, lat, lng, time = [] }) { // const rclient = getRedis(); // const redisKey = `${pg.options.database}:gis-format:${layer}:${lat}:${lng}`; // const cacheData = await rclient.get(redisKey); // if (cacheData && !config.local) return JSON.parse(cacheData); const { rows: styles = [] } = await pg.query(`select style_id as id, dataset from gis.style where style_id=any($1::text[]) union all select dataset_id as id, json_build_array(json_build_object('pk', pk, 'table', table_name, 'query', query, 'card', setting->>'card', 'columns', column_list)) as dataset from bi.dataset a where dataset_id=any($1::text[])`, [layer.split(',')]); time.push(Date.now()); if (!styles?.length) { return { message: `style not found: ${layer}`, status: 400 }; } const { srids } = await pg.queryCache?.('select json_agg(srid) as srids from spatial_ref_sys').then((res1) => res1.rows?.[0] || {}) || {}; const layers = styles.reduce((acc, curr) => { curr.dataset?.filter((el) => el.table && (el.pk || pg.pk?.[el.table])) ?.forEach((el) => acc.push({ layer: curr.id, pk: el.pk || pg.pk?.[el.table], key: el.key, table: el.table, query: el.query, template: el.card, column_list: el.column_list, columns: el.columns || el.column_list?.map((el) => el.name)?.join(','), srid: el.srid || '4326', geom: el.geom || 'geom', step: srids?.includes(el.srid - 0) && el.srid !== '4326' ? 10 : 0.0002, })); return acc; }, []) .filter((el) => el.pk && el.layer) .filter((el) => table ? el.table === table : true); if (!layers.length) { return { message: 'data not found', status: 404 }; } const point = `srid=4326;point(${lng} ${lat})`; // ${el.columns?.split?.filter?.((el) => el) ? `,${el.columns?.split?.filter?.((el) => el) || ''}` : ''} const q = layers.map((el) => `select ${el.pk}, '${el.layer}' as layer, row_to_json(t) as data, st_asgeojson(${el.geom})::json as geom from ${el.table} t where ${el.query || '1=1'} and ${id ? `${el.pk}::text='${id.replace(/'/g, "''")}'` : '1=1'} and case when ST_GeometryType(geom) in ('ST_Polygon','ST_MultiPolygon') then st_intersects(geom,st_buffer('${point}',${el.step})) when ST_GeometryType(geom) in ('ST_Line','ST_MultiLineString') then st_distance(geom,'${point}') < ${el.step} else false end`).join(' union all '); // if (config.local && config.debug) console.log(q); const { rows: objects = [] } = await pg.query(q) || {}; time.push(Date.now()); const rows = objects.map((row) => { const layerData = layers.find((el) => el.layer === row?.layer) || {}; const rowData = layerData?.columns?.split?.filter?.((el) => el) ? layerData?.columns?.split?.filter?.((el) => el).reduce((acc, curr) => Object.assign(acc, { [curr]: row.data?.[curr] }), {}) : row.data; return { ...rowData, ...row, ...layerData, data: undefined, id: layerData.pk ? row?.[layerData.pk] : undefined, geom: row.geom, }; }); const { pk, layer: layerId, card, template } = rows[0] || {}; const dataset = layers.find((el) => el.layer === rows?.[0]?.layer) || {}; const columnList = (dataset.column_list || dataset.columns)?.reduce?.((acc, curr) => Object.assign(acc, { [curr.name]: curr.title || curr.ua || curr.name }), {}) || {}; const columns = card ? Object.keys(card).map(el => `${el}| ${card[el]}`).join('|') : Object.keys(columnList)?.map((key) => `${columnList[key]}| ${key}`).join('|'); const html = columns && rows?.[0] ? await descriptionList(rows[0], { hash: { columns } }) : undefined; time.push(Date.now()); await Promise.all(rows.map(async () => { const layerData = layers.find((el) => el.layer === rows?.[0]?.layer) || {}; const columns = layerData.column_list || layerData.columns; if (columns?.length && Array.isArray(columns)) { await metaFormat({ rows, columns }); } })); time.push(Date.now()); const resp = { id: rows?.[0]?.[pk], layers: layerId, template, data: rows?.[0], rows, html }; // await rclient.set(redisKey, JSON.stringify(resp), 'EX', 5 * 60); return resp; } export default getDataByLatLng