diff --git a/.versionrc.json b/.versionrc.json index 8d3e462cb..c7629c0f5 100644 --- a/.versionrc.json +++ b/.versionrc.json @@ -4,6 +4,10 @@ "type": "feat", "section": "Features" }, + { + "type": "feature", + "section": "Features" + }, { "type": "fix", "section": "Bug Fixes" @@ -51,4 +55,4 @@ ], "commitUrlFormat": "https://source.mapcomplete.org/MapComplete/MapComplete/commits/{{hash}}", "compareUrlFormat": "https://source.mapcomplete.org/MapComplete/MapComplete/compare/{{previousTag}}...{{currentTag}}" -} \ No newline at end of file +} diff --git a/CHANGELOG.md b/CHANGELOG.md index 78a7f4c74..4fe40b694 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,19 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [0.51.1](https://source.mapcomplete.org/MapComplete/MapComplete/compare/v0.51.0...v0.51.1) (2025-04-23) + + +### Bug Fixes + +* actually upload images to notes ([a870724](https://source.mapcomplete.org/MapComplete/MapComplete/commits/a8707243cf186846ead4a02fb9e62d24f91e14e1)) + + +### Theme improvements + +* **mobility_hub:** Add examples and show sign type ([b5a365d](https://source.mapcomplete.org/MapComplete/MapComplete/commits/b5a365d3c31ac95c6042161288918d1d725323ad)) +* **mobility_hub:** Add question about physical marker ([f59cf14](https://source.mapcomplete.org/MapComplete/MapComplete/commits/f59cf1430af7a0722a553b7bceaac589db3dab6d)) + ## [0.51.0](https://source.mapcomplete.org/MapComplete/MapComplete/compare/v0.50.8...v0.51.0) (2025-04-15) ### [0.50.8](https://source.mapcomplete.org/MapComplete/MapComplete/compare/v0.50.7...v0.50.8) (2025-04-15) diff --git a/package-lock.json b/package-lock.json index 32b176ff5..efeb94581 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ "name": "mapcomplete", - "version": "0.51.0", + "version": "0.51.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "mapcomplete", - "version": "0.51.0", + "version": "0.51.1", "hasInstallScript": true, "license": "GPL-3.0-or-later", "dependencies": { diff --git a/package.json b/package.json index c74f16fd7..6bfc4cfa1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mapcomplete", - "version": "0.51.0", + "version": "0.51.1", "repository": "https://source.mapcomplete.org/MapComplete/MapComplete", "description": "A small website to edit OSM easily", "bugs": "hhttps://source.mapcomplete.org/MapComplete/MapComplete/issues", diff --git a/src/Logic/ImageProviders/ImageUploadManager.ts b/src/Logic/ImageProviders/ImageUploadManager.ts index 3524efb84..ed4438612 100644 --- a/src/Logic/ImageProviders/ImageUploadManager.ts +++ b/src/Logic/ImageProviders/ImageUploadManager.ts @@ -212,7 +212,7 @@ export class ImageUploadManager { args.featureId ) - if (args.featureId.startsWith("note/")) { + if (!isNaN(Number(args.featureId))) { // This is an OSM-note const url = result.absoluteUrl await this._osmConnection.addCommentToNote(args.featureId, url) diff --git a/src/Logic/Osm/OsmObject.ts b/src/Logic/Osm/OsmObject.ts index 6a7e4687a..563a9e1ba 100644 --- a/src/Logic/Osm/OsmObject.ts +++ b/src/Logic/Osm/OsmObject.ts @@ -330,6 +330,9 @@ ${nds}${tags} } private isPolygon(): boolean { + if (this.coordinates.length === 0) { + return false + } // Compare lat and lon seperately, as the coordinate array might not be a reference to the same object if ( this.coordinates[0][0] !== this.coordinates[this.coordinates.length - 1][0] || diff --git a/src/UI/History/AggregateView.svelte b/src/UI/History/AggregateView.svelte index 69bc1248b..c4b8bb8ec 100644 --- a/src/UI/History/AggregateView.svelte +++ b/src/UI/History/AggregateView.svelte @@ -10,6 +10,9 @@ import Tr from "../Base/Tr.svelte" import AccordionSingle from "../Flowbite/AccordionSingle.svelte" import Translations from "../i18n/Translations" + import TagRenderingChart from "../BigComponents/TagRenderingChart" + import ToSvelte from "../Base/ToSvelte.svelte" + import type { TagRenderingConfigJson } from "../../Models/ThemeConfig/Json/TagRenderingConfigJson" export let onlyShowUsername: string[] export let features: Feature[] @@ -25,10 +28,11 @@ key: string value?: string oldValue?: string + step: OsmObject }[] > = allHistories.mapD((histories) => HistoryUtils.fullHistoryDiff(histories, usernames)) - const trs = shared_questions.tagRenderings.map((tr) => new TagRenderingConfig(tr)) + const trs = shared_questions.tagRenderings.map((tr) => new TagRenderingConfig(tr)) function detectQuestion(key: string): TagRenderingConfig { return trs.find((tr) => tr.freeform?.key === key) @@ -40,17 +44,19 @@ tr: TagRenderingConfig count: number values: { value: string; count: number }[] + features: Feature[] }[] > = allDiffs.mapD((allDiffs) => { - const keyCounts = new Map>() + const keyCounts = new Map>() for (const diff of allDiffs) { const k = diff.key if (!keyCounts.has(k)) { - keyCounts.set(k, new Map()) + keyCounts.set(k, new Map()) } const valueCounts = keyCounts.get(k) const v = diff.value ?? "" - valueCounts.set(v, 1 + (valueCounts.get(v) ?? 0)) + const oldFeaturesList = valueCounts.get(v) ?? [] + valueCounts.set(v, [...oldFeaturesList, diff.step]) } const perKey: { @@ -58,19 +64,25 @@ tr: TagRenderingConfig count: number values: { value: string; count: number }[] + features: Feature[] }[] = [] - keyCounts.forEach((values, key) => { - const keyTotal: { value: string; count: number }[] = [] + keyCounts.forEach((values: Map, key: string) => { + const keyTotal: { value: string; features: Feature[] }[] = [] values.forEach((count, value) => { - keyTotal.push({ value, count }) + keyTotal.push({ value, features: count.map(step => step.asGeoJson()) }) }) - let countForKey = 0 - for (const { count } of keyTotal) { - countForKey += count + let countForKey: Feature[] = [] + for (const { features } of keyTotal) { + countForKey.push(...features) } - keyTotal.sort((a, b) => b.count - a.count) + keyTotal.sort((a, b) => b.features.length - a.features.length) const tr = detectQuestion(key) - perKey.push({ count: countForKey, tr, key, values: keyTotal }) + perKey.push({ + count: countForKey.length, tr, key, values: keyTotal.map(({ value, features }) => ({ + value, + count: features.length + })), features: countForKey + }) }) perKey.sort((a, b) => b.count - a.count) @@ -105,6 +117,20 @@ {/each} + {#if diff.tr} +
+ + +
+ {:else} + Could not create a graph + {/if} {/each} {/if} diff --git a/src/UI/History/HistoryUtils.ts b/src/UI/History/HistoryUtils.ts index 1b2c4bc20..9816b9e4b 100644 --- a/src/UI/History/HistoryUtils.ts +++ b/src/UI/History/HistoryUtils.ts @@ -44,22 +44,37 @@ export class HistoryUtils { .filter((ch) => ch.oldValue !== ch.value) } - public static fullHistoryDiff(histories: OsmObject[][], onlyShowUsername?: Set) { - const allDiffs: { key: string; oldValue?: string; value?: string }[] = [].concat( - ...histories.map((history) => { - const filtered = history.filter( - (step) => - !onlyShowUsername || - onlyShowUsername?.has(step.tags["_last_edit:contributor"]) - ) - const diffs: { - key: string - value?: string - oldValue?: string - }[][] = filtered.map((step) => HistoryUtils.tagHistoryDiff(step, history)) - return [].concat(...diffs) - }) - ) + public static fullHistoryDiff(histories: OsmObject[][], onlyShowUsername?: Set): { + key: string; + value?: string; + oldValue?: string; + step: OsmObject + }[] { + + const allDiffs: { + key: string; + value?: string; + oldValue?: string; + step: OsmObject + }[] = [] + for (const history of histories) { + const filtered = history.filter( + (step) => + !onlyShowUsername || + onlyShowUsername?.has(step.tags["_last_edit:contributor"]) + ) + for (const step of filtered) { + const diff: { + key: string; + value?: string; + oldValue?: string; + step: OsmObject + }[] = HistoryUtils.tagHistoryDiff(step, history) + allDiffs.push(...diff) + } + } + + return allDiffs } } diff --git a/src/UI/Image/UploadImage.svelte b/src/UI/Image/UploadImage.svelte index 5ed042a93..bb606f3cd 100644 --- a/src/UI/Image/UploadImage.svelte +++ b/src/UI/Image/UploadImage.svelte @@ -13,7 +13,6 @@ import FileSelector from "../Base/FileSelector.svelte" import LoginButton from "../Base/LoginButton.svelte" import { Translation } from "../i18n/Translation" - import LayerConfig from "../../Models/ThemeConfig/LayerConfig" import type { Feature } from "geojson" import Camera from "@babeard/svelte-heroicons/mini/Camera" diff --git a/src/UI/InspectorGUI.svelte b/src/UI/InspectorGUI.svelte index a8c316e3e..6b292a473 100644 --- a/src/UI/InspectorGUI.svelte +++ b/src/UI/InspectorGUI.svelte @@ -70,6 +70,8 @@ searchIsRunning.set(false) } }) + + let state = { mapProperties: maplibremap, searchState: { @@ -164,6 +166,19 @@ let showPreviouslyVisited = new UIEventSource(true) const t = Translations.t.inspector + + function search(suggestion?: GeocodeResult) { + suggestion ??= searchSuggestions?.data?.[0] + console.log("Seaching", suggestion) + if (!suggestion) { + return + } + map.data.flyTo({ + zoom: 14, + center: [suggestion.lon, suggestion.lat] + }) + } +
@@ -251,12 +266,13 @@
search()} isFocused={searchIsFocussed} value={searchvalue} on:focus={() => state.searchState.showSearchDrawer.set(true)} /> {#if $searchSuggestions?.length > 0 || $searchIsFocussed} - + search(event.detail)} /> {/if}
diff --git a/src/UI/Search/GeocodeResult.svelte b/src/UI/Search/GeocodeResult.svelte index 196439e70..fac73d3ea 100644 --- a/src/UI/Search/GeocodeResult.svelte +++ b/src/UI/Search/GeocodeResult.svelte @@ -13,6 +13,7 @@ import FeaturePropertiesStore from "../../Logic/FeatureSource/Actors/FeaturePropertiesStore" import SearchState from "../../Logic/State/SearchState" import ArrowUp from "@babeard/svelte-heroicons/mini/ArrowUp" + import { createEventDispatcher } from "svelte" export let entry: GeocodeResult export let state: { @@ -40,8 +41,9 @@ let mapRotation = state.mapProperties.rotation let inView = state.mapProperties.bounds.mapD((bounds) => bounds.contains([entry.lon, entry.lat])) + let dispatch = createEventDispatcher<{ select: GeocodeResult }>() function select() { - state.searchState.applyGeocodeResult(entry) + dispatch("select", entry) } diff --git a/src/UI/Search/SearchResults.svelte b/src/UI/Search/SearchResults.svelte index 508d72c1f..29fd8408c 100644 --- a/src/UI/Search/SearchResults.svelte +++ b/src/UI/Search/SearchResults.svelte @@ -55,7 +55,9 @@ {#if $allowFilters} {/if} - + { + state.searchState.applyGeocodeResult(select.detail) + }}> {#if $recentlySeen?.length > 0}