2 import UrlSubmitForm from '../components/UrlSubmitForm.svelte';
4 import { map_store } from '../lib/stores.js';
5 import { get } from 'svelte/store';
7 let { bStructuredSearch = false, api_request_params = {} } = $props();
9 let sViewBox = $state();
11 // lat,lon are later set in update_reverse_link()
12 let lat; // eslint-disable-line no-unused-vars
13 let lon; // eslint-disable-line no-unused-vars
15 function map_viewbox_as_string(map) {
16 var bounds = map.getBounds();
17 var west = bounds.getWest();
18 var east = bounds.getEast();
20 if ((east - west) >= 360) { // covers more than whole planet
21 west = map.getCenter().lng - 179.999;
22 east = map.getCenter().lng + 179.999;
24 east = L.latLng(77, east).wrap().lng;
25 west = L.latLng(77, west).wrap().lng;
28 west.toFixed(5), // left
29 bounds.getNorth().toFixed(5), // top
30 east.toFixed(5), // right
31 bounds.getSouth().toFixed(5) // bottom
35 function set_viewbox(map) {
36 let use_viewbox = document.getElementById('use_viewbox');
37 if (use_viewbox && use_viewbox.checked) {
38 sViewBox = map_viewbox_as_string(map);
44 function update_reverse_link(map) {
45 let center_lat_lng = map.wrapLatLng(map.getCenter());
46 lat = center_lat_lng.lat.toFixed(5);
47 lon = center_lat_lng.lng.toFixed(5);
50 map_store.subscribe(map => {
53 map.on('move', function () {
55 update_reverse_link(map);
58 map.on('load', function () {
60 update_reverse_link(map);
64 function reset_viewbox() {
65 let map = get(map_store);
66 if (map) { set_viewbox(map); }
69 function set_bounded(e) {
70 document.querySelector('input[name=bounded]').value = e.target.checked ? 1 : '';
73 function set_dedupe(e) {
74 document.querySelector('input[name=dedupe]').value = e.target.checked ? 1 : 0;
77 function set_api_param(e) {
78 document.querySelector('input[name=' + e.target.dataset.apiParam + ']').value = e.target.value;
82 {#snippet submitButton()}
83 <div class="col-auto">
84 <button type="submit" class="btn btn-primary btn-sm">Search</button>
86 name="viewbox" value="{sViewBox || ''}" />
88 name="dedupe" value="{api_request_params.dedupe === 0 ? 0 : 1}" />
90 name="bounded" value="{api_request_params.bounded ? 1 : ''}" />
92 name="accept-language" value="{api_request_params['accept-language'] || ''}" />
94 name="countrycodes" value="{api_request_params.countrycodes || ''}"
95 pattern="^[a-zA-Z]{'{2}'}(,[a-zA-Z]{'{2}'})*$" />
97 name="limit" value="{api_request_params.limit || ''}" />
99 name="polygon_threshold" value="{api_request_params.polygon_threshold || ''}" />
101 name="layer" value="{api_request_params.layer || ''}" />
105 {#snippet simpleSearchForm()}
106 <div class="col-auto">
110 class="form-control form-control-sm"
112 value="{api_request_params.q || ''}" />
114 {@render submitButton()}
117 {#snippet structuredSearchForm()}
118 <div class="col-auto">
119 <input name="street" type="text" class="form-control form-control-sm me-1"
120 placeholder="House number/Street"
121 value="{api_request_params.street || ''}" />
123 <div class="col-auto">
124 <input name="city" type="text" class="form-control form-control-sm me-1"
126 value="{api_request_params.city || ''}" />
128 <div class="col-auto">
129 <input id="county" name="county" type="text" class="form-control form-control-sm me-1"
131 value="{api_request_params.county || ''}" />
133 <div class="col-auto">
134 <input name="state" type="text" class="form-control form-control-sm me-1"
136 value="{api_request_params.state || ''}" />
138 <div class="col-auto">
139 <input name="country" type="text" class="form-control form-control-sm me-1"
140 placeholder="Country"
141 value="{api_request_params.country || ''}" />
143 <div class="col-auto">
144 <input name="postalcode" type="text" class="form-control form-control-sm me-1"
145 placeholder="Postal Code"
146 value="{api_request_params.postalcode || ''}" />
148 {@render submitButton()}
151 <ul class="nav nav-tabs">
152 <li class="nav-item">
153 <a class="nav-link" class:active={!bStructuredSearch} data-bs-toggle="tab" href="#simple">
157 <li class="nav-item">
158 <a class="nav-link" class:active={bStructuredSearch} data-bs-toggle="tab" href="#structured">
164 <div class="tab-content py-2">
165 <div class="tab-pane" class:active={!bStructuredSearch} id="simple" role="tabpanel">
166 <UrlSubmitForm page="search" content={simpleSearchForm} />
168 <div class="tab-pane" class:active={bStructuredSearch} id="structured" role="tabpanel">
169 <UrlSubmitForm page="search" content={structuredSearchForm} />
171 </div> <!-- /tab-content -->
173 <!-- Additional options -->
174 <details id="searchAdvancedOptions">
175 <summary><small>Advanced options</small></summary>
178 <div class="form-check form-check-inline">
179 <label class="form-check-label" for="use_viewbox">apply viewbox</label>
180 <input type="checkbox" class="form-check-input api-param-setting"
181 id="use_viewbox" checked={api_request_params.viewbox} onchange={reset_viewbox}>
186 <div class="form-check form-check-inline">
187 <label class="form-check-label" for="option_bounded">bounded to viewbox</label>
188 <input type="checkbox" class="form-check-input api-param-setting"
189 id="option_bounded" checked={!!api_request_params.bounded} onchange={set_bounded}>
194 <div class="form-check form-check-inline">
195 <label class="form-check-label" for="option_dedupe">deduplicate results</label>
196 <input type="checkbox"
197 class="form-check-input api-param-setting"
199 checked={api_request_params.dedupe === 0 ? 0 : 1}
200 onchange={set_dedupe}>
205 <label for="option_limit">Maximum number of results</label>
207 class="form-control form-control-sm d-inline w-auto api-param-setting"
208 data-api-param="limit" id="option_limit" min="1" max="50"
209 value="{api_request_params.limit || ''}"
210 onchange={set_api_param}>
214 <label for="option_polygon_threshold">Polygon simplification</label>
216 class="form-control form-control-sm d-inline w-auto api-param-setting"
217 data-api-param="polygon_threshold" id="option_polygon_threshold"
218 min="0.0" max="1.0" step="0.001"
219 value="{api_request_params.polygon_threshold || ''}"
220 onchange={set_api_param}>
224 <label for="accept_lang">Languages</label>
225 <input type="text" placeholder="e.g. en,zh-Hant"
226 class="form-control form-control-sm d-inline w-auto api-param-setting"
227 data-api-param="accept-language" id="accept_lang" size="15"
228 value="{api_request_params['accept-language'] || ''}"
229 onchange={set_api_param}>
233 <label for="option_ccode">Country Codes</label>
234 <input type="text" placeholder="e.g. de,gb"
235 class="form-control form-control-sm d-inline w-auto api-param-setting"
236 data-api-param="countrycodes" id="option_ccode" size="15"
237 value="{api_request_params.countrycodes || ''}"
238 pattern="^[a-zA-Z]{'{2}'}(,[a-zA-Z]{'{2}'})*$"
239 onchange={set_api_param}>
242 <label for="option_layer">Layer</label>
243 <input id="option_layer" name="layer" placeholder="e.g. address,poi,railway,natural,manmade"
244 value="{api_request_params.layer || ''}"
245 data-api-param="layer" onchange={set_api_param}
246 class="form-control form-control-sm d-inline w-auto api-param-setting">
258 padding: 0.1rem 1rem;
266 #searchAdvancedOptions ul {
267 list-style-type: none;
272 #searchAdvancedOptions li {
273 display: inline-block;
276 border: 1px dotted #ccc;
280 #searchAdvancedOptions label {