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