]> git.openstreetmap.org Git - nominatim-ui.git/blob - src/components/SearchSection.svelte
Rebundle latest version
[nominatim-ui.git] / src / components / SearchSection.svelte
1 <script>
2   import UrlSubmitForm from '../components/UrlSubmitForm.svelte';
3
4   import { map_store } from '../lib/stores.js';
5   import { get } from 'svelte/store';
6
7   export let bStructuredSearch = false;
8   export let api_request_params = {};
9   let sViewBox;
10   // lat,lon are later set in update_reverse_link()
11   let lat; // eslint-disable-line no-unused-vars
12   let lon; // eslint-disable-line no-unused-vars
13
14   function map_viewbox_as_string(map) {
15     var bounds = map.getBounds();
16     var west = bounds.getWest();
17     var east = bounds.getEast();
18
19     if ((east - west) >= 360) { // covers more than whole planet
20       west = map.getCenter().lng - 179.999;
21       east = map.getCenter().lng + 179.999;
22     }
23     east = L.latLng(77, east).wrap().lng;
24     west = L.latLng(77, west).wrap().lng;
25
26     return [
27       west.toFixed(5), // left
28       bounds.getNorth().toFixed(5), // top
29       east.toFixed(5), // right
30       bounds.getSouth().toFixed(5) // bottom
31     ].join(',');
32   }
33
34   function set_viewbox(map) {
35     let use_viewbox = document.getElementById('use_viewbox');
36     if (use_viewbox && use_viewbox.checked) {
37       sViewBox = map_viewbox_as_string(map);
38     } else {
39       sViewBox = '';
40     }
41   }
42
43   function update_reverse_link(map) {
44     let center_lat_lng = map.wrapLatLng(map.getCenter());
45     lat = center_lat_lng.lat.toFixed(5);
46     lon = center_lat_lng.lng.toFixed(5);
47   }
48
49   map_store.subscribe(map => {
50     if (!map) { return; }
51
52     map.on('move', function () {
53       set_viewbox(map);
54       update_reverse_link(map);
55     });
56
57     map.on('load', function () {
58       set_viewbox(map);
59       update_reverse_link(map);
60     });
61   });
62
63   function reset_viewbox() {
64     let map = get(map_store);
65     if (map) { set_viewbox(map); }
66   }
67
68   function set_bounded(e) {
69     document.querySelector('input[name=bounded]').value = e.target.checked ? 1 : '';
70   }
71
72   function set_dedupe(e) {
73     document.querySelector('input[name=dedupe]').value = e.target.checked ? 1 : 0;
74   }
75
76   function set_api_param(e) {
77     document.querySelector('input[name=' + e.target.dataset.apiParam + ']').value = e.target.value;
78   }
79 </script>
80
81 <ul class="nav nav-tabs">
82   <li class="nav-item">
83     <a class="nav-link" class:active={!bStructuredSearch} data-bs-toggle="tab" href="#simple">
84       Simple
85     </a>
86   </li>
87   <li class="nav-item">
88     <a class="nav-link" class:active={bStructuredSearch} data-bs-toggle="tab" href="#structured">
89       Structured
90     </a>
91   </li>
92 </ul>
93
94 <div class="tab-content py-2">
95   <div class="tab-pane" class:active={!bStructuredSearch} id="simple" role="tabpanel">
96     <UrlSubmitForm page="search">
97       <div class="col-auto">
98         <input id="q"
99                name="q"
100                type="text"
101                class="form-control form-control-sm"
102                placeholder="Search"
103                value="{api_request_params.q || ''}" />
104       </div>
105       <div class="col-auto">
106         <button type="submit" class="btn btn-primary btn-sm mx-1">Search</button>
107         <input type="hidden"
108                name="viewbox" value="{sViewBox || ''}" />
109         <input type="hidden"
110                name="dedupe" value="{api_request_params.dedupe === 0 ? 0 : 1}" />
111         <input type="hidden"
112                name="bounded" value="{api_request_params.bounded ? 1 : ''}" />
113         <input type="hidden"
114                name="accept-language"value="{api_request_params['accept-language'] || ''}" />
115         <input type="hidden"
116                name="countrycodes" value="{api_request_params.countrycodes || ''}"
117                                    pattern="^[a-zA-Z]{'{2}'}(,[a-zA-Z]{'{2}'})*$" />
118         <input type="hidden"
119                name="limit" value="{api_request_params.limit || ''}" />
120         <input type="hidden"
121                name="polygon_threshold" value="{api_request_params.polygon_threshold || ''}" />
122         <input type="hidden"
123                name="layer" value="{api_request_params.layer || ''}" />
124       </div>
125     </UrlSubmitForm>
126   </div>
127   <div class="tab-pane" class:active={bStructuredSearch} id="structured" role="tabpanel">
128     <UrlSubmitForm page="search">
129       <div class="col-auto">
130         <input name="street" type="text" class="form-control form-control-sm me-1"
131                placeholder="House number/Street"
132                value="{api_request_params.street || ''}" />
133       </div>
134       <div class="col-auto">
135         <input name="city" type="text" class="form-control form-control-sm me-1"
136                placeholder="City"
137                value="{api_request_params.city || ''}" />
138       </div>
139       <div class="col-auto">
140         <input id="county" name="county" type="text" class="form-control form-control-sm me-1"
141                placeholder="County"
142                value="{api_request_params.county || ''}" />
143       </div>
144       <div class="col-auto">
145         <input name="state" type="text" class="form-control form-control-sm me-1"
146                placeholder="State"
147                value="{api_request_params.state || ''}" />
148       </div>
149       <div class="col-auto">
150         <input name="country" type="text" class="form-control form-control-sm me-1"
151                placeholder="Country"
152                value="{api_request_params.country || ''}" />
153       </div>
154       <div class="col-auto">
155         <input name="postalcode" type="text" class="form-control form-control-sm me-1"
156                placeholder="Postal Code"
157                value="{api_request_params.postalcode || ''}" />
158       </div>
159       <div class="col-auto">
160         <button type="submit" class="btn btn-primary btn-sm">Search</button>
161         <input type="hidden"
162                name="viewbox" value="{sViewBox || ''}" />
163         <input type="hidden"
164                name="dedupe" value="{api_request_params.dedupe === 0 ? 0 : 1}" />
165         <input type="hidden"
166                name="bounded" value="{api_request_params.bounded ? 1 : ''}" />
167         <input type="hidden"
168                name="accept-language" value="{api_request_params['accept-language'] || ''}" />
169         <input type="hidden"
170                name="countrycodes" value="{api_request_params.countrycodes || ''}"
171                                    pattern="^[a-zA-Z]{'{2}'}(,[a-zA-Z]{'{2}'})*$" />
172         <input type="hidden"
173                name="limit" value="{api_request_params.limit || ''}" />
174         <input type="hidden"
175                name="polygon_threshold" value="{api_request_params.polygon_threshold || ''}" />
176         <input type="hidden"
177                name="layer" value="{api_request_params.layer || ''}" />
178       </div>
179     </UrlSubmitForm>
180   </div>
181 </div> <!-- /tab-content -->
182
183 <!-- Additional options -->
184 <details id="searchAdvancedOptions">
185   <summary><small>Advanced options</small></summary>
186   <ul>
187     <li>
188       <div class="form-check form-check-inline">
189         <label class="form-check-label" for="use_viewbox">apply viewbox</label>
190         <input type="checkbox" class="form-check-input api-param-setting"
191                id="use_viewbox" checked={api_request_params.viewbox} on:change={reset_viewbox}>
192       </div>
193     </li>
194
195     <li>
196       <div class="form-check form-check-inline">
197         <label class="form-check-label" for="option_bounded">bounded to viewbox</label>
198         <input type="checkbox" class="form-check-input api-param-setting"
199                id="option_bounded" checked={!!api_request_params.bounded} on:change={set_bounded}>
200       </div>
201     </li>
202
203     <li>
204       <div class="form-check form-check-inline">
205         <label class="form-check-label" for="option_dedupe">deduplicate results</label>
206         <input type="checkbox"
207                class="form-check-input api-param-setting"
208                id="option_dedupe"
209                checked={api_request_params.dedupe === 0 ? 0 : 1}
210                on:change={set_dedupe}>
211       </div>
212     </li>
213
214     <li>
215       <label for="option_limit">Maximum number of results</label>
216       <input type="number"
217              class="form-control form-control-sm d-inline w-auto api-param-setting"
218              data-api-param="limit" id="option_limit" min="1" max="50"
219              value="{api_request_params.limit || ''}"
220              on:change={set_api_param}>
221     </li>
222
223     <li>
224       <label for="option_polygon_threshold">Polygon simplification</label>
225       <input type="number"
226              class="form-control form-control-sm d-inline w-auto api-param-setting"
227              data-api-param="polygon_threshold" id="option_polygon_threshold"
228              min="0.0" max="1.0" step="0.001"
229              value="{api_request_params.polygon_threshold || ''}"
230              on:change={set_api_param}>
231     </li>
232
233     <li>
234       <label for="accept_lang">Languages</label>
235       <input type="text" placeholder="e.g. en,zh-Hant"
236              class="form-control form-control-sm d-inline w-auto api-param-setting"
237              data-api-param="accept-language" id="accept_lang" size="15"
238              value="{api_request_params['accept-language'] || ''}"
239              on:change={set_api_param}>
240     </li>
241
242     <li>
243       <label for="option_ccode">Country Codes</label>
244       <input type="text" placeholder="e.g. de,gb"
245             class="form-control form-control-sm d-inline w-auto api-param-setting"
246              data-api-param="countrycodes" id="option_ccode" size="15"
247              value="{api_request_params.countrycodes || ''}"
248              pattern="^[a-zA-Z]{'{2}'}(,[a-zA-Z]{'{2}'})*$"
249              on:change={set_api_param}>
250     </li>
251     <li>
252       <label for="option_layer">Layer</label>
253       <input id="option_layer" name="layer" placeholder="e.g. address,poi,railway,natural,manmade"
254         value="{api_request_params.layer || ''}"
255         data-api-param="layer" on:change={set_api_param}
256         class="form-control form-control-sm d-inline w-auto api-param-setting">
257     </li>
258   </ul>
259 </details>
260
261 <style>
262   .nav-tabs {
263     font-size: 0.8em;
264     margin-top: -1em;
265   }
266
267   .nav-link {
268     padding: 0.1rem 1rem;
269   }
270
271   #q {
272     width: 500px;
273     max-width: 100%;
274   }
275
276   #searchAdvancedOptions ul {
277     list-style-type: none;
278     padding: 0;
279     font-size: 0.85rem;
280   }
281
282   #searchAdvancedOptions li {
283     display: inline-block;
284     padding: 4px 10px;
285     border-radius: 5px;
286     border: 1px dotted #ccc;
287     margin-right: 1em;
288   }
289
290   #searchAdvancedOptions label {
291     margin-right: 0.5em;
292   }
293
294 </style>