diff --git a/Gruntfile.js b/Gruntfile.js
index 94cbd21..9d83fee 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -25,7 +25,8 @@ module.exports = function(grunt) {
'vendor/mobiscroll.custom-2.5.4.min.js',
'vendor/jquery.scrollintoview.min.js',
'vendor/overthrow.js',
- 'vendor/leaflet/leaflet.js'],
+ 'vendor/leaflet/leaflet.js',
+ 'vendor/Control.OSMGeocoder.js'],
// the location of the resulting JS file
dest: 'dist/js/libs.js'
},
@@ -80,12 +81,18 @@ module.exports = function(grunt) {
src: '*',
dest: 'dist/img/'
},
- libimages: {
+ libbootstrapimages: {
expand: true,
cwd: 'vendor/bootstrap/img/',
src: '*',
dest: 'dist/img/'
},
+ libimages: {
+ expand: true,
+ cwd: 'vendor/img/',
+ src: '*',
+ dest: 'dist/img/'
+ },
// leafletimages: { We don't use default marker
// expand: true,
// cwd: 'vendor/leaflet/images/',
@@ -203,7 +210,7 @@ module.exports = function(grunt) {
grunt.registerTask('cordova', ['default', 'copy:cordova_www', 'copy:cordova_override_debug']);
- grunt.registerTask('copy-app', ['copy:apphtml', 'copy:appimages', 'copy:libimages', 'copy:leafletcssimages']);
+ grunt.registerTask('copy-app', ['copy:apphtml', 'copy:appimages', 'copy:libimages', 'copy:libbootstrapimages', 'copy:leafletcssimages']);
grunt.registerTask('default', ['browserify', 'seeds', 'concat', 'copy-app', 'handlebars', 'manifest']);
grunt.registerTask('deploy_demo', ['default', 'shell:deploy_demo']);
diff --git a/app/js/map/SourcesLayer.coffee b/app/js/map/SourcesLayer.coffee
index f3849ac..abe96e4 100644
--- a/app/js/map/SourcesLayer.coffee
+++ b/app/js/map/SourcesLayer.coffee
@@ -82,7 +82,7 @@ module.exports = class SourcesLayer extends L.LayerGroup
Id: <%=source.code%>
Name: <%=source.name%>
-
+
''',
{ source: source })
diff --git a/app/js/pages/SourceMapPage.coffee b/app/js/pages/SourceMapPage.coffee
index 1255147..09ad429 100644
--- a/app/js/pages/SourceMapPage.coffee
+++ b/app/js/pages/SourceMapPage.coffee
@@ -34,6 +34,10 @@ class SourceMapPage extends Page
# Create layer control
L.control.layers(baseLayers).addTo(@map)
+ # Create geocoder
+ osmGeocoder = new L.Control.OSMGeocoder()
+ @map.addControl(osmGeocoder)
+
# Setup marker display when map is loaded
@map.whenReady =>
@sourceDisplay = new SourceDisplay(@db, @pager).addTo(@map)
diff --git a/vendor/Control.OSMGeocoder.css b/vendor/Control.OSMGeocoder.css
new file mode 100644
index 0000000..75cac81
--- /dev/null
+++ b/vendor/Control.OSMGeocoder.css
@@ -0,0 +1,43 @@
+.leaflet-control-geocoder a {
+ background-position: 50% 50%;
+ background-repeat: no-repeat;
+ display: block;
+}
+
+.leaflet-control-geocoder {
+ box-shadow: 0 1px 7px #999;
+ background: #f8f8f9;
+ -moz-border-radius: 8px;
+ -webkit-border-radius: 8px;
+ border-radius: 8px;
+}
+
+.leaflet-control-geocoder a {
+ background-image: url(../img/geocoder.png);
+ width: 36px;
+ height: 36px;
+}
+
+.leaflet-touch .leaflet-control-geocoder a {
+ width: 44px;
+ height: 44px;
+}
+
+.leaflet-control-geocoder .leaflet-control-geocoder-form,
+.leaflet-control-geocoder-expanded .leaflet-control-geocoder-toggle {
+ display: none;
+}
+
+.leaflet-control-geocoder-expanded .leaflet-control-geocoder-form {
+ display: block;
+ position: relative;
+}
+
+.leaflet-control-geocoder-expanded .leaflet-control-geocoder-form {
+ padding: 5px;
+ margin-bottom: 0px; /* Override bootstrap */
+}
+
+.leaflet-control-geocoder-expanded .leaflet-control-geocoder-form .input-append {
+ margin-bottom: 0px; /* Override bootstrap */
+}
diff --git a/vendor/Control.OSMGeocoder.js b/vendor/Control.OSMGeocoder.js
new file mode 100644
index 0000000..df86890
--- /dev/null
+++ b/vendor/Control.OSMGeocoder.js
@@ -0,0 +1,125 @@
+L.Control.OSMGeocoder = L.Control.extend({
+ options: {
+ collapsed: true,
+ position: 'topright',
+ text: 'Locate',
+ bounds: null, // L.LatLngBounds
+ email: null, // String
+ callback: function (results) {
+ console.log(results);
+ var bbox = results[0].boundingbox,
+ first = new L.LatLng(bbox[0], bbox[2]),
+ second = new L.LatLng(bbox[1], bbox[3]),
+ bounds = new L.LatLngBounds([first, second]);
+ this._map.fitBounds(bounds);
+ }
+ },
+
+ _callbackId: 0,
+
+ initialize: function (options) {
+ L.Util.setOptions(this, options);
+ },
+
+ onAdd: function (map) {
+ this._map = map;
+ var className = 'leaflet-control-geocoder',
+ container = this._container = L.DomUtil.create('div', className);
+
+ L.DomEvent.disableClickPropagation(container);
+
+ var form = this._form = L.DomUtil.create('form', className + '-form');
+
+ var input = this._input = document.createElement('input');
+ input.className = "span4"
+ input.type = "text";
+
+ var submit = document.createElement('button');
+ submit.className = "btn"
+ submit.type = "submit";
+ submit.innerHTML = this.options.text;
+
+ var div = document.createElement('div');
+ div.className = "input-append";
+ div.appendChild(input);
+ div.appendChild(submit);
+
+ form.appendChild(div);
+
+ L.DomEvent.addListener(form, 'submit', this._geocode, this);
+
+ if (this.options.collapsed) {
+ L.DomEvent.addListener(container, 'mouseover', this._expand, this);
+ L.DomEvent.addListener(container, 'mouseout', this._collapse, this);
+
+ var link = this._layersLink = L.DomUtil.create('a', className + '-toggle', container);
+ link.href = '#';
+ link.title = 'Nominatim Geocoder';
+
+ L.DomEvent.addListener(link, L.Browser.touch ? 'click' : 'focus', this._expand, this);
+
+ this._map.on('movestart', this._collapse, this);
+ } else {
+ this._expand();
+ }
+
+ container.appendChild(form);
+
+ return container;
+ },
+
+ _geocode : function (event) {
+ L.DomEvent.preventDefault(event);
+ //http://wiki.openstreetmap.org/wiki/Nominatim
+ this._callbackId = "_l_osmgeocoder_" + (this._callbackId++);
+ window[this._callbackId] = L.Util.bind(this.options.callback, this);
+
+
+ /* Set up params to send to Nominatim */
+ var params = {
+ // Defaults
+ q: this._input.value,
+ json_callback : this._callbackId,
+ format: 'json'
+ };
+
+ if (this.options.bounds && this.options.bounds != null) {
+ if( this.options.bounds instanceof L.LatLngBounds ) {
+ params.viewbox = this.options.bounds.toBBoxString();
+ params.bounded = 1;
+ }
+ else {
+ console.log('bounds must be of type L.LatLngBounds');
+ return;
+ }
+ }
+
+ if (this.options.email && this.options.email != null) {
+ if (typeof this.options.email == 'string') {
+ params.email = this.options.email;
+ }
+ else{
+ console.log('email must be a string');
+ }
+ }
+
+ var url = " http://nominatim.openstreetmap.org/search" + L.Util.getParamString(params),
+ script = document.createElement("script");
+
+
+
+
+ script.type = "text/javascript";
+ script.src = url;
+ script.id = this._callbackId;
+ document.getElementsByTagName("head")[0].appendChild(script);
+ },
+
+ _expand: function () {
+ L.DomUtil.addClass(this._container, 'leaflet-control-geocoder-expanded');
+ },
+
+ _collapse: function () {
+ this._container.className = this._container.className.replace(' leaflet-control-geocoder-expanded', '');
+ }
+});
diff --git a/vendor/img/geocoder.png b/vendor/img/geocoder.png
new file mode 100644
index 0000000..7778cd0
Binary files /dev/null and b/vendor/img/geocoder.png differ