2 import { fetch_from_api, update_html_title } from '../lib/api_utils.js';
3 import { page } from '../lib/stores.js';
6 osmLink, wikipediaLink, coverageType, isAdminBoundary,
7 formatAddressRank, formatKeywordToken, formatOSMType
8 } from '../lib/helpers.js';
9 import Header from '../components/Header.svelte';
10 import MapIcon from '../components/MapIcon.svelte';
11 import SearchSectionDetails from '../components/SearchSectionDetails.svelte';
12 import DetailsOneRow from '../components/DetailsOneRow.svelte';
13 import DetailsLink from '../components/DetailsLink.svelte';
14 import DetailsPostcodeHint from '../components/DetailsPostcodeHint.svelte';
15 import InfoRow from '../components/DetailsInfoRow.svelte';
16 import InfoRowList from '../components/DetailsInfoRowList.svelte';
17 import Map from '../components/Map.svelte';
21 let api_request_params;
22 let api_request_finished = false;
24 function loaddata(search_params) {
25 api_request_params = {
26 place_id: search_params.get('place_id'),
27 osmtype: search_params.get('osmtype'),
28 osmid: search_params.get('osmid'),
29 class: search_params.get('class'),
30 keywords: search_params.get('keywords'),
32 hierarchy: (search_params.get('hierarchy') === '1' ? 1 : 0),
37 api_request_finished = false;
39 if (api_request_params.place_id || (api_request_params.osmtype && api_request_params.osmid)) {
41 if (api_request_params.place_id) {
42 update_html_title('Details for ' + api_request_params.place_id);
44 update_html_title('Details for ' + api_request_params.osmtype + api_request_params.osmid);
47 fetch_from_api('details', api_request_params, function (data) {
48 window.scrollTo(0, 0);
49 api_request_finished = true;
50 aPlace = (data && !data.error) ? data : undefined;
57 function place_has_keywords(aThisPlace) {
58 // Return false if Nominatim API sends 'keywords: { name: [], address: [] }'
59 // Like no longer needed after Nominatim version 4.3
61 aThisPlace.keywords && aThisPlace.keywords.name && aThisPlace.keywords.address
62 && (aThisPlace.keywords.name.length > 0 || aThisPlace.keywords.address.length > 0)
68 if (pageinfo.tab === 'details') {
69 loaddata(pageinfo.params);
70 base_url = window.location.search;
73 $: reverse_only = Nominatim_Config.Reverse_Only;
77 <SearchSectionDetails api_request_params={api_request_params}/>
80 <div class="container">
83 <div class="col-sm-10">
85 {aPlace.localname || `${formatOSMType(aPlace.osm_type)} ${aPlace.osm_id}` }
86 <small><DetailsLink feature={aPlace}>link to this page</DetailsLink></small>
89 <div class="col-sm-2 text-end">
90 <MapIcon aPlace={aPlace} />
94 <div class="col-md-6">
95 <table id="locationdetails" class="table table-striped table-responsive">
97 <InfoRow title="Name">
98 {#if aPlace.names && typeof (aPlace.names) === 'object'
99 && Object.keys(aPlace.names).length}
100 <InfoRowList items={aPlace.names} />
102 <span class="noname fw-bold">No Name</span>
105 <InfoRow title="Type">{aPlace.category}:{aPlace.type}</InfoRow>
106 <InfoRow title="Last Updated">{aPlace.indexed_date}</InfoRow>
107 {#if (isAdminBoundary(aPlace)) }
108 <InfoRow title="Admin Level">{aPlace.admin_level}</InfoRow>
110 <InfoRow title="Search Rank">{aPlace.rank_search}</InfoRow>
111 <InfoRow title="Address Rank">
112 {aPlace.rank_address} ({formatAddressRank(aPlace.rank_address)})
114 {#if aPlace.calculated_importance}
115 <InfoRow title="Importance">
116 {aPlace.calculated_importance}
117 {#if !aPlace.importance} (estimated){/if}
120 <InfoRow title="Coverage">{coverageType(aPlace)}</InfoRow>
121 <InfoRow title="Centre Point (lat,lon)">
122 {aPlace.centroid.coordinates[1]},{aPlace.centroid.coordinates[0]}
124 <!-- eslint-disable-next-line svelte/no-at-html-tags -->
125 <InfoRow title="OSM">{@html osmLink(aPlace)}</InfoRow>
126 <InfoRow title="Place Id">
128 (<a href="https://nominatim.org/release-docs/develop/api/Output/#place_id-is-not-a-persistent-id">
132 {#if aPlace.calculated_wikipedia}
133 <!-- eslint-disable-next-line svelte/no-at-html-tags -->
134 <InfoRow title="Wikipedia Calculated">{@html wikipediaLink(aPlace)}</InfoRow>
136 <InfoRow title="Computed Postcode">
137 {#if aPlace.calculated_postcode}
138 {aPlace.calculated_postcode}
139 <DetailsPostcodeHint postcode={aPlace.calculated_postcode}
140 lat={aPlace.centroid.coordinates[1]}
141 lon={aPlace.centroid.coordinates[0]} />
144 <InfoRow title="Address Tags"><InfoRowList items={aPlace.addresstags} /></InfoRow>
145 <InfoRow title="Extra Tags"><InfoRowList items={aPlace.extratags} /></InfoRow>
149 <div class="col-md-6">
150 <div id="map-wrapper">
151 <Map current_result={aPlace} />
156 <div class="col-md-12">
158 <table id="address" class="table table-striped table-small">
164 <th>Address rank</th>
172 {#each aPlace.address as addressLine}
173 <DetailsOneRow addressLine={addressLine}
174 bMarkUnusedLines={true}
175 bDistanceInMeters={false} />
179 {#if aPlace.linked_places}
180 <tr class="all-columns"><td colspan="7"><h2>Linked Places</h2></td></tr>
181 {#each aPlace.linked_places as addressLine}
182 <DetailsOneRow addressLine={addressLine}
183 bMarkUnusedLines={true}
184 bDistanceInMeters={true} />
189 <tr class="all-columns"><td colspan="7"><h2>Keywords</h2></td></tr>
190 {#if api_request_params.keywords}
192 {#if place_has_keywords(aPlace)}
193 <tr class="all-columns"><td colspan="7"><h3>Name Keywords</h3></td></tr>
194 {#each aPlace.keywords.name as keyword}
196 <td>{formatKeywordToken(keyword.token)}</td>
198 <td>word id: {keyword.id}</td>
203 {#if aPlace.keywords.address}
204 <tr class="all-columns"><td colspan="7"><h3>Address Keywords</h3></td></tr>
205 {#each aPlace.keywords.address as keyword}
207 <td>{formatKeywordToken(keyword.token)}</td>
209 <td>word id: {keyword.id}</td>
215 <tr><td>Place has no keywords</td></tr>
220 <a class="btn btn-outline-secondary btn-sm"
221 href="{base_url}&keywords=1">display keywords</a>
227 <tr class="all-columns"><td colspan="7"><h2>Parent Of</h2></td></tr>
228 {#if api_request_params.hierarchy}
229 {#if aPlace.hierarchy && typeof (aPlace.hierarchy) === 'object'
230 && Object.keys(aPlace.hierarchy).length}
231 {#each Object.keys(aPlace.hierarchy) as type}
232 <tr class="all-columns"><td colspan="7"><h3>{type}</h3></td></tr>
233 {#each aPlace.hierarchy[type] as line}
234 <DetailsOneRow addressLine={line} bDistanceInMeters={true} />
238 {#if Object.keys(aPlace.hierarchy) > 500}
239 <p>There are more child objects which are not shown.</p>
242 <tr><td>Place is not parent of other places</td></tr>
247 <a class="btn btn-outline-secondary btn-sm"
248 href="{base_url}&hierarchy=1">display child places</a>
256 {:else if (window.location.search !== '' && api_request_finished)}
269 h1 small :global(a) {
277 background-color: white;
285 background-color: white !important;
289 border-top: none !important;
290 padding-left: 0 !important;
292 :global(span.noname){
301 border: 1px solid #666;