Control.Geocoder.js 61 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971
  1. var leafletControlGeocoder = (function (exports, L) {
  2. function _interopNamespace(e) {
  3. if (e && e.__esModule) return e;
  4. var n = Object.create(null);
  5. if (e) {
  6. Object.keys(e).forEach(function (k) {
  7. if (k !== 'default') {
  8. var d = Object.getOwnPropertyDescriptor(e, k);
  9. Object.defineProperty(n, k, d.get ? d : {
  10. enumerable: true,
  11. get: function () {
  12. return e[k];
  13. }
  14. });
  15. }
  16. });
  17. }
  18. n['default'] = e;
  19. return n;
  20. }
  21. var L__namespace = /*#__PURE__*/_interopNamespace(L);
  22. function _inheritsLoose(subClass, superClass) {
  23. subClass.prototype = Object.create(superClass.prototype);
  24. subClass.prototype.constructor = subClass;
  25. subClass.__proto__ = superClass;
  26. }
  27. function _assertThisInitialized(self) {
  28. if (self === void 0) {
  29. throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
  30. }
  31. return self;
  32. }
  33. /**
  34. * @internal
  35. */
  36. function geocodingParams(options, params) {
  37. return L__namespace.Util.extend(params, options.geocodingQueryParams);
  38. }
  39. /**
  40. * @internal
  41. */
  42. function reverseParams(options, params) {
  43. return L__namespace.Util.extend(params, options.reverseQueryParams);
  44. }
  45. /**
  46. * @internal
  47. */
  48. var lastCallbackId = 0; // Adapted from handlebars.js
  49. // https://github.com/wycats/handlebars.js/
  50. /**
  51. * @internal
  52. */
  53. var badChars = /[&<>"'`]/g;
  54. /**
  55. * @internal
  56. */
  57. var possible = /[&<>"'`]/;
  58. /**
  59. * @internal
  60. */
  61. var escape = {
  62. '&': '&amp;',
  63. '<': '&lt;',
  64. '>': '&gt;',
  65. '"': '&quot;',
  66. "'": '&#x27;',
  67. '`': '&#x60;'
  68. };
  69. /**
  70. * @internal
  71. */
  72. function escapeChar(chr) {
  73. return escape[chr];
  74. }
  75. /**
  76. * @internal
  77. */
  78. function htmlEscape(string) {
  79. if (string == null) {
  80. return '';
  81. } else if (!string) {
  82. return string + '';
  83. } // Force a string conversion as this will be done by the append regardless and
  84. // the regex test will do this transparently behind the scenes, causing issues if
  85. // an object's to string has escaped characters in it.
  86. string = '' + string;
  87. if (!possible.test(string)) {
  88. return string;
  89. }
  90. return string.replace(badChars, escapeChar);
  91. }
  92. /**
  93. * @internal
  94. */
  95. function jsonp(url, params, callback, context, jsonpParam) {
  96. var callbackId = '_l_geocoder_' + lastCallbackId++;
  97. params[jsonpParam || 'callback'] = callbackId;
  98. window[callbackId] = L__namespace.Util.bind(callback, context);
  99. var script = document.createElement('script');
  100. script.type = 'text/javascript';
  101. script.src = url + getParamString(params);
  102. script.id = callbackId;
  103. document.getElementsByTagName('head')[0].appendChild(script);
  104. }
  105. /**
  106. * @internal
  107. */
  108. function getJSON(url, params, callback) {
  109. var xmlHttp = new XMLHttpRequest();
  110. xmlHttp.onreadystatechange = function () {
  111. if (xmlHttp.readyState !== 4) {
  112. return;
  113. }
  114. var message;
  115. if (xmlHttp.status !== 200 && xmlHttp.status !== 304) {
  116. message = '';
  117. } else if (typeof xmlHttp.response === 'string') {
  118. // IE doesn't parse JSON responses even with responseType: 'json'.
  119. try {
  120. message = JSON.parse(xmlHttp.response);
  121. } catch (e) {
  122. // Not a JSON response
  123. message = xmlHttp.response;
  124. }
  125. } else {
  126. message = xmlHttp.response;
  127. }
  128. callback(message);
  129. };
  130. xmlHttp.open('GET', url + getParamString(params), true);
  131. xmlHttp.responseType = 'json';
  132. xmlHttp.setRequestHeader('Accept', 'application/json');
  133. xmlHttp.send(null);
  134. }
  135. /**
  136. * @internal
  137. */
  138. function template(str, data) {
  139. return str.replace(/\{ *([\w_]+) *\}/g, function (str, key) {
  140. var value = data[key];
  141. if (value === undefined) {
  142. value = '';
  143. } else if (typeof value === 'function') {
  144. value = value(data);
  145. }
  146. return htmlEscape(value);
  147. });
  148. }
  149. /**
  150. * @internal
  151. */
  152. function getParamString(obj, existingUrl, uppercase) {
  153. var params = [];
  154. for (var i in obj) {
  155. var key = encodeURIComponent(uppercase ? i.toUpperCase() : i);
  156. var value = obj[i];
  157. if (!Array.isArray(value)) {
  158. params.push(key + '=' + encodeURIComponent(String(value)));
  159. } else {
  160. for (var j = 0; j < value.length; j++) {
  161. params.push(key + '=' + encodeURIComponent(value[j]));
  162. }
  163. }
  164. }
  165. return (!existingUrl || existingUrl.indexOf('?') === -1 ? '?' : '&') + params.join('&');
  166. }
  167. /**
  168. * Implementation of the [ArcGIS geocoder](https://developers.arcgis.com/features/geocoding/)
  169. */
  170. var ArcGis = /*#__PURE__*/function () {
  171. function ArcGis(options) {
  172. this.options = {
  173. serviceUrl: 'https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer',
  174. apiKey: ''
  175. };
  176. L__namespace.Util.setOptions(this, options);
  177. }
  178. var _proto = ArcGis.prototype;
  179. _proto.geocode = function geocode(query, cb, context) {
  180. var params = geocodingParams(this.options, {
  181. token: this.options.apiKey,
  182. SingleLine: query,
  183. outFields: 'Addr_Type',
  184. forStorage: false,
  185. maxLocations: 10,
  186. f: 'json'
  187. });
  188. getJSON(this.options.serviceUrl + '/findAddressCandidates', params, function (data) {
  189. var results = [];
  190. if (data.candidates && data.candidates.length) {
  191. for (var i = 0; i <= data.candidates.length - 1; i++) {
  192. var loc = data.candidates[i];
  193. var latLng = L__namespace.latLng(loc.location.y, loc.location.x);
  194. var latLngBounds = L__namespace.latLngBounds(L__namespace.latLng(loc.extent.ymax, loc.extent.xmax), L__namespace.latLng(loc.extent.ymin, loc.extent.xmin));
  195. results[i] = {
  196. name: loc.address,
  197. bbox: latLngBounds,
  198. center: latLng
  199. };
  200. }
  201. }
  202. cb.call(context, results);
  203. });
  204. };
  205. _proto.suggest = function suggest(query, cb, context) {
  206. return this.geocode(query, cb, context);
  207. };
  208. _proto.reverse = function reverse(location, scale, cb, context) {
  209. var params = reverseParams(this.options, {
  210. location: location.lng + ',' + location.lat,
  211. distance: 100,
  212. f: 'json'
  213. });
  214. getJSON(this.options.serviceUrl + '/reverseGeocode', params, function (data) {
  215. var result = [];
  216. if (data && !data.error) {
  217. var center = L__namespace.latLng(data.location.y, data.location.x);
  218. var bbox = L__namespace.latLngBounds(center, center);
  219. result.push({
  220. name: data.address.Match_addr,
  221. center: center,
  222. bbox: bbox
  223. });
  224. }
  225. cb.call(context, result);
  226. });
  227. };
  228. return ArcGis;
  229. }();
  230. /**
  231. * [Class factory method](https://leafletjs.com/reference.html#class-class-factories) for {@link ArcGis}
  232. * @param options the options
  233. */
  234. function arcgis(options) {
  235. return new ArcGis(options);
  236. }
  237. /**
  238. * Implementation of the [Bing Locations API](https://docs.microsoft.com/en-us/bingmaps/rest-services/locations/)
  239. */
  240. var Bing = /*#__PURE__*/function () {
  241. function Bing(options) {
  242. this.options = {
  243. serviceUrl: 'https://dev.virtualearth.net/REST/v1/Locations'
  244. };
  245. L__namespace.Util.setOptions(this, options);
  246. }
  247. var _proto = Bing.prototype;
  248. _proto.geocode = function geocode(query, cb, context) {
  249. var params = geocodingParams(this.options, {
  250. query: query,
  251. key: this.options.apiKey
  252. });
  253. jsonp(this.options.apiKey, params, function (data) {
  254. var results = [];
  255. if (data.resourceSets.length > 0) {
  256. for (var i = data.resourceSets[0].resources.length - 1; i >= 0; i--) {
  257. var resource = data.resourceSets[0].resources[i],
  258. bbox = resource.bbox;
  259. results[i] = {
  260. name: resource.name,
  261. bbox: L__namespace.latLngBounds([bbox[0], bbox[1]], [bbox[2], bbox[3]]),
  262. center: L__namespace.latLng(resource.point.coordinates)
  263. };
  264. }
  265. }
  266. cb.call(context, results);
  267. }, this, 'jsonp');
  268. };
  269. _proto.reverse = function reverse(location, scale, cb, context) {
  270. var params = reverseParams(this.options, {
  271. key: this.options.apiKey
  272. });
  273. jsonp(this.options.serviceUrl + location.lat + ',' + location.lng, params, function (data) {
  274. var results = [];
  275. for (var i = data.resourceSets[0].resources.length - 1; i >= 0; i--) {
  276. var resource = data.resourceSets[0].resources[i],
  277. bbox = resource.bbox;
  278. results[i] = {
  279. name: resource.name,
  280. bbox: L__namespace.latLngBounds([bbox[0], bbox[1]], [bbox[2], bbox[3]]),
  281. center: L__namespace.latLng(resource.point.coordinates)
  282. };
  283. }
  284. cb.call(context, results);
  285. }, this, 'jsonp');
  286. };
  287. return Bing;
  288. }();
  289. /**
  290. * [Class factory method](https://leafletjs.com/reference.html#class-class-factories) for {@link Bing}
  291. * @param options the options
  292. */
  293. function bing(options) {
  294. return new Bing(options);
  295. }
  296. var Google = /*#__PURE__*/function () {
  297. function Google(options) {
  298. this.options = {
  299. serviceUrl: 'https://maps.googleapis.com/maps/api/geocode/json'
  300. };
  301. L__namespace.Util.setOptions(this, options);
  302. }
  303. var _proto = Google.prototype;
  304. _proto.geocode = function geocode(query, cb, context) {
  305. var params = geocodingParams(this.options, {
  306. key: this.options.apiKey,
  307. address: query
  308. });
  309. getJSON(this.options.serviceUrl, params, function (data) {
  310. var results = [];
  311. if (data.results && data.results.length) {
  312. for (var i = 0; i <= data.results.length - 1; i++) {
  313. var loc = data.results[i];
  314. var latLng = L__namespace.latLng(loc.geometry.location);
  315. var latLngBounds = L__namespace.latLngBounds(L__namespace.latLng(loc.geometry.viewport.northeast), L__namespace.latLng(loc.geometry.viewport.southwest));
  316. results[i] = {
  317. name: loc.formatted_address,
  318. bbox: latLngBounds,
  319. center: latLng,
  320. properties: loc.address_components
  321. };
  322. }
  323. }
  324. cb.call(context, results);
  325. });
  326. };
  327. _proto.reverse = function reverse(location, scale, cb, context) {
  328. var params = reverseParams(this.options, {
  329. key: this.options.apiKey,
  330. latlng: location.lat + ',' + location.lng
  331. });
  332. getJSON(this.options.serviceUrl, params, function (data) {
  333. var results = [];
  334. if (data.results && data.results.length) {
  335. for (var i = 0; i <= data.results.length - 1; i++) {
  336. var loc = data.results[i];
  337. var center = L__namespace.latLng(loc.geometry.location);
  338. var bbox = L__namespace.latLngBounds(L__namespace.latLng(loc.geometry.viewport.northeast), L__namespace.latLng(loc.geometry.viewport.southwest));
  339. results[i] = {
  340. name: loc.formatted_address,
  341. bbox: bbox,
  342. center: center,
  343. properties: loc.address_components
  344. };
  345. }
  346. }
  347. cb.call(context, results);
  348. });
  349. };
  350. return Google;
  351. }();
  352. /**
  353. * [Class factory method](https://leafletjs.com/reference.html#class-class-factories) for {@link Google}
  354. * @param options the options
  355. */
  356. function google(options) {
  357. return new Google(options);
  358. }
  359. /**
  360. * Implementation of the [HERE Geocoder API](https://developer.here.com/documentation/geocoder/topics/introduction.html)
  361. */
  362. var HERE = /*#__PURE__*/function () {
  363. function HERE(options) {
  364. this.options = {
  365. serviceUrl: 'https://geocoder.api.here.com/6.2/',
  366. app_id: '',
  367. app_code: '',
  368. apiKey: '',
  369. maxResults: 5
  370. };
  371. L__namespace.Util.setOptions(this, options);
  372. if (options.apiKey) throw Error('apiKey is not supported, use app_id/app_code instead!');
  373. }
  374. var _proto = HERE.prototype;
  375. _proto.geocode = function geocode(query, cb, context) {
  376. var params = geocodingParams(this.options, {
  377. searchtext: query,
  378. gen: 9,
  379. app_id: this.options.app_id,
  380. app_code: this.options.app_code,
  381. jsonattributes: 1,
  382. maxresults: this.options.maxResults
  383. });
  384. this.getJSON(this.options.serviceUrl + 'geocode.json', params, cb, context);
  385. };
  386. _proto.reverse = function reverse(location, scale, cb, context) {
  387. var prox = location.lat + ',' + location.lng;
  388. if (this.options.reverseGeocodeProxRadius) {
  389. prox += ',' + this.options.reverseGeocodeProxRadius;
  390. }
  391. var params = reverseParams(this.options, {
  392. prox: prox,
  393. mode: 'retrieveAddresses',
  394. app_id: this.options.app_id,
  395. app_code: this.options.app_code,
  396. gen: 9,
  397. jsonattributes: 1,
  398. maxresults: this.options.maxResults
  399. });
  400. this.getJSON(this.options.serviceUrl + 'reversegeocode.json', params, cb, context);
  401. };
  402. _proto.getJSON = function getJSON$1(url, params, cb, context) {
  403. getJSON(url, params, function (data) {
  404. var results = [];
  405. if (data.response.view && data.response.view.length) {
  406. for (var i = 0; i <= data.response.view[0].result.length - 1; i++) {
  407. var loc = data.response.view[0].result[i].location;
  408. var center = L__namespace.latLng(loc.displayPosition.latitude, loc.displayPosition.longitude);
  409. var bbox = L__namespace.latLngBounds(L__namespace.latLng(loc.mapView.topLeft.latitude, loc.mapView.topLeft.longitude), L__namespace.latLng(loc.mapView.bottomRight.latitude, loc.mapView.bottomRight.longitude));
  410. results[i] = {
  411. name: loc.address.label,
  412. properties: loc.address,
  413. bbox: bbox,
  414. center: center
  415. };
  416. }
  417. }
  418. cb.call(context, results);
  419. });
  420. };
  421. return HERE;
  422. }();
  423. /**
  424. * Implementation of the new [HERE Geocoder API](https://developer.here.com/documentation/geocoding-search-api/api-reference-swagger.html)
  425. */
  426. var HEREv2 = /*#__PURE__*/function () {
  427. function HEREv2(options) {
  428. this.options = {
  429. serviceUrl: 'https://geocode.search.hereapi.com/v1',
  430. apiKey: '',
  431. app_id: '',
  432. app_code: '',
  433. maxResults: 10
  434. };
  435. L__namespace.Util.setOptions(this, options);
  436. }
  437. var _proto2 = HEREv2.prototype;
  438. _proto2.geocode = function geocode(query, cb, context) {
  439. var params = geocodingParams(this.options, {
  440. q: query,
  441. apiKey: this.options.apiKey,
  442. limit: this.options.maxResults
  443. });
  444. if (!params.at && !params["in"]) {
  445. throw Error('at / in parameters not found. Please define coordinates (at=latitude,longitude) or other (in) in your geocodingQueryParams.');
  446. }
  447. this.getJSON(this.options.serviceUrl + '/discover', params, cb, context);
  448. };
  449. _proto2.reverse = function reverse(location, scale, cb, context) {
  450. var params = reverseParams(this.options, {
  451. at: location.lat + ',' + location.lng,
  452. limit: this.options.reverseGeocodeProxRadius,
  453. apiKey: this.options.apiKey
  454. });
  455. this.getJSON(this.options.serviceUrl + '/revgeocode', params, cb, context);
  456. };
  457. _proto2.getJSON = function getJSON$1(url, params, cb, context) {
  458. getJSON(url, params, function (data) {
  459. var results = [];
  460. if (data.items && data.items.length) {
  461. for (var i = 0; i <= data.items.length - 1; i++) {
  462. var item = data.items[i];
  463. var latLng = L__namespace.latLng(item.position.lat, item.position.lng);
  464. var bbox = void 0;
  465. if (item.mapView) {
  466. bbox = L__namespace.latLngBounds(L__namespace.latLng(item.mapView.south, item.mapView.west), L__namespace.latLng(item.mapView.north, item.mapView.east));
  467. } else {
  468. // Using only position when not provided
  469. bbox = L__namespace.latLngBounds(L__namespace.latLng(item.position.lat, item.position.lng), L__namespace.latLng(item.position.lat, item.position.lng));
  470. }
  471. results[i] = {
  472. name: item.address.label,
  473. properties: item.address,
  474. bbox: bbox,
  475. center: latLng
  476. };
  477. }
  478. }
  479. cb.call(context, results);
  480. });
  481. };
  482. return HEREv2;
  483. }();
  484. /**
  485. * [Class factory method](https://leafletjs.com/reference.html#class-class-factories) for {@link HERE}
  486. * @param options the options
  487. */
  488. function here(options) {
  489. if (options.apiKey) {
  490. return new HEREv2(options);
  491. } else {
  492. return new HERE(options);
  493. }
  494. }
  495. /**
  496. * Parses basic latitude/longitude strings such as `'50.06773 14.37742'`, `'N50.06773 W14.37742'`, `'S 50° 04.064 E 014° 22.645'`, or `'S 50° 4′ 03.828″, W 14° 22′ 38.712″'`
  497. * @param query the latitude/longitude string to parse
  498. * @returns the parsed latitude/longitude
  499. */
  500. function parseLatLng(query) {
  501. var match; // regex from https://github.com/openstreetmap/openstreetmap-website/blob/master/app/controllers/geocoder_controller.rb
  502. if (match = query.match(/^([NS])\s*(\d{1,3}(?:\.\d*)?)\W*([EW])\s*(\d{1,3}(?:\.\d*)?)$/)) {
  503. // [NSEW] decimal degrees
  504. return L__namespace.latLng((/N/i.test(match[1]) ? 1 : -1) * +match[2], (/E/i.test(match[3]) ? 1 : -1) * +match[4]);
  505. } else if (match = query.match(/^(\d{1,3}(?:\.\d*)?)\s*([NS])\W*(\d{1,3}(?:\.\d*)?)\s*([EW])$/)) {
  506. // decimal degrees [NSEW]
  507. return L__namespace.latLng((/N/i.test(match[2]) ? 1 : -1) * +match[1], (/E/i.test(match[4]) ? 1 : -1) * +match[3]);
  508. } 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*)?)?['′]?$/)) {
  509. // [NSEW] degrees, decimal minutes
  510. return L__namespace.latLng((/N/i.test(match[1]) ? 1 : -1) * (+match[2] + +match[3] / 60), (/E/i.test(match[4]) ? 1 : -1) * (+match[5] + +match[6] / 60));
  511. } 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])$/)) {
  512. // degrees, decimal minutes [NSEW]
  513. return L__namespace.latLng((/N/i.test(match[3]) ? 1 : -1) * (+match[1] + +match[2] / 60), (/E/i.test(match[6]) ? 1 : -1) * (+match[4] + +match[5] / 60));
  514. } 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*)?)?["″]?$/)) {
  515. // [NSEW] degrees, minutes, decimal seconds
  516. return L__namespace.latLng((/N/i.test(match[1]) ? 1 : -1) * (+match[2] + +match[3] / 60 + +match[4] / 3600), (/E/i.test(match[5]) ? 1 : -1) * (+match[6] + +match[7] / 60 + +match[8] / 3600));
  517. } 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])$/)) {
  518. // degrees, minutes, decimal seconds [NSEW]
  519. return L__namespace.latLng((/N/i.test(match[4]) ? 1 : -1) * (+match[1] + +match[2] / 60 + +match[3] / 3600), (/E/i.test(match[8]) ? 1 : -1) * (+match[5] + +match[6] / 60 + +match[7] / 3600));
  520. } else if (match = query.match(/^\s*([+-]?\d+(?:\.\d*)?)\s*[\s,]\s*([+-]?\d+(?:\.\d*)?)\s*$/)) {
  521. return L__namespace.latLng(+match[1], +match[2]);
  522. }
  523. }
  524. /**
  525. * Parses basic latitude/longitude strings such as `'50.06773 14.37742'`, `'N50.06773 W14.37742'`, `'S 50° 04.064 E 014° 22.645'`, or `'S 50° 4′ 03.828″, W 14° 22′ 38.712″'`
  526. */
  527. var LatLng = /*#__PURE__*/function () {
  528. function LatLng(options) {
  529. this.options = {
  530. next: undefined,
  531. sizeInMeters: 10000
  532. };
  533. L__namespace.Util.setOptions(this, options);
  534. }
  535. var _proto = LatLng.prototype;
  536. _proto.geocode = function geocode(query, cb, context) {
  537. var center = parseLatLng(query);
  538. if (center) {
  539. var results = [{
  540. name: query,
  541. center: center,
  542. bbox: center.toBounds(this.options.sizeInMeters)
  543. }];
  544. cb.call(context, results);
  545. } else if (this.options.next) {
  546. this.options.next.geocode(query, cb, context);
  547. }
  548. };
  549. return LatLng;
  550. }();
  551. /**
  552. * [Class factory method](https://leafletjs.com/reference.html#class-class-factories) for {@link LatLng}
  553. * @param options the options
  554. */
  555. function latLng(options) {
  556. return new LatLng(options);
  557. }
  558. /**
  559. * Implementation of the [Mapbox Geocoding](https://www.mapbox.com/api-documentation/#geocoding)
  560. */
  561. var Mapbox = /*#__PURE__*/function () {
  562. function Mapbox(options) {
  563. this.options = {
  564. serviceUrl: 'https://api.mapbox.com/geocoding/v5/mapbox.places/'
  565. };
  566. L__namespace.Util.setOptions(this, options);
  567. }
  568. var _proto = Mapbox.prototype;
  569. _proto._getProperties = function _getProperties(loc) {
  570. var properties = {
  571. text: loc.text,
  572. address: loc.address
  573. };
  574. for (var j = 0; j < (loc.context || []).length; j++) {
  575. var id = loc.context[j].id.split('.')[0];
  576. properties[id] = loc.context[j].text; // Get country code when available
  577. if (loc.context[j].short_code) {
  578. properties['countryShortCode'] = loc.context[j].short_code;
  579. }
  580. }
  581. return properties;
  582. };
  583. _proto.geocode = function geocode(query, cb, context) {
  584. var _this = this;
  585. var params = geocodingParams(this.options, {
  586. access_token: this.options.apiKey
  587. });
  588. if (params.proximity !== undefined && params.proximity.lat !== undefined && params.proximity.lng !== undefined) {
  589. params.proximity = params.proximity.lng + ',' + params.proximity.lat;
  590. }
  591. getJSON(this.options.serviceUrl + encodeURIComponent(query) + '.json', params, function (data) {
  592. var results = [];
  593. if (data.features && data.features.length) {
  594. for (var i = 0; i <= data.features.length - 1; i++) {
  595. var loc = data.features[i];
  596. var center = L__namespace.latLng(loc.center.reverse());
  597. var bbox = void 0;
  598. if (loc.bbox) {
  599. bbox = L__namespace.latLngBounds(L__namespace.latLng(loc.bbox.slice(0, 2).reverse()), L__namespace.latLng(loc.bbox.slice(2, 4).reverse()));
  600. } else {
  601. bbox = L__namespace.latLngBounds(center, center);
  602. }
  603. results[i] = {
  604. name: loc.place_name,
  605. bbox: bbox,
  606. center: center,
  607. properties: _this._getProperties(loc)
  608. };
  609. }
  610. }
  611. cb.call(context, results);
  612. });
  613. };
  614. _proto.suggest = function suggest(query, cb, context) {
  615. return this.geocode(query, cb, context);
  616. };
  617. _proto.reverse = function reverse(location, scale, cb, context) {
  618. var _this2 = this;
  619. var url = this.options.serviceUrl + location.lng + ',' + location.lat + '.json';
  620. var param = reverseParams(this.options, {
  621. access_token: this.options.apiKey
  622. });
  623. getJSON(url, param, function (data) {
  624. var results = [];
  625. if (data.features && data.features.length) {
  626. for (var i = 0; i <= data.features.length - 1; i++) {
  627. var loc = data.features[i];
  628. var center = L__namespace.latLng(loc.center.reverse());
  629. var bbox = void 0;
  630. if (loc.bbox) {
  631. bbox = L__namespace.latLngBounds(L__namespace.latLng(loc.bbox.slice(0, 2).reverse()), L__namespace.latLng(loc.bbox.slice(2, 4).reverse()));
  632. } else {
  633. bbox = L__namespace.latLngBounds(center, center);
  634. }
  635. results[i] = {
  636. name: loc.place_name,
  637. bbox: bbox,
  638. center: center,
  639. properties: _this2._getProperties(loc)
  640. };
  641. }
  642. }
  643. cb.call(context, results);
  644. });
  645. };
  646. return Mapbox;
  647. }();
  648. /**
  649. * [Class factory method](https://leafletjs.com/reference.html#class-class-factories) for {@link Mapbox}
  650. * @param options the options
  651. */
  652. function mapbox(options) {
  653. return new Mapbox(options);
  654. }
  655. /**
  656. * Implementation of the [MapQuest Geocoding API](http://developer.mapquest.com/web/products/dev-services/geocoding-ws)
  657. */
  658. var MapQuest = /*#__PURE__*/function () {
  659. function MapQuest(options) {
  660. this.options = {
  661. serviceUrl: 'https://www.mapquestapi.com/geocoding/v1'
  662. };
  663. L__namespace.Util.setOptions(this, options); // MapQuest seems to provide URI encoded API keys,
  664. // so to avoid encoding them twice, we decode them here
  665. this.options.apiKey = decodeURIComponent(this.options.apiKey);
  666. }
  667. var _proto = MapQuest.prototype;
  668. _proto._formatName = function _formatName() {
  669. return [].slice.call(arguments).filter(function (s) {
  670. return !!s;
  671. }).join(', ');
  672. };
  673. _proto.geocode = function geocode(query, cb, context) {
  674. var params = geocodingParams(this.options, {
  675. key: this.options.apiKey,
  676. location: query,
  677. limit: 5,
  678. outFormat: 'json'
  679. });
  680. getJSON(this.options.serviceUrl + '/address', params, L__namespace.Util.bind(function (data) {
  681. var results = [];
  682. if (data.results && data.results[0].locations) {
  683. for (var i = data.results[0].locations.length - 1; i >= 0; i--) {
  684. var loc = data.results[0].locations[i];
  685. var center = L__namespace.latLng(loc.latLng);
  686. results[i] = {
  687. name: this._formatName(loc.street, loc.adminArea4, loc.adminArea3, loc.adminArea1),
  688. bbox: L__namespace.latLngBounds(center, center),
  689. center: center
  690. };
  691. }
  692. }
  693. cb.call(context, results);
  694. }, this));
  695. };
  696. _proto.reverse = function reverse(location, scale, cb, context) {
  697. var params = reverseParams(this.options, {
  698. key: this.options.apiKey,
  699. location: location.lat + ',' + location.lng,
  700. outputFormat: 'json'
  701. });
  702. getJSON(this.options.serviceUrl + '/reverse', params, L__namespace.Util.bind(function (data) {
  703. var results = [];
  704. if (data.results && data.results[0].locations) {
  705. for (var i = data.results[0].locations.length - 1; i >= 0; i--) {
  706. var loc = data.results[0].locations[i];
  707. var center = L__namespace.latLng(loc.latLng);
  708. results[i] = {
  709. name: this._formatName(loc.street, loc.adminArea4, loc.adminArea3, loc.adminArea1),
  710. bbox: L__namespace.latLngBounds(center, center),
  711. center: center
  712. };
  713. }
  714. }
  715. cb.call(context, results);
  716. }, this));
  717. };
  718. return MapQuest;
  719. }();
  720. /**
  721. * [Class factory method](https://leafletjs.com/reference.html#class-class-factories) for {@link MapQuest}
  722. * @param options the options
  723. */
  724. function mapQuest(options) {
  725. return new MapQuest(options);
  726. }
  727. /**
  728. * Implementation of the [Neutrino API](https://www.neutrinoapi.com/api/geocode-address/)
  729. */
  730. var Neutrino = /*#__PURE__*/function () {
  731. function Neutrino(options) {
  732. this.options = {
  733. userId: undefined,
  734. apiKey: undefined,
  735. serviceUrl: 'https://neutrinoapi.com/'
  736. };
  737. L__namespace.Util.setOptions(this, options);
  738. } // https://www.neutrinoapi.com/api/geocode-address/
  739. var _proto = Neutrino.prototype;
  740. _proto.geocode = function geocode(query, cb, context) {
  741. var params = geocodingParams(this.options, {
  742. apiKey: this.options.apiKey,
  743. userId: this.options.userId,
  744. //get three words and make a dot based string
  745. address: query.split(/\s+/).join('.')
  746. });
  747. getJSON(this.options.serviceUrl + 'geocode-address', params, function (data) {
  748. var results = [];
  749. if (data.locations) {
  750. data.geometry = data.locations[0];
  751. var center = L__namespace.latLng(data.geometry['latitude'], data.geometry['longitude']);
  752. var bbox = L__namespace.latLngBounds(center, center);
  753. results[0] = {
  754. name: data.geometry.address,
  755. bbox: bbox,
  756. center: center
  757. };
  758. }
  759. cb.call(context, results);
  760. });
  761. };
  762. _proto.suggest = function suggest(query, cb, context) {
  763. return this.geocode(query, cb, context);
  764. } // https://www.neutrinoapi.com/api/geocode-reverse/
  765. ;
  766. _proto.reverse = function reverse(location, scale, cb, context) {
  767. var params = reverseParams(this.options, {
  768. apiKey: this.options.apiKey,
  769. userId: this.options.userId,
  770. latitude: location.lat,
  771. longitude: location.lng
  772. });
  773. getJSON(this.options.serviceUrl + 'geocode-reverse', params, function (data) {
  774. var results = [];
  775. if (data.status.status == 200 && data.found) {
  776. var center = L__namespace.latLng(location.lat, location.lng);
  777. var bbox = L__namespace.latLngBounds(center, center);
  778. results[0] = {
  779. name: data.address,
  780. bbox: bbox,
  781. center: center
  782. };
  783. }
  784. cb.call(context, results);
  785. });
  786. };
  787. return Neutrino;
  788. }();
  789. /**
  790. * [Class factory method](https://leafletjs.com/reference.html#class-class-factories) for {@link Neutrino}
  791. * @param options the options
  792. */
  793. function neutrino(options) {
  794. return new Neutrino(options);
  795. }
  796. /**
  797. * Implementation of the [Nominatim](https://wiki.openstreetmap.org/wiki/Nominatim) geocoder.
  798. *
  799. * This is the default geocoding service used by the control, unless otherwise specified in the options.
  800. *
  801. * Unless using your own Nominatim installation, please refer to the [Nominatim usage policy](https://operations.osmfoundation.org/policies/nominatim/).
  802. */
  803. var Nominatim = /*#__PURE__*/function () {
  804. function Nominatim(options) {
  805. this.options = {
  806. serviceUrl: 'https://nominatim.openstreetmap.org/',
  807. htmlTemplate: function htmlTemplate(r) {
  808. var address = r.address;
  809. var className;
  810. var parts = [];
  811. if (address.road || address.building) {
  812. parts.push('{building} {road} {house_number}');
  813. }
  814. if (address.city || address.town || address.village || address.hamlet) {
  815. className = parts.length > 0 ? 'leaflet-control-geocoder-address-detail' : '';
  816. parts.push('<span class="' + className + '">{postcode} {city} {town} {village} {hamlet}</span>');
  817. }
  818. if (address.state || address.country) {
  819. className = parts.length > 0 ? 'leaflet-control-geocoder-address-context' : '';
  820. parts.push('<span class="' + className + '">{state} {country}</span>');
  821. }
  822. return template(parts.join('<br/>'), address);
  823. }
  824. };
  825. L__namespace.Util.setOptions(this, options || {});
  826. }
  827. var _proto = Nominatim.prototype;
  828. _proto.geocode = function geocode(query, cb, context) {
  829. var _this = this;
  830. var params = geocodingParams(this.options, {
  831. q: query,
  832. limit: 5,
  833. format: 'json',
  834. addressdetails: 1
  835. });
  836. getJSON(this.options.serviceUrl + 'search', params, function (data) {
  837. var results = [];
  838. for (var i = data.length - 1; i >= 0; i--) {
  839. var bbox = data[i].boundingbox;
  840. for (var j = 0; j < 4; j++) {
  841. bbox[j] = +bbox[j];
  842. }
  843. results[i] = {
  844. icon: data[i].icon,
  845. name: data[i].display_name,
  846. html: _this.options.htmlTemplate ? _this.options.htmlTemplate(data[i]) : undefined,
  847. bbox: L__namespace.latLngBounds([bbox[0], bbox[2]], [bbox[1], bbox[3]]),
  848. center: L__namespace.latLng(data[i].lat, data[i].lon),
  849. properties: data[i]
  850. };
  851. }
  852. cb.call(context, results);
  853. });
  854. };
  855. _proto.reverse = function reverse(location, scale, cb, context) {
  856. var _this2 = this;
  857. var params = reverseParams(this.options, {
  858. lat: location.lat,
  859. lon: location.lng,
  860. zoom: Math.round(Math.log(scale / 256) / Math.log(2)),
  861. addressdetails: 1,
  862. format: 'json'
  863. });
  864. getJSON(this.options.serviceUrl + 'reverse', params, function (data) {
  865. var result = [];
  866. if (data && data.lat && data.lon) {
  867. var center = L__namespace.latLng(data.lat, data.lon);
  868. var bbox = L__namespace.latLngBounds(center, center);
  869. result.push({
  870. name: data.display_name,
  871. html: _this2.options.htmlTemplate ? _this2.options.htmlTemplate(data) : undefined,
  872. center: center,
  873. bbox: bbox,
  874. properties: data
  875. });
  876. }
  877. cb.call(context, result);
  878. });
  879. };
  880. return Nominatim;
  881. }();
  882. /**
  883. * [Class factory method](https://leafletjs.com/reference.html#class-class-factories) for {@link Nominatim}
  884. * @param options the options
  885. */
  886. function nominatim(options) {
  887. return new Nominatim(options);
  888. }
  889. /**
  890. * Implementation of the [Plus codes](https://plus.codes/) (formerly OpenLocationCode) (requires [open-location-code](https://www.npmjs.com/package/open-location-code))
  891. */
  892. var OpenLocationCode = /*#__PURE__*/function () {
  893. function OpenLocationCode(options) {
  894. L__namespace.Util.setOptions(this, options);
  895. }
  896. var _proto = OpenLocationCode.prototype;
  897. _proto.geocode = function geocode(query, cb, context) {
  898. try {
  899. var decoded = this.options.OpenLocationCode.decode(query);
  900. var result = {
  901. name: query,
  902. center: L__namespace.latLng(decoded.latitudeCenter, decoded.longitudeCenter),
  903. bbox: L__namespace.latLngBounds(L__namespace.latLng(decoded.latitudeLo, decoded.longitudeLo), L__namespace.latLng(decoded.latitudeHi, decoded.longitudeHi))
  904. };
  905. cb.call(context, [result]);
  906. } catch (e) {
  907. console.warn(e); // eslint-disable-line no-console
  908. cb.call(context, []);
  909. }
  910. };
  911. _proto.reverse = function reverse(location, scale, cb, context) {
  912. try {
  913. var code = this.options.OpenLocationCode.encode(location.lat, location.lng, this.options.codeLength);
  914. var result = {
  915. name: code,
  916. center: L__namespace.latLng(location.lat, location.lng),
  917. bbox: L__namespace.latLngBounds(L__namespace.latLng(location.lat, location.lng), L__namespace.latLng(location.lat, location.lng))
  918. };
  919. cb.call(context, [result]);
  920. } catch (e) {
  921. console.warn(e); // eslint-disable-line no-console
  922. cb.call(context, []);
  923. }
  924. };
  925. return OpenLocationCode;
  926. }();
  927. /**
  928. * [Class factory method](https://leafletjs.com/reference.html#class-class-factories) for {@link OpenLocationCode}
  929. * @param options the options
  930. */
  931. function openLocationCode(options) {
  932. return new OpenLocationCode(options);
  933. }
  934. /**
  935. * Implementation of the [OpenCage Data API](https://opencagedata.com/)
  936. */
  937. var OpenCage = /*#__PURE__*/function () {
  938. function OpenCage(options) {
  939. this.options = {
  940. serviceUrl: 'https://api.opencagedata.com/geocode/v1/json'
  941. };
  942. L__namespace.Util.setOptions(this, options);
  943. }
  944. var _proto = OpenCage.prototype;
  945. _proto.geocode = function geocode(query, cb, context) {
  946. var params = geocodingParams(this.options, {
  947. key: this.options.apiKey,
  948. q: query
  949. });
  950. getJSON(this.options.serviceUrl, params, function (data) {
  951. var results = [];
  952. if (data.results && data.results.length) {
  953. for (var i = 0; i < data.results.length; i++) {
  954. var loc = data.results[i];
  955. var center = L__namespace.latLng(loc.geometry);
  956. var bbox = void 0;
  957. if (loc.annotations && loc.annotations.bounds) {
  958. bbox = L__namespace.latLngBounds(L__namespace.latLng(loc.annotations.bounds.northeast), L__namespace.latLng(loc.annotations.bounds.southwest));
  959. } else {
  960. bbox = L__namespace.latLngBounds(center, center);
  961. }
  962. results.push({
  963. name: loc.formatted,
  964. bbox: bbox,
  965. center: center
  966. });
  967. }
  968. }
  969. cb.call(context, results);
  970. });
  971. };
  972. _proto.suggest = function suggest(query, cb, context) {
  973. return this.geocode(query, cb, context);
  974. };
  975. _proto.reverse = function reverse(location, scale, cb, context) {
  976. var params = reverseParams(this.options, {
  977. key: this.options.apiKey,
  978. q: [location.lat, location.lng].join(',')
  979. });
  980. getJSON(this.options.serviceUrl, params, function (data) {
  981. var results = [];
  982. if (data.results && data.results.length) {
  983. for (var i = 0; i < data.results.length; i++) {
  984. var loc = data.results[i];
  985. var center = L__namespace.latLng(loc.geometry);
  986. var bbox = void 0;
  987. if (loc.annotations && loc.annotations.bounds) {
  988. bbox = L__namespace.latLngBounds(L__namespace.latLng(loc.annotations.bounds.northeast), L__namespace.latLng(loc.annotations.bounds.southwest));
  989. } else {
  990. bbox = L__namespace.latLngBounds(center, center);
  991. }
  992. results.push({
  993. name: loc.formatted,
  994. bbox: bbox,
  995. center: center
  996. });
  997. }
  998. }
  999. cb.call(context, results);
  1000. });
  1001. };
  1002. return OpenCage;
  1003. }();
  1004. function opencage(options) {
  1005. return new OpenCage(options);
  1006. }
  1007. /**
  1008. * Implementation of the [Pelias](https://pelias.io/), [geocode.earth](https://geocode.earth/) geocoder (formerly Mapzen Search)
  1009. */
  1010. var Pelias = /*#__PURE__*/function () {
  1011. function Pelias(options) {
  1012. this.options = {
  1013. serviceUrl: 'https://api.geocode.earth/v1'
  1014. };
  1015. this._lastSuggest = 0;
  1016. L__namespace.Util.setOptions(this, options);
  1017. }
  1018. var _proto = Pelias.prototype;
  1019. _proto.geocode = function geocode(query, cb, context) {
  1020. var _this = this;
  1021. var params = geocodingParams(this.options, {
  1022. api_key: this.options.apiKey,
  1023. text: query
  1024. });
  1025. getJSON(this.options.serviceUrl + '/search', params, function (data) {
  1026. cb.call(context, _this._parseResults(data, 'bbox'));
  1027. });
  1028. };
  1029. _proto.suggest = function suggest(query, cb, context) {
  1030. var _this2 = this;
  1031. var params = geocodingParams(this.options, {
  1032. api_key: this.options.apiKey,
  1033. text: query
  1034. });
  1035. getJSON(this.options.serviceUrl + '/autocomplete', params, function (data) {
  1036. if (data.geocoding.timestamp > _this2._lastSuggest) {
  1037. _this2._lastSuggest = data.geocoding.timestamp;
  1038. cb.call(context, _this2._parseResults(data, 'bbox'));
  1039. }
  1040. });
  1041. };
  1042. _proto.reverse = function reverse(location, scale, cb, context) {
  1043. var _this3 = this;
  1044. var params = reverseParams(this.options, {
  1045. api_key: this.options.apiKey,
  1046. 'point.lat': location.lat,
  1047. 'point.lon': location.lng
  1048. });
  1049. getJSON(this.options.serviceUrl + '/reverse', params, function (data) {
  1050. cb.call(context, _this3._parseResults(data, 'bounds'));
  1051. });
  1052. };
  1053. _proto._parseResults = function _parseResults(data, bboxname) {
  1054. var results = [];
  1055. L__namespace.geoJSON(data, {
  1056. pointToLayer: function pointToLayer(feature, latlng) {
  1057. return L__namespace.circleMarker(latlng);
  1058. },
  1059. onEachFeature: function onEachFeature(feature, layer) {
  1060. var result = {};
  1061. var bbox;
  1062. var center;
  1063. if (layer.getBounds) {
  1064. bbox = layer.getBounds();
  1065. center = bbox.getCenter();
  1066. } else if (layer.feature.bbox) {
  1067. center = layer.getLatLng();
  1068. bbox = L__namespace.latLngBounds(L__namespace.GeoJSON.coordsToLatLng(layer.feature.bbox.slice(0, 2)), L__namespace.GeoJSON.coordsToLatLng(layer.feature.bbox.slice(2, 4)));
  1069. } else {
  1070. center = layer.getLatLng();
  1071. bbox = L__namespace.latLngBounds(center, center);
  1072. }
  1073. result.name = layer.feature.properties.label;
  1074. result.center = center;
  1075. result[bboxname] = bbox;
  1076. result.properties = layer.feature.properties;
  1077. results.push(result);
  1078. }
  1079. });
  1080. return results;
  1081. };
  1082. return Pelias;
  1083. }();
  1084. /**
  1085. * [Class factory method](https://leafletjs.com/reference.html#class-class-factories) for {@link Pelias}
  1086. * @param options the options
  1087. */
  1088. function pelias(options) {
  1089. return new Pelias(options);
  1090. }
  1091. var GeocodeEarth = Pelias;
  1092. var geocodeEarth = pelias;
  1093. /**
  1094. * r.i.p.
  1095. * @deprecated
  1096. */
  1097. var Mapzen = Pelias;
  1098. /**
  1099. * r.i.p.
  1100. * @deprecated
  1101. */
  1102. var mapzen = pelias;
  1103. /**
  1104. * Implementation of the [Openrouteservice](https://openrouteservice.org/dev/#/api-docs/geocode) geocoder
  1105. */
  1106. var Openrouteservice = /*#__PURE__*/function (_Pelias) {
  1107. _inheritsLoose(Openrouteservice, _Pelias);
  1108. function Openrouteservice(options) {
  1109. return _Pelias.call(this, L__namespace.Util.extend({
  1110. serviceUrl: 'https://api.openrouteservice.org/geocode'
  1111. }, options)) || this;
  1112. }
  1113. return Openrouteservice;
  1114. }(Pelias);
  1115. /**
  1116. * [Class factory method](https://leafletjs.com/reference.html#class-class-factories) for {@link Openrouteservice}
  1117. * @param options the options
  1118. */
  1119. function openrouteservice(options) {
  1120. return new Openrouteservice(options);
  1121. }
  1122. /**
  1123. * Implementation of the [Photon](http://photon.komoot.de/) geocoder
  1124. */
  1125. var Photon = /*#__PURE__*/function () {
  1126. function Photon(options) {
  1127. this.options = {
  1128. serviceUrl: 'https://photon.komoot.io/api/',
  1129. reverseUrl: 'https://photon.komoot.io/reverse/',
  1130. nameProperties: ['name', 'street', 'suburb', 'hamlet', 'town', 'city', 'state', 'country']
  1131. };
  1132. L__namespace.Util.setOptions(this, options);
  1133. }
  1134. var _proto = Photon.prototype;
  1135. _proto.geocode = function geocode(query, cb, context) {
  1136. var params = geocodingParams(this.options, {
  1137. q: query
  1138. });
  1139. getJSON(this.options.serviceUrl, params, L__namespace.Util.bind(function (data) {
  1140. cb.call(context, this._decodeFeatures(data));
  1141. }, this));
  1142. };
  1143. _proto.suggest = function suggest(query, cb, context) {
  1144. return this.geocode(query, cb, context);
  1145. };
  1146. _proto.reverse = function reverse(latLng, scale, cb, context) {
  1147. var params = reverseParams(this.options, {
  1148. lat: latLng.lat,
  1149. lon: latLng.lng
  1150. });
  1151. getJSON(this.options.reverseUrl, params, L__namespace.Util.bind(function (data) {
  1152. cb.call(context, this._decodeFeatures(data));
  1153. }, this));
  1154. };
  1155. _proto._decodeFeatures = function _decodeFeatures(data) {
  1156. var results = [];
  1157. if (data && data.features) {
  1158. for (var i = 0; i < data.features.length; i++) {
  1159. var f = data.features[i];
  1160. var c = f.geometry.coordinates;
  1161. var center = L__namespace.latLng(c[1], c[0]);
  1162. var extent = f.properties.extent;
  1163. var bbox = extent ? L__namespace.latLngBounds([extent[1], extent[0]], [extent[3], extent[2]]) : L__namespace.latLngBounds(center, center);
  1164. results.push({
  1165. name: this._decodeFeatureName(f),
  1166. html: this.options.htmlTemplate ? this.options.htmlTemplate(f) : undefined,
  1167. center: center,
  1168. bbox: bbox,
  1169. properties: f.properties
  1170. });
  1171. }
  1172. }
  1173. return results;
  1174. };
  1175. _proto._decodeFeatureName = function _decodeFeatureName(f) {
  1176. return (this.options.nameProperties || []).map(function (p) {
  1177. return f.properties[p];
  1178. }).filter(function (v) {
  1179. return !!v;
  1180. }).join(', ');
  1181. };
  1182. return Photon;
  1183. }();
  1184. /**
  1185. * [Class factory method](https://leafletjs.com/reference.html#class-class-factories) for {@link Photon}
  1186. * @param options the options
  1187. */
  1188. function photon(options) {
  1189. return new Photon(options);
  1190. }
  1191. /**
  1192. * Implementation of the What3Words service
  1193. */
  1194. var What3Words = /*#__PURE__*/function () {
  1195. function What3Words(options) {
  1196. this.options = {
  1197. serviceUrl: 'https://api.what3words.com/v2/'
  1198. };
  1199. L__namespace.Util.setOptions(this, options);
  1200. }
  1201. var _proto = What3Words.prototype;
  1202. _proto.geocode = function geocode(query, cb, context) {
  1203. //get three words and make a dot based string
  1204. getJSON(this.options.serviceUrl + 'forward', geocodingParams(this.options, {
  1205. key: this.options.apiKey,
  1206. addr: query.split(/\s+/).join('.')
  1207. }), function (data) {
  1208. var results = [];
  1209. if (data.geometry) {
  1210. var latLng = L__namespace.latLng(data.geometry['lat'], data.geometry['lng']);
  1211. var latLngBounds = L__namespace.latLngBounds(latLng, latLng);
  1212. results[0] = {
  1213. name: data.words,
  1214. bbox: latLngBounds,
  1215. center: latLng
  1216. };
  1217. }
  1218. cb.call(context, results);
  1219. });
  1220. };
  1221. _proto.suggest = function suggest(query, cb, context) {
  1222. return this.geocode(query, cb, context);
  1223. };
  1224. _proto.reverse = function reverse(location, scale, cb, context) {
  1225. getJSON(this.options.serviceUrl + 'reverse', reverseParams(this.options, {
  1226. key: this.options.apiKey,
  1227. coords: [location.lat, location.lng].join(',')
  1228. }), function (data) {
  1229. var results = [];
  1230. if (data.status.status == 200) {
  1231. var center = L__namespace.latLng(data.geometry['lat'], data.geometry['lng']);
  1232. var bbox = L__namespace.latLngBounds(center, center);
  1233. results[0] = {
  1234. name: data.words,
  1235. bbox: bbox,
  1236. center: center
  1237. };
  1238. }
  1239. cb.call(context, results);
  1240. });
  1241. };
  1242. return What3Words;
  1243. }();
  1244. /**
  1245. * [Class factory method](https://leafletjs.com/reference.html#class-class-factories) for {@link What3Words}
  1246. * @param options the options
  1247. */
  1248. function what3words(options) {
  1249. return new What3Words(options);
  1250. }
  1251. var geocoders = {
  1252. __proto__: null,
  1253. geocodingParams: geocodingParams,
  1254. reverseParams: reverseParams,
  1255. ArcGis: ArcGis,
  1256. arcgis: arcgis,
  1257. Bing: Bing,
  1258. bing: bing,
  1259. Google: Google,
  1260. google: google,
  1261. HERE: HERE,
  1262. HEREv2: HEREv2,
  1263. here: here,
  1264. parseLatLng: parseLatLng,
  1265. LatLng: LatLng,
  1266. latLng: latLng,
  1267. Mapbox: Mapbox,
  1268. mapbox: mapbox,
  1269. MapQuest: MapQuest,
  1270. mapQuest: mapQuest,
  1271. Neutrino: Neutrino,
  1272. neutrino: neutrino,
  1273. Nominatim: Nominatim,
  1274. nominatim: nominatim,
  1275. OpenLocationCode: OpenLocationCode,
  1276. openLocationCode: openLocationCode,
  1277. OpenCage: OpenCage,
  1278. opencage: opencage,
  1279. Pelias: Pelias,
  1280. pelias: pelias,
  1281. GeocodeEarth: GeocodeEarth,
  1282. geocodeEarth: geocodeEarth,
  1283. Mapzen: Mapzen,
  1284. mapzen: mapzen,
  1285. Openrouteservice: Openrouteservice,
  1286. openrouteservice: openrouteservice,
  1287. Photon: Photon,
  1288. photon: photon,
  1289. What3Words: What3Words,
  1290. what3words: what3words
  1291. };
  1292. /**
  1293. * Leaflet mixins https://leafletjs.com/reference-1.7.1.html#class-includes
  1294. * for TypeScript https://www.typescriptlang.org/docs/handbook/mixins.html
  1295. * @internal
  1296. */
  1297. var EventedControl = // eslint-disable-next-line @typescript-eslint/no-unused-vars
  1298. function EventedControl() {// empty
  1299. };
  1300. L__namespace.Util.extend(EventedControl.prototype, L__namespace.Control.prototype);
  1301. L__namespace.Util.extend(EventedControl.prototype, L__namespace.Evented.prototype);
  1302. /**
  1303. * This is the geocoder control. It works like any other [Leaflet control](https://leafletjs.com/reference.html#control), and is added to the map.
  1304. */
  1305. var GeocoderControl = /*#__PURE__*/function (_EventedControl) {
  1306. _inheritsLoose(GeocoderControl, _EventedControl);
  1307. /**
  1308. * Instantiates a geocoder control (to be invoked using `new`)
  1309. * @param options the options
  1310. */
  1311. function GeocoderControl(options) {
  1312. var _this;
  1313. _this = _EventedControl.call(this, options) || this;
  1314. _this.options = {
  1315. showUniqueResult: true,
  1316. showResultIcons: false,
  1317. collapsed: true,
  1318. expand: 'touch',
  1319. position: 'topright',
  1320. placeholder: 'Search...',
  1321. errorMessage: 'Nothing found.',
  1322. iconLabel: 'Initiate a new search',
  1323. query: '',
  1324. queryMinLength: 1,
  1325. suggestMinLength: 3,
  1326. suggestTimeout: 250,
  1327. defaultMarkGeocode: true
  1328. };
  1329. _this._requestCount = 0;
  1330. L__namespace.Util.setOptions(_assertThisInitialized(_this), options);
  1331. if (!_this.options.geocoder) {
  1332. _this.options.geocoder = new Nominatim();
  1333. }
  1334. return _this;
  1335. }
  1336. var _proto = GeocoderControl.prototype;
  1337. _proto.addThrobberClass = function addThrobberClass() {
  1338. L__namespace.DomUtil.addClass(this._container, 'leaflet-control-geocoder-throbber');
  1339. };
  1340. _proto.removeThrobberClass = function removeThrobberClass() {
  1341. L__namespace.DomUtil.removeClass(this._container, 'leaflet-control-geocoder-throbber');
  1342. }
  1343. /**
  1344. * Returns the container DOM element for the control and add listeners on relevant map events.
  1345. * @param map the map instance
  1346. * @see https://leafletjs.com/reference.html#control-onadd
  1347. */
  1348. ;
  1349. _proto.onAdd = function onAdd(map) {
  1350. var _this2 = this;
  1351. var className = 'leaflet-control-geocoder';
  1352. var container = L__namespace.DomUtil.create('div', className + ' leaflet-bar');
  1353. var icon = L__namespace.DomUtil.create('button', className + '-icon', container);
  1354. var form = this._form = L__namespace.DomUtil.create('div', className + '-form', container);
  1355. this._map = map;
  1356. this._container = container;
  1357. icon.innerHTML = '&nbsp;';
  1358. icon.type = 'button';
  1359. icon.setAttribute('aria-label', this.options.iconLabel);
  1360. var input = this._input = L__namespace.DomUtil.create('input', '', form);
  1361. input.type = 'text';
  1362. input.value = this.options.query;
  1363. input.placeholder = this.options.placeholder;
  1364. L__namespace.DomEvent.disableClickPropagation(input);
  1365. this._errorElement = L__namespace.DomUtil.create('div', className + '-form-no-error', container);
  1366. this._errorElement.innerHTML = this.options.errorMessage;
  1367. this._alts = L__namespace.DomUtil.create('ul', className + '-alternatives leaflet-control-geocoder-alternatives-minimized', container);
  1368. L__namespace.DomEvent.disableClickPropagation(this._alts);
  1369. L__namespace.DomEvent.addListener(input, 'keydown', this._keydown, this);
  1370. if (this.options.geocoder.suggest) {
  1371. L__namespace.DomEvent.addListener(input, 'input', this._change, this);
  1372. }
  1373. L__namespace.DomEvent.addListener(input, 'blur', function () {
  1374. if (_this2.options.collapsed && !_this2._preventBlurCollapse) {
  1375. _this2._collapse();
  1376. }
  1377. _this2._preventBlurCollapse = false;
  1378. });
  1379. if (this.options.collapsed) {
  1380. if (this.options.expand === 'click') {
  1381. L__namespace.DomEvent.addListener(container, 'click', function (e) {
  1382. if (e.button === 0 && e.detail !== 2) {
  1383. _this2._toggle();
  1384. }
  1385. });
  1386. } else if (this.options.expand === 'touch') {
  1387. L__namespace.DomEvent.addListener(container, L__namespace.Browser.touch ? 'touchstart mousedown' : 'mousedown', function (e) {
  1388. _this2._toggle();
  1389. e.preventDefault(); // mobile: clicking focuses the icon, so UI expands and immediately collapses
  1390. e.stopPropagation();
  1391. }, this);
  1392. } else {
  1393. L__namespace.DomEvent.addListener(container, 'mouseover', this._expand, this);
  1394. L__namespace.DomEvent.addListener(container, 'mouseout', this._collapse, this);
  1395. this._map.on('movestart', this._collapse, this);
  1396. }
  1397. } else {
  1398. this._expand();
  1399. if (L__namespace.Browser.touch) {
  1400. L__namespace.DomEvent.addListener(container, 'touchstart', function () {
  1401. return _this2._geocode();
  1402. });
  1403. } else {
  1404. L__namespace.DomEvent.addListener(container, 'click', function () {
  1405. return _this2._geocode();
  1406. });
  1407. }
  1408. }
  1409. if (this.options.defaultMarkGeocode) {
  1410. this.on('markgeocode', this.markGeocode, this);
  1411. }
  1412. this.on('startgeocode', this.addThrobberClass, this);
  1413. this.on('finishgeocode', this.removeThrobberClass, this);
  1414. this.on('startsuggest', this.addThrobberClass, this);
  1415. this.on('finishsuggest', this.removeThrobberClass, this);
  1416. L__namespace.DomEvent.disableClickPropagation(container);
  1417. return container;
  1418. }
  1419. /**
  1420. * Sets the query string on the text input
  1421. * @param string the query string
  1422. */
  1423. ;
  1424. _proto.setQuery = function setQuery(string) {
  1425. this._input.value = string;
  1426. return this;
  1427. };
  1428. _proto._geocodeResult = function _geocodeResult(results, suggest) {
  1429. if (!suggest && this.options.showUniqueResult && results.length === 1) {
  1430. this._geocodeResultSelected(results[0]);
  1431. } else if (results.length > 0) {
  1432. this._alts.innerHTML = '';
  1433. this._results = results;
  1434. L__namespace.DomUtil.removeClass(this._alts, 'leaflet-control-geocoder-alternatives-minimized');
  1435. L__namespace.DomUtil.addClass(this._container, 'leaflet-control-geocoder-options-open');
  1436. for (var i = 0; i < results.length; i++) {
  1437. this._alts.appendChild(this._createAlt(results[i], i));
  1438. }
  1439. } else {
  1440. L__namespace.DomUtil.addClass(this._container, 'leaflet-control-geocoder-options-error');
  1441. L__namespace.DomUtil.addClass(this._errorElement, 'leaflet-control-geocoder-error');
  1442. }
  1443. }
  1444. /**
  1445. * Marks a geocoding result on the map
  1446. * @param result the geocoding result
  1447. */
  1448. ;
  1449. _proto.markGeocode = function markGeocode(event) {
  1450. var result = event.geocode;
  1451. this._map.fitBounds(result.bbox);
  1452. if (this._geocodeMarker) {
  1453. this._map.removeLayer(this._geocodeMarker);
  1454. }
  1455. this._geocodeMarker = new L__namespace.Marker(result.center).bindPopup(result.html || result.name).addTo(this._map).openPopup();
  1456. return this;
  1457. };
  1458. _proto._geocode = function _geocode(suggest) {
  1459. var _this3 = this;
  1460. var value = this._input.value;
  1461. if (!suggest && value.length < this.options.queryMinLength) {
  1462. return;
  1463. }
  1464. var requestCount = ++this._requestCount;
  1465. var cb = function cb(results) {
  1466. if (requestCount === _this3._requestCount) {
  1467. var _event = {
  1468. input: value,
  1469. results: results
  1470. };
  1471. _this3.fire(suggest ? 'finishsuggest' : 'finishgeocode', _event);
  1472. _this3._geocodeResult(results, suggest);
  1473. }
  1474. };
  1475. this._lastGeocode = value;
  1476. if (!suggest) {
  1477. this._clearResults();
  1478. }
  1479. var event = {
  1480. input: value
  1481. };
  1482. this.fire(suggest ? 'startsuggest' : 'startgeocode', event);
  1483. if (suggest) {
  1484. this.options.geocoder.suggest(value, cb);
  1485. } else {
  1486. this.options.geocoder.geocode(value, cb);
  1487. }
  1488. };
  1489. _proto._geocodeResultSelected = function _geocodeResultSelected(geocode) {
  1490. var event = {
  1491. geocode: geocode
  1492. };
  1493. this.fire('markgeocode', event);
  1494. };
  1495. _proto._toggle = function _toggle() {
  1496. if (L__namespace.DomUtil.hasClass(this._container, 'leaflet-control-geocoder-expanded')) {
  1497. this._collapse();
  1498. } else {
  1499. this._expand();
  1500. }
  1501. };
  1502. _proto._expand = function _expand() {
  1503. L__namespace.DomUtil.addClass(this._container, 'leaflet-control-geocoder-expanded');
  1504. this._input.select();
  1505. this.fire('expand');
  1506. };
  1507. _proto._collapse = function _collapse() {
  1508. L__namespace.DomUtil.removeClass(this._container, 'leaflet-control-geocoder-expanded');
  1509. L__namespace.DomUtil.addClass(this._alts, 'leaflet-control-geocoder-alternatives-minimized');
  1510. L__namespace.DomUtil.removeClass(this._errorElement, 'leaflet-control-geocoder-error');
  1511. L__namespace.DomUtil.removeClass(this._container, 'leaflet-control-geocoder-options-open');
  1512. L__namespace.DomUtil.removeClass(this._container, 'leaflet-control-geocoder-options-error');
  1513. this._input.blur(); // mobile: keyboard shouldn't stay expanded
  1514. this.fire('collapse');
  1515. };
  1516. _proto._clearResults = function _clearResults() {
  1517. L__namespace.DomUtil.addClass(this._alts, 'leaflet-control-geocoder-alternatives-minimized');
  1518. this._selection = null;
  1519. L__namespace.DomUtil.removeClass(this._errorElement, 'leaflet-control-geocoder-error');
  1520. L__namespace.DomUtil.removeClass(this._container, 'leaflet-control-geocoder-options-open');
  1521. L__namespace.DomUtil.removeClass(this._container, 'leaflet-control-geocoder-options-error');
  1522. };
  1523. _proto._createAlt = function _createAlt(result, index) {
  1524. var _this4 = this;
  1525. var li = L__namespace.DomUtil.create('li', ''),
  1526. a = L__namespace.DomUtil.create('a', '', li),
  1527. icon = this.options.showResultIcons && result.icon ? L__namespace.DomUtil.create('img', '', a) : null,
  1528. text = result.html ? undefined : document.createTextNode(result.name),
  1529. mouseDownHandler = function mouseDownHandler(e) {
  1530. // In some browsers, a click will fire on the map if the control is
  1531. // collapsed directly after mousedown. To work around this, we
  1532. // wait until the click is completed, and _then_ collapse the
  1533. // control. Messy, but this is the workaround I could come up with
  1534. // for #142.
  1535. _this4._preventBlurCollapse = true;
  1536. L__namespace.DomEvent.stop(e);
  1537. _this4._geocodeResultSelected(result);
  1538. L__namespace.DomEvent.on(li, 'click touchend', function () {
  1539. if (_this4.options.collapsed) {
  1540. _this4._collapse();
  1541. } else {
  1542. _this4._clearResults();
  1543. }
  1544. });
  1545. };
  1546. if (icon) {
  1547. icon.src = result.icon;
  1548. }
  1549. li.setAttribute('data-result-index', String(index));
  1550. if (result.html) {
  1551. a.innerHTML = a.innerHTML + result.html;
  1552. } else if (text) {
  1553. a.appendChild(text);
  1554. } // Use mousedown and not click, since click will fire _after_ blur,
  1555. // causing the control to have collapsed and removed the items
  1556. // before the click can fire.
  1557. L__namespace.DomEvent.addListener(li, 'mousedown touchstart', mouseDownHandler, this);
  1558. return li;
  1559. };
  1560. _proto._keydown = function _keydown(e) {
  1561. var _this5 = this;
  1562. var select = function select(dir) {
  1563. if (_this5._selection) {
  1564. L__namespace.DomUtil.removeClass(_this5._selection, 'leaflet-control-geocoder-selected');
  1565. _this5._selection = _this5._selection[dir > 0 ? 'nextSibling' : 'previousSibling'];
  1566. }
  1567. if (!_this5._selection) {
  1568. _this5._selection = _this5._alts[dir > 0 ? 'firstChild' : 'lastChild'];
  1569. }
  1570. if (_this5._selection) {
  1571. L__namespace.DomUtil.addClass(_this5._selection, 'leaflet-control-geocoder-selected');
  1572. }
  1573. };
  1574. switch (e.keyCode) {
  1575. // Escape
  1576. case 27:
  1577. if (this.options.collapsed) {
  1578. this._collapse();
  1579. } else {
  1580. this._clearResults();
  1581. }
  1582. break;
  1583. // Up
  1584. case 38:
  1585. select(-1);
  1586. break;
  1587. // Up
  1588. case 40:
  1589. select(1);
  1590. break;
  1591. // Enter
  1592. case 13:
  1593. if (this._selection) {
  1594. var index = parseInt(this._selection.getAttribute('data-result-index'), 10);
  1595. this._geocodeResultSelected(this._results[index]);
  1596. this._clearResults();
  1597. } else {
  1598. this._geocode();
  1599. }
  1600. break;
  1601. default:
  1602. return;
  1603. }
  1604. L__namespace.DomEvent.preventDefault(e);
  1605. };
  1606. _proto._change = function _change() {
  1607. var _this6 = this;
  1608. var v = this._input.value;
  1609. if (v !== this._lastGeocode) {
  1610. clearTimeout(this._suggestTimeout);
  1611. if (v.length >= this.options.suggestMinLength) {
  1612. this._suggestTimeout = setTimeout(function () {
  1613. return _this6._geocode(true);
  1614. }, this.options.suggestTimeout);
  1615. } else {
  1616. this._clearResults();
  1617. }
  1618. }
  1619. };
  1620. return GeocoderControl;
  1621. }(EventedControl);
  1622. /**
  1623. * [Class factory method](https://leafletjs.com/reference.html#class-class-factories) for {@link GeocoderControl}
  1624. * @param options the options
  1625. */
  1626. function geocoder(options) {
  1627. return new GeocoderControl(options);
  1628. }
  1629. /* @preserve
  1630. * Leaflet Control Geocoder
  1631. * https://github.com/perliedman/leaflet-control-geocoder
  1632. *
  1633. * Copyright (c) 2012 sa3m (https://github.com/sa3m)
  1634. * Copyright (c) 2018 Per Liedman
  1635. * All rights reserved.
  1636. */
  1637. L__namespace.Util.extend(GeocoderControl, geocoders);
  1638. L__namespace.Util.extend(L__namespace.Control, {
  1639. Geocoder: GeocoderControl,
  1640. geocoder: geocoder
  1641. });
  1642. exports.Geocoder = GeocoderControl;
  1643. exports.default = GeocoderControl;
  1644. exports.geocoder = geocoder;
  1645. exports.geocoders = geocoders;
  1646. return exports;
  1647. }({}, L));
  1648. //# sourceMappingURL=Control.Geocoder.js.map