| 
									
										
										
										
											2022-08-02 19:50:17 +02:00
										 |  |  | /** | 
					
						
							|  |  |  |  * The statistics-gui shows statistics from previous MapComplete-edits | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2022-10-27 01:50:01 +02:00
										 |  |  | import { UIEventSource } from "../Logic/UIEventSource" | 
					
						
							|  |  |  | import { VariableUiElement } from "./Base/VariableUIElement" | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | import Loading from "./Base/Loading" | 
					
						
							| 
									
										
										
										
											2022-10-27 01:50:01 +02:00
										 |  |  | import { Utils } from "../Utils" | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | import Combine from "./Base/Combine" | 
					
						
							| 
									
										
										
										
											2023-12-06 03:07:36 +01:00
										 |  |  | import TagRenderingChart, { StackedRenderingChart } from "./BigComponents/TagRenderingChart" | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | import BaseUIElement from "./BaseUIElement" | 
					
						
							|  |  |  | import Title from "./Base/Title" | 
					
						
							|  |  |  | import { FixedUiElement } from "./Base/FixedUiElement" | 
					
						
							| 
									
										
										
										
											2022-10-27 01:50:01 +02:00
										 |  |  | import List from "./Base/List" | 
					
						
							| 
									
										
										
										
											2024-10-17 04:06:03 +02:00
										 |  |  | import ThemeConfig from "../Models/ThemeConfig/ThemeConfig" | 
					
						
							| 
									
										
										
										
											2023-07-15 18:04:30 +02:00
										 |  |  | import mcChanges from "../../src/assets/generated/themes/mapcomplete-changes.json" | 
					
						
							| 
									
										
										
										
											2023-04-24 03:22:43 +02:00
										 |  |  | import SvelteUIElement from "./Base/SvelteUIElement" | 
					
						
							|  |  |  | import Filterview from "./BigComponents/Filterview.svelte" | 
					
						
							|  |  |  | import FilteredLayer from "../Models/FilteredLayer" | 
					
						
							| 
									
										
										
										
											2024-02-09 23:05:05 +01:00
										 |  |  | import { SubtleButton } from "./Base/SubtleButton" | 
					
						
							|  |  |  | import { GeoOperations } from "../Logic/GeoOperations" | 
					
						
							| 
									
										
										
										
											2024-09-20 15:27:04 +02:00
										 |  |  | import { FeatureCollection, Polygon } from "geojson" | 
					
						
							| 
									
										
										
										
											2024-02-09 23:05:05 +01:00
										 |  |  | import { Feature } from "geojson" | 
					
						
							| 
									
										
										
										
											2023-04-24 03:22:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-15 16:26:43 +02:00
										 |  |  | class StatsticsForOverviewFile extends Combine { | 
					
						
							| 
									
										
										
										
											2022-08-22 13:34:47 +02:00
										 |  |  |     constructor(homeUrl: string, paths: string[]) { | 
					
						
							| 
									
										
										
										
											2022-10-27 01:50:01 +02:00
										 |  |  |         paths = paths.filter((p) => !p.endsWith("file-overview.json")) | 
					
						
							| 
									
										
										
										
											2024-10-17 04:06:03 +02:00
										 |  |  |         const layer = new ThemeConfig(<any>mcChanges, true).layers[0] | 
					
						
							| 
									
										
										
										
											2023-04-24 03:22:43 +02:00
										 |  |  |         const filteredLayer = new FilteredLayer(layer) | 
					
						
							|  |  |  |         const filterPanel = new Combine([ | 
					
						
							|  |  |  |             new Title("Filters"), | 
					
						
							|  |  |  |             new SvelteUIElement(Filterview, { filteredLayer }), | 
					
						
							|  |  |  |         ]) | 
					
						
							| 
									
										
										
										
											2024-10-19 14:44:55 +02:00
										 |  |  |         filteredLayer.currentFilter.addCallbackAndRun((tf) => { | 
					
						
							| 
									
										
										
										
											2024-09-20 15:27:04 +02:00
										 |  |  |             console.log("Filters are", tf) | 
					
						
							|  |  |  |         }) | 
					
						
							| 
									
										
										
										
											2022-08-22 13:34:47 +02:00
										 |  |  |         const downloaded = new UIEventSource<{ features: ChangeSetData[] }[]>([]) | 
					
						
							| 
									
										
										
										
											2022-08-02 19:50:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-22 13:34:47 +02:00
										 |  |  |         for (const filepath of paths) { | 
					
						
							| 
									
										
										
										
											2022-10-27 01:50:01 +02:00
										 |  |  |             if (filepath.endsWith("file-overview.json")) { | 
					
						
							| 
									
										
										
										
											2022-09-14 17:58:10 +02:00
										 |  |  |                 continue | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             Utils.downloadJson(homeUrl + filepath).then((data) => { | 
					
						
							| 
									
										
										
										
											2022-09-14 17:58:10 +02:00
										 |  |  |                 if (data === undefined) { | 
					
						
							| 
									
										
										
										
											2022-09-14 17:58:10 +02:00
										 |  |  |                     return | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2022-09-14 17:58:10 +02:00
										 |  |  |                 if (data.features === undefined) { | 
					
						
							| 
									
										
										
										
											2022-09-14 17:58:10 +02:00
										 |  |  |                     data.features = data | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 data?.features?.forEach((item) => { | 
					
						
							| 
									
										
										
										
											2022-10-27 01:50:01 +02:00
										 |  |  |                     item.properties = { ...item.properties, ...item.properties.metadata } | 
					
						
							| 
									
										
										
										
											2022-08-22 13:34:47 +02:00
										 |  |  |                     delete item.properties.metadata | 
					
						
							| 
									
										
										
										
											2022-08-02 19:50:17 +02:00
										 |  |  |                 }) | 
					
						
							| 
									
										
										
										
											2022-08-22 13:34:47 +02:00
										 |  |  |                 downloaded.data.push(data) | 
					
						
							|  |  |  |                 downloaded.ping() | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-08-20 12:46:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const loading = new Loading( | 
					
						
							|  |  |  |             new VariableUiElement( | 
					
						
							|  |  |  |                 downloaded.map((dl) => "Downloaded " + dl.length + " items out of " + paths.length) | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-22 13:34:47 +02:00
										 |  |  |         super([ | 
					
						
							|  |  |  |             filterPanel, | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             new VariableUiElement( | 
					
						
							|  |  |  |                 downloaded.map( | 
					
						
							|  |  |  |                     (downloaded) => { | 
					
						
							|  |  |  |                         if (downloaded.length !== paths.length) { | 
					
						
							|  |  |  |                             return loading | 
					
						
							| 
									
										
										
										
											2022-08-22 13:34:47 +02:00
										 |  |  |                         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-24 03:22:43 +02:00
										 |  |  |                         const overview = ChangesetsOverview.fromDirtyData( | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                             [].concat(...downloaded.map((d) => d.features)) | 
					
						
							| 
									
										
										
										
											2023-04-24 03:22:43 +02:00
										 |  |  |                         ).filter((cs) => filteredLayer.isShown(<any>cs.properties)) | 
					
						
							|  |  |  |                         console.log("Overview is", overview) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                         if (overview._meta.length === 0) { | 
					
						
							|  |  |  |                             return "No data matched the filter" | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                         const dateStrings = Utils.NoNull( | 
					
						
							|  |  |  |                             overview._meta.map((cs) => cs.properties.date) | 
					
						
							|  |  |  |                         ) | 
					
						
							|  |  |  |                         const dates: number[] = dateStrings.map((d) => new Date(d).getTime()) | 
					
						
							|  |  |  |                         const mindate = Math.min(...dates) | 
					
						
							|  |  |  |                         const maxdate = Math.max(...dates) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                         const diffInDays = (maxdate - mindate) / (1000 * 60 * 60 * 24) | 
					
						
							|  |  |  |                         console.log("Diff in days is ", diffInDays, "got", overview._meta.length) | 
					
						
							|  |  |  |                         const trs = layer.tagRenderings.filter( | 
					
						
							|  |  |  |                             (tr) => tr.mappings?.length > 0 || tr.freeform?.key !== undefined | 
					
						
							|  |  |  |                         ) | 
					
						
							| 
									
										
										
										
											2022-09-14 17:58:10 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                         const allKeys = new Set<string>() | 
					
						
							|  |  |  |                         for (const cs of overview._meta) { | 
					
						
							|  |  |  |                             for (const propertiesKey in cs.properties) { | 
					
						
							|  |  |  |                                 allKeys.add(propertiesKey) | 
					
						
							|  |  |  |                             } | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                         console.log("All keys:", allKeys) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                         const valuesToSum = [ | 
					
						
							| 
									
										
										
										
											2022-09-14 19:15:50 +02:00
										 |  |  |                             "create", | 
					
						
							|  |  |  |                             "modify", | 
					
						
							|  |  |  |                             "delete", | 
					
						
							| 
									
										
										
										
											2022-09-14 17:58:10 +02:00
										 |  |  |                             "answer", | 
					
						
							|  |  |  |                             "move", | 
					
						
							|  |  |  |                             "deletion", | 
					
						
							|  |  |  |                             "add-image", | 
					
						
							|  |  |  |                             "plantnet-ai-detection", | 
					
						
							|  |  |  |                             "import", | 
					
						
							|  |  |  |                             "conflation", | 
					
						
							|  |  |  |                             "link-image", | 
					
						
							| 
									
										
										
										
											2022-10-27 01:50:01 +02:00
										 |  |  |                             "soft-delete", | 
					
						
							|  |  |  |                         ] | 
					
						
							| 
									
										
										
										
											2022-09-14 17:58:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-27 01:50:01 +02:00
										 |  |  |                         const allThemes = Utils.Dedup(overview._meta.map((f) => f.properties.theme)) | 
					
						
							| 
									
										
										
										
											2022-09-14 17:58:10 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-14 19:15:50 +02:00
										 |  |  |                         const excludedThemes = new Set<string>() | 
					
						
							| 
									
										
										
										
											2022-10-27 01:50:01 +02:00
										 |  |  |                         if (allThemes.length > 1) { | 
					
						
							|  |  |  |                             excludedThemes.add("grb") | 
					
						
							|  |  |  |                             excludedThemes.add("etymology") | 
					
						
							| 
									
										
										
										
											2022-09-15 15:29:49 +02:00
										 |  |  |                         } | 
					
						
							| 
									
										
										
										
											2022-09-14 19:15:50 +02:00
										 |  |  |                         const summedValues = valuesToSum | 
					
						
							| 
									
										
										
										
											2022-10-27 01:50:01 +02:00
										 |  |  |                             .map((key) => [key, overview.sum(key, excludedThemes)]) | 
					
						
							|  |  |  |                             .filter((kv) => kv[1] != 0) | 
					
						
							|  |  |  |                             .map((kv) => kv.join(": ")) | 
					
						
							| 
									
										
										
										
											2022-09-14 17:58:10 +02:00
										 |  |  |                         const elements: BaseUIElement[] = [ | 
					
						
							| 
									
										
										
										
											2022-10-27 01:50:01 +02:00
										 |  |  |                             new Title( | 
					
						
							|  |  |  |                                 allThemes.length === 1 | 
					
						
							|  |  |  |                                     ? "General statistics for " + allThemes[0] | 
					
						
							|  |  |  |                                     : "General statistics (excluding etymology- and GRB-theme changes)" | 
					
						
							|  |  |  |                             ), | 
					
						
							| 
									
										
										
										
											2022-09-14 17:58:10 +02:00
										 |  |  |                             new Combine([ | 
					
						
							|  |  |  |                                 overview._meta.length + " changesets match the filters", | 
					
						
							| 
									
										
										
										
											2022-10-27 01:50:01 +02:00
										 |  |  |                                 new List(summedValues), | 
					
						
							| 
									
										
										
										
											2022-09-14 17:58:10 +02:00
										 |  |  |                             ]).SetClass("flex flex-col border rounded-xl"), | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-27 01:50:01 +02:00
										 |  |  |                             new Title("Breakdown"), | 
					
						
							| 
									
										
										
										
											2022-09-14 17:58:10 +02:00
										 |  |  |                         ] | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                         for (const tr of trs) { | 
					
						
							| 
									
										
										
										
											2023-04-24 03:22:43 +02:00
										 |  |  |                             if (tr.question === undefined) { | 
					
						
							|  |  |  |                                 continue | 
					
						
							|  |  |  |                             } | 
					
						
							|  |  |  |                             console.log(tr) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                             let total = undefined | 
					
						
							|  |  |  |                             if (tr.freeform?.key !== undefined) { | 
					
						
							|  |  |  |                                 total = new Set( | 
					
						
							|  |  |  |                                     overview._meta.map((f) => f.properties[tr.freeform.key]) | 
					
						
							|  |  |  |                                 ).size | 
					
						
							|  |  |  |                             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                             try { | 
					
						
							|  |  |  |                                 elements.push( | 
					
						
							|  |  |  |                                     new Combine([ | 
					
						
							|  |  |  |                                         new Title(tr.question ?? tr.id).SetClass("p-2"), | 
					
						
							|  |  |  |                                         total > 1 ? total + " unique value" : undefined, | 
					
						
							| 
									
										
										
										
											2023-12-06 03:07:36 +01:00
										 |  |  |                                         new Title("By number of changesets", 4).SetClass("p-2"), | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                                         new StackedRenderingChart(tr, <any>overview._meta, { | 
					
						
							|  |  |  |                                             period: diffInDays <= 367 ? "day" : "month", | 
					
						
							|  |  |  |                                             groupToOtherCutoff: | 
					
						
							|  |  |  |                                                 total > 50 ? 25 : total > 10 ? 3 : 0, | 
					
						
							| 
									
										
										
										
											2023-12-06 03:07:36 +01:00
										 |  |  |                                         }).SetStyle("width: 75%; height: 600px"), | 
					
						
							|  |  |  |                                         new TagRenderingChart(<any>overview._meta, tr, { | 
					
						
							|  |  |  |                                             groupToOtherCutoff: | 
					
						
							|  |  |  |                                                 total > 50 ? 25 : total > 10 ? 3 : 0, | 
					
						
							|  |  |  |                                             chartType: "doughnut", | 
					
						
							|  |  |  |                                             chartclasses: "w-8 h-8", | 
					
						
							|  |  |  |                                             sort: true, | 
					
						
							|  |  |  |                                         }).SetStyle("width: 25rem"), | 
					
						
							|  |  |  |                                         new Title("By number of modifications", 4).SetClass("p-2"), | 
					
						
							|  |  |  |                                         new StackedRenderingChart( | 
					
						
							|  |  |  |                                             tr, | 
					
						
							|  |  |  |                                             <any>Utils.Clone(overview._meta), | 
					
						
							|  |  |  |                                             { | 
					
						
							|  |  |  |                                                 period: diffInDays <= 367 ? "day" : "month", | 
					
						
							|  |  |  |                                                 groupToOtherCutoff: total > 50 ? 10 : 0, | 
					
						
							|  |  |  |                                                 sumFields: valuesToSum, | 
					
						
							|  |  |  |                                             } | 
					
						
							|  |  |  |                                         ).SetStyle("width: 100%; height: 600px"), | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                                     ]).SetClass("block border-2 border-subtle p-2 m-2 rounded-xl") | 
					
						
							|  |  |  |                                 ) | 
					
						
							|  |  |  |                             } catch (e) { | 
					
						
							|  |  |  |                                 console.log("Could not generate a chart", e) | 
					
						
							|  |  |  |                                 elements.push( | 
					
						
							|  |  |  |                                     new FixedUiElement( | 
					
						
							|  |  |  |                                         "No relevant information for " + tr.question.txt | 
					
						
							|  |  |  |                                     ) | 
					
						
							|  |  |  |                                 ) | 
					
						
							|  |  |  |                             } | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-20 13:33:38 +01:00
										 |  |  |                         elements.push( | 
					
						
							|  |  |  |                             new SubtleButton(undefined, "Download as csv").onClick(() => { | 
					
						
							|  |  |  |                                 const data = GeoOperations.toCSV(overview._meta, { | 
					
						
							|  |  |  |                                     ignoreTags: | 
					
						
							|  |  |  |                                         /^((deletion:node)|(import:node)|(move:node)|(soft-delete:))/, | 
					
						
							|  |  |  |                                 }) | 
					
						
							|  |  |  |                                 Utils.offerContentsAsDownloadableFile(data, "statistics.csv", { | 
					
						
							|  |  |  |                                     mimetype: "text/csv", | 
					
						
							| 
									
										
										
										
											2024-02-09 23:05:05 +01:00
										 |  |  |                                 }) | 
					
						
							| 
									
										
										
										
											2024-02-20 13:33:38 +01:00
										 |  |  |                             }) | 
					
						
							|  |  |  |                         ) | 
					
						
							| 
									
										
										
										
											2024-02-09 23:05:05 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                         return new Combine(elements) | 
					
						
							|  |  |  |                     }, | 
					
						
							| 
									
										
										
										
											2023-04-24 03:22:43 +02:00
										 |  |  |                     [filteredLayer.currentFilter] | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 ) | 
					
						
							|  |  |  |             ).SetClass("block w-full h-full"), | 
					
						
							| 
									
										
										
										
											2022-08-22 13:34:47 +02:00
										 |  |  |         ]) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         this.SetClass("block w-full h-full") | 
					
						
							| 
									
										
										
										
											2022-08-22 13:34:47 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-08-20 12:46:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-15 16:26:43 +02:00
										 |  |  | class StatisticsGUI extends VariableUiElement { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     private static readonly homeUrl = | 
					
						
							| 
									
										
										
										
											2023-01-09 20:38:05 +01:00
										 |  |  |         "https://raw.githubusercontent.com/pietervdvn/MapComplete-data/main/changeset-metadata/" | 
					
						
							| 
									
										
										
										
											2022-08-22 13:34:47 +02:00
										 |  |  |     private static readonly stats_files = "file-overview.json" | 
					
						
							| 
									
										
										
										
											2022-08-18 23:37:44 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     constructor() { | 
					
						
							|  |  |  |         const index = UIEventSource.FromPromise( | 
					
						
							|  |  |  |             Utils.downloadJson(StatisticsGUI.homeUrl + StatisticsGUI.stats_files) | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         super( | 
					
						
							|  |  |  |             index.map((paths) => { | 
					
						
							|  |  |  |                 if (paths === undefined) { | 
					
						
							|  |  |  |                     return new Loading("Loading overview...") | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2022-08-02 19:50:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-15 16:26:43 +02:00
										 |  |  |                 return new StatsticsForOverviewFile(StatisticsGUI.homeUrl, paths) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             }) | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2022-08-24 16:02:16 +02:00
										 |  |  |         this.SetClass("block w-full h-full") | 
					
						
							| 
									
										
										
										
											2022-08-02 19:50:17 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-18 23:37:44 +02:00
										 |  |  | class ChangesetsOverview { | 
					
						
							|  |  |  |     private static readonly theme_remappings = { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         metamap: "maps", | 
					
						
							|  |  |  |         groen: "buurtnatuur", | 
					
						
							| 
									
										
										
										
											2022-08-18 23:37:44 +02:00
										 |  |  |         "updaten van metadata met mapcomplete": "buurtnatuur", | 
					
						
							|  |  |  |         "Toevoegen of dit natuurreservaat toegangkelijk is": "buurtnatuur", | 
					
						
							|  |  |  |         "wiki:mapcomplete/fritures": "fritures", | 
					
						
							|  |  |  |         "wiki:MapComplete/Fritures": "fritures", | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         lits: "lit", | 
					
						
							|  |  |  |         pomp: "cyclofix", | 
					
						
							| 
									
										
										
										
											2022-08-18 23:37:44 +02:00
										 |  |  |         "wiki:user:joost_schouppe/campersite": "campersite", | 
					
						
							|  |  |  |         "wiki-user-joost_schouppe-geveltuintjes": "geveltuintjes", | 
					
						
							|  |  |  |         "wiki-user-joost_schouppe-campersite": "campersite", | 
					
						
							|  |  |  |         "wiki-User-joost_schouppe-campersite": "campersite", | 
					
						
							|  |  |  |         "wiki-User-joost_schouppe-geveltuintjes": "geveltuintjes", | 
					
						
							|  |  |  |         "wiki:User:joost_schouppe/campersite": "campersite", | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         arbres: "arbres_llefia", | 
					
						
							|  |  |  |         aed_brugge: "aed", | 
					
						
							| 
									
										
										
										
											2022-08-18 23:37:44 +02:00
										 |  |  |         "https://llefia.org/arbres/mapcomplete.json": "arbres_llefia", | 
					
						
							|  |  |  |         "https://llefia.org/arbres/mapcomplete1.json": "arbres_llefia", | 
					
						
							|  |  |  |         "toevoegen of dit natuurreservaat toegangkelijk is": "buurtnatuur", | 
					
						
							|  |  |  |         "testing mapcomplete 0.0.0": "buurtnatuur", | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         entrances: "indoor", | 
					
						
							|  |  |  |         "https://raw.githubusercontent.com/osmbe/play/master/mapcomplete/geveltuinen/geveltuinen.json": | 
					
						
							|  |  |  |             "geveltuintjes", | 
					
						
							| 
									
										
										
										
											2022-08-18 23:37:44 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     public readonly _meta: ChangeSetData[] | 
					
						
							| 
									
										
										
										
											2022-08-18 23:37:44 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     private constructor(meta: ChangeSetData[]) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         this._meta = Utils.NoNull(meta) | 
					
						
							| 
									
										
										
										
											2022-08-18 23:37:44 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-09 23:05:05 +01:00
										 |  |  |     public static fromDirtyData(meta: ChangeSetData[]): ChangesetsOverview { | 
					
						
							| 
									
										
										
										
											2023-04-24 03:22:43 +02:00
										 |  |  |         return new ChangesetsOverview(meta?.map((cs) => ChangesetsOverview.cleanChangesetData(cs))) | 
					
						
							| 
									
										
										
										
											2022-09-14 17:58:10 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-18 23:37:44 +02:00
										 |  |  |     private static cleanChangesetData(cs: ChangeSetData): ChangeSetData { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         if (cs === undefined) { | 
					
						
							| 
									
										
										
										
											2022-08-22 13:34:47 +02:00
										 |  |  |             return undefined | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         if (cs.properties.editor?.startsWith("iD")) { | 
					
						
							|  |  |  |             // We also fetch based on hashtag, so some edits with iD show up as well
 | 
					
						
							| 
									
										
										
										
											2022-08-22 13:34:47 +02:00
										 |  |  |             return undefined | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-08-18 23:37:44 +02:00
										 |  |  |         if (cs.properties.theme === undefined) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             cs.properties.theme = cs.properties.comment.substr( | 
					
						
							|  |  |  |                 cs.properties.comment.lastIndexOf("#") + 1 | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2022-08-18 23:37:44 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         cs.properties.theme = cs.properties.theme.toLowerCase() | 
					
						
							|  |  |  |         const remapped = ChangesetsOverview.theme_remappings[cs.properties.theme] | 
					
						
							|  |  |  |         cs.properties.theme = remapped ?? cs.properties.theme | 
					
						
							|  |  |  |         if (cs.properties.theme.startsWith("https://raw.githubusercontent.com/")) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             cs.properties.theme = | 
					
						
							|  |  |  |                 "gh://" + cs.properties.theme.substr("https://raw.githubusercontent.com/".length) | 
					
						
							| 
									
										
										
										
											2022-08-18 23:37:44 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         if (cs.properties.modify + cs.properties.delete + cs.properties.create == 0) { | 
					
						
							|  |  |  |             cs.properties.theme = "EMPTY CS" | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         try { | 
					
						
							|  |  |  |             cs.properties.host = new URL(cs.properties.host).host | 
					
						
							| 
									
										
										
										
											2022-10-27 01:50:01 +02:00
										 |  |  |         } catch (e) {} | 
					
						
							| 
									
										
										
										
											2022-08-18 23:37:44 +02:00
										 |  |  |         return cs | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-04-24 03:22:43 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     public filter(predicate: (cs: ChangeSetData) => boolean) { | 
					
						
							|  |  |  |         return new ChangesetsOverview(this._meta.filter(predicate)) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public sum(key: string, excludeThemes: Set<string>): number { | 
					
						
							|  |  |  |         let s = 0 | 
					
						
							|  |  |  |         for (const feature of this._meta) { | 
					
						
							|  |  |  |             if (excludeThemes.has(feature.properties.theme)) { | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             const parsed = Number(feature.properties[key]) | 
					
						
							|  |  |  |             if (!isNaN(parsed)) { | 
					
						
							|  |  |  |                 s += parsed | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return s | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-08-18 23:37:44 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2022-08-02 19:50:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-09 23:05:05 +01:00
										 |  |  | interface ChangeSetData extends Feature<Polygon> { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     id: number | 
					
						
							|  |  |  |     type: "Feature" | 
					
						
							|  |  |  |     geometry: { | 
					
						
							|  |  |  |         type: "Polygon" | 
					
						
							|  |  |  |         coordinates: [number, number][][] | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     properties: { | 
					
						
							|  |  |  |         check_user: null | 
					
						
							|  |  |  |         reasons: [] | 
					
						
							|  |  |  |         tags: [] | 
					
						
							|  |  |  |         features: [] | 
					
						
							|  |  |  |         user: string | 
					
						
							|  |  |  |         uid: string | 
					
						
							|  |  |  |         editor: string | 
					
						
							|  |  |  |         comment: string | 
					
						
							|  |  |  |         comments_count: number | 
					
						
							|  |  |  |         source: string | 
					
						
							|  |  |  |         imagery_used: string | 
					
						
							|  |  |  |         date: string | 
					
						
							|  |  |  |         reviewed_features: [] | 
					
						
							|  |  |  |         create: number | 
					
						
							|  |  |  |         modify: number | 
					
						
							|  |  |  |         delete: number | 
					
						
							|  |  |  |         area: number | 
					
						
							|  |  |  |         is_suspect: boolean | 
					
						
							|  |  |  |         harmful: any | 
					
						
							|  |  |  |         checked: boolean | 
					
						
							|  |  |  |         check_date: any | 
					
						
							|  |  |  |         host: string | 
					
						
							|  |  |  |         theme: string | 
					
						
							|  |  |  |         imagery: string | 
					
						
							|  |  |  |         language: string | 
					
						
							| 
									
										
										
										
											2022-08-02 19:50:17 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2023-04-24 03:22:43 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | new StatisticsGUI().AttachTo("main") |