location_nnearest.mjs

/**
## /location/nnearest

The module exports a utility method for the nnearest query template.

@requires /utils/xhr
@module /location/nnearest
*/

/**
@function nnearest

@description
The nnearest method gets coordinates from a feature geometry passed in the params argument.

A parameterised query to the get_nnearest template will be sent. The n for the nearest records query param is implied by the count property value of a cluster feature.

The records returned from the query are presented in a list popup positioned on the feature geometry.

Clicking on a list element allows to get the location associated with the query response record.

@param {object} params Parameter for the nnearest location query.
@property {mapview} params.mapview The mapview for locations layer.
@property {layer} params.later The locations layer.
@property {object} params.feature Query records nnearest to the feature.geometry.
@property {string} params.table The database table for the query.
*/
export default async function nnearest(params) {
  const featureProperties = params.feature.getProperties();

  const fGeom = params.feature.getGeometry();
  const fCoord = fGeom.getCoordinates();
  const coords = ol.proj.transform(
    fCoord,
    `EPSG:${params.mapview.srid}`,
    `EPSG:${params.layer.srid}`,
  );

  const response = await mapp.utils.xhr(
    `${params.mapview.host}/api/query/get_nnearest?` +
      mapp.utils.paramString({
        locale: params.mapview.locale.key,
        layer: params.layer.key,
        geom: params.layer.geom,
        qID: params.layer.qID,
        label: params.layer.cluster?.label || params.layer.qID,
        table: params.table,
        filter: params.layer.filter?.current,
        n:
          featureProperties.count > (params.max || 99)
            ? params.max || 99
            : featureProperties.count,
        x: coords[0],
        y: coords[1],
        coords: coords,
      }),
  );

  const list = response.map(
    (li) => mapp.utils.html.node`<li 
    onclick=${(e) => {
      params.mapview.popup(null);
      mapp.location.get({
        layer: params.layer,
        table: params.table,
        id: li.id,
        marker: ol.proj.transform(
          li.coords,
          'EPSG:' + params.layer.srid,
          'EPSG:' + params.mapview.srid,
        ),
      });
    }}>${li.label || '"' + params.layer.cluster?.label + '"'}`,
  );

  const content = mapp.utils.html.node`<ul class="list">${list}`;

  params.mapview.popup({
    coords: ol.proj.transform(
      coords,
      'EPSG:' + params.layer.srid,
      'EPSG:' + params.mapview.srid,
    ),
    autoPan: true,
    content,
  });
}