Add theme introspecting mapcomplete changes

This commit is contained in:
pietervdvn 2022-01-16 02:00:55 +01:00
parent ccb548816f
commit 2e2a6965e7
8 changed files with 275 additions and 47 deletions

View file

@ -83,7 +83,7 @@ export default class GeoJsonSource implements FeatureSourceForLayer, Tiled {
if (self.layer.layerDef.source.mercatorCrs) {
json = GeoOperations.GeoJsonToWGS84(json)
}
const time = new Date();
const newFeatures: { feature: any, freshness: Date } [] = []
let i = 0;

View file

@ -2,7 +2,7 @@ import {Utils} from "../Utils";
export default class Constants {
public static vNumber = "0.14.0-alpha-5";
public static vNumber = "0.14.0-rc-1";
public static ImgurApiKey = '7070e7167f0a25a'
public static readonly mapillary_client_token_v4 = "MLY|4441509239301885|b40ad2d3ea105435bd40c7e76993ae85"

View file

@ -5,7 +5,7 @@ import Combine from "../Base/Combine";
import {FixedUiElement} from "../Base/FixedUiElement";
import {Utils} from "../../Utils";
import BaseUIElement from "../BaseUIElement";
import Translations from "../i18n/Translations";
import Svg from "../../Svg";
export default class Histogram<T> extends VariableUiElement {
@ -13,9 +13,9 @@ export default class Histogram<T> extends VariableUiElement {
"#ff5858",
"#ffad48",
"#ffff59",
"#9d62d9",
"#56bd56",
"#63a9ff",
"#9d62d9",
"#fa61fa"
]
@ -24,6 +24,51 @@ export default class Histogram<T> extends VariableUiElement {
countTitle: string | BaseUIElement,
assignColor?: (t0: string) => string
) {
const sortMode = new UIEventSource<"name" | "name-rev" | "count" | "count-rev">("name")
const sortName = new VariableUiElement(sortMode.map(m => {
switch (m) {
case "name":
return Svg.up_svg()
case "name-rev":
return Svg.up_svg().SetStyle("transform: rotate(180deg)")
default:
return Svg.circle_svg()
}
}))
const titleHeader = new Combine([sortName.SetClass("w-4 mr-2"), title]).SetClass("flex")
.onClick(() => {
if (sortMode.data === "name") {
sortMode.setData("name-rev")
} else {
sortMode.setData("name")
}
})
const sortCount = new VariableUiElement(sortMode.map(m => {
switch (m) {
case "count":
return Svg.up_svg()
case "count-rev":
return Svg.up_svg().SetStyle("transform: rotate(180deg)")
default:
return Svg.circle_svg()
}
}))
const countHeader = new Combine([sortCount.SetClass("w-4 mr-2"), countTitle]).SetClass("flex").onClick(() => {
if (sortMode.data === "count-rev") {
sortMode.setData("count")
} else {
sortMode.setData("count-rev")
}
})
const header = [
titleHeader,
countHeader
]
super(values.map(values => {
if (values === undefined) {
@ -39,7 +84,21 @@ export default class Histogram<T> extends VariableUiElement {
}
const keys = Array.from(counts.keys());
keys.sort()
switch (sortMode.data) {
case "name":
keys.sort()
break;
case "name-rev":
keys.sort().reverse()
break;
case "count":
keys.sort((k0, k1) => counts.get(k0) - counts.get(k1))
break;
case "count-rev":
keys.sort((k0, k1) => counts.get(k1) - counts.get(k0))
break;
}
const max = Math.max(...Array.from(counts.values()))
@ -57,7 +116,7 @@ export default class Histogram<T> extends VariableUiElement {
}
return new Table(
[Translations.W(title), countTitle],
header,
keys.map(key => [
key,
new Combine([
@ -69,6 +128,6 @@ export default class Histogram<T> extends VariableUiElement {
]),
keys.map(_ => ["width: 20%"])
).SetClass("w-full");
}));
}, [sortMode]));
}
}

View file

@ -399,12 +399,12 @@ export default class SpecialVisualizations {
},
{
name: "title",
doc: "The text to put above the given values column",
doc: "This text will be placed above the texts (in the first column of the visulasition)",
defaultValue: ""
},
{
name: "countHeader",
doc: "The text to put above the counts",
doc: "This text will be placed above the bars",
defaultValue: ""
},
{

View file

@ -137,14 +137,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
}
public static NoNull<T>(array: T[]): T[] {
const ls: T[] = [];
for (const t of array) {
if (t === undefined || t === null) {
continue;
}
ls.push(t);
}
return ls;
return array.filter(o => o !== undefined && o !== null)
}
public static Hist(array: string[]): Map<string, number> {

View file

@ -1,3 +1,170 @@
{
"id": "mapcomplete-changes",
"title": {
"en": "Changes made with MapComplete"
},
"shortDescription": {
"en": "Shows changes made by MapComplete"
},
"description": {
"en": "This maps shows all the changes made with MapComplete"
},
"language": [
"en"
],
"maintainer": "",
"icon": "./assets/svg/logo.svg",
"hideFromOverview": true,
"version": "0",
"startLat": 0,
"startLon": 0,
"startZoom": 1,
"widenFactor": 0.05,
"clustering": false,
"layers": [
{
"id": "mapcomplete-changes",
"name": {
"en": "Changeset centers"
},
"minzoom": 0,
"source": {
"osmTags": "editor~*",
"geoJson": "https://raw.githubusercontent.com/pietervdvn/MapComplete-data/main/mapcomplete-changes/tile_{z}_{x}_{y}.geojson",
"geoJsonZoomLevel": 8,
"maxCacheAge": 0
},
"calculatedTags": [
"_last_edit:contributor:lc:=feat.properties['_last_edit:contributor'].toLowerCase()"
],
"title": {
"render": {
"en": "Changeset for {theme}"
}
},
"description": {
"en": "Shows all MapComplete changes"
},
"tagRenderings": [
{
"id": "contributor",
"render": {
"en": "Change made by <a href='https://openstreetmap.org/user/{_last_edit:contributor}' target='_blank'>{_last_edit:contributor}</a>"
}
},
{
"id": "theme",
"render": {
"en": "Change with theme <a href='https://mapcomplete.osm.be/{theme}'>{theme}</a>"
},
"mappings": [
{
"if": "theme~http.*",
"then": {
"en": "Change with <b>unofficial</b> theme <a href='https://mapcomplete.osm.be/theme.html?userlayout={theme}'>{theme}</a>"
}
}
]
}
],
"mapRendering": [
{
"location": [
"point",
"centroid"
],
"icon": {"render":"teardrop:#00cc00",
"mappings": [{"if":"theme=aed","then":"./assets/themes/aed/logo.svg"},{"if":"theme=aed_brugge","then":"./assets/themes/aed/logo.svg"},{"if":"theme=artwork","then":"./assets/themes/artwork/artwork.svg"},{"if":"theme=benches","then":"./assets/themes/benches/bench_poi.svg"},{"if":"theme=bicyclelib","then":"./assets/themes/bicyclelib/logo.svg"},{"if":"theme=binoculars","then":"./assets/layers/binocular/telescope.svg"},{"if":"theme=bookcases","then":"./assets/themes/bookcases/bookcase.svg"},{"if":"theme=buurtnatuur","then":"./assets/themes/buurtnatuur/groen_logo.svg"},{"if":"theme=cafes_and_pubs","then":"./assets/layers/cafe_pub/pub.svg"},{"if":"theme=campersite","then":"./assets/themes/campersite/caravan.svg"},{"if":"theme=charging_stations","then":"./assets/themes/charging_stations/logo.svg"},{"if":"theme=climbing","then":"./assets/themes/climbing/climbing_icon.svg"},{"if":"theme=cycle_highways","then":"./assets/themes/cycle_highways/fietssnelwegen-logo.svg"},{"if":"theme=cycle_infra","then":"./assets/themes/cycle_infra/cycle-infra.svg"},{"if":"theme=cyclenodes","then":"./assets/themes/cyclenodes/logo.svg"},{"if":"theme=cyclestreets","then":"./assets/themes/cyclestreets/F111.svg"},{"if":"theme=cyclofix","then":"./assets/themes/cyclofix/logo.svg"},{"if":"theme=drinking_water","then":"./assets/themes/drinking_water/logo.svg"},{"if":"theme=entrances","then":"./assets/layers/entrance/door.svg"},{"if":"theme=etymology","then":"./assets/layers/etymology/logo.svg"},{"if":"theme=facadegardens","then":"./assets/themes/facadegardens/geveltuin.svg"},{"if":"theme=food","then":"./assets/layers/food/restaurant.svg"},{"if":"theme=fritures","then":"./assets/themes/fritures/logo.svg"},{"if":"theme=fruit_trees","then":"./assets/themes/fruit_trees/fruit_tree.svg"},{"if":"theme=ghostbikes","then":"./assets/themes/ghostbikes/logo.svg"},{"if":"theme=grb","then":"./assets/themes/grb_import/housenumber_blank.svg"},{"if":"theme=grb_fixme","then":"./assets/svg/bug.svg"},{"if":"theme=missing_streets","then":"./assets/svg/robot.svg"},{"if":"theme=hackerspaces","then":"./assets/themes/hackerspaces/glider.svg"},{"if":"theme=hailhydrant","then":"./assets/themes/hailhydrant/logo.svg"},{"if":"theme=mapcomplete-changes","then":"./assets/svg/logo.svg"},{"if":"theme=maps","then":"./assets/themes/maps/logo.svg"},{"if":"theme=nature","then":"./assets/themes/nature/logo.svg"},{"if":"theme=natuurpunt","then":"./assets/themes/natuurpunt/natuurpunt.png"},{"if":"theme=notes","then":"./assets/svg/resolved.svg"},{"if":"theme=observation_towers","then":"./assets/layers/observation_tower/Tower_observation.svg"},{"if":"theme=openwindpowermap","then":"./assets/themes/openwindpowermap/wind_turbine.svg"},{"if":"theme=parkings","then":"./assets/themes/parkings/parkings.svg"},{"if":"theme=personal","then":"./assets/svg/addSmall.svg"},{"if":"theme=play_forests","then":"./assets/layers/play_forest/icon.svg"},{"if":"theme=playgrounds","then":"./assets/themes/playgrounds/playground.svg"},{"if":"theme=postal_codes","then":"./assets/themes/postal_codes/townhall.svg"},{"if":"theme=postboxes","then":"./assets/themes/postboxes/postbox.svg"},{"if":"theme=shops","then":"./assets/themes/shops/shop.svg"},{"if":"theme=sidewalks","then":"./assets/svg/bug.svg"},{"if":"theme=speelplekken","then":"./assets/themes/speelplekken/logo.svg"},{"if":"theme=sport_pitches","then":"./assets/layers/sport_pitch/table_tennis.svg"},{"if":"theme=street_lighting","then":"./assets/layers/street_lamps/street_lamp.svg"},{"if":"theme=street_lighting_assen","then":"./assets/layers/street_lamps/street_lamp.svg"},{"if":"theme=surveillance","then":"./assets/themes/surveillance/logo.svg"},{"if":"theme=toerisme_vlaanderen","then":"./assets/svg/teardrop_with_hole_green.svg"},{"if":"theme=toilets","then":"./assets/themes/toilets/toilets.svg"},{"if":"theme=trees","then":"./assets/themes/trees/logo.svg"},{"if":"theme=uk_addresses","then":"./assets/themes/uk_addresses/housenumber_unknown.svg"},{"if":"theme=waste_basket","then":"./assets/themes/waste_basket/waste_basket.svg"}]
}
},
"iconSize": "30,30,bottom"
}
],
"filter": [
{
"id": "theme-search",
"options": [
{
"osmTags": "theme~.*{search}.*",
"fields": [
{
"name": "search"
}
],
"question": {
"en": "Themename contains {search}"
}
}
]
},
{
"id": "created_by",
"options": [
{
"osmTags": "_last_edit:contributor:lc~.*{search}.*",
"fields": [
{
"name": "search"
}
],
"question": {
"en": "Made by contributor {search}"
}
}
]
},
{
"id": "not_created_by",
"options": [
{
"osmTags": "_last_edit:contributor:lc!~.*{search}.*",
"fields": [
{
"name": "search"
}
],
"question": {
"en": "<b>Not</b> made by contributor {search}"
}
}
]
}
]
},
{
"builtin": "current_view",
"override": {
"title": "Statistics on changesets in the current view",
"tagRenderings": [
{
"id": "link_to_more",
"render": {
"en": "More statistics can be found <a href='https://github.com/pietervdvn/MapComplete/tree/develop/Docs/Tools/graphs' target='_blank'>here</a>"
}
},
{
"id": "hist_themes",
"render": "{histogram(_embedded_cs:themes, Themename, Number of changesets)}"
},
{
"id": "hist_themes",
"render": "{histogram(_embedded_cs:users, Contributor, Number of changesets)}"
}
],
"calculatedTags": [
"_embedded_cs=feat.overlapWith('mapcomplete-changes').map(f => f.feat.properties)",
"_embedded_cs:themes=feat.get('_embedded_cs').map(cs => cs.theme)",
"_embedded_cs:users=feat.get('_embedded_cs').map(cs => cs['_last_edit:contributor'])"
],
"+mapRendering": [{
"location": [
"point"
],
"icon":"statistics:black",
"iconSize": "30,30,center"
}]
}
}
]
}

View file

@ -748,14 +748,14 @@ video {
right: 0.75rem;
}
.top-4 {
top: 1rem;
}
.bottom-0 {
bottom: 0px;
}
.top-4 {
top: 1rem;
}
.right-1\/3 {
right: 33.333333%;
}
@ -1096,6 +1096,10 @@ video {
width: 6rem;
}
.w-6 {
width: 1.5rem;
}
.w-10 {
width: 2.5rem;
}
@ -1120,8 +1124,8 @@ video {
width: 2.75rem;
}
.w-6 {
width: 1.5rem;
.w-4 {
width: 1rem;
}
.w-16 {
@ -1182,23 +1186,6 @@ video {
transform: var(--tw-transform);
}
@-webkit-keyframes spin {
to {
transform: rotate(360deg);
}
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
.animate-spin {
-webkit-animation: spin 1s linear infinite;
animation: spin 1s linear infinite;
}
@-webkit-keyframes pulse {
50% {
opacity: .5;
@ -1216,6 +1203,23 @@ video {
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
@-webkit-keyframes spin {
to {
transform: rotate(360deg);
}
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
.animate-spin {
-webkit-animation: spin 1s linear infinite;
animation: spin 1s linear infinite;
}
.cursor-pointer {
cursor: pointer;
}
@ -1339,6 +1343,10 @@ video {
border-radius: 0.5rem;
}
.rounded-sm {
border-radius: 0.125rem;
}
.rounded-l {
border-top-left-radius: 0.25rem;
border-bottom-left-radius: 0.25rem;
@ -1564,16 +1572,16 @@ video {
line-height: 1.75rem;
}
.text-2xl {
font-size: 1.5rem;
line-height: 2rem;
}
.text-lg {
font-size: 1.125rem;
line-height: 1.75rem;
}
.text-2xl {
font-size: 1.5rem;
line-height: 2rem;
}
.text-4xl {
font-size: 2.25rem;
line-height: 2.5rem;

View file

@ -112,12 +112,13 @@ class LayerOverviewUtils {
writeFileSync("./assets/generated/known_layers.json", JSON.stringify(Array.from(sharedLayers.values())))
/*
writeFileSync('./assets/themes/mapcomplete-changes/icons-mapping.txt', JSON.stringify(
Array.from(sharedThemes.values()).map(th => ({
if: "theme=" + th.id,
then: th.icon
}))
))
)) //*/
}