leaflet-control-geocoder-rails 1.0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2bd793b5d00b310fc19f137bea576ce60c2653da
4
+ data.tar.gz: 54722185a5b710a2b6ee9cbcb6baed88845a06ad
5
+ SHA512:
6
+ metadata.gz: ba7de21c79d43aeacb81aaf67793ba9f1361436e546b1b1ec4496d82b59625618c2f351b0c68c39708605d650aacc8deae40b4a7370d238dcc8c641bc685ae63
7
+ data.tar.gz: f8721e29f69a585f94f7534d401e49a6250e21a51080b91d062fe43b865db9c9a5f185fb6b01028c764cb17f9204e3d23f8e5dda13bdf186fa885ce2dd135088
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in leaflet-draw-rails.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,4 @@
1
+ Frédéric Rodrigo
2
+ Samuel Piquet, Mappy
3
+
4
+ Apache 2.0 license.
data/README.md ADDED
@@ -0,0 +1,27 @@
1
+ # leaflet-control-geocoder-rails
2
+
3
+ [leaflet-control-geocoder](https://github.com/perliedman/leaflet-control-geocoder) packaged for the rails asset pipeline
4
+
5
+ ## Installation
6
+
7
+ Add `leaflet-control-geocoder-rails` to your Gemfile and run `bundle install`:
8
+
9
+ gem 'leaflet-control-geocoder-rails'
10
+
11
+ Include javascript assets in `app/assets/javascripts/application.js`
12
+
13
+ //= require Control.Geocoder
14
+
15
+ Include stylesheets assets in `app/assets/stylesheets/application.css`
16
+
17
+ *= require Control.Geocoder
18
+
19
+ Look at leaflet-control-geocoder for further usage details.
20
+
21
+ ## Contributing
22
+
23
+ Fork & send a pull with decent commit messages
24
+
25
+ ## Credits
26
+
27
+ [perliedman](https://github.com/perliedman)
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,18 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/leaflet-control-geocoder-rails/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["perliedman"]
6
+ # gem.email = [""]
7
+
8
+ gem.homepage = "https://github.com/perliedman/leaflet-control-geocoder"
9
+ gem.name = "leaflet-control-geocoder-rails"
10
+ gem.description = %q{leaflet-control-geocoder plugin packaged for the rails 3 asset pipeline}
11
+ gem.summary = %q{leaflet-control-geocoder plugin for rails 3}
12
+ gem.license = "BSD 2-Clause"
13
+
14
+ gem.files = `git ls-files`.split($\)
15
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
16
+ gem.require_paths = ["lib"]
17
+ gem.version = Leaflet::Control::Geocoder::Rails::VERSION
18
+ end
@@ -0,0 +1,15 @@
1
+ require "leaflet-draw-rails/version"
2
+
3
+ module Leaflet
4
+ module Control
5
+ module Geocoder
6
+ module Rails
7
+ # make me a rails engine
8
+ class Engine < ::Rails::Engine
9
+ initializer 'leaflet-rails.precompile' do |app|
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,9 @@
1
+ module Leaflet
2
+ module Control
3
+ module Geocoder
4
+ module Rails
5
+ VERSION = "1.0.0.1"
6
+ end
7
+ end
8
+ end
9
+ end
Binary file
Binary file
@@ -0,0 +1,733 @@
1
+ (function (factory) {
2
+ // Packaging/modules magic dance
3
+ var L;
4
+ if (typeof define === 'function' && define.amd) {
5
+ // AMD
6
+ define(['leaflet'], factory);
7
+ } else if (typeof module !== 'undefined') {
8
+ // Node/CommonJS
9
+ L = require('leaflet');
10
+ module.exports = factory(L);
11
+ } else {
12
+ // Browser globals
13
+ if (typeof window.L === 'undefined')
14
+ throw 'Leaflet must be loaded first';
15
+ factory(window.L);
16
+ }
17
+ }(function (L) {
18
+ 'use strict';
19
+ L.Control.Geocoder = L.Control.extend({
20
+ options: {
21
+ showResultIcons: false,
22
+ collapsed: true,
23
+ expand: 'click',
24
+ position: 'topright',
25
+ placeholder: 'Search...',
26
+ errorMessage: 'Nothing found.'
27
+ },
28
+
29
+ _callbackId: 0,
30
+
31
+ initialize: function (options) {
32
+ L.Util.setOptions(this, options);
33
+ if (!this.options.geocoder) {
34
+ this.options.geocoder = new L.Control.Geocoder.Nominatim();
35
+ }
36
+ },
37
+
38
+ onAdd: function (map) {
39
+ var className = 'leaflet-control-geocoder',
40
+ container = L.DomUtil.create('div', className),
41
+ icon = L.DomUtil.create('div', 'leaflet-control-geocoder-icon', container),
42
+ form = this._form = L.DomUtil.create('form', className + '-form', container),
43
+ input;
44
+
45
+ this._map = map;
46
+ this._container = container;
47
+ input = this._input = L.DomUtil.create('input');
48
+ input.type = 'text';
49
+ input.placeholder = this.options.placeholder;
50
+
51
+ L.DomEvent.addListener(input, 'keydown', this._keydown, this);
52
+ //L.DomEvent.addListener(input, 'onpaste', this._clearResults, this);
53
+ //L.DomEvent.addListener(input, 'oninput', this._clearResults, this);
54
+
55
+ this._errorElement = document.createElement('div');
56
+ this._errorElement.className = className + '-form-no-error';
57
+ this._errorElement.innerHTML = this.options.errorMessage;
58
+
59
+ this._alts = L.DomUtil.create('ul', className + '-alternatives leaflet-control-geocoder-alternatives-minimized');
60
+
61
+ form.appendChild(input);
62
+ form.appendChild(this._errorElement);
63
+ container.appendChild(this._alts);
64
+
65
+ L.DomEvent.addListener(form, 'submit', this._geocode, this);
66
+
67
+ if (this.options.collapsed) {
68
+ if (this.options.expand === 'click') {
69
+ L.DomEvent.addListener(icon, 'click', function(e) {
70
+ // TODO: touch
71
+ if (e.button === 0 && e.detail === 1) {
72
+ this._toggle();
73
+ }
74
+ }, this);
75
+ } else {
76
+ L.DomEvent.addListener(icon, 'mouseover', this._expand, this);
77
+ L.DomEvent.addListener(icon, 'mouseout', this._collapse, this);
78
+ this._map.on('movestart', this._collapse, this);
79
+ }
80
+ } else {
81
+ this._expand();
82
+ }
83
+
84
+ L.DomEvent.disableClickPropagation(container);
85
+
86
+ return container;
87
+ },
88
+
89
+ _geocodeResult: function (results) {
90
+ L.DomUtil.removeClass(this._container, 'leaflet-control-geocoder-throbber');
91
+ if (results.length === 1) {
92
+ this._geocodeResultSelected(results[0]);
93
+ } else if (results.length > 0) {
94
+ this._alts.innerHTML = '';
95
+ this._results = results;
96
+ L.DomUtil.removeClass(this._alts, 'leaflet-control-geocoder-alternatives-minimized');
97
+ for (var i = 0; i < results.length; i++) {
98
+ this._alts.appendChild(this._createAlt(results[i], i));
99
+ }
100
+ } else {
101
+ L.DomUtil.addClass(this._errorElement, 'leaflet-control-geocoder-error');
102
+ }
103
+ },
104
+
105
+ markGeocode: function(result) {
106
+ this._map.fitBounds(result.bbox);
107
+
108
+ if (this._geocodeMarker) {
109
+ this._map.removeLayer(this._geocodeMarker);
110
+ }
111
+
112
+ this._geocodeMarker = new L.Marker(result.center)
113
+ .bindPopup(result.html || result.name)
114
+ .addTo(this._map)
115
+ .openPopup();
116
+
117
+ return this;
118
+ },
119
+
120
+ _geocode: function(event) {
121
+ L.DomEvent.preventDefault(event);
122
+
123
+ L.DomUtil.addClass(this._container, 'leaflet-control-geocoder-throbber');
124
+ this._clearResults();
125
+ this.options.geocoder.geocode(this._input.value, this._geocodeResult, this);
126
+
127
+ return false;
128
+ },
129
+
130
+ _geocodeResultSelected: function(result) {
131
+ if (this.options.collapsed) {
132
+ this._collapse();
133
+ } else {
134
+ this._clearResults();
135
+ }
136
+ this.markGeocode(result);
137
+ },
138
+
139
+ _toggle: function() {
140
+ if (this._container.className.indexOf('leaflet-control-geocoder-expanded') >= 0) {
141
+ this._collapse();
142
+ } else {
143
+ this._expand();
144
+ }
145
+ },
146
+
147
+ _expand: function () {
148
+ L.DomUtil.addClass(this._container, 'leaflet-control-geocoder-expanded');
149
+ this._input.select();
150
+ },
151
+
152
+ _collapse: function () {
153
+ this._container.className = this._container.className.replace(' leaflet-control-geocoder-expanded', '');
154
+ L.DomUtil.addClass(this._alts, 'leaflet-control-geocoder-alternatives-minimized');
155
+ L.DomUtil.removeClass(this._errorElement, 'leaflet-control-geocoder-error');
156
+ },
157
+
158
+ _clearResults: function () {
159
+ L.DomUtil.addClass(this._alts, 'leaflet-control-geocoder-alternatives-minimized');
160
+ this._selection = null;
161
+ L.DomUtil.removeClass(this._errorElement, 'leaflet-control-geocoder-error');
162
+ },
163
+
164
+ _createAlt: function(result, index) {
165
+ var li = document.createElement('li'),
166
+ a = L.DomUtil.create('a', '', li),
167
+ icon = this.options.showResultIcons && result.icon ? L.DomUtil.create('img', '', a) : null,
168
+ text = result.html ? undefined : document.createTextNode(result.name);
169
+
170
+ if (icon) {
171
+ icon.src = result.icon;
172
+ }
173
+
174
+ a.href = '#';
175
+ a.setAttribute('data-result-index', index);
176
+
177
+ if (result.html) {
178
+ a.innerHTML = result.html;
179
+ } else {
180
+ a.appendChild(text);
181
+ }
182
+
183
+ L.DomEvent.addListener(li, 'click', function clickHandler(e) {
184
+ L.DomEvent.preventDefault(e);
185
+ this._geocodeResultSelected(result);
186
+ }, this);
187
+
188
+ return li;
189
+ },
190
+
191
+ _keydown: function(e) {
192
+ var _this = this,
193
+ select = function select(dir) {
194
+ if (_this._selection) {
195
+ L.DomUtil.removeClass(_this._selection.firstChild, 'leaflet-control-geocoder-selected');
196
+ _this._selection = _this._selection[dir > 0 ? 'nextSibling' : 'previousSibling'];
197
+ }
198
+ if (!_this._selection) {
199
+ _this._selection = _this._alts[dir > 0 ? 'firstChild' : 'lastChild'];
200
+ }
201
+
202
+ if (_this._selection) {
203
+ L.DomUtil.addClass(_this._selection.firstChild, 'leaflet-control-geocoder-selected');
204
+ }
205
+ };
206
+
207
+ switch (e.keyCode) {
208
+ // Escape
209
+ case 27:
210
+ this._collapse();
211
+ break;
212
+ // Up
213
+ case 38:
214
+ select(-1);
215
+ L.DomEvent.preventDefault(e);
216
+ break;
217
+ // Up
218
+ case 40:
219
+ select(1);
220
+ L.DomEvent.preventDefault(e);
221
+ break;
222
+ // Enter
223
+ case 13:
224
+ if (this._selection) {
225
+ var index = parseInt(this._selection.firstChild.getAttribute('data-result-index'), 10);
226
+ this._geocodeResultSelected(this._results[index]);
227
+ this._clearResults();
228
+ L.DomEvent.preventDefault(e);
229
+ }
230
+ }
231
+ return true;
232
+ }
233
+ });
234
+
235
+ L.Control.geocoder = function(id, options) {
236
+ return new L.Control.Geocoder(id, options);
237
+ };
238
+
239
+ L.Control.Geocoder.callbackId = 0;
240
+ L.Control.Geocoder.jsonp = function(url, params, callback, context, jsonpParam) {
241
+ var callbackId = '_l_geocoder_' + (L.Control.Geocoder.callbackId++);
242
+ params[jsonpParam || 'callback'] = callbackId;
243
+ window[callbackId] = L.Util.bind(callback, context);
244
+ var script = document.createElement('script');
245
+ script.type = 'text/javascript';
246
+ script.src = url + L.Util.getParamString(params);
247
+ script.id = callbackId;
248
+ document.getElementsByTagName('head')[0].appendChild(script);
249
+ };
250
+ L.Control.Geocoder.getJSON = function(url, params, callback) {
251
+ var xmlHttp = new XMLHttpRequest();
252
+ xmlHttp.open( "GET", url + L.Util.getParamString(params), true);
253
+ xmlHttp.send(null);
254
+ xmlHttp.onreadystatechange = function () {
255
+ if (xmlHttp.readyState != 4) return;
256
+ if (xmlHttp.status != 200 && req.status != 304) return;
257
+ callback(JSON.parse(xmlHttp.response));
258
+ };
259
+ };
260
+
261
+ L.Control.Geocoder.template = function (str, data, htmlEscape) {
262
+ return str.replace(/\{ *([\w_]+) *\}/g, function (str, key) {
263
+ var value = data[key];
264
+ if (value === undefined) {
265
+ value = '';
266
+ } else if (typeof value === 'function') {
267
+ value = value(data);
268
+ }
269
+ return L.Control.Geocoder.htmlEscape(value);
270
+ });
271
+ };
272
+
273
+ // Adapted from handlebars.js
274
+ // https://github.com/wycats/handlebars.js/
275
+ L.Control.Geocoder.htmlEscape = (function() {
276
+ var badChars = /[&<>"'`]/g;
277
+ var possible = /[&<>"'`]/;
278
+ var escape = {
279
+ '&': '&amp;',
280
+ '<': '&lt;',
281
+ '>': '&gt;',
282
+ '"': '&quot;',
283
+ '\'': '&#x27;',
284
+ '`': '&#x60;'
285
+ };
286
+
287
+ function escapeChar(chr) {
288
+ return escape[chr];
289
+ }
290
+
291
+ return function(string) {
292
+ if (string == null) {
293
+ return '';
294
+ } else if (!string) {
295
+ return string + '';
296
+ }
297
+
298
+ // Force a string conversion as this will be done by the append regardless and
299
+ // the regex test will do this transparently behind the scenes, causing issues if
300
+ // an object's to string has escaped characters in it.
301
+ string = '' + string;
302
+
303
+ if (!possible.test(string)) {
304
+ return string;
305
+ }
306
+ return string.replace(badChars, escapeChar);
307
+ };
308
+ })();
309
+
310
+ L.Control.Geocoder.Nominatim = L.Class.extend({
311
+ options: {
312
+ serviceUrl: '//nominatim.openstreetmap.org/',
313
+ geocodingQueryParams: {},
314
+ reverseQueryParams: {},
315
+ htmlTemplate: function(r) {
316
+ var a = r.address,
317
+ parts = [];
318
+ if (a.road || a.building) {
319
+ parts.push('{building} {road} {house_number}');
320
+ }
321
+
322
+ if (a.city || a.town || a.village) {
323
+ parts.push('<span class="' + (parts.length > 0 ? 'leaflet-control-geocoder-address-detail' : '') +
324
+ '">{postcode} {city}{town}{village}</span>');
325
+ }
326
+
327
+ if (a.state || a.country) {
328
+ parts.push('<span class="' + (parts.length > 0 ? 'leaflet-control-geocoder-address-context' : '') +
329
+ '">{state} {country}</span>');
330
+ }
331
+
332
+ return L.Control.Geocoder.template(parts.join('<br/>'), a, true);
333
+ }
334
+ },
335
+
336
+ initialize: function(options) {
337
+ L.Util.setOptions(this, options);
338
+ },
339
+
340
+ geocode: function(query, cb, context) {
341
+ L.Control.Geocoder.jsonp(this.options.serviceUrl + 'search/', L.extend({
342
+ q: query,
343
+ limit: 5,
344
+ format: 'json',
345
+ addressdetails: 1
346
+ }, this.options.geocodingQueryParams),
347
+ function(data) {
348
+ var results = [];
349
+ for (var i = data.length - 1; i >= 0; i--) {
350
+ var bbox = data[i].boundingbox;
351
+ for (var j = 0; j < 4; j++) bbox[j] = parseFloat(bbox[j]);
352
+ results[i] = {
353
+ icon: data[i].icon,
354
+ name: data[i].display_name,
355
+ html: this.options.htmlTemplate ?
356
+ this.options.htmlTemplate(data[i])
357
+ : undefined,
358
+ bbox: L.latLngBounds([bbox[0], bbox[2]], [bbox[1], bbox[3]]),
359
+ center: L.latLng(data[i].lat, data[i].lon),
360
+ properties: data[i]
361
+ };
362
+ }
363
+ cb.call(context, results);
364
+ }, this, 'json_callback');
365
+ },
366
+
367
+ reverse: function(location, scale, cb, context) {
368
+ L.Control.Geocoder.jsonp(this.options.serviceUrl + 'reverse/', L.extend({
369
+ lat: location.lat,
370
+ lon: location.lng,
371
+ zoom: Math.round(Math.log(scale / 256) / Math.log(2)),
372
+ addressdetails: 1,
373
+ format: 'json'
374
+ }, this.options.reverseQueryParams), function(data) {
375
+ var result = [],
376
+ loc;
377
+
378
+ if (data && data.lat && data.lon) {
379
+ loc = L.latLng(data.lat, data.lon);
380
+ result.push({
381
+ name: data.display_name,
382
+ html: this.options.htmlTemplate ?
383
+ this.options.htmlTemplate(data)
384
+ : undefined,
385
+ center: loc,
386
+ bounds: L.latLngBounds(loc, loc),
387
+ properties: data
388
+ });
389
+ }
390
+
391
+ cb.call(context, result);
392
+ }, this, 'json_callback');
393
+ }
394
+ });
395
+
396
+ L.Control.Geocoder.nominatim = function(options) {
397
+ return new L.Control.Geocoder.Nominatim(options);
398
+ };
399
+
400
+ L.Control.Geocoder.Bing = L.Class.extend({
401
+ initialize: function(key) {
402
+ this.key = key;
403
+ },
404
+
405
+ geocode : function (query, cb, context) {
406
+ L.Control.Geocoder.jsonp('//dev.virtualearth.net/REST/v1/Locations', {
407
+ query: query,
408
+ key : this.key
409
+ }, function(data) {
410
+ var results = [];
411
+ for (var i = data.resourceSets[0].resources.length - 1; i >= 0; i--) {
412
+ var resource = data.resourceSets[0].resources[i],
413
+ bbox = resource.bbox;
414
+ results[i] = {
415
+ name: resource.name,
416
+ bbox: L.latLngBounds([bbox[0], bbox[1]], [bbox[2], bbox[3]]),
417
+ center: L.latLng(resource.point.coordinates)
418
+ };
419
+ }
420
+ cb.call(context, results);
421
+ }, this, 'jsonp');
422
+ },
423
+
424
+ reverse: function(location, scale, cb, context) {
425
+ L.Control.Geocoder.jsonp('//dev.virtualearth.net/REST/v1/Locations/' + location.lat + ',' + location.lng, {
426
+ key : this.key
427
+ }, function(data) {
428
+ var results = [];
429
+ for (var i = data.resourceSets[0].resources.length - 1; i >= 0; i--) {
430
+ var resource = data.resourceSets[0].resources[i],
431
+ bbox = resource.bbox;
432
+ results[i] = {
433
+ name: resource.name,
434
+ bbox: L.latLngBounds([bbox[0], bbox[1]], [bbox[2], bbox[3]]),
435
+ center: L.latLng(resource.point.coordinates)
436
+ };
437
+ }
438
+ cb.call(context, results);
439
+ }, this, 'jsonp');
440
+ }
441
+ });
442
+
443
+ L.Control.Geocoder.bing = function(key) {
444
+ return new L.Control.Geocoder.Bing(key);
445
+ };
446
+
447
+ L.Control.Geocoder.RaveGeo = L.Class.extend({
448
+ options: {
449
+ querySuffix: '',
450
+ deepSearch: true,
451
+ wordBased: false
452
+ },
453
+
454
+ jsonp: function(params, callback, context) {
455
+ var callbackId = '_l_geocoder_' + (L.Control.Geocoder.callbackId++),
456
+ paramParts = [];
457
+ params.prepend = callbackId + '(';
458
+ params.append = ')';
459
+ for (var p in params) {
460
+ paramParts.push(p + '=' + escape(params[p]));
461
+ }
462
+
463
+ window[callbackId] = L.Util.bind(callback, context);
464
+ var script = document.createElement('script');
465
+ script.type = 'text/javascript';
466
+ script.src = this._serviceUrl + '?' + paramParts.join('&');
467
+ script.id = callbackId;
468
+ document.getElementsByTagName('head')[0].appendChild(script);
469
+ },
470
+
471
+ initialize: function(serviceUrl, scheme, options) {
472
+ L.Util.setOptions(this, options);
473
+
474
+ this._serviceUrl = serviceUrl;
475
+ this._scheme = scheme;
476
+ },
477
+
478
+ geocode: function(query, cb, context) {
479
+ L.Control.Geocoder.jsonp(this._serviceUrl, {
480
+ address: query + this.options.querySuffix,
481
+ scheme: this._scheme,
482
+ outputFormat: 'jsonp',
483
+ deepSearch: this.options.deepSearch,
484
+ wordBased: this.options.wordBased
485
+ }, function(data) {
486
+ var results = [];
487
+ for (var i = data.length - 1; i >= 0; i--) {
488
+ var r = data[i],
489
+ c = L.latLng(r.y, r.x);
490
+ results[i] = {
491
+ name: r.address,
492
+ bbox: L.latLngBounds([c]),
493
+ center: c
494
+ };
495
+ }
496
+ cb.call(context, results);
497
+ }, this);
498
+ }
499
+ });
500
+
501
+ L.Control.Geocoder.raveGeo = function(serviceUrl, scheme, options) {
502
+ return new L.Control.Geocoder.RaveGeo(serviceUrl, scheme, options);
503
+ };
504
+
505
+ L.Control.Geocoder.MapQuest = L.Class.extend({
506
+ initialize: function(key) {
507
+ // MapQuest seems to provide URI encoded API keys,
508
+ // so to avoid encoding them twice, we decode them here
509
+ this._key = decodeURIComponent(key);
510
+ },
511
+
512
+ _formatName: function() {
513
+ var r = [],
514
+ i;
515
+ for (i = 0; i < arguments.length; i++) {
516
+ if (arguments[i]) {
517
+ r.push(arguments[i]);
518
+ }
519
+ }
520
+
521
+ return r.join(', ');
522
+ },
523
+
524
+ geocode: function(query, cb, context) {
525
+ L.Control.Geocoder.jsonp('//www.mapquestapi.com/geocoding/v1/address', {
526
+ key: this._key,
527
+ location: query,
528
+ limit: 5,
529
+ outFormat: 'json'
530
+ }, function(data) {
531
+ var results = [],
532
+ loc,
533
+ latLng;
534
+ if (data.results && data.results[0].locations) {
535
+ for (var i = data.results[0].locations.length - 1; i >= 0; i--) {
536
+ loc = data.results[0].locations[i];
537
+ latLng = L.latLng(loc.latLng);
538
+ results[i] = {
539
+ name: this._formatName(loc.street, loc.adminArea4, loc.adminArea3, loc.adminArea1),
540
+ bbox: L.latLngBounds(latLng, latLng),
541
+ center: latLng
542
+ };
543
+ }
544
+ }
545
+
546
+ cb.call(context, results);
547
+ }, this);
548
+ },
549
+
550
+ reverse: function(location, scale, cb, context) {
551
+ L.Control.Geocoder.jsonp('//www.mapquestapi.com/geocoding/v1/reverse', {
552
+ key: this._key,
553
+ location: location.lat + ',' + location.lng,
554
+ outputFormat: 'json'
555
+ }, function(data) {
556
+ var results = [],
557
+ loc,
558
+ latLng;
559
+ if (data.results && data.results[0].locations) {
560
+ for (var i = data.results[0].locations.length - 1; i >= 0; i--) {
561
+ loc = data.results[0].locations[i];
562
+ latLng = L.latLng(loc.latLng);
563
+ results[i] = {
564
+ name: this._formatName(loc.street, loc.adminArea4, loc.adminArea3, loc.adminArea1),
565
+ bbox: L.latLngBounds(latLng, latLng),
566
+ center: latLng
567
+ };
568
+ }
569
+ }
570
+
571
+ cb.call(context, results);
572
+ }, this);
573
+ }
574
+ });
575
+
576
+ L.Control.Geocoder.mapQuest = function(key) {
577
+ return new L.Control.Geocoder.MapQuest(key);
578
+ };
579
+
580
+ L.Control.Geocoder.Mapbox = L.Class.extend({
581
+ options: {
582
+ service_url: 'https://api.tiles.mapbox.com/v4/geocode/mapbox.places-v1/'
583
+ },
584
+
585
+ initialize: function(access_token) {
586
+ this._access_token = access_token;
587
+ },
588
+
589
+ geocode: function(query, cb, context) {
590
+ L.Control.Geocoder.getJSON(this.options.service_url + encodeURIComponent(query) + '.json', {
591
+ access_token: this._access_token,
592
+ }, function(data) {
593
+ var results = [],
594
+ loc,
595
+ latLng,
596
+ latLngBounds;
597
+ if (data.features && data.features.length) {
598
+ for (var i = 0; i <= data.features.length - 1; i++) {
599
+ loc = data.features[i];
600
+ latLng = L.latLng(loc.center.reverse());
601
+ if(loc.hasOwnProperty('bbox'))
602
+ {
603
+ latLngBounds = L.latLngBounds(L.latLng(loc.bbox.slice(0, 2).reverse()), L.latLng(loc.bbox.slice(2, 4).reverse()));
604
+ }
605
+ else
606
+ {
607
+ latLngBounds = L.latLngBounds(latLng, latLng);
608
+ }
609
+ results[i] = {
610
+ name: loc.place_name,
611
+ bbox: latLngBounds,
612
+ center: latLng
613
+ };
614
+ }
615
+ }
616
+
617
+ cb.call(context, results);
618
+ });
619
+ },
620
+
621
+ reverse: function(location, scale, cb, context) {
622
+ L.Control.Geocoder.getJSON(this.options.service_url + encodeURIComponent(location.lng) + ',' + encodeURIComponent(location.lat) + '.json', {
623
+ access_token: this._access_token,
624
+ }, function(data) {
625
+ var results = [],
626
+ loc,
627
+ latLng,
628
+ latLngBounds;
629
+ if (data.features && data.features.length) {
630
+ for (var i = 0; i <= data.features.length - 1; i++) {
631
+ loc = data.features[i];
632
+ latLng = L.latLng(loc.center.reverse());
633
+ if(loc.hasOwnProperty('bbox'))
634
+ {
635
+ latLngBounds = L.latLngBounds(L.latLng(loc.bbox.slice(0, 2).reverse()), L.latLng(loc.bbox.slice(2, 4).reverse()));
636
+ }
637
+ else
638
+ {
639
+ latLngBounds = L.latLngBounds(latLng, latLng);
640
+ }
641
+ results[i] = {
642
+ name: loc.place_name,
643
+ bbox: latLngBounds,
644
+ center: latLng
645
+ };
646
+ }
647
+ }
648
+
649
+ cb.call(context, results);
650
+ });
651
+ }
652
+ });
653
+
654
+ L.Control.Geocoder.mapbox = function(access_token) {
655
+ return new L.Control.Geocoder.Mapbox(access_token);
656
+ };
657
+
658
+ L.Control.Geocoder.Google = L.Class.extend({
659
+ options: {
660
+ service_url: 'https://maps.googleapis.com/maps/api/geocode/json'
661
+ },
662
+
663
+ initialize: function(key) {
664
+ this._key = key;
665
+ },
666
+
667
+ geocode: function(query, cb, context) {
668
+ var params = {
669
+ address: query,
670
+ };
671
+ if(this._key && this._key.length)
672
+ {
673
+ params['key'] = this._key
674
+ }
675
+
676
+ L.Control.Geocoder.getJSON(this.options.service_url, params, function(data) {
677
+ var results = [],
678
+ loc,
679
+ latLng,
680
+ latLngBounds;
681
+ if (data.results && data.results.length) {
682
+ for (var i = 0; i <= data.results.length - 1; i++) {
683
+ loc = data.results[i];
684
+ latLng = L.latLng(loc.geometry.location);
685
+ latLngBounds = L.latLngBounds(L.latLng(loc.geometry.viewport.northeast), L.latLng(loc.geometry.viewport.southwest));
686
+ results[i] = {
687
+ name: loc.formatted_address,
688
+ bbox: latLngBounds,
689
+ center: latLng
690
+ };
691
+ }
692
+ }
693
+
694
+ cb.call(context, results);
695
+ });
696
+ },
697
+
698
+ reverse: function(location, scale, cb, context) {
699
+ var params = {
700
+ latlng: encodeURIComponent(location.lat) + ',' + encodeURIComponent(location.lng)
701
+ };
702
+ if(this._key && this._key.length)
703
+ {
704
+ params['key'] = this._key
705
+ }
706
+ L.Control.Geocoder.getJSON(this.options.service_url, params, function(data) {
707
+ var results = [],
708
+ loc,
709
+ latLng,
710
+ latLngBounds;
711
+ if (data.results && data.results.length) {
712
+ for (var i = 0; i <= data.results.length - 1; i++) {
713
+ loc = data.results[i];
714
+ latLng = L.latLng(loc.geometry.location);
715
+ latLngBounds = L.latLngBounds(L.latLng(loc.geometry.viewport.northeast), L.latLng(loc.geometry.viewport.southwest));
716
+ results[i] = {
717
+ name: loc.formatted_address,
718
+ bbox: latLngBounds,
719
+ center: latLng
720
+ };
721
+ }
722
+ }
723
+
724
+ cb.call(context, results);
725
+ });
726
+ }
727
+ });
728
+
729
+ L.Control.Geocoder.google = function(key) {
730
+ return new L.Control.Geocoder.Google(key);
731
+ };
732
+ return L.Control.Geocoder;
733
+ }));
@@ -0,0 +1,140 @@
1
+ .leaflet-control-geocoder {
2
+ background: white;
3
+ box-shadow: 0 1px 7px rgba(0,0,0,0.65);
4
+ -webkit-border-radius: 4px;
5
+ border-radius: 4px;
6
+ line-height: 26px;
7
+ overflow: hidden;
8
+ }
9
+
10
+ .leaflet-touch .leaflet-control-geocoder {
11
+ box-shadow: none;
12
+ border: 2px solid rgba(0,0,0,0.2);
13
+ background-clip: padding-box;
14
+ line-height: 30px;
15
+ }
16
+
17
+ .leaflet-control-geocoder-form {
18
+ display: inline;
19
+ }
20
+
21
+ .leaflet-control-geocoder-form input, .leaflet-control-geocoder-form ul, .leaflet-control-geocoder-error {
22
+ border: 0;
23
+ color: transparent;
24
+ background: white;
25
+ }
26
+
27
+ .leaflet-control-geocoder-form input {
28
+ font-size: 16px;
29
+ width: 0;
30
+ transition: width 0.125s ease-in;
31
+ }
32
+
33
+ .leaflet-touch .leaflet-control-geocoder-form input {
34
+ font-size: 22px;
35
+ }
36
+
37
+ .leaflet-control-geocoder-icon {
38
+ width: 26px;
39
+ height: 26px;
40
+ background-image: url(<%= asset_path 'geocoder.png' %>);
41
+ background-repeat: no-repeat;
42
+ background-position: center;
43
+ float: right;
44
+ cursor: pointer;
45
+ }
46
+
47
+ .leaflet-touch .leaflet-control-geocoder-icon {
48
+ margin-top: 2px;
49
+ width: 30px;
50
+ }
51
+
52
+ .leaflet-control-geocoder-throbber .leaflet-control-geocoder-icon {
53
+ background-image: url(<%= asset_path 'throbber.gif' %>);
54
+ }
55
+
56
+ .leaflet-control-geocoder-expanded input, .leaflet-control-geocoder-error {
57
+ width: 226px;
58
+ margin: 0 0 0 4px;
59
+ padding: 0 0 0 4px;
60
+ vertical-align: middle;
61
+ color: #000;
62
+ }
63
+
64
+ .leaflet-control-geocoder-form input:focus {
65
+ outline: none;
66
+ }
67
+
68
+ .leaflet-control-geocoder-form button {
69
+ display: none;
70
+ }
71
+
72
+ .leaflet-control-geocoder-form-no-error {
73
+ display: none;
74
+ }
75
+
76
+ .leaflet-control-geocoder-error {
77
+ margin-top: 8px;
78
+ display: block;
79
+ color: #444;
80
+ }
81
+
82
+ ul.leaflet-control-geocoder-alternatives {
83
+ width: 260px;
84
+ overflow: hidden;
85
+ text-overflow: ellipsis;
86
+ white-space: nowrap;
87
+ list-style: none;
88
+ padding: 0;
89
+ transition: height 0.125s ease-in;
90
+ }
91
+
92
+ .leaflet-control-geocoder-alternatives-minimized {
93
+ width: 0 !important;
94
+ height: 0;
95
+ overflow: hidden;
96
+ margin: 0;
97
+ padding: 0;
98
+ }
99
+
100
+ .leaflet-control-geocoder-alternatives li {
101
+ width: 100%;
102
+ overflow: hidden;
103
+ text-overflow: ellipsis;
104
+ border-bottom: 1px solid #eee;
105
+ padding: 0;
106
+ }
107
+
108
+
109
+ .leaflet-control-geocoder-alternatives li:last-child {
110
+ border-bottom: none;
111
+ }
112
+
113
+ .leaflet-control-geocoder-alternatives a {
114
+ display: block;
115
+ text-decoration: none;
116
+ color: black;
117
+ padding: 6px 8px 16px 6px;
118
+ font-size: 14px;
119
+ line-height: 1;
120
+ font-weight: bold;
121
+ }
122
+
123
+ .leaflet-touch .leaflet-control-geocoder-alternatives a {
124
+ font-size: 18px;
125
+ }
126
+
127
+ .leaflet-control-geocoder-alternatives a:hover, .leaflet-control-geocoder-selected {
128
+ background-color: #ddd;
129
+ }
130
+
131
+ .leaflet-control-geocoder-address-detail {
132
+ font-size: 12px;
133
+ font-weight: normal;
134
+ }
135
+
136
+ .leaflet-control-geocoder-address-context {
137
+ color: #666;
138
+ font-size: 12px;
139
+ font-weight: lighter;
140
+ }
metadata ADDED
@@ -0,0 +1,54 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: leaflet-control-geocoder-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - perliedman
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-10-14 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: leaflet-control-geocoder plugin packaged for the rails 3 asset pipeline
14
+ email:
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - Gemfile
20
+ - LICENSE
21
+ - README.md
22
+ - Rakefile
23
+ - leaflet-control-geocoder-rails.gemspec
24
+ - lib/leaflet-control-geocoder-rails.rb
25
+ - lib/leaflet-control-geocoder-rails/version.rb
26
+ - vendor/assets/images/geocoder.png
27
+ - vendor/assets/images/throbber.gif
28
+ - vendor/assets/javascripts/Control.Geocoder.js
29
+ - vendor/assets/stylesheets/Control.Geocoder.css.erb
30
+ homepage: https://github.com/perliedman/leaflet-control-geocoder
31
+ licenses:
32
+ - BSD 2-Clause
33
+ metadata: {}
34
+ post_install_message:
35
+ rdoc_options: []
36
+ require_paths:
37
+ - lib
38
+ required_ruby_version: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ required_rubygems_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ requirements: []
49
+ rubyforge_project:
50
+ rubygems_version: 2.2.2
51
+ signing_key:
52
+ specification_version: 4
53
+ summary: leaflet-control-geocoder plugin for rails 3
54
+ test_files: []