Source: bemap-services-v2/search/bemap-near-poi-search.js

/**
 * BeNomad BeMap JavaScript API - NearPoiSearch (v1.5)
 *
 * Promise-based wrapper around `POST service/nearpoi/1.0`. Returns the POIs
 * reachable from a coordinate within a distance budget.
 *
 * Wire shape mirrors the BeMap server contract (cross-checked against
 * `bemap-flutter-api/lib/service/near_poi/provider/near_poi.dart`).
 *
 * Typical use:
 *
 *   var search = new bemap.NearPoiSearch(ctx);
 *   search.nearPoi(new bemap.NearPoiRequest({
 *       coordinate: new bemap.Coordinate(2.3522, 48.8566),
 *       distance: 800,
 *       transportType: bemap.TransportMode.CAR,
 *       orderBy: bemap.NearPoiOrder.DISTANCE_ASC
 *   })).then(function(response) {
 *       response.getPoints().forEach(function(p) { ... });
 *   });
 *
 * @since 1.5.0
 * @public
 * @constructor
 * @extends {bemap.ServiceV2}
 * @param {bemap.Context} context BeMap-JS-API Context. Mandatory.
 * @param {Object} [options]
 */
bemap.NearPoiSearch = function(context, options) {
    bemap.ServiceV2.call(this, context, options);
};
bemap.inherits(bemap.NearPoiSearch, bemap.ServiceV2);

/**
 * Send a near-POI request.
 *
 * @public
 * @param {bemap.NearPoiRequest|bemap.Coordinate|bemap.CoordinateSat} arg
 *   - A typed `NearPoiRequest` (preferred).
 *   - Or a bare coordinate; in that case the second argument carries
 *     `{ distance, transportType, orderBy, enablePolyline, enableEncodedPolyline }`.
 * @param {Object} [filters] Filter shorthand when the first arg is a bare coordinate.
 * @param {Object} [options]
 * @param {String} [options.geoserver]
 * @param {AbortSignal} [options.signal]
 * @return {Promise<bemap.NearPoiResponse>}
 */
bemap.NearPoiSearch.prototype.nearPoi = function(arg, filters, options) {
    var request;
    var opts;
    if (arg instanceof bemap.NearPoiRequest) {
        request = arg;
        opts = filters || {};
    } else if (arg instanceof bemap.Coordinate || arg instanceof bemap.CoordinateSat
            || (arg && typeof arg.lon === 'number' && typeof arg.lat === 'number')) {
        var merged = { coordinate: arg };
        if (filters) {
            for (var k in filters) {
                if (Object.prototype.hasOwnProperty.call(filters, k)) merged[k] = filters[k];
            }
        }
        request = new bemap.NearPoiRequest(merged);
        opts = options || {};
    } else {
        return Promise.reject(new bemap.Error({
            code: bemap.Error.NETWORK,
            message: 'NearPoiSearch.nearPoi requires a NearPoiRequest or a Coordinate'
        }));
    }

    var body = request.toJson();
    if (!body.geoserver) body.geoserver = opts.geoserver || this.ctx.getGeoserver();

    return this._post('service/nearpoi/1.0', body, opts)
        .then(function(json) {
            return bemap.NearPoiResponse.fromJson(json);
        });
};