/**
* BeNomad BeMap JavaScript API - ChargingStationSearchRequest (v1.5)
*
* Strongly-typed request builder for `POST service/chargingstation/search/1.0`.
*
* Wire shape cross-checked against the BeMap server contract in
* `bemap_idea/.../service/v1_0_0/model/chargingStation/ChargingStationSearchRequest.java`
* and verified live on `bemap-beta.benomad.com`.
*
* Required: at least one provider name (`providers`) AND one spatial
* selector — `coordinate` + `radius`, `corridor` + `radius`, or `boundingBox`.
*
* Example — circular search around Paris:
*
* var req = new bemap.ChargingStationSearchRequest({
* providers: ['ecoMovement'],
* coordinate: new bemap.Coordinate(2.35, 48.85),
* radius: 2000,
* maxPoolResult: 25,
* options: [bemap.ChargingStationOption.PATH_POOL_MAP]
* });
*
* @since 1.5.0
* @public
* @constructor
* @param {Object} [options]
* @param {bemap.ChargingStationMode} [options.mode=LOCAL_OR_REMOTE]
* @param {Array.<bemap.ChargingStationOption>} [options.options]
* @param {Number} [options.pathAutoMaxPool=20]
* When the `PATH_AUTO` option is used, drop to point-level depth as
* soon as the result count is below this threshold.
* @param {Array.<String>} options.providers
* Provider names (e.g. `'ecoMovement'`). Only names exposed by the
* current user's ACL are accepted server-side.
* @param {bemap.Coordinate|bemap.CoordinateSat|{lon:Number, lat:Number}} [options.coordinate]
* Search centre. Required with `radius` unless `corridor` or `boundingBox` is set.
* @param {Array.<bemap.Coordinate>} [options.corridor]
* Polyline corridor around which to search. Mutually exclusive with
* `coordinate` and `boundingBox`.
* @param {Number} [options.radius]
* Search radius in meters. Required with `coordinate` or `corridor`.
* @param {bemap.BoundingBox} [options.boundingBox]
* Rectangular search window. Mutually exclusive with `coordinate` and `corridor`.
* @param {Number} [options.maxPoolResult] Max pools in the response.
* @param {Number} [options.maxProviderResult] Max items the server fetches from each provider.
* @param {Array.<Number>} [options.connectorIdFilters] Connector type IDs to keep.
* @param {String} [options.poolIdFilter] Restrict result to a single pool by ID.
* @param {String} [options.stationIdFilter] Restrict result to a single station by ID.
* @param {String} [options.pointIdFilter] Restrict result to a single charging point by ID.
* @param {Number} [options.filtersVersion=1] Filter engine version. Server default is 1.
* @param {Array.<String>} [options.filters] Filter expressions — see BeMap docs.
* @param {String} [options.language] ISO 639-1 language for address fields.
* @param {String} [options.geoserver] Override the Context's geoserver for this call.
*/
bemap.ChargingStationSearchRequest = function(options) {
var opts = options || {};
this.mode = opts.mode || bemap.ChargingStationMode.LOCAL_OR_REMOTE;
this.options = Array.isArray(opts.options) ? opts.options.slice() : null;
this.pathAutoMaxPool = (typeof opts.pathAutoMaxPool === 'number') ? opts.pathAutoMaxPool : 20;
this.providers = Array.isArray(opts.providers) ? opts.providers.slice() : null;
this.coordinate = opts.coordinate || null;
this.corridor = Array.isArray(opts.corridor) ? opts.corridor.slice() : null;
this.radius = (typeof opts.radius === 'number') ? opts.radius : 0;
this.boundingBox = opts.boundingBox || null;
this.maxPoolResult = (typeof opts.maxPoolResult === 'number') ? opts.maxPoolResult : 0;
this.maxProviderResult = (typeof opts.maxProviderResult === 'number') ? opts.maxProviderResult : 0;
this.connectorIdFilters = Array.isArray(opts.connectorIdFilters) ? opts.connectorIdFilters.slice() : null;
this.poolIdFilter = opts.poolIdFilter || null;
this.stationIdFilter = opts.stationIdFilter || null;
this.pointIdFilter = opts.pointIdFilter || null;
this.filtersVersion = (typeof opts.filtersVersion === 'number') ? opts.filtersVersion : 1;
this.filters = Array.isArray(opts.filters) ? opts.filters.slice() : null;
this.language = opts.language || null;
this.geoserver = opts.geoserver || null;
};
/**
* Tiny module-private serialisation helpers for `Coordinate` / `BoundingBox`.
* Not attached to the public `bemap` namespace — internal to this file.
* @private
*/
bemap.ChargingStationSearchRequest._coordToJson = function(c) {
if (!c) return null;
var lon = (typeof c.getLon === 'function') ? c.getLon() : (c.lon !== undefined ? c.lon : c.longitude);
var lat = (typeof c.getLat === 'function') ? c.getLat() : (c.lat !== undefined ? c.lat : c.latitude);
return { lon: lon, lat: lat };
};
bemap.ChargingStationSearchRequest._bboxToJson = function(b) {
if (!b) return null;
if (typeof b.getMinLon === 'function') {
return {
topLeft: { lon: b.getMinLon(), lat: b.getMaxLat() },
bottomRight: { lon: b.getMaxLon(), lat: b.getMinLat() }
};
}
return b;
};
/**
* Serialise the request to the JSON shape consumed by the BeMap server.
* Null / empty fields are dropped so the payload stays minimal.
*
* @public
* @return {Object}
*/
bemap.ChargingStationSearchRequest.prototype.toJson = function() {
var body = { mode: this.mode };
var coordToJson = bemap.ChargingStationSearchRequest._coordToJson;
var bboxToJson = bemap.ChargingStationSearchRequest._bboxToJson;
if (this.options && this.options.length) body.options = this.options.slice();
// Only suppress the default (20). Explicit `0` MUST reach the wire so
// it can mean "never auto-switch" per server semantics.
if (this.pathAutoMaxPool !== 20) body.pathAutoMaxPool = this.pathAutoMaxPool;
if (this.providers && this.providers.length) body.providers = this.providers.slice();
if (this.coordinate) body.coordinate = coordToJson(this.coordinate);
if (this.corridor && this.corridor.length) body.corridor = this.corridor.map(coordToJson);
if (this.radius > 0) body.radius = this.radius;
if (this.boundingBox) body.bbox = bboxToJson(this.boundingBox);
if (this.maxPoolResult > 0) body.maxPoolResult = this.maxPoolResult;
if (this.maxProviderResult > 0) body.maxProviderResult = this.maxProviderResult;
if (this.connectorIdFilters && this.connectorIdFilters.length) body.connectorIdFilters = this.connectorIdFilters.slice();
if (this.poolIdFilter) body.poolIdFilter = this.poolIdFilter;
if (this.stationIdFilter) body.stationIdFilter = this.stationIdFilter;
if (this.pointIdFilter) body.pointIdFilter = this.pointIdFilter;
// Same default-suppression pattern: server default is 1, only emit on override.
if (this.filtersVersion !== 1) body.filtersVersion = this.filtersVersion;
if (this.filters && this.filters.length) body.filters = this.filters.slice();
if (this.language) body.language = this.language;
if (this.geoserver) body.geoserver = this.geoserver;
return body;
};