]> git.openstreetmap.org Git - nominatim-ui.git/blob - src/components/SearchSectionReverse.svelte
70174b697ed9f1ba552a582d1079ec518806cb07
[nominatim-ui.git] / src / components / SearchSectionReverse.svelte
1 <script>
2   import UrlSubmitForm from '../components/UrlSubmitForm.svelte';
3
4   import { zoomLevels } from '../lib/helpers.js';
5   import { map_store, refresh_page } from '../lib/stores.js';
6
7   export let lat = '';
8   export let lon = '';
9   export let zoom = '';
10   export let api_request_params = {};
11
12   function gotoCoordinates(newlat, newlon, newzoom) {
13     if (newlat === null || newlon === null) return;
14
15     let params = new URLSearchParams();
16     params.set('lat', newlat);
17     params.set('lon', newlon);
18     params.set('zoom', newzoom || zoom);
19     refresh_page('reverse', params);
20   }
21
22   map_store.subscribe(map => {
23     if (map) {
24       map.on('click', (e) => {
25         let coords = e.latlng.wrap();
26         gotoCoordinates(coords.lat.toFixed(5), coords.lng.toFixed(5));
27       });
28     }
29   });
30
31   // common mistake is to copy&paste latitude and longitude into the 'lat' search box
32   function maybeSplitLatitude(e) {
33     var coords_split = e.target.value.split(/,|%2C/);
34     if (coords_split.length === 2) {
35       document.querySelector('input[name=lat]').value = L.Util.trim(coords_split[0]);
36       document.querySelector('input[name=lon]').value = L.Util.trim(coords_split[1]);
37     }
38   }
39
40   function set_api_param(e) {
41     document.querySelector('input[name=' + e.target.dataset.apiParam + ']').value = e.target.value;
42   }
43 </script>
44
45 <UrlSubmitForm page="reverse">
46   <div class="col-auto">
47     <label for="reverse-lat">lat</label>
48   </div>
49   <div class="col-auto">
50     <input id="reverse-lat"
51            name="lat"
52            type="text"
53            class="form-control form-control-sm d-inline"
54            placeholder="latitude"
55            pattern="^-?\d+(\.\d+)?$"
56            bind:value={lat}
57            on:change={maybeSplitLatitude} />
58   </div>
59   <div class="col-auto">
60     <button id="switch-coords"
61        on:click|preventDefault|stopPropagation={() => gotoCoordinates(lon, lat)}
62        class="btn btn-outline-secondary btn-sm"
63        title="switch lat and lon">&lt;&gt;</button>
64   </div>
65   <div class="col-auto">
66     <label for="reverse-lon">lon</label>
67   </div>
68   <div class="col-auto">
69     <input id="reverse-lon"
70            name="lon"
71            type="text"
72            class="form-control form-control-sm"
73            placeholder="longitude"
74            pattern="^-?\d+(\.\d+)?$"
75            bind:value={lon} />
76   </div>
77   <div class="col-auto">
78     <label for="reverse-zoom">max zoom</label>
79   </div>
80   <div class="col-auto">
81     <select id="reverse-zoom" name="zoom" class="form-select form-select-sm" bind:value={zoom}>
82       <option value="">---</option>
83       {#each zoomLevels() as zoomTitle, i}
84         <option value="{i}">{i} - {zoomTitle}</option>
85       {/each}
86     </select>
87   </div>
88   <input type="hidden"
89          name="layer" value="{api_request_params.layer || ''}" />
90   <div class="col-auto">
91     <button type="submit" class="btn btn-primary btn-sm mx-1">Search</button>
92   </div>
93 </UrlSubmitForm>
94
95 <!-- Additional options -->
96 <details id="searchAdvancedOptions" class="mt-2">
97   <summary><small>Advanced options</small></summary>
98   <ul>
99     <li>
100       <label for="option_layer">Layer</label>
101       <input id="option_layer" name="layer" placeholder="e.g. address,poi,railway,natural,manmade"
102         value="{api_request_params.layer || ''}"
103         data-api-param="layer" on:change={set_api_param}
104         class="form-control form-control-sm d-inline w-auto api-param-setting">
105     </li>
106   </ul>
107 </details>
108
109 <style>
110   label {
111     font-size: 0.9rem;
112     margin-top: 0.3rem;
113   }
114
115   #switch-coords {
116     font-size: 0.6rem;
117     font-weight: bold;
118     cursor: pointer;
119     padding: 2px;
120     margin: 5px;
121   }
122
123   #searchAdvancedOptions ul {
124     list-style-type: none;
125     padding: 0;
126     font-size: 0.85rem;
127   }
128
129   #searchAdvancedOptions li {
130     display: inline-block;
131     padding: 4px 10px;
132     border-radius: 5px;
133     border: 1px dotted #ccc;
134     margin-right: 1em;
135   }
136
137   #searchAdvancedOptions label {
138     margin-right: 0.5em;
139   }
140
141   @media (max-width: 850px) {
142     #reverse-lon, #reverse-lat, #reverse-zoom {
143       width: 8em;
144     }
145   }
146 </style>