]> git.openstreetmap.org Git - nominatim.git/blob - website/js/nominatim-ui.js
for search,details in format=HTML return geometry in geojson, not wkt. No longer...
[nominatim.git] / website / js / nominatim-ui.js
1 var map;
2 var last_click_latlng;
3
4 function parse_and_normalize_geojson_string(raw_string){
5     // normalize places the geometry into a featurecollection, similar to
6     // https://github.com/mapbox/geojson-normalize
7     var parsed_geojson = {
8         type: "FeatureCollection",
9         features: [
10             {
11                 type: "Feature",
12                 geometry: JSON.parse(raw_string),
13                 properties: {}
14             }
15         ]
16     };
17     return parsed_geojson;
18 }
19
20 jQuery(document).on('ready', function(){
21
22     if ( !$('#search-page,#reverse-page').length ){ return; }
23     
24     var is_reverse_search = !!( $('#reverse-page').length );
25
26     $('#q').focus();
27
28     map = new L.map('map', {
29                 attributionControl: (nominatim_map_init.tile_attribution && nominatim_map_init.tile_attribution.length),
30                 scrollWheelZoom:    !L.Browser.touch,
31                 touchZoom:          false
32             });
33
34     L.tileLayer(nominatim_map_init.tile_url, {
35         noWrap: true, // otherwise we end up with click coordinates like latitude -728
36         // moved to footer
37         attribution: (nominatim_map_init.tile_attribution || null ) //'&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
38     }).addTo(map);
39
40     map.setView([nominatim_map_init.lat, nominatim_map_init.lon], nominatim_map_init.zoom);
41
42     if ( is_reverse_search ){
43         // We don't need a marker, but an L.circle instance changes radius once you zoom in/out
44         var cm = L.circleMarker([nominatim_map_init.lat,nominatim_map_init.lon], { radius: 5, weight: 2, fillColor: '#ff7800', color: 'red', opacity: 0.75, clickable: false});
45         cm.addTo(map);
46     }
47
48     var MapPositionControl = L.Control.extend({
49             options: {
50                     position: 'topright'
51             },
52
53             onAdd: function (map) {
54                     var container = L.DomUtil.create('div', 'my-custom-control');
55
56                     $(container).text('show map bounds').addClass('leaflet-bar btn btn-sm btn-default').on('click', function(e){
57                         e.preventDefault();
58                         e.stopPropagation();
59                         $('#map-position').show();
60                         $(container).hide();
61                     });
62                     $('#map-position-close a').on('click', function(e){
63                         e.preventDefault();
64                         e.stopPropagation();
65                         $('#map-position').hide();
66                         $(container).show();
67                     });
68
69                     return container;
70             }
71     });
72
73     map.addControl(new MapPositionControl());
74
75
76     function display_map_position(mouse_lat_lng){
77
78         html_mouse = "mouse position " + (mouse_lat_lng ? [mouse_lat_lng.lat.toFixed(5), mouse_lat_lng.lng.toFixed(5)].join(',') : '-');
79         html_click = "last click: " + (last_click_latlng ? [last_click_latlng.lat.toFixed(5),last_click_latlng.lng.toFixed(5)].join(',') : '-');
80
81         html_center = 
82             "map center: " + 
83             map.getCenter().lat.toFixed(5) + ',' + map.getCenter().lng.toFixed(5) +
84             " <a target='_blank' href='" + map_link_to_osm() + "'>view on osm.org</a>";
85
86         html_zoom = "map zoom: " + map.getZoom();
87
88         html_viewbox = "viewbox: " + map_viewbox_as_string();
89
90         $('#map-position-inner').html([html_center,html_zoom,html_viewbox,html_click,html_mouse].join('<br/>'));
91
92         var reverse_params = {
93             lat: map.getCenter().lat.toFixed(5),
94             lon: map.getCenter().lng.toFixed(5),
95             zoom: map.getZoom(),
96             format: 'html'
97         }
98         $('#switch-to-reverse').attr('href', 'reverse.php?' + $.param(reverse_params));
99
100         $('input#use_viewbox').trigger('change');
101     }
102
103     function update_viewbox_field(){
104         // hidden HTML field
105         $('input[name=viewbox]').val( $('input#use_viewbox').prop('checked') ? map_viewbox_as_string() : '');
106     }
107
108     map.on('move', function(e) {
109         display_map_position();
110         update_viewbox_field();
111     });
112
113     map.on('mousemove', function(e) {
114         display_map_position(e.latlng);
115     });
116
117     map.on('click', function(e) {
118         last_click_latlng = e.latlng;
119         display_map_position();
120     });
121
122     map.on('load', function(e){
123         display_map_position();
124     });
125
126
127     $('input#use_viewbox').on('change', function(){
128         update_viewbox_field();
129     });
130
131
132
133     function map_viewbox_as_string() {
134         // since .toBBoxString() doesn't round numbers
135         return [
136             map.getBounds().getSouthWest().lng.toFixed(5), // left
137             map.getBounds().getNorthEast().lat.toFixed(5), // top
138             map.getBounds().getNorthEast().lng.toFixed(5), // right
139             map.getBounds().getSouthWest().lat.toFixed(5)  // bottom
140         ].join(',');
141     }
142     function map_link_to_osm(){
143         return "http://openstreetmap.org/#map=" + map.getZoom() + "/" + map.getCenter().lat + "/" + map.getCenter().lng;
144     }
145
146     function get_result_element(position){
147         return $('.result').eq(position);
148     }
149     function marker_for_result(result){
150         return L.marker([result.lat,result.lon], {riseOnHover:true,title:result.name });
151     }
152     function circle_for_result(result){
153         return L.circleMarker([result.lat,result.lon], { radius: 10, weight: 2, fillColor: '#ff7800', color: 'blue', opacity: 0.75, clickable: !is_reverse_search});
154     }
155
156     var layerGroup = new L.layerGroup().addTo(map);
157     function highlight_result(position, bool_focus){
158         var result = nominatim_results[position];
159         if (!result){ return }
160         var result_el = get_result_element(position);
161
162         $('.result').removeClass('highlight');
163         result_el.addClass('highlight');
164
165         layerGroup.clearLayers();
166
167         if (result.lat){
168             var circle = circle_for_result(result);
169             circle.on('click', function(){
170                 highlight_result(position);
171             });
172             layerGroup.addLayer(circle);            
173         }
174         if (result.aBoundingBox){
175
176             var bounds = [[result.aBoundingBox[0]*1,result.aBoundingBox[2]*1], [result.aBoundingBox[1]*1,result.aBoundingBox[3]*1]];
177             map.fitBounds(bounds);
178
179             if (result.asgeojson && result.asgeojson.match(/(Polygon)|(Line)/) ){
180
181                 var geojson_layer = L.geoJson(
182                     parse_and_normalize_geojson_string(result.asgeojson),
183                     {
184                         // http://leafletjs.com/reference-1.0.3.html#path-option
185                         style: function(feature) {
186                             return { interactive: false, color: 'blue' }; 
187                         }
188                     }
189                 );
190                 layerGroup.addLayer(geojson_layer);
191             }
192             else {
193                 // var layer = L.rectangle(bounds, {color: "#ff7800", weight: 1} );
194                 // layerGroup.addLayer(layer);
195             }
196         }
197         else {
198             if ( is_reverse_search ){
199                 // make sure the search coordinates are in the map view as well
200                 map.fitBounds([[result.lat,result.lon], [nominatim_map_init.lat,nominatim_map_init.lon]], {padding: [50,50], maxZoom: map.getZoom()});
201
202                 // better, but causes a leaflet warning
203                 // map.panInsideBounds([[result.lat,result.lon], [nominatim_map_init.lat,nominatim_map_init.lon]], {animate: false});
204             }
205             else {
206                 map.panTo([result.lat,result.lon], result.zoom || nominatim_map_init.zoom);
207             }
208         }
209
210         // var crosshairIcon = L.icon({
211         //  iconUrl:     'images/crosshair.png',
212         //  iconSize:    [12, 12],
213         //  iconAnchor:  [6, 6],
214         // });
215         // var crossMarker = new L.Marker([result.lat,result.lon], { icon: crosshairIcon, clickable: false});
216         // layerGroup.addLayer(crossMarker);
217
218
219
220         if (bool_focus){
221             $('#map').focus();
222         }
223     }
224
225
226     $('.result').on('click', function(e){
227         highlight_result($(this).data('position'), true);
228     });
229
230     if ( is_reverse_search ){
231         map.on('click', function(e){
232             $('form input[name=lat]').val( e.latlng.lat);
233             $('form input[name=lon]').val( e.latlng.lng);
234             $('form').submit();
235         });
236
237         $('#switch-coords').on('click', function(e){
238             var lat = $('form input[name=lat]').val();
239             var lon = $('form input[name=lon]').val();
240             $('form input[name=lat]').val(lon);
241             $('form input[name=lon]').val(lat);
242             $('form').submit();
243         });
244     }
245
246     highlight_result(0, false);
247
248
249 });
250
251
252 jQuery(document).on('ready', function(){
253
254     if ( !$('#details-page').length ){ return; }
255
256
257         map = new L.map('map', {
258                     // center: [nominatim_map_init.lat, nominatim_map_init.lon],
259                     // zoom:   nominatim_map_init.zoom,
260                     attributionControl: (nominatim_map_init.tile_attribution && nominatim_map_init.tile_attribution.length),
261                     scrollWheelZoom:    false,
262                     touchZoom:          false,
263                 });
264
265
266         L.tileLayer(nominatim_map_init.tile_url, {
267             // moved to footer
268             attribution: (nominatim_map_init.tile_attribution || null ) //'&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
269         }).addTo(map);
270
271
272         var layerGroup = new L.layerGroup().addTo(map);
273
274         var circle = L.circleMarker([nominatim_result.lat,nominatim_result.lon], { radius: 10, weight: 2, fillColor: '#ff7800', color: 'blue', opacity: 0.75});
275         map.addLayer(circle);
276
277         if ( nominatim_result.asgeojson ){
278
279             var geojson_layer = L.geoJson(
280                 parse_and_normalize_geojson_string(nominatim_result.asgeojson),
281                 {
282                     // http://leafletjs.com/reference-1.0.3.html#path-option
283                     style: function(feature) {
284                         return { interactive: false, color: 'blue' }; 
285                     }
286                 }
287             );
288             map.addLayer(geojson_layer);
289             map.fitBounds(geojson_layer.getBounds());
290         } else {
291             map.setView([nominatim_result.lat,nominatim_result.lon],10);
292         }
293
294
295
296 });
297