+
+ {#if $searchTerm.length > 0 && results === undefined}
+
+
+
+ {:else if results?.length > 0}
+
+
+
-
- {#each results as entry (entry)}
- close()} {entry} {state} />
- {/each}
+ {#each results as entry (entry)}
+
+ {/each}
+
+
+
+
+
close()}>
+
+
-
close()}>
-
-
-
-{/if}
+ {:else }
+
+
+ {#if $searchTerm.length > 0}
+
+ No results found for {$searchTerm}
+ {/if}
+
+ {#if $recentlySeen?.length > 0}
+
+
Recent searches
+ {#each $recentlySeen as entry}
+
+ {/each}
+ {/if}
+
+ {/if}
+
+
+
+
diff --git a/src/UI/Map/Icon.svelte b/src/UI/Map/Icon.svelte
index 2fa9d5145..21bb340ac 100644
--- a/src/UI/Map/Icon.svelte
+++ b/src/UI/Map/Icon.svelte
@@ -23,7 +23,7 @@
import Brick_wall_round from "../../assets/svg/Brick_wall_round.svelte"
import Gps_arrow from "../../assets/svg/Gps_arrow.svelte"
import { HeartIcon, PencilIcon, WifiIcon } from "@babeard/svelte-heroicons/solid"
- import { HeartIcon as HeartOutlineIcon } from "@babeard/svelte-heroicons/outline"
+ import { HeartIcon as HeartOutlineIcon, HomeIcon } from "@babeard/svelte-heroicons/outline"
import Confirm from "../../assets/svg/Confirm.svelte"
import Not_found from "../../assets/svg/Not_found.svelte"
import { twMerge } from "tailwind-merge"
@@ -31,7 +31,7 @@
import Mastodon from "../../assets/svg/Mastodon.svelte"
import Party from "../../assets/svg/Party.svelte"
import AddSmall from "../../assets/svg/AddSmall.svelte"
- import { LinkIcon } from "@babeard/svelte-heroicons/mini"
+ import { GlobeAltIcon, LinkIcon } from "@babeard/svelte-heroicons/mini"
import Square_rounded from "../../assets/svg/Square_rounded.svelte"
import Bug from "../../assets/svg/Bug.svelte"
import Cross_bottom_right from "../../assets/svg/Cross_bottom_right.svelte"
@@ -39,6 +39,9 @@
import Gear from "../../assets/svg/Gear.svelte"
import { DesktopComputerIcon, UserCircleIcon } from "@rgossiaux/svelte-heroicons/solid"
import Relocation from "../../assets/svg/Relocation.svelte"
+ import BuildingOffice2 from "@babeard/svelte-heroicons/outline/BuildingOffice2"
+ import Train from "../../assets/svg/Train.svelte"
+ import Airport from "../../assets/svg/Airport.svelte"
/**
* Renders a single icon.
@@ -146,10 +149,21 @@
{:else if icon === "user_circle"}
+ {:else if icon==="globe_alt"}
+
+ {:else if icon === "building_office_2"}
+
+ {:else if icon === "house"}
+
+ {:else if icon === "train"}
+
+ {:else if icon === "airport"}
+
{:else if Utils.isEmoji(icon)}
{icon}
+
{:else}
{/if}
diff --git a/src/UI/SpecialVisualization.ts b/src/UI/SpecialVisualization.ts
index 72699ad0f..fa656b3f1 100644
--- a/src/UI/SpecialVisualization.ts
+++ b/src/UI/SpecialVisualization.ts
@@ -29,6 +29,7 @@ import LayoutSource from "../Logic/FeatureSource/Sources/LayoutSource"
import { Map as MlMap } from "maplibre-gl"
import ShowDataLayer from "./Map/ShowDataLayer"
import { CombinedFetcher } from "../Logic/Web/NearbyImagesSearch"
+import { RecentSearch } from "../Logic/Geocoding/RecentSearch"
/**
* The state needed to render a special Visualisation.
@@ -95,6 +96,8 @@ export interface SpecialVisualizationState {
readonly previewedImage: UIEventSource
readonly nearbyImageSearcher: CombinedFetcher
readonly geolocation: GeoLocationHandler
+ readonly recentlySearched: RecentSearch
+
showCurrentLocationOn(map: Store): ShowDataLayer
reportError(message: string): Promise
diff --git a/src/Utils.ts b/src/Utils.ts
index eb8503387..e8a8d1400 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -114,7 +114,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
"version",
"wayHandling",
"widenFactor",
- "width",
+ "width"
]
private static extraKeys = [
"nl",
@@ -133,7 +133,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
"yes",
"no",
"true",
- "false",
+ "false"
]
private static injectedDownloads = {}
private static _download_cache = new Map<
@@ -150,7 +150,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
if (Utils.runningFromConsole) {
return
}
- DOMPurify.addHook("afterSanitizeAttributes", function (node) {
+ DOMPurify.addHook("afterSanitizeAttributes", function(node) {
// set all elements owning target to target=_blank + add noopener noreferrer
const target = node.getAttribute("target")
if (target) {
@@ -163,7 +163,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
public static purify(src: string): string {
return DOMPurify.sanitize(src, {
USE_PROFILES: { html: true },
- ADD_ATTR: ["target"], // Don't remove target='_blank'. Note that Utils.initDomPurify does add a hook which automatically adds 'rel=noopener'
+ ADD_ATTR: ["target"] // Don't remove target='_blank'. Note that Utils.initDomPurify does add a hook which automatically adds 'rel=noopener'
})
}
@@ -193,7 +193,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
parsed[spec.name] = arg
}
- return parsed
+ return parsed
}
static EncodeXmlValue(str) {
@@ -344,7 +344,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
console.error("Error while calculating a lazy property", e)
return undefined
}
- },
+ }
})
}
@@ -368,7 +368,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
whenDone()
}
})
- },
+ }
})
}
@@ -651,7 +651,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
if (!Array.isArray(targetV)) {
throw new Error(
"Cannot concatenate: value to add is not an array: " +
- JSON.stringify(targetV)
+ JSON.stringify(targetV)
)
}
if (Array.isArray(sourceV)) {
@@ -659,9 +659,9 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
} else {
throw new Error(
"Could not merge concatenate " +
- JSON.stringify(sourceV) +
- " and " +
- JSON.stringify(targetV)
+ JSON.stringify(sourceV) +
+ " and " +
+ JSON.stringify(targetV)
)
}
} else {
@@ -922,7 +922,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
continue
}
const i = part.charCodeAt(0)
- result += '"' + keys[i] + '":' + part.substring(1)
+ result += "\"" + keys[i] + "\":" + part.substring(1)
}
return result
@@ -1000,7 +1000,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
resolve({
error: "other error: " + xhr.statusText + ", " + xhr.responseText,
url,
- statuscode: xhr.status,
+ statuscode: xhr.status
})
}
}
@@ -1014,12 +1014,12 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
xhr.onerror = (ev: ProgressEvent) =>
reject(
"Could not get " +
- url +
- ", xhr status code is " +
- xhr.status +
- " (" +
- xhr.statusText +
- ")"
+ url +
+ ", xhr status code is " +
+ xhr.status +
+ " (" +
+ xhr.statusText +
+ ")"
)
})
}
@@ -1077,12 +1077,13 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
}
const promise =
/*NO AWAIT as we work with the promise directly */ Utils.downloadJsonAdvanced(
- url,
- headers
- )
+ url,
+ headers
+ )
Utils._download_cache.set(url, { promise, timestamp: new Date().getTime() })
return await promise
}
+
public static async downloadJson(
url: string,
headers?: Record
@@ -1271,7 +1272,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
): T[] {
const withDistance: [T, number][] = ts.map((t) => [
t,
- Utils.levenshteinDistance(getName(t), reference),
+ Utils.levenshteinDistance(getName(t), reference)
])
withDistance.sort(([_, a], [__, b]) => a - b)
return withDistance.map((n) => n[0])
@@ -1393,7 +1394,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
return {
r: Utils.percentageToNumber(match[1]),
g: Utils.percentageToNumber(match[2]),
- b: Utils.percentageToNumber(match[3]),
+ b: Utils.percentageToNumber(match[3])
}
}
@@ -1404,14 +1405,14 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
return {
r: parseInt(hex.substr(1, 1), 16),
g: parseInt(hex.substr(2, 1), 16),
- b: parseInt(hex.substr(3, 1), 16),
+ b: parseInt(hex.substr(3, 1), 16)
}
}
return {
r: parseInt(hex.substr(1, 2), 16),
g: parseInt(hex.substr(3, 2), 16),
- b: parseInt(hex.substr(5, 2), 16),
+ b: parseInt(hex.substr(5, 2), 16)
}
}
@@ -1586,7 +1587,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
line: Number(line),
column: Number(column),
markdownLocation,
- filename: path.substring(path.lastIndexOf("/") + 1),
+ filename: path.substring(path.lastIndexOf("/") + 1)
}
}
@@ -1611,8 +1612,8 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
* Utils.simplifyStringForSearch("abc def; ghi 564") // => "abcdefghi564"
* Utils.simplifyStringForSearch("âbc déf; ghi 564") // => "abcdefghi564"
*/
- public static simplifyStringForSearch(str: string): string{
- return Utils.RemoveDiacritics(str) .toLowerCase().replace(/[^a-z0-9]/g, "")
+ public static simplifyStringForSearch(str: string): string {
+ return Utils.RemoveDiacritics(str).toLowerCase().replace(/[^a-z0-9]/g, "")
}
public static randomString(length: number): string {
@@ -1723,6 +1724,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
}
private static readonly _metrixPrefixes = ["", "k", "M", "G", "T", "P", "E"]
+
/**
* Converts a big number (e.g. 1000000) into a rounded postfixed verion (e.g. 1M)
*
@@ -1737,6 +1739,34 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
return n + Utils._metrixPrefixes[index]
}
+ /**
+ * Rounds to a human-number
+ * @param number
+ *
+ * Utils.roundHuman(7) // => 7
+ * Utils.roundHuman(147) // => 150
+ * Utils.roundHuman(386) // => 375
+ * Utils.roundHuman(521) // => 500
+ */
+ public static roundHuman(number: number) {
+ if (number <= 25) {
+ return number
+ }
+ if (number < 100) {
+ return 5 * Math.round(number / 5)
+ }
+ if (number < 250) {
+ return 10 * Math.round(number / 10)
+
+ }
+ if (number < 500) {
+ return 25 * Math.round(number / 25)
+
+ }
+ return 50 * Math.round(number / 50)
+
+ }
+
static NoNullInplace(layers: any[]): void {
for (let i = layers.length - 1; i >= 0; i--) {
if (layers[i] === null || layers[i] === undefined) {
diff --git a/src/assets/svg/Airport.svelte b/src/assets/svg/Airport.svelte
new file mode 100644
index 000000000..b56c711d0
--- /dev/null
+++ b/src/assets/svg/Airport.svelte
@@ -0,0 +1,4 @@
+
+
\ No newline at end of file
diff --git a/src/assets/svg/Train.svelte b/src/assets/svg/Train.svelte
new file mode 100644
index 000000000..8718befad
--- /dev/null
+++ b/src/assets/svg/Train.svelte
@@ -0,0 +1,4 @@
+
+
\ No newline at end of file