Something went wrong on our end
-
Timothee P authoredTimothee P authored
Control.Geocoder.js 57.64 KiB
/* @preserve
* Leaflet Control Geocoder 1.13.0
* https://github.com/perliedman/leaflet-control-geocoder
*
* Copyright (c) 2012 sa3m (https://github.com/sa3m)
* Copyright (c) 2018 Per Liedman
* All rights reserved.
*/
this.L = this.L || {};
this.L.Control = this.L.Control || {};
this.L.Control.Geocoder = (function (L) {
'use strict';
L = L && Object.prototype.hasOwnProperty.call(L, 'default') ? L['default'] : L;
var lastCallbackId = 0;
// Adapted from handlebars.js
// https://github.com/wycats/handlebars.js/
var badChars = /[&<>"'`]/g;
var possible = /[&<>"'`]/;
var escape = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": ''',
'`': '`'
};
function escapeChar(chr) {
return escape[chr];
}
function htmlEscape(string) {
if (string == null) {
return '';
} else if (!string) {
return string + '';
}
// Force a string conversion as this will be done by the append regardless and
// the regex test will do this transparently behind the scenes, causing issues if
// an object's to string has escaped characters in it.
string = '' + string;
if (!possible.test(string)) {
return string;
}
return string.replace(badChars, escapeChar);
}
function jsonp(url, params, callback, context, jsonpParam) {
var callbackId = '_l_geocoder_' + lastCallbackId++;
params[jsonpParam || 'callback'] = callbackId;
window[callbackId] = L.Util.bind(callback, context);
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url + getParamString(params);
script.id = callbackId;
document.getElementsByTagName('head')[0].appendChild(script);
}
function getJSON(url, params, callback) {
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function () {
if (xmlHttp.readyState !== 4) {
return;
}
var message;
if (xmlHttp.status !== 200 && xmlHttp.status !== 304) {
message = '';
} else if (typeof xmlHttp.response === 'string') {
// IE doesn't parse JSON responses even with responseType: 'json'.
try {
message = JSON.parse(xmlHttp.response);
} catch (e) {
// Not a JSON response
message = xmlHttp.response;
}
} else {
message = xmlHttp.response;
}
callback(message);
};
xmlHttp.open('GET', url + getParamString(params), true);
xmlHttp.responseType = 'json';
xmlHttp.setRequestHeader('Accept', 'application/json');
xmlHttp.send(null);
}
function template(str, data) {
return str.replace(/\{ *([\w_]+) *\}/g, function (str, key) {
var value = data[key];
if (value === undefined) {
value = '';
} else if (typeof value === 'function') {
value = value(data);
}
return htmlEscape(value);
});
}
function getParamString(obj, existingUrl, uppercase) {
var params = [];
for (var i in obj) {
var key = encodeURIComponent(uppercase ? i.toUpperCase() : i);
var value = obj[i];
if (!L.Util.isArray(value)) {
params.push(key + '=' + encodeURIComponent(value));
} else {
for (var j = 0; j < value.length; j++) {
params.push(key + '=' + encodeURIComponent(value[j]));
}
}
}
return (!existingUrl || existingUrl.indexOf('?') === -1 ? '?' : '&') + params.join('&');
}
var ArcGis = L.Class.extend({
options: {
service_url: 'https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer'
},
initialize: function (accessToken, options) {
L.setOptions(this, options);
this._accessToken = accessToken;
},
geocode: function (query, cb, context) {
var params = {
SingleLine: query,
outFields: 'Addr_Type',
forStorage: false,
maxLocations: 10,
f: 'json'
};
if (this._key && this._key.length) {
params.token = this._key;
}
getJSON(
this.options.service_url + '/findAddressCandidates',
L.extend(params, this.options.geocodingQueryParams),
function (data) {
var results = [],
loc,
latLng,
latLngBounds;
if (data.candidates && data.candidates.length) {
for (var i = 0; i <= data.candidates.length - 1; i++) {
loc = data.candidates[i];
latLng = L.latLng(loc.location.y, loc.location.x);
latLngBounds = L.latLngBounds(
L.latLng(loc.extent.ymax, loc.extent.xmax),
L.latLng(loc.extent.ymin, loc.extent.xmin)
);
results[i] = {
name: loc.address,
bbox: latLngBounds,
center: latLng
};
}
}
cb.call(context, results);
}
);
},
suggest: function (query, cb, context) {
return this.geocode(query, cb, context);
},
reverse: function (location, scale, cb, context) {
var params = {
location: encodeURIComponent(location.lng) + ',' + encodeURIComponent(location.lat),
distance: 100,
f: 'json'
};
getJSON(this.options.service_url + '/reverseGeocode', params, function (data) {
var result = [],
loc;
if (data && !data.error) {
loc = L.latLng(data.location.y, data.location.x);
result.push({
name: data.address.Match_addr,
center: loc,
bounds: L.latLngBounds(loc, loc)
});
}
cb.call(context, result);
});
}
});
function arcgis(accessToken, options) {
return new ArcGis(accessToken, options);
}
var Bing = L.Class.extend({
initialize: function (key) {
this.key = key;
},
geocode: function (query, cb, context) {
jsonp(
'https://dev.virtualearth.net/REST/v1/Locations',
{
query: query,
key: this.key
},
function (data) {
var results = [];
if (data.resourceSets.length > 0) {
for (var i = data.resourceSets[0].resources.length - 1; i >= 0; i--) {
var resource = data.resourceSets[0].resources[i],
bbox = resource.bbox;
results[i] = {
name: resource.name,
bbox: L.latLngBounds([bbox[0], bbox[1]], [bbox[2], bbox[3]]),
center: L.latLng(resource.point.coordinates)
};
}
}
cb.call(context, results);
},
this,
'jsonp'
);
},
reverse: function (location, scale, cb, context) {
jsonp(
'//dev.virtualearth.net/REST/v1/Locations/' + location.lat + ',' + location.lng,
{
key: this.key
},
function (data) {
var results = [];
for (var i = data.resourceSets[0].resources.length - 1; i >= 0; i--) {
var resource = data.resourceSets[0].resources[i],
bbox = resource.bbox;
results[i] = {
name: resource.name,
bbox: L.latLngBounds([bbox[0], bbox[1]], [bbox[2], bbox[3]]),
center: L.latLng(resource.point.coordinates)
};
}
cb.call(context, results);
},
this,
'jsonp'
);
}
});
function bing(key) {
return new Bing(key);
}
var Google = L.Class.extend({
options: {
serviceUrl: 'https://maps.googleapis.com/maps/api/geocode/json',
geocodingQueryParams: {},
reverseQueryParams: {}
},
initialize: function (key, options) {
this._key = key;
L.setOptions(this, options);
// Backwards compatibility
this.options.serviceUrl = this.options.service_url || this.options.serviceUrl;
},
geocode: function (query, cb, context) {
var params = {
address: query
};
if (this._key && this._key.length) {
params.key = this._key;
}
params = L.Util.extend(params, this.options.geocodingQueryParams);
getJSON(this.options.serviceUrl, params, function (data) {
var results = [],
loc,
latLng,
latLngBounds;
if (data.results && data.results.length) {
for (var i = 0; i <= data.results.length - 1; i++) {
loc = data.results[i];
latLng = L.latLng(loc.geometry.location);
latLngBounds = L.latLngBounds(
L.latLng(loc.geometry.viewport.northeast),
L.latLng(loc.geometry.viewport.southwest)
);
results[i] = {
name: loc.formatted_address,
bbox: latLngBounds,
center: latLng,
properties: loc.address_components
};
}
}
cb.call(context, results);
});
},
reverse: function (location, scale, cb, context) {
var params = {
latlng: encodeURIComponent(location.lat) + ',' + encodeURIComponent(location.lng)
};
params = L.Util.extend(params, this.options.reverseQueryParams);
if (this._key && this._key.length) {
params.key = this._key;
}
getJSON(this.options.serviceUrl, params, function (data) {
var results = [],
loc,
latLng,
latLngBounds;
if (data.results && data.results.length) {
for (var i = 0; i <= data.results.length - 1; i++) {
loc = data.results[i];
latLng = L.latLng(loc.geometry.location);
latLngBounds = L.latLngBounds(
L.latLng(loc.geometry.viewport.northeast),
L.latLng(loc.geometry.viewport.southwest)
);
results[i] = {
name: loc.formatted_address,
bbox: latLngBounds,
center: latLng,
properties: loc.address_components
};
}
}
cb.call(context, results);
});
}
});
function google(key, options) {
return new Google(key, options);
}
var HERE = L.Class.extend({
options: {
geocodeUrl: 'https://geocoder.api.here.com/6.2/geocode.json',
reverseGeocodeUrl: 'https://reverse.geocoder.api.here.com/6.2/reversegeocode.json',
app_id: '<insert your app_id here>',
app_code: '<insert your app_code here>',
geocodingQueryParams: {},
reverseQueryParams: {},
reverseGeocodeProxRadius: null
},
initialize: function (options) {
L.setOptions(this, options);
},
geocode: function (query, cb, context) {
var params = {
searchtext: query,
gen: 9,
app_id: this.options.app_id,
app_code: this.options.app_code,
jsonattributes: 1
};
params = L.Util.extend(params, this.options.geocodingQueryParams);
this.getJSON(this.options.geocodeUrl, params, cb, context);
},
reverse: function (location, scale, cb, context) {
var _proxRadius = this.options.reverseGeocodeProxRadius
? this.options.reverseGeocodeProxRadius
: null;
var proxRadius = _proxRadius ? ',' + encodeURIComponent(_proxRadius) : '';
var params = {
prox: encodeURIComponent(location.lat) + ',' + encodeURIComponent(location.lng) + proxRadius,
mode: 'retrieveAddresses',
app_id: this.options.app_id,
app_code: this.options.app_code,
gen: 9,
jsonattributes: 1
};
params = L.Util.extend(params, this.options.reverseQueryParams);
this.getJSON(this.options.reverseGeocodeUrl, params, cb, context);
},
getJSON: function (url, params, cb, context) {
getJSON(url, params, function (data) {
var results = [],
loc,
latLng,
latLngBounds;
if (data.response.view && data.response.view.length) {
for (var i = 0; i <= data.response.view[0].result.length - 1; i++) {
loc = data.response.view[0].result[i].location;
latLng = L.latLng(loc.displayPosition.latitude, loc.displayPosition.longitude);
latLngBounds = L.latLngBounds(
L.latLng(loc.mapView.topLeft.latitude, loc.mapView.topLeft.longitude),
L.latLng(loc.mapView.bottomRight.latitude, loc.mapView.bottomRight.longitude)
);
results[i] = {
name: loc.address.label,
properties: loc.address,
bbox: latLngBounds,
center: latLng
};
}
}
cb.call(context, results);
});
}
});
function here(options) {
return new HERE(options);
}
var LatLng = L.Class.extend({
options: {
// the next geocoder to use
next: undefined,
sizeInMeters: 10000
},
initialize: function (options) {
L.Util.setOptions(this, options);
},
geocode: function (query, cb, context) {
var match;
var center;
// regex from https://github.com/openstreetmap/openstreetmap-website/blob/master/app/controllers/geocoder_controller.rb
if ((match = query.match(/^([NS])\s*(\d{1,3}(?:\.\d*)?)\W*([EW])\s*(\d{1,3}(?:\.\d*)?)$/))) {
// [NSEW] decimal degrees
center = L.latLng(
(/N/i.test(match[1]) ? 1 : -1) * parseFloat(match[2]),
(/E/i.test(match[3]) ? 1 : -1) * parseFloat(match[4])
);
} else if (
(match = query.match(/^(\d{1,3}(?:\.\d*)?)\s*([NS])\W*(\d{1,3}(?:\.\d*)?)\s*([EW])$/))
) {
// decimal degrees [NSEW]
center = L.latLng(
(/N/i.test(match[2]) ? 1 : -1) * parseFloat(match[1]),
(/E/i.test(match[4]) ? 1 : -1) * parseFloat(match[3])
);
} else if (
(match = query.match(
/^([NS])\s*(\d{1,3})°?\s*(\d{1,3}(?:\.\d*)?)?['′]?\W*([EW])\s*(\d{1,3})°?\s*(\d{1,3}(?:\.\d*)?)?['′]?$/
))
) {
// [NSEW] degrees, decimal minutes
center = L.latLng(
(/N/i.test(match[1]) ? 1 : -1) * (parseFloat(match[2]) + parseFloat(match[3] / 60)),
(/E/i.test(match[4]) ? 1 : -1) * (parseFloat(match[5]) + parseFloat(match[6] / 60))
);
} else if (
(match = query.match(
/^(\d{1,3})°?\s*(\d{1,3}(?:\.\d*)?)?['′]?\s*([NS])\W*(\d{1,3})°?\s*(\d{1,3}(?:\.\d*)?)?['′]?\s*([EW])$/
))
) {
// degrees, decimal minutes [NSEW]
center = L.latLng(
(/N/i.test(match[3]) ? 1 : -1) * (parseFloat(match[1]) + parseFloat(match[2] / 60)),
(/E/i.test(match[6]) ? 1 : -1) * (parseFloat(match[4]) + parseFloat(match[5] / 60))
);
} else if (
(match = query.match(
/^([NS])\s*(\d{1,3})°?\s*(\d{1,2})['′]?\s*(\d{1,3}(?:\.\d*)?)?["″]?\W*([EW])\s*(\d{1,3})°?\s*(\d{1,2})['′]?\s*(\d{1,3}(?:\.\d*)?)?["″]?$/
))
) {
// [NSEW] degrees, minutes, decimal seconds
center = L.latLng(
(/N/i.test(match[1]) ? 1 : -1) *
(parseFloat(match[2]) + parseFloat(match[3] / 60 + parseFloat(match[4] / 3600))),
(/E/i.test(match[5]) ? 1 : -1) *
(parseFloat(match[6]) + parseFloat(match[7] / 60) + parseFloat(match[8] / 3600))
);
} else if (
(match = query.match(
/^(\d{1,3})°?\s*(\d{1,2})['′]?\s*(\d{1,3}(?:\.\d*)?)?["″]\s*([NS])\W*(\d{1,3})°?\s*(\d{1,2})['′]?\s*(\d{1,3}(?:\.\d*)?)?["″]?\s*([EW])$/
))
) {
// degrees, minutes, decimal seconds [NSEW]
center = L.latLng(
(/N/i.test(match[4]) ? 1 : -1) *
(parseFloat(match[1]) + parseFloat(match[2] / 60 + parseFloat(match[3] / 3600))),
(/E/i.test(match[8]) ? 1 : -1) *
(parseFloat(match[5]) + parseFloat(match[6] / 60) + parseFloat(match[7] / 3600))
);
} else if (
(match = query.match(/^\s*([+-]?\d+(?:\.\d*)?)\s*[\s,]\s*([+-]?\d+(?:\.\d*)?)\s*$/))
) {
center = L.latLng(parseFloat(match[1]), parseFloat(match[2]));
}
if (center) {
var results = [
{
name: query,
center: center,
bbox: center.toBounds(this.options.sizeInMeters)
}
];
cb.call(context, results);
} else if (this.options.next) {
this.options.next.geocode(query, cb, context);
}
}
});
function latLng(options) {
return new LatLng(options);
}
var Mapbox = L.Class.extend({
options: {
serviceUrl: 'https://api.mapbox.com/geocoding/v5/mapbox.places/',
geocodingQueryParams: {},
reverseQueryParams: {}
},
initialize: function (accessToken, options) {
L.setOptions(this, options);
this.options.geocodingQueryParams.access_token = accessToken;
this.options.reverseQueryParams.access_token = accessToken;
},
geocode: function (query, cb, context) {
var params = this.options.geocodingQueryParams;
if (
params.proximity !== undefined &&
params.proximity.lat !== undefined &&
params.proximity.lng !== undefined
) {
params.proximity = params.proximity.lng + ',' + params.proximity.lat;
}
getJSON(this.options.serviceUrl + encodeURIComponent(query) + '.json', params, function (data) {
var results = [],
loc,
latLng,
latLngBounds;
if (data.features && data.features.length) {
for (var i = 0; i <= data.features.length - 1; i++) {
loc = data.features[i];
latLng = L.latLng(loc.center.reverse());
if (loc.bbox) {
latLngBounds = L.latLngBounds(
L.latLng(loc.bbox.slice(0, 2).reverse()),
L.latLng(loc.bbox.slice(2, 4).reverse())
);
} else {
latLngBounds = L.latLngBounds(latLng, latLng);
}
var properties = {
text: loc.text,
address: loc.address
};
for (var j = 0; j < (loc.context || []).length; j++) {
var id = loc.context[j].id.split('.')[0];
properties[id] = loc.context[j].text;
// Get country code when available
if (loc.context[j].short_code) {
properties['countryShortCode'] = loc.context[j].short_code;
}
}
results[i] = {
name: loc.place_name,
bbox: latLngBounds,
center: latLng,
properties: properties
};
}
}
cb.call(context, results);
});
},
suggest: function (query, cb, context) {
return this.geocode(query, cb, context);
},
reverse: function (location, scale, cb, context) {
getJSON(
this.options.serviceUrl +
encodeURIComponent(location.lng) +
',' +
encodeURIComponent(location.lat) +
'.json',
this.options.reverseQueryParams,
function (data) {
var results = [],
loc,
latLng,
latLngBounds;
if (data.features && data.features.length) {
for (var i = 0; i <= data.features.length - 1; i++) {
loc = data.features[i];
latLng = L.latLng(loc.center.reverse());
if (loc.bbox) {
latLngBounds = L.latLngBounds(
L.latLng(loc.bbox.slice(0, 2).reverse()),
L.latLng(loc.bbox.slice(2, 4).reverse())
);
} else {
latLngBounds = L.latLngBounds(latLng, latLng);
}
results[i] = {
name: loc.place_name,
bbox: latLngBounds,
center: latLng
};
}
}
cb.call(context, results);
}
);
}
});
function mapbox(accessToken, options) {
return new Mapbox(accessToken, options);
}
var MapQuest = L.Class.extend({
options: {
serviceUrl: 'https://www.mapquestapi.com/geocoding/v1'
},
initialize: function (key, options) {
// MapQuest seems to provide URI encoded API keys,
// so to avoid encoding them twice, we decode them here
this._key = decodeURIComponent(key);
L.Util.setOptions(this, options);
},
_formatName: function () {
var r = [],
i;
for (i = 0; i < arguments.length; i++) {
if (arguments[i]) {
r.push(arguments[i]);
}
}
return r.join(', ');
},
geocode: function (query, cb, context) {
getJSON(
this.options.serviceUrl + '/address',
{
key: this._key,
location: query,
limit: 5,
outFormat: 'json'
},
L.bind(function (data) {
var results = [],
loc,
latLng;
if (data.results && data.results[0].locations) {
for (var i = data.results[0].locations.length - 1; i >= 0; i--) {
loc = data.results[0].locations[i];
latLng = L.latLng(loc.latLng);
results[i] = {
name: this._formatName(loc.street, loc.adminArea4, loc.adminArea3, loc.adminArea1),
bbox: L.latLngBounds(latLng, latLng),
center: latLng
};
}
}
cb.call(context, results);
}, this)
);
},
reverse: function (location, scale, cb, context) {
getJSON(
this.options.serviceUrl + '/reverse',
{
key: this._key,
location: location.lat + ',' + location.lng,
outputFormat: 'json'
},
L.bind(function (data) {
var results = [],
loc,
latLng;
if (data.results && data.results[0].locations) {
for (var i = data.results[0].locations.length - 1; i >= 0; i--) {
loc = data.results[0].locations[i];
latLng = L.latLng(loc.latLng);
results[i] = {
name: this._formatName(loc.street, loc.adminArea4, loc.adminArea3, loc.adminArea1),
bbox: L.latLngBounds(latLng, latLng),
center: latLng
};
}
}
cb.call(context, results);
}, this)
);
}
});
function mapQuest(key, options) {
return new MapQuest(key, options);
}
var Neutrino = L.Class.extend({
options: {
userId: '<insert your userId here>',
apiKey: '<insert your apiKey here>',
serviceUrl: 'https://neutrinoapi.com/'
},
initialize: function (options) {
L.Util.setOptions(this, options);
},
// https://www.neutrinoapi.com/api/geocode-address/
geocode: function (query, cb, context) {
getJSON(
this.options.serviceUrl + 'geocode-address',
{
apiKey: this.options.apiKey,
userId: this.options.userId,
//get three words and make a dot based string
address: query.split(/\s+/).join('.')
},
function (data) {
var results = [],
latLng,
latLngBounds;
if (data.locations) {
data.geometry = data.locations[0];
latLng = L.latLng(data.geometry['latitude'], data.geometry['longitude']);
latLngBounds = L.latLngBounds(latLng, latLng);
results[0] = {
name: data.geometry.address,
bbox: latLngBounds,
center: latLng
};
}
cb.call(context, results);
}
);
},
suggest: function (query, cb, context) {
return this.geocode(query, cb, context);
},
// https://www.neutrinoapi.com/api/geocode-reverse/
reverse: function (location, scale, cb, context) {
getJSON(
this.options.serviceUrl + 'geocode-reverse',
{
apiKey: this.options.apiKey,
userId: this.options.userId,
latitude: location.lat,
longitude: location.lng
},
function (data) {
var results = [],
latLng,
latLngBounds;
if (data.status.status == 200 && data.found) {
latLng = L.latLng(location.lat, location.lng);
latLngBounds = L.latLngBounds(latLng, latLng);
results[0] = {
name: data.address,
bbox: latLngBounds,
center: latLng
};
}
cb.call(context, results);
}
);
}
});
function neutrino(accessToken) {
return new Neutrino(accessToken);
}
var Nominatim = L.Class.extend({
options: {
serviceUrl: 'https://nominatim.openstreetmap.org/',
geocodingQueryParams: {},
reverseQueryParams: {},
htmlTemplate: function (r) {
var a = r.address,
className,
parts = [];
if (a.road || a.building) {
parts.push('{building} {road} {house_number}');
}
if (a.city || a.town || a.village || a.hamlet) {
className = parts.length > 0 ? 'leaflet-control-geocoder-address-detail' : '';
parts.push(
'<span class="' + className + '">{postcode} {city} {town} {village} {hamlet}</span>'
);
}
if (a.state || a.country) {
className = parts.length > 0 ? 'leaflet-control-geocoder-address-context' : '';
parts.push('<span class="' + className + '">{state} {country}</span>');
}
return template(parts.join('<br/>'), a);
}
},
initialize: function (options) {
L.Util.setOptions(this, options);
},
geocode: function (query, cb, context) {
getJSON(
this.options.serviceUrl + 'search',
L.extend(
{
q: query,
limit: 5,
format: 'json',
addressdetails: 1
},
this.options.geocodingQueryParams
),
L.bind(function (data) {
var results = [];
for (var i = data.length - 1; i >= 0; i--) {
var bbox = data[i].boundingbox;
for (var j = 0; j < 4; j++) bbox[j] = parseFloat(bbox[j]);
results[i] = {
icon: data[i].icon,
name: data[i].display_name,
html: this.options.htmlTemplate ? this.options.htmlTemplate(data[i]) : undefined,
bbox: L.latLngBounds([bbox[0], bbox[2]], [bbox[1], bbox[3]]),
center: L.latLng(data[i].lat, data[i].lon),
properties: data[i]
};
}
cb.call(context, results);
}, this)
);
},
suggest: function (query, cb, context) {
return this.geocode(query, cb, context);
},
reverse: function (location, scale, cb, context) {
getJSON(
this.options.serviceUrl + 'reverse',
L.extend(
{
lat: location.lat,
lon: location.lng,
zoom: Math.round(Math.log(scale / 256) / Math.log(2)),
addressdetails: 1,
format: 'json'
},
this.options.reverseQueryParams
),
L.bind(function (data) {
var result = [],
loc;
if (data && data.lat && data.lon) {
loc = L.latLng(data.lat, data.lon);
result.push({
name: data.display_name,
html: this.options.htmlTemplate ? this.options.htmlTemplate(data) : undefined,
center: loc,
bounds: L.latLngBounds(loc, loc),
properties: data
});
}
cb.call(context, result);
}, this)
);
}
});
function nominatim(options) {
return new Nominatim(options);
}
var OpenLocationCode = L.Class.extend({
options: {
OpenLocationCode: undefined,
codeLength: undefined
},
initialize: function (options) {
L.setOptions(this, options);
},
geocode: function (query, cb, context) {
try {
var decoded = this.options.OpenLocationCode.decode(query);
var result = {
name: query,
center: L.latLng(decoded.latitudeCenter, decoded.longitudeCenter),
bbox: L.latLngBounds(
L.latLng(decoded.latitudeLo, decoded.longitudeLo),
L.latLng(decoded.latitudeHi, decoded.longitudeHi)
)
};
cb.call(context, [result]);
} catch (e) {
console.warn(e); // eslint-disable-line no-console
cb.call(context, []);
}
},
reverse: function (location, scale, cb, context) {
try {
var code = this.options.OpenLocationCode.encode(
location.lat,
location.lng,
this.options.codeLength
);
var result = {
name: code,
center: L.latLng(location.lat, location.lng),
bbox: L.latLngBounds(
L.latLng(location.lat, location.lng),
L.latLng(location.lat, location.lng)
)
};
cb.call(context, [result]);
} catch (e) {
console.warn(e); // eslint-disable-line no-console
cb.call(context, []);
}
}
});
function openLocationCode(options) {
return new OpenLocationCode(options);
}
var OpenCage = L.Class.extend({
options: {
serviceUrl: 'https://api.opencagedata.com/geocode/v1/json',
geocodingQueryParams: {},
reverseQueryParams: {}
},
initialize: function (apiKey, options) {
L.setOptions(this, options);
this._accessToken = apiKey;
},
geocode: function (query, cb, context) {
var params = {
key: this._accessToken,
q: query
};
params = L.extend(params, this.options.geocodingQueryParams);
getJSON(this.options.serviceUrl, params, function (data) {
var results = [],
latLng,
latLngBounds,
loc;
if (data.results && data.results.length) {
for (var i = 0; i < data.results.length; i++) {
loc = data.results[i];
latLng = L.latLng(loc.geometry);
if (loc.annotations && loc.annotations.bounds) {
latLngBounds = L.latLngBounds(
L.latLng(loc.annotations.bounds.northeast),
L.latLng(loc.annotations.bounds.southwest)
);
} else {
latLngBounds = L.latLngBounds(latLng, latLng);
}
results.push({
name: loc.formatted,
bbox: latLngBounds,
center: latLng
});
}
}
cb.call(context, results);
});
},
suggest: function (query, cb, context) {
return this.geocode(query, cb, context);
},
reverse: function (location, scale, cb, context) {
var params = {
key: this._accessToken,
q: [location.lat, location.lng].join(',')
};
params = L.extend(params, this.options.reverseQueryParams);
getJSON(this.options.serviceUrl, params, function (data) {
var results = [],
latLng,
latLngBounds,
loc;
if (data.results && data.results.length) {
for (var i = 0; i < data.results.length; i++) {
loc = data.results[i];
latLng = L.latLng(loc.geometry);
if (loc.annotations && loc.annotations.bounds) {
latLngBounds = L.latLngBounds(
L.latLng(loc.annotations.bounds.northeast),
L.latLng(loc.annotations.bounds.southwest)
);
} else {
latLngBounds = L.latLngBounds(latLng, latLng);
}
results.push({
name: loc.formatted,
bbox: latLngBounds,
center: latLng
});
}
}
cb.call(context, results);
});
}
});
function opencage(apiKey, options) {
return new OpenCage(apiKey, options);
}
var Pelias = L.Class.extend({
options: {
serviceUrl: 'https://api.geocode.earth/v1',
geocodingQueryParams: {},
reverseQueryParams: {}
},
initialize: function (apiKey, options) {
L.Util.setOptions(this, options);
this._apiKey = apiKey;
this._lastSuggest = 0;
},
geocode: function (query, cb, context) {
var _this = this;
getJSON(
this.options.serviceUrl + '/search',
L.extend(
{
api_key: this._apiKey,
text: query
},
this.options.geocodingQueryParams
),
function (data) {
cb.call(context, _this._parseResults(data, 'bbox'));
}
);
},
suggest: function (query, cb, context) {
var _this = this;
getJSON(
this.options.serviceUrl + '/autocomplete',
L.extend(
{
api_key: this._apiKey,
text: query
},
this.options.geocodingQueryParams
),
L.bind(function (data) {
if (data.geocoding.timestamp > this._lastSuggest) {
this._lastSuggest = data.geocoding.timestamp;
cb.call(context, _this._parseResults(data, 'bbox'));
}
}, this)
);
},
reverse: function (location, scale, cb, context) {
var _this = this;
getJSON(
this.options.serviceUrl + '/reverse',
L.extend(
{
api_key: this._apiKey,
'point.lat': location.lat,
'point.lon': location.lng
},
this.options.reverseQueryParams
),
function (data) {
cb.call(context, _this._parseResults(data, 'bounds'));
}
);
},
_parseResults: function (data, bboxname) {
var results = [];
L.geoJson(data, {
pointToLayer: function (feature, latlng) {
return L.circleMarker(latlng);
},
onEachFeature: function (feature, layer) {
var result = {},
bbox,
center;
if (layer.getBounds) {
bbox = layer.getBounds();
center = bbox.getCenter();
} else if (layer.feature.bbox) {
center = layer.getLatLng();
bbox = L.latLngBounds(
L.GeoJSON.coordsToLatLng(layer.feature.bbox.slice(0, 2)),
L.GeoJSON.coordsToLatLng(layer.feature.bbox.slice(2, 4))
);
} else {
center = layer.getLatLng();
bbox = L.latLngBounds(center, center);
}
result.name = layer.feature.properties.label;
result.center = center;
result[bboxname] = bbox;
result.properties = layer.feature.properties;
results.push(result);
}
});
return results;
}
});
function pelias(apiKey, options) {
return new Pelias(apiKey, options);
}
var GeocodeEarth = Pelias;
var geocodeEarth = pelias;
var Mapzen = Pelias; // r.i.p.
var mapzen = pelias;
var Openrouteservice = Mapzen.extend({
options: {
serviceUrl: 'https://api.openrouteservice.org/geocode'
}
});
function openrouteservice(apiKey, options) {
return new Openrouteservice(apiKey, options);
}
var Photon = L.Class.extend({
options: {
serviceUrl: 'https://photon.komoot.de/api/',
reverseUrl: 'https://photon.komoot.de/reverse/',
nameProperties: ['name', 'street', 'suburb', 'hamlet', 'town', 'city', 'state', 'country']
},
initialize: function (options) {
L.setOptions(this, options);
},
geocode: function (query, cb, context) {
var params = L.extend(
{
q: query
},
this.options.geocodingQueryParams
);
getJSON(
this.options.serviceUrl,
params,
L.bind(function (data) {
cb.call(context, this._decodeFeatures(data));
}, this)
);
},
suggest: function (query, cb, context) {
return this.geocode(query, cb, context);
},
reverse: function (latLng, scale, cb, context) {
var params = L.extend(
{
lat: latLng.lat,
lon: latLng.lng
},
this.options.reverseQueryParams
);
getJSON(
this.options.reverseUrl,
params,
L.bind(function (data) {
cb.call(context, this._decodeFeatures(data));
}, this)
);
},
_decodeFeatures: function (data) {
var results = [],
i,
f,
c,
latLng,
extent,
bbox;
if (data && data.features) {
for (i = 0; i < data.features.length; i++) {
f = data.features[i];
c = f.geometry.coordinates;
latLng = L.latLng(c[1], c[0]);
extent = f.properties.extent;
if (extent) {
bbox = L.latLngBounds([extent[1], extent[0]], [extent[3], extent[2]]);
} else {
bbox = L.latLngBounds(latLng, latLng);
}
results.push({
name: this._decodeFeatureName(f),
html: this.options.htmlTemplate ? this.options.htmlTemplate(f) : undefined,
center: latLng,
bbox: bbox,
properties: f.properties
});
}
}
return results;
},
_decodeFeatureName: function (f) {
return (this.options.nameProperties || [])
.map(function (p) {
return f.properties[p];
})
.filter(function (v) {
return !!v;
})
.join(', ');
}
});
function photon(options) {
return new Photon(options);
}
const TYPE_LABEL = {
housenumber: 'Numéro',
street: 'Rue',
locality: 'Lieux-dit',
municipality: 'Commune',
};
var AddOk = L.Class.extend({
options: {
serviceUrl: 'https://api-adresse.data.gouv.fr',
limit: 5,
htmlTemplate: function (r) {
var parts = [];
/* some available classes:
leaflet-control-geocoder-address-detail
leaflet-control-geocoder-address-context
*/
parts.push('<span class="leaflet-control-geocoder-address-item"> {label} </span>({type})<span>' + '</span>');
parts.push('<span class="' + (parts.length > 0 ? 'leaflet-control-geocoder-address-detail' : '') +
'">{context}</span>');
return template(parts.join('<br/>'), r);
}
},
initialize: function (options) {
L.setOptions(this, options);
},
geocode: function (query, cb, context) {
var params = L.extend({
q: query,
limit: this.options.limit
}, this.options.geocodingQueryParams);
var that = this;
getJSON(this.options.serviceUrl + '/search/', params, function (data) {
var results = [],
i,
f,
c,
latLng,
extent,
bbox;
if (data && data.features) {
for (i = 0; i < data.features.length; i++) {
f = data.features[i];
c = f.geometry.coordinates;
latLng = L.latLng(c[1], c[0]);
extent = f.properties.extent;
if (extent) {
bbox = L.latLngBounds([extent[1], extent[0]], [extent[3], extent[2]]);
} else {
bbox = L.latLngBounds(latLng, latLng);
}
// Translate the type in french
if (f.properties.type) {
f.properties.type = TYPE_LABEL[f.properties.type];
}
results.push({
name: f.properties.name,
center: latLng,
bbox: bbox,
html: that.options.htmlTemplate ?
that.options.htmlTemplate(f.properties)
: undefined
});
}
}
cb.call(context, results);
});
},
suggest: function (query, cb, context) {
return this.geocode(query, cb, context);
},
reverse: function (location, scale, cb, context) {
var params = L.extend({
lat: location.lat,
lon: location.lng
}, this.options.reverseQueryParams);
var that = this;
getJSON(this.options.serviceUrl + '/reverse/', params, function (data) {
var results = [],
i,
f,
c,
latLng,
extent,
bbox;
if (data && data.features) {
for (i = 0; i < data.features.length; i++) {
f = data.features[i];
c = f.geometry.coordinates;
latLng = L.latLng(c[1], c[0]);
extent = f.properties.extent;
if (extent) {
bbox = L.latLngBounds([extent[1], extent[0]], [extent[3], extent[2]]);
} else {
bbox = L.latLngBounds(latLng, latLng);
}
results.push({
name: f.properties.name,
center: latLng,
bbox: bbox,
html: that.options.htmlTemplate ?
that.options.htmlTemplate(f.properties)
: undefined
});
}
}
cb.call(context, results);
});
}
});
function addok(key) {
return new AddOk(key);
}
var What3Words = L.Class.extend({
options: {
serviceUrl: 'https://api.what3words.com/v2/'
},
initialize: function (accessToken) {
this._accessToken = accessToken;
},
geocode: function (query, cb, context) {
//get three words and make a dot based string
getJSON(
this.options.serviceUrl + 'forward',
{
key: this._accessToken,
addr: query.split(/\s+/).join('.')
},
function (data) {
var results = [],
latLng,
latLngBounds;
if (data.geometry) {
latLng = L.latLng(data.geometry['lat'], data.geometry['lng']);
latLngBounds = L.latLngBounds(latLng, latLng);
results[0] = {
name: data.words,
bbox: latLngBounds,
center: latLng
};
}
cb.call(context, results);
}
);
},
suggest: function (query, cb, context) {
return this.geocode(query, cb, context);
},
reverse: function (location, scale, cb, context) {
getJSON(
this.options.serviceUrl + 'reverse',
{
key: this._accessToken,
coords: [location.lat, location.lng].join(',')
},
function (data) {
var results = [],
latLng,
latLngBounds;
if (data.status.status == 200) {
latLng = L.latLng(data.geometry['lat'], data.geometry['lng']);
latLngBounds = L.latLngBounds(latLng, latLng);
results[0] = {
name: data.words,
bbox: latLngBounds,
center: latLng
};
}
cb.call(context, results);
}
);
}
});
function what3words(accessToken) {
return new What3Words(accessToken);
}
var geocoders = /*#__PURE__*/Object.freeze({
__proto__: null,
ArcGis: ArcGis,
arcgis: arcgis,
Bing: Bing,
bing: bing,
Google: Google,
google: google,
HERE: HERE,
here: here,
LatLng: LatLng,
latLng: latLng,
Mapbox: Mapbox,
mapbox: mapbox,
MapQuest: MapQuest,
mapQuest: mapQuest,
Neutrino: Neutrino,
neutrino: neutrino,
Nominatim: Nominatim,
nominatim: nominatim,
OpenLocationCode: OpenLocationCode,
openLocationCode: openLocationCode,
OpenCage: OpenCage,
opencage: opencage,
Pelias: Pelias,
pelias: pelias,
GeocodeEarth: GeocodeEarth,
geocodeEarth: geocodeEarth,
Mapzen: Mapzen,
mapzen: mapzen,
Openrouteservice: Openrouteservice,
openrouteservice: openrouteservice,
Photon: Photon,
photon: photon,
AddOk: AddOk,
addok: addok,
What3Words: What3Words,
what3words: what3words
});
var Geocoder = L.Control.extend({
options: {
showUniqueResult: true,
showResultIcons: false,
collapsed: true,
expand: 'touch', // options: touch, click, anythingelse
position: 'topright',
placeholder: 'Search...',
errorMessage: 'Nothing found.',
iconLabel: 'Initiate a new search',
queryMinLength: 1,
suggestMinLength: 3,
suggestTimeout: 250,
defaultMarkGeocode: true
},
includes: L.Evented.prototype || L.Mixin.Events,
initialize: function (options) {
L.Util.setOptions(this, options);
if (!this.options.geocoder) {
this.options.geocoder = new Nominatim();
}
this._requestCount = 0;
},
addThrobberClass: function () {
L.DomUtil.addClass(this._container, 'leaflet-control-geocoder-throbber');
},
removeThrobberClass: function () {
L.DomUtil.removeClass(this._container, 'leaflet-control-geocoder-throbber');
},
onAdd: function (map) {
var className = 'leaflet-control-geocoder',
container = L.DomUtil.create('div', className + ' leaflet-bar'),
icon = L.DomUtil.create('button', className + '-icon', container),
form = (this._form = L.DomUtil.create('div', className + '-form', container)),
input;
this._map = map;
this._container = container;
icon.innerHTML = ' ';
icon.type = 'button';
icon.setAttribute('aria-label', this.options.iconLabel);
input = this._input = L.DomUtil.create('input', '', form);
input.type = 'text';
input.value = this.options.query || '';
input.placeholder = this.options.placeholder;
L.DomEvent.disableClickPropagation(input);
this._errorElement = L.DomUtil.create('div', className + '-form-no-error', container);
this._errorElement.innerHTML = this.options.errorMessage;
this._alts = L.DomUtil.create(
'ul',
className + '-alternatives leaflet-control-geocoder-alternatives-minimized',
container
);
L.DomEvent.disableClickPropagation(this._alts);
L.DomEvent.addListener(input, 'keydown', this._keydown, this);
if (this.options.geocoder.suggest) {
L.DomEvent.addListener(input, 'input', this._change, this);
}
L.DomEvent.addListener(
input,
'blur',
function () {
if (this.options.collapsed && !this._preventBlurCollapse) {
this._collapse();
}
this._preventBlurCollapse = false;
},
this
);
if (this.options.collapsed) {
if (this.options.expand === 'click') {
L.DomEvent.addListener(
container,
'click',
function (e) {
if (e.button === 0 && e.detail !== 2) {
this._toggle();
}
},
this
);
} else if (this.options.expand === 'touch') {
L.DomEvent.addListener(
container,
L.Browser.touch ? 'touchstart mousedown' : 'mousedown',
function (e) {
this._toggle();
e.preventDefault(); // mobile: clicking focuses the icon, so UI expands and immediately collapses
e.stopPropagation();
},
this
);
} else {
L.DomEvent.addListener(container, 'mouseover', this._expand, this);
L.DomEvent.addListener(container, 'mouseout', this._collapse, this);
this._map.on('movestart', this._collapse, this);
}
} else {
this._expand();
if (L.Browser.touch) {
L.DomEvent.addListener(
container,
'touchstart',
function () {
this._geocode();
},
this
);
} else {
L.DomEvent.addListener(
container,
'click',
function () {
this._geocode();
},
this
);
}
}
if (this.options.defaultMarkGeocode) {
this.on('markgeocode', this.markGeocode, this);
}
this.on('startgeocode', this.addThrobberClass, this);
this.on('finishgeocode', this.removeThrobberClass, this);
this.on('startsuggest', this.addThrobberClass, this);
this.on('finishsuggest', this.removeThrobberClass, this);
L.DomEvent.disableClickPropagation(container);
return container;
},
setQuery: function (string) {
this._input.value = string;
return this;
},
_geocodeResult: function (results, suggest) {
if (!suggest && this.options.showUniqueResult && results.length === 1) {
this._geocodeResultSelected(results[0]);
} else if (results.length > 0) {
this._alts.innerHTML = '';
this._results = results;
L.DomUtil.removeClass(this._alts, 'leaflet-control-geocoder-alternatives-minimized');
L.DomUtil.addClass(this._container, 'leaflet-control-geocoder-options-open');
for (var i = 0; i < results.length; i++) {
this._alts.appendChild(this._createAlt(results[i], i));
}
} else {
L.DomUtil.addClass(this._container, 'leaflet-control-geocoder-options-error');
L.DomUtil.addClass(this._errorElement, 'leaflet-control-geocoder-error');
}
},
markGeocode: function (result) {
result = result.geocode || result;
this._map.fitBounds(result.bbox);
if (this._geocodeMarker) {
this._map.removeLayer(this._geocodeMarker);
}
const CustomIcon = L.Icon.extend({ //* recreate leaflet default icon, because not working out of box, reason not found
options: {
iconUrl: "data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAABkAAAApCAYAAADAk4LOAAAFgUlEQVR4Aa1XA5BjWRTN2oW17d3YaZtr2962HUzbDNpjszW24mRt28p47v7zq/bXZtrp/lWnXr337j3nPCe85NcypgSFdugCpW5YoDAMRaIMqRi6aKq5E3YqDQO3qAwjVWrD8Ncq/RBpykd8oZUb/kaJutow8r1aP9II0WmLKLIsJyv1w/kqw9Ch2MYdB++12Onxee/QMwvf4/Dk/Lfp/i4nxTXtOoQ4pW5Aj7wpici1A9erdAN2OH64x8OSP9j3Ft3b7aWkTg/Fm91siTra0f9on5sQr9INejH6CUUUpavjFNq1B+Oadhxmnfa8RfEmN8VNAsQhPqF55xHkMzz3jSmChWU6f7/XZKNH+9+hBLOHYozuKQPxyMPUKkrX/K0uWnfFaJGS1QPRtZsOPtr3NsW0uyh6NNCOkU3Yz+bXbT3I8G3xE5EXLXtCXbbqwCO9zPQYPRTZ5vIDXD7U+w7rFDEoUUf7ibHIR4y6bLVPXrz8JVZEql13trxwue/uDivd3fkWRbS6/IA2bID4uk0UpF1N8qLlbBlXs4Ee7HLTfV1j54APvODnSfOWBqtKVvjgLKzF5YdEk5ewRkGlK0i33Eofffc7HT56jD7/6U+qH3Cx7SBLNntH5YIPvODnyfIXZYRVDPqgHtLs5ABHD3YzLuespb7t79FY34DjMwrVrcTuwlT55YMPvOBnRrJ4VXTdNnYug5ucHLBjEpt30701A3Ts+HEa73u6dT3FNWwflY86eMHPk+Yu+i6pzUpRrW7SNDg5JHR4KapmM5Wv2E8Tfcb1HoqqHMHU+uWDD7zg54mz5/2BSnizi9T1Dg4QQXLToGNCkb6tb1NU+QAlGr1++eADrzhn/u8Q2YZhQVlZ5+CAOtqfbhmaUCS1ezNFVm2imDbPmPng5wmz+gwh+oHDce0eUtQ6OGDIyR0uUhUsoO3vfDmmgOezH0mZN59x7MBi++WDL1g/eEiU3avlidO671bkLfwbw5XV2P8Pzo0ydy4t2/0eu33xYSOMOD8hTf4CrBtGMSoXfPLchX+J0ruSePw3LZeK0juPJbYzrhkH0io7B3k164hiGvawhOKMLkrQLyVpZg8rHFW7E2uHOL888IBPlNZ1FPzstSJM694fWr6RwpvcJK60+0HCILTBzZLFNdtAzJaohze60T8qBzyh5ZuOg5e7uwQppofEmf2++DYvmySqGBuKaicF1blQjhuHdvCIMvp8whTTfZzI7RldpwtSzL+F1+wkdZ2TBOW2gIF88PBTzD/gpeREAMEbxnJcaJHNHrpzji0gQCS6hdkEeYt9DF/2qPcEC8RM28Hwmr3sdNyht00byAut2k3gufWNtgtOEOFGUwcXWNDbdNbpgBGxEvKkOQsxivJx33iow0Vw5S6SVTrpVq11ysA2Rp7gTfPfktc6zhtXBBC+adRLshf6sG2RfHPZ5EAc4sVZ83yCN00Fk/4kggu40ZTvIEm5g24qtU4KjBrx/BTTH8ifVASAG7gKrnWxJDcU7x8X6Ecczhm3o6YicvsLXWfh3Ch1W0k8x0nXF+0fFxgt4phz8QvypiwCCFKMqXCnqXExjq10beH+UUA7+nG6mdG/Pu0f3LgFcGrl2s0kNNjpmoJ9o4B29CMO8dMT4Q5ox8uitF6fqsrJOr8qnwNbRzv6hSnG5wP+64C7h9lp30hKNtKdWjtdkbuPA19nJ7Tz3zR/ibgARbhb4AlhavcBebmTHcFl2fvYEnW0ox9xMxKBS8btJ+KiEbq9zA4RthQXDhPa0T9TEe69gWupwc6uBUphquXgf+/FrIjweHQS4/pduMe5ERUMHUd9xv8ZR98CxkS4F2n3EUrUZ10EYNw7BWm9x1GiPssi3GgiGRDKWRYZfXlON+dfNbM+GgIwYdwAAAAASUVORK5CYII=",
shadowUrl: "data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAACkAAAApCAQAAAACach9AAACMUlEQVR4Ae3ShY7jQBAE0Aoz/f9/HTMzhg1zrdKUrJbdx+Kd2nD8VNudfsL/Th///dyQN2TH6f3y/BGpC379rV+S+qqetBOxImNQXL8JCAr2V4iMQXHGNJxeCfZXhSRBcQMfvkOWUdtfzlLgAENmZDcmo2TVmt8OSM2eXxBp3DjHSMFutqS7SbmemzBiR+xpKCNUIRkdkkYxhAkyGoBvyQFEJEefwSmmvBfJuJ6aKqKWnAkvGZOaZXTUgFqYULWNSHUckZuR1HIIimUExutRxwzOLROIG4vKmCKQt364mIlhSyzAf1m9lHZHJZrlAOMMztRRiKimp/rpdJDc9Awry5xTZCte7FHtuS8wJgeYGrex28xNTd086Dik7vUMscQOa8y4DoGtCCSkAKlNwpgNtphjrC6MIHUkR6YWxxs6Sc5xqn222mmCRFzIt8lEdKx+ikCtg91qS2WpwVfBelJCiQJwvzixfI9cxZQWgiSJelKnwBElKYtDOb2MFbhmUigbReQBV0Cg4+qMXSxXSyGUn4UbF8l+7qdSGnTC0XLCmahIgUHLhLOhpVCtw4CzYXvLQWQbJNmxoCsOKAxSgBJno75avolkRw8iIAFcsdc02e9iyCd8tHwmeSSoKTowIgvscSGZUOA7PuCN5b2BX9mQM7S0wYhMNU74zgsPBj3HU7wguAfnxxjFQGBE6pwN+GjME9zHY7zGp8wVxMShYX9NXvEWD3HbwJf4giO4CFIQxXScH1/TM+04kkBiAAAAAElFTkSuQmCC",
iconSize: [25, 41],
iconAnchor: [12.5, 41],
popupAnchor: [0, -40]
}
});
const icon = new CustomIcon()
this._geocodeMarker = new L.Marker(result.center, { icon })
.bindPopup(result.html || result.name)
.addTo(this._map)
.openPopup();
return this;
},
_geocode: function (suggest) {
var value = this._input.value;
if (!suggest && value.length < this.options.queryMinLength) {
return;
}
var requestCount = ++this._requestCount,
mode = suggest ? 'suggest' : 'geocode',
eventData = { input: value };
this._lastGeocode = value;
if (!suggest) {
this._clearResults();
}
this.fire('start' + mode, eventData);
this.options.geocoder[mode](
value,
function (results) {
if (requestCount === this._requestCount) {
eventData.results = results;
this.fire('finish' + mode, eventData);
this._geocodeResult(results, suggest);
}
},
this
);
},
_geocodeResultSelected: function (result) {
this.fire('markgeocode', { geocode: result });
},
_toggle: function () {
if (L.DomUtil.hasClass(this._container, 'leaflet-control-geocoder-expanded')) {
this._collapse();
} else {
this._expand();
}
},
_expand: function () {
L.DomUtil.addClass(this._container, 'leaflet-control-geocoder-expanded');
this._input.select();
this.fire('expand');
},
_collapse: function () {
L.DomUtil.removeClass(this._container, 'leaflet-control-geocoder-expanded');
L.DomUtil.addClass(this._alts, 'leaflet-control-geocoder-alternatives-minimized');
L.DomUtil.removeClass(this._errorElement, 'leaflet-control-geocoder-error');
L.DomUtil.removeClass(this._container, 'leaflet-control-geocoder-options-open');
L.DomUtil.removeClass(this._container, 'leaflet-control-geocoder-options-error');
this._input.blur(); // mobile: keyboard shouldn't stay expanded
this.fire('collapse');
},
_clearResults: function () {
L.DomUtil.addClass(this._alts, 'leaflet-control-geocoder-alternatives-minimized');
this._selection = null;
L.DomUtil.removeClass(this._errorElement, 'leaflet-control-geocoder-error');
L.DomUtil.removeClass(this._container, 'leaflet-control-geocoder-options-open');
L.DomUtil.removeClass(this._container, 'leaflet-control-geocoder-options-error');
},
_createAlt: function (result, index) {
var li = L.DomUtil.create('li', ''),
a = L.DomUtil.create('a', '', li),
icon = this.options.showResultIcons && result.icon ? L.DomUtil.create('img', '', a) : null,
text = result.html ? undefined : document.createTextNode(result.name),
mouseDownHandler = function mouseDownHandler(e) {
// In some browsers, a click will fire on the map if the control is
// collapsed directly after mousedown. To work around this, we
// wait until the click is completed, and _then_ collapse the
// control. Messy, but this is the workaround I could come up with
// for #142.
this._preventBlurCollapse = true;
L.DomEvent.stop(e);
this._geocodeResultSelected(result);
L.DomEvent.on(
li,
'click touchend',
function () {
if (this.options.collapsed) {
this._collapse();
} else {
this._clearResults();
}
},
this
);
};
if (icon) {
icon.src = result.icon;
}
li.setAttribute('data-result-index', index);
if (result.html) {
a.innerHTML = a.innerHTML + result.html;
} else {
a.appendChild(text);
}
// Use mousedown and not click, since click will fire _after_ blur,
// causing the control to have collapsed and removed the items
// before the click can fire.
L.DomEvent.addListener(li, 'mousedown touchstart', mouseDownHandler, this);
return li;
},
_keydown: function (e) {
var _this = this,
select = function select(dir) {
if (_this._selection) {
L.DomUtil.removeClass(_this._selection, 'leaflet-control-geocoder-selected');
_this._selection = _this._selection[dir > 0 ? 'nextSibling' : 'previousSibling'];
}
if (!_this._selection) {
_this._selection = _this._alts[dir > 0 ? 'firstChild' : 'lastChild'];
}
if (_this._selection) {
L.DomUtil.addClass(_this._selection, 'leaflet-control-geocoder-selected');
}
};
switch (e.keyCode) {
// Escape
case 27:
if (this.options.collapsed) {
this._collapse();
} else {
this._clearResults();
}
break;
// Up
case 38:
select(-1);
break;
// Up
case 40:
select(1);
break;
// Enter
case 13:
if (this._selection) {
var index = parseInt(this._selection.getAttribute('data-result-index'), 10);
this._geocodeResultSelected(this._results[index]);
this._clearResults();
} else {
this._geocode();
}
break;
default:
return;
}
L.DomEvent.preventDefault(e);
},
_change: function () {
var v = this._input.value;
if (v !== this._lastGeocode) {
clearTimeout(this._suggestTimeout);
if (v.length >= this.options.suggestMinLength) {
this._suggestTimeout = setTimeout(
L.bind(function () {
this._geocode(true);
}, this),
this.options.suggestTimeout
);
} else {
this._clearResults();
}
}
}
});
function geocoder(options) {
return new Geocoder(options);
}
L.Util.extend(Geocoder, geocoders);
L.Util.extend(L.Control, {
Geocoder: Geocoder,
geocoder: geocoder
});
return Geocoder;
}(L));
//# sourceMappingURL=Control.Geocoder.js.map