X-Git-Url: https://git.openstreetmap.org./nominatim-ui.git/blobdiff_plain/7fb117a636add8eeb8b574286e1ef0a8a2209c6d..e0d087f4a2b5fbc758de432f8932de296279a82f:/src/assets/js/searchpage.js?ds=inline diff --git a/src/assets/js/searchpage.js b/src/assets/js/searchpage.js index e0754dd..be9c20a 100755 --- a/src/assets/js/searchpage.js +++ b/src/assets/js/searchpage.js @@ -1,345 +1,454 @@ -/********************************************************* -* FORWARD/REVERSE SEARCH PAGE -*********************************************************/ - - -function display_map_position(mouse_lat_lng){ - - html_mouse = "mouse position " + (mouse_lat_lng ? [mouse_lat_lng.lat.toFixed(5), mouse_lat_lng.lng.toFixed(5)].join(',') : '-'); - html_click = "last click: " + (last_click_latlng ? [last_click_latlng.lat.toFixed(5),last_click_latlng.lng.toFixed(5)].join(',') : '-'); - - html_center = - "map center: " + - map.getCenter().lat.toFixed(5) + ',' + map.getCenter().lng.toFixed(5) + - " view on osm.org"; - - html_zoom = "map zoom: " + map.getZoom(); - - html_viewbox = "viewbox: " + map_viewbox_as_string(); - - $('#map-position-inner').html([html_center,html_zoom,html_viewbox,html_click,html_mouse].join('
')); - - var reverse_params = { - // lat: map.getCenter().lat.toFixed(5), - // lon: map.getCenter().lng.toFixed(5), - // zoom: 2, - // format: 'html' - } - $('#switch-to-reverse').attr('href', 'reverse.html?' + $.param(reverse_params)); - - $('input#use_viewbox').trigger('change'); +// ********************************************************* +// FORWARD/REVERSE SEARCH PAGE +// ********************************************************* + + +function display_map_position(mouse_lat_lng) { + // + if (mouse_lat_lng) { + mouse_lat_lng = map.wrapLatLng(mouse_lat_lng); + } + + var html_mouse = 'mouse position: -'; + if (mouse_lat_lng) { + html_mouse = 'mouse position: ' + + [mouse_lat_lng.lat.toFixed(5), mouse_lat_lng.lng.toFixed(5)].join(','); + } + var html_click = 'last click: -'; + if (last_click_latlng) { + html_click = 'last click: ' + + [last_click_latlng.lat.toFixed(5), last_click_latlng.lng.toFixed(5)].join(','); + } + + var html_center = 'map center: ' + + map.getCenter().lat.toFixed(5) + ',' + map.getCenter().lng.toFixed(5) + + ' view on osm.org'; + + var html_zoom = 'map zoom: ' + map.getZoom(); + var html_viewbox = 'viewbox: ' + map_viewbox_as_string(); + + $('#map-position-inner').html([ + html_center, + html_zoom, + html_viewbox, + html_click, + html_mouse + ].join('
')); + + var center_lat_lng = map.wrapLatLng(map.getCenter()); + var reverse_params = { + lat: center_lat_lng.lat.toFixed(5), + lon: center_lat_lng.lng.toFixed(5) + // zoom: 2, + // format: 'html' + }; + $('#switch-to-reverse').attr('href', 'reverse.html?' + $.param(reverse_params)); + + $('input#use_viewbox').trigger('change'); } - - - -function init_map_on_search_page(is_reverse_search, nominatim_results, request_lat, request_lon, init_zoom) { - - map = new L.map('map', { - // center: [nominatim_map_init.lat, nominatim_map_init.lon], - // zoom: nominatim_map_init.zoom, - attributionControl: (get_config_value('Map_Tile_Attribution') && get_config_value('Map_Tile_Attribution').length), - scrollWheelZoom: true, // !L.Browser.touch, - touchZoom: false, - }); - - - L.tileLayer(get_config_value('Map_Tile_URL'), { - noWrap: true, // otherwise we end up with click coordinates like latitude -728 - // moved to footer - attribution: (get_config_value('Map_Tile_Attribution') || null ) //'© OpenStreetMap contributors' - }).addTo(map); - - // console.log(Nominatim_Config); - - map.setView([request_lat, request_lon], init_zoom); - - var osm2 = new L.TileLayer(get_config_value('Map_Tile_URL'), {minZoom: 0, maxZoom: 13, attribution: (get_config_value('Map_Tile_Attribution') || null )}); - var miniMap = new L.Control.MiniMap(osm2, {toggleDisplay: true}).addTo(map); - - if (is_reverse_search) { - // We don't need a marker, but an L.circle instance changes radius once you zoom in/out - var cm = L.circleMarker([request_lat, request_lon], { radius: 5, weight: 2, fillColor: '#ff7800', color: 'red', opacity: 0.75, clickable: false}); - cm.addTo(map); - } - - var MapPositionControl = L.Control.extend({ - options: { - position: 'topright' - }, - onAdd: function (map) { - var container = L.DomUtil.create('div', 'my-custom-control'); - - $(container).text('show map bounds').addClass('leaflet-bar btn btn-sm btn-default').on('click', function(e){ - e.preventDefault(); - e.stopPropagation(); - $('#map-position').show(); - $(container).hide(); - }); - $('#map-position-close a').on('click', function(e){ - e.preventDefault(); - e.stopPropagation(); - $('#map-position').hide(); - $(container).show(); - }); - - return container; - } - }); - - map.addControl(new MapPositionControl()); - - - - - - function update_viewbox_field(){ - // hidden HTML field - $('input[name=viewbox]').val( $('input#use_viewbox').prop('checked') ? map_viewbox_as_string() : ''); +function init_map_on_search_page(is_reverse_search, nominatim_results, request_lat, + request_lon, init_zoom) { + + var attribution = get_config_value('Map_Tile_Attribution') || null; + map = new L.map('map', { + // center: [nominatim_map_init.lat, nominatim_map_init.lon], + // zoom: nominatim_map_init.zoom, + attributionControl: (attribution && attribution.length), + scrollWheelZoom: true, // !L.Browser.touch, + touchZoom: false + }); + + + L.tileLayer(get_config_value('Map_Tile_URL'), { + // moved to footer + // '© OpenStreetMap contributors' + attribution: attribution + }).addTo(map); + + // console.log(Nominatim_Config); + + map.setView([request_lat, request_lon], init_zoom); + + var osm2 = new L.TileLayer(get_config_value('Map_Tile_URL'), { + minZoom: 0, + maxZoom: 13, + attribution: attribution + }); + new L.Control.MiniMap(osm2, { toggleDisplay: true }).addTo(map); + + if (is_reverse_search) { + // We don't need a marker, but an L.circle instance changes radius once you zoom in/out + var cm = L.circleMarker( + [request_lat, request_lon], + { + radius: 5, + weight: 2, + fillColor: '#ff7800', + color: 'red', + opacity: 0.75, + zIndexOffset: 100, + clickable: false + } + ); + cm.addTo(map); + } else { + var search_params = new URLSearchParams(window.location.search); + var viewbox = search_params.get('viewbox'); + if (viewbox) { + var coords = viewbox.split(','); // ,,, + var bounds = L.latLngBounds([coords[1], coords[0]], [coords[3], coords[2]]); + L.rectangle(bounds, { + color: '#69d53e', + weight: 3, + dashArray: '5 5', + opacity: 0.8, + fill: false + }).addTo(map); } - - map.on('move', function(e) { - display_map_position(); - update_viewbox_field(); - }); - - map.on('mousemove', function(e) { - display_map_position(e.latlng); - }); - - map.on('click', function(e) { - last_click_latlng = e.latlng; - display_map_position(); - }); - - map.on('load', function(e){ - display_map_position(); - }); - - - $('input#use_viewbox').on('change', function(){ - update_viewbox_field(); - }); - - - - - function get_result_element(position){ - return $('.result').eq(position); - } - function marker_for_result(result){ - return L.marker([result.lat,result.lon], {riseOnHover:true,title:result.name }); + } + + var MapPositionControl = L.Control.extend({ + options: { + position: 'topright' + }, + onAdd: function (/* map */) { + var container = L.DomUtil.create('div', 'my-custom-control'); + + $(container).text('show map bounds') + .addClass('leaflet-bar btn btn-sm btn-outline-secondary') + .on('click', function (e) { + e.preventDefault(); + e.stopPropagation(); + $('#map-position').show(); + $(container).hide(); + }); + $('#map-position-close a').on('click', function (e) { + e.preventDefault(); + e.stopPropagation(); + $('#map-position').hide(); + $(container).show(); + }); + + return container; } - function circle_for_result(result){ - return L.circleMarker([result.lat,result.lon], { radius: 10, weight: 2, fillColor: '#ff7800', color: 'blue', opacity: 0.75, clickable: !is_reverse_search}); + }); + + map.addControl(new MapPositionControl()); + + + + + + function update_viewbox_field() { + // hidden HTML field + $('input[name=viewbox]') + .val($('input#use_viewbox') + .prop('checked') ? map_viewbox_as_string() : ''); + } + + map.on('move', function () { + display_map_position(); + update_viewbox_field(); + }); + + map.on('mousemove', function (e) { + display_map_position(e.latlng); + }); + + map.on('click', function (e) { + last_click_latlng = e.latlng; + display_map_position(); + }); + + map.on('load', function () { + display_map_position(); + }); + + $('input#use_viewbox').on('change', function () { + update_viewbox_field(); + }); + + function get_result_element(position) { + return $('.result').eq(position); + } + // function marker_for_result(result) { + // return L.marker([result.lat, result.lon], { riseOnHover: true, title: result.name }); + // } + function circle_for_result(result) { + var cm_style = { + radius: 10, + weight: 2, + fillColor: '#ff7800', + color: 'blue', + opacity: 0.75, + clickable: !is_reverse_search + }; + return L.circleMarker([result.lat, result.lon], cm_style); + } + + var layerGroup = (new L.layerGroup()).addTo(map); + + function highlight_result(position, bool_focus) { + var result = nominatim_results[position]; + if (!result) { return; } + var result_el = get_result_element(position); + + $('.result').removeClass('highlight'); + result_el.addClass('highlight'); + + layerGroup.clearLayers(); + + if (result.lat) { + var circle = circle_for_result(result); + circle.on('click', function () { + highlight_result(position); + }); + layerGroup.addLayer(circle); } - var layerGroup = new L.layerGroup().addTo(map); - function highlight_result(position, bool_focus){ - var result = nominatim_results[position]; - if (!result){ return } - var result_el = get_result_element(position); - - $('.result').removeClass('highlight'); - result_el.addClass('highlight'); - - layerGroup.clearLayers(); - - if (result.lat){ - var circle = circle_for_result(result); - circle.on('click', function(){ - highlight_result(position); - }); - layerGroup.addLayer(circle); - } - if (result.aBoundingBox){ - - var bounds = [[result.aBoundingBox[0]*1,result.aBoundingBox[2]*1], [result.aBoundingBox[1]*1,result.aBoundingBox[3]*1]]; - map.fitBounds(bounds); - - if (result.asgeojson && result.asgeojson.match(/(Polygon)|(Line)/) ){ - - var geojson_layer = L.geoJson( - parse_and_normalize_geojson_string(result.asgeojson), - { - // http://leafletjs.com/reference-1.0.3.html#path-option - style: function(feature) { - return { interactive: false, color: 'blue' }; - } - } - ); - layerGroup.addLayer(geojson_layer); + if (result.boundingbox) { + var bbox = [ + [result.boundingbox[0] * 1, result.boundingbox[2] * 1], + [result.boundingbox[1] * 1, result.boundingbox[3] * 1] + ]; + map.fitBounds(bbox); + + if (result.geojson && result.geojson.type.match(/(Polygon)|(Line)/)) { + // + var geojson_layer = L.geoJson( + parse_and_normalize_geojson_string(result.geojson), + { + // https://leafletjs.com/reference-1.0.3.html#path-option + style: function (/* feature */) { + return { interactive: false, color: 'blue' }; } - // else { - // var layer = L.rectangle(bounds, {color: "#ff7800", weight: 1} ); - // layerGroup.addLayer(layer); - // } - } - else { - var result_coord = L.latLng(result.lat, result.lon); - if ( result_coord ){ - if ( is_reverse_search ){ - // console.dir([result_coord, [request_lat, request_lon]]); - // make sure the search coordinates are in the map view as well - map.fitBounds([result_coord, [request_lat, request_lon]], {padding: [50,50], maxZoom: map.getZoom()}); - - // better, but causes a leaflet warning - // map.panInsideBounds([[result.lat,result.lon], [nominatim_map_init.lat,nominatim_map_init.lon]], {animate: false}); - } - else { - map.panTo(result_coord, result.zoom || get_config_value('Map_Default_Zoom')); - } + } + ); + layerGroup.addLayer(geojson_layer); + } + // else { + // var layer = L.rectangle(bounds, {color: "#ff7800", weight: 1} ); + // layerGroup.addLayer(layer); + // } + } else { + var result_coord = L.latLng(result.lat, result.lon); + if (result_coord) { + if (is_reverse_search) { + // console.dir([result_coord, [request_lat, request_lon]]); + // make sure the search coordinates are in the map view as well + map.fitBounds( + [result_coord, [request_lat, request_lon]], + { + padding: [50, 50], + maxZoom: map.getZoom() } + ); + } else { + map.panTo(result_coord, result.zoom || get_config_value('Map_Default_Zoom')); } - if (bool_focus){ - $('#map').focus(); - } + } } - - - $('.result').on('click', function(e){ - highlight_result($(this).data('position'), true); - }); - - if ( is_reverse_search ){ - map.on('click', function(e){ - $('form input[name=lat]').val( e.latlng.lat); - $('form input[name=lon]').val( e.latlng.lng); - $('form').submit(); - }); - - $('#switch-coords').on('click', function(e){ - e.preventDefault(); - e.stopPropagation(); - var lat = $('form input[name=lat]').val(); - var lon = $('form input[name=lon]').val(); - $('form input[name=lat]').val(lon); - $('form input[name=lon]').val(lat); - $('form').submit(); - }); + if (bool_focus) { + $('#map').focus(); } + } - highlight_result(0, false); - - // common mistake is to copy&paste latitude and longitude into the 'lat' search box - $('form input[name=lat]').on('change', function(){ - var coords = $(this).val().split(','); - if (coords.length == 2) { - $(this).val(L.Util.trim(coords[0])); - $(this).siblings('input[name=lon]').val(L.Util.trim(coords[1])); - } - }); -}; + $('.result').on('click', function () { + highlight_result($(this).data('position'), true); + }); + if (is_reverse_search) { + map.on('click', function (e) { + $('form input[name=lat]').val(e.latlng.lat); + $('form input[name=lon]').val(e.latlng.wrap().lng); + $('form').submit(); + }); + $('#switch-coords').on('click', function (e) { + e.preventDefault(); + e.stopPropagation(); + var lat = $('form input[name=lat]').val(); + var lon = $('form input[name=lon]').val(); + $('form input[name=lat]').val(lon); + $('form input[name=lon]').val(lat); + $('form').submit(); + }); + } + highlight_result(0, false); + // common mistake is to copy&paste latitude and longitude into the 'lat' search box + $('form input[name=lat]').on('change', function () { + var coords_split = $(this).val().split(','); + if (coords_split.length === 2) { + $(this).val(L.Util.trim(coords_split[0])); + $(this).siblings('input[name=lon]').val(L.Util.trim(coords_split[1])); + } + }); +} -jQuery(document).ready(function(){ - - if ( !$('#search-page,#reverse-page').length ){ return; } - - var is_reverse_search = !!( $('#reverse-page').length ); - var endpoint = is_reverse_search ? 'reverse' : 'search'; - - - var search_params = new URLSearchParams(location.search); - - // return view('search', [ - // 'sQuery' => $sQuery, - // 'bAsText' => '', - // 'sViewBox' => '', - // 'aSearchResults' => $aSearchResults, - // 'sMoreURL' => 'example.com', - // 'sDataDate' => $this->fetch_status_date(), - // 'sApiURL' => $url - // ]); - - if (is_reverse_search) { - var api_request_params = { - // lat: typeof(search_params.get('lat') !== 'undefined') ? search_params.get('lat') : get_config_value('Map_Default_Lat'), - // lon: typeof(search_params.get('lon') !== 'undefined') ? search_params.get('lon') : get_config_value('Map_Default_Lon'), - lat: search_params.get('lat'), - lon: search_params.get('lon'), - zoom: (search_params.get('zoom') !== '' ? search_params.get('zoom') : get_config_value('Map_Default_Zoom')), - format: 'jsonv2' - } +function search_page_load() { - var context = { - // aPlace: aPlace, - fLat: api_request_params.lat, - fLon: api_request_params.lon, - iZoom: (search_params.get('zoom') !== '' ? api_request_params.zoom : undefined) - }; + var is_reverse_search = window.location.pathname.match(/reverse/); + var search_params = new URLSearchParams(window.location.search); - if (api_request_params.lat && api_request_params.lon) { + // return view('search', [ + // 'sQuery' => $sQuery, + // 'bAsText' => '', + // 'sViewBox' => '', + // 'aSearchResults' => $aSearchResults, + // 'sMoreURL' => 'example.com', + // 'sDataDate' => $this->fetch_status_date(), + // 'sApiURL' => $url + // ]); - fetch_from_api('reverse', api_request_params, function(aPlace){ + var api_request_params; + var context; - if (aPlace.error) { - aPlace = null; - } + if (is_reverse_search) { + api_request_params = { + lat: search_params.get('lat'), + lon: search_params.get('lon'), + zoom: (search_params.get('zoom') > 1 + ? search_params.get('zoom') + : get_config_value('Reverse_Default_Search_Zoom')), + format: 'jsonv2' + }; - context.aPlace = aPlace; + context = { + // aPlace: aPlace, + fLat: api_request_params.lat, + fLon: api_request_params.lon, + iZoom: (search_params.get('zoom') > 1 + ? api_request_params.zoom + : get_config_value('Reverse_Default_Search_Zoom')) + }; - render_template($('main'), 'reversepage-template', context); + update_html_title(); + if (api_request_params.lat && api_request_params.lon) { - init_map_on_search_page(is_reverse_search, [aPlace], api_request_params.lat, api_request_params.lon, api_request_params.zoom); + fetch_from_api('reverse', api_request_params, function (aPlace) { - update_data_date(); - }); - } else { - render_template($('main'), 'reversepage-template', context); - - init_map_on_search_page(is_reverse_search, [], get_config_value('Map_Default_Lat'), get_config_value('Map_Default_Lon'), get_config_value('Map_Default_Zoom')); + if (aPlace.error) { + aPlace = null; } - } else { - var api_request_params = { - q: search_params.get('q'), - polygon_geojson: search_params.get('polygon_geojson') ? 1 : 0, - polygon: search_params.get('polygon'), - viewbox: search_params.get('viewbox'), - format: 'jsonv2' - }; + context.aPlace = aPlace; - var context = { - // aSearchResults: aResults, - sQuery: api_request_params.q, - sViewBox: '', - env: Nominatim_Config, - sMoreURL: '' - }; + render_template($('main'), 'reversepage-template', context); + update_html_title('Reverse result for ' + + api_request_params.lat + + ',' + + api_request_params.lon); - if (api_request_params.q) { + init_map_on_search_page( + is_reverse_search, + [aPlace], + api_request_params.lat, + api_request_params.lon, + api_request_params.zoom + ); - fetch_from_api('search', api_request_params, function(aResults){ + update_data_date(); + }); + } else { + render_template($('main'), 'reversepage-template', context); + + init_map_on_search_page( + is_reverse_search, + [], + get_config_value('Map_Default_Lat'), + get_config_value('Map_Default_Lon'), + get_config_value('Map_Default_Zoom') + ); + } - context.aSearchResults = aResults; + } else { + api_request_params = { + q: search_params.get('q'), + street: search_params.get('street'), + city: search_params.get('city'), + county: search_params.get('county'), + state: search_params.get('state'), + country: search_params.get('country'), + postalcode: search_params.get('postalcode'), + polygon_geojson: get_config_value('Search_AreaPolygons', false) ? 1 : 0, + viewbox: search_params.get('viewbox'), + exclude_place_ids: search_params.get('exclude_place_ids'), + format: 'jsonv2' + }; + + context = { + sQuery: api_request_params.q, + sViewBox: search_params.get('viewbox'), + env: {} + }; + + if (api_request_params.street || api_request_params.city || api_request_params.county + || api_request_params.state || api_request_params.country || api_request_params.postalcode) { + context.hStructured = { + street: api_request_params.street, + city: api_request_params.city, + county: api_request_params.county, + state: api_request_params.state, + country: api_request_params.country, + postalcode: api_request_params.postalcode + }; + } - render_template($('main'), 'searchpage-template', context); + if (api_request_params.q || context.hStructured) { - init_map_on_search_page(is_reverse_search, aResults, get_config_value('Map_Default_Lat'), get_config_value('Map_Default_Lon'), get_config_value('Map_Default_Zoom')); + fetch_from_api('search', api_request_params, function (aResults) { - $('#q').focus(); + context.aSearchResults = aResults; - update_data_date(); - }); - } else { - render_template($('main'), 'searchpage-template', context); + if (aResults.length >= 10) { + var aExcludePlaceIds = []; + if (search_params.has('exclude_place_ids')) { + aExcludePlaceIds.search_params.get('exclude_place_ids').split(','); + } + for (var i = 0; i < aResults.length; i += 1) { + aExcludePlaceIds.push(aResults[i].place_id); + } - init_map_on_search_page(is_reverse_search, [], get_config_value('Map_Default_Lat'), get_config_value('Map_Default_Lon'), get_config_value('Map_Default_Zoom')); + var parsed_url = new URLSearchParams(window.location.search); + parsed_url.set('exclude_place_ids', aExcludePlaceIds.join(',')); + context.sMoreURL = '?' + parsed_url.toString(); } + render_template($('main'), 'searchpage-template', context); + update_html_title('Result for ' + api_request_params.q); - } -}); + init_map_on_search_page( + is_reverse_search, + aResults, + get_config_value('Map_Default_Lat'), + get_config_value('Map_Default_Lon'), + get_config_value('Map_Default_Zoom') + ); + $('#q').focus(); + update_data_date(); + }); + } else { + render_template($('main'), 'searchpage-template', context); + + init_map_on_search_page( + is_reverse_search, + [], + get_config_value('Map_Default_Lat'), + get_config_value('Map_Default_Lon'), + get_config_value('Map_Default_Zoom') + ); + } + } +}