Merge branch 'develop' into feature/upload-gpx-to-osm

This commit is contained in:
pietervdvn 2022-08-02 19:51:00 +02:00
commit 9424364f3f
7 changed files with 233 additions and 96 deletions

View file

@ -27,7 +27,10 @@ Devcontainer (see more details later).
To develop and build MapComplete, you
0. Make a fork and clone the repository. (We recommend a shallow clone with `git clone --filter=blob:none <repo>`)
0. Install the nodejs version specified in [.tool-versions](./.tool-versions)
0. Install `python3` if you do not have it already
- On linux: `sudo apt install python3`
- On windows: find the latest download on the [Python Releases for Windows page](https://www.python.org/downloads/windows/)
0. Install the nodejs version specified in [/.tool-versions](/.tool-versions)
- On linux: install npm first `sudo apt install npm`, then install `n` using npm: ` npm install -g n`, which can
then install node with `n install <node-version>`
- You can [use asdf to manage your runtime versions](https://asdf-vm.com/).
@ -72,11 +75,12 @@ To use the WSL in Visual Studio Code:
or `userlayout=true#<layout configuration>` as [Query parameter](URL_Parameters.md). Note that the shorter URLs (
e.g. `bookcases.html`, `aed.html`, ...) _don't_ exist on the development version.
### Dependencie
Dependencies
------------
`make` , `python3` `g++`
(run `nix-env -iA nixos.gnumake nixos.gdc nixos.python3`)
(Nix users may run `nix-env -iA nixos.gnumake nixos.gdc nixos.python3`)
Automatic deployment
--------------------

102
UI/StatisticsGUI.ts Normal file
View file

@ -0,0 +1,102 @@
/**
* The statistics-gui shows statistics from previous MapComplete-edits
*/
import {UIEventSource} from "../Logic/UIEventSource";
import {VariableUiElement} from "./Base/VariableUIElement";
import ChartJs from "./Base/ChartJs";
import Loading from "./Base/Loading";
import {Utils} from "../Utils";
import Combine from "./Base/Combine";
export default class StatisticsGUI {
public static setup(): void{
new VariableUiElement(index.map(paths => {
if (paths === undefined) {
return new Loading("Loading overview...")
}
const downloaded = new UIEventSource<{ features: ChangeSetData[] }[]>([])
for (const filepath of paths) {
Utils.downloadJson(homeUrl + filepath).then(data => {
downloaded.data.push(data)
downloaded.ping()
})
}
return new VariableUiElement(downloaded.map(downloaded => {
const themeBreakdown = new Map<string, number>()
for (const feats of downloaded) {
console.log("Feats:", feats)
for (const feat of feats.features) {
const key = feat.properties.metadata.theme
const count = themeBreakdown.get(key) ?? 0
themeBreakdown.set(key, count + 1)
}
}
const keys = Array.from(themeBreakdown.keys())
const values = keys.map( k => themeBreakdown.get(k))
console.log(keys, values)
return new Combine([
"Got " + downloaded.length + " files out of " + paths.length,
new ChartJs({
type: "pie",
data: {
datasets: [{data: values}],
labels: keys
}
}).SetClass("w-1/3 h-full")
]).SetClass("block w-full h-full")
})).SetClass("block w-full h-full")
})).SetClass("block w-full h-full").AttachTo("maindiv")
}
}
const homeUrl = "https://raw.githubusercontent.com/pietervdvn/MapComplete/develop/Docs/Tools/stats/"
const stats_files = "file-overview.json"
const index = UIEventSource.FromPromise(Utils.downloadJson(homeUrl + stats_files))
interface ChangeSetData {
"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,
"metadata": {
"host": string,
"theme": string,
"imagery": string,
"language": string
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

View file

@ -325,6 +325,82 @@
}
]
},
{
"id": "hydrant-diameter",
"question": {
"en": "What is the pipe diameter of this hydrant?"
},
"freeform": {
"key": "fire_hydrant:diameter",
"placeholder": {
"en": "Pipe diameter"
},
"type": "int"
},
"render": {
"en": "Pipe diameter: {canonical(fire_hydrant:diameter)}"
}
},
{
"id": "hydrant-couplings",
"question": {
"en": "What kind of couplings does this hydrant have?"
},
"freeform": {
"key": "couplings:type",
"placeholder": {
"en": "Coupling type"
},
"type": "string"
},
"mappings": [
{
"if": "couplings:type=Storz",
"then": {
"en": "Storz coupling"
},
"icon": {
"path": "./assets/layers/hydrant/storz.jpg",
"class": "large"
}
},
{
"if": "couplings:type=UNI",
"then": {
"en": "UNI coupling"
}
},
{
"if": "couplings:type=Barcelona",
"then": {
"en": "Barcelona coupling"
},
"icon": {
"path": "./assets/layers/hydrant/barcelona.jpg",
"class": "large"
}
}
],
"multiAnswer": true,
"render": {
"en": "Couplings: {couplings:type}"
}
},
{
"id": "hydrant-couplings-diameters",
"question": {
"en": "What diameter are the couplings of this hydrant?"
},
"freeform": {
"key": "couplings:diameters",
"placeholder": {
"en": "Coupling diameters"
}
},
"render": {
"en": "Coupling diameters: {couplings:diameters}"
}
},
"images"
],
"presets": [
@ -375,5 +451,31 @@
"render": "8"
}
}
],
"units": [
{
"applicableUnits": [
{
"default": true,
"canonicalDenomination": "",
"alternativeDenomination": [
"mm",
"millimeter",
"millimeters"
],
"human": {
"en": "millimeters",
"nl": "millimeter"
},
"humanSingular": {
"en": "millimeter",
"nl": "millimeter"
}
}
],
"appliesToKey": [
"fire_hydrant:diameter"
]
}
]
}

View file

@ -0,0 +1,22 @@
[
{
"path": "barcelona.jpg",
"license": "CC-BY-SA",
"authors": [
"CLIGNER"
],
"sources": [
"https://commons.wikimedia.org/wiki/File:Gama_racores_UNE23400_ligatura.JPG"
]
},
{
"path": "storz.jpg",
"license": "CC-BY-SA",
"authors": [
"Karl Gruber"
],
"sources": [
"https://commons.wikimedia.org/wiki/File:Festkupplung.jpg"
]
}
]

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

93
test.ts
View file

@ -1,93 +0,0 @@
import {Utils} from "./Utils";
import Loading from "./UI/Base/Loading";
import {UIEventSource} from "./Logic/UIEventSource";
import {VariableUiElement} from "./UI/Base/VariableUIElement";
import ChartJs from "./UI/Base/ChartJs";
import Combine from "./UI/Base/Combine";
const homeUrl = "https://raw.githubusercontent.com/pietervdvn/MapComplete/develop/Docs/Tools/stats/"
const stats_files = "file-overview.json"
const index = UIEventSource.FromPromise(Utils.downloadJson(homeUrl + stats_files))
interface ChangeSetData {
"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,
"metadata": {
"host": string,
"theme": string,
"imagery": string,
"language": string
}
}
}
new VariableUiElement(index.map(paths => {
if (paths === undefined) {
return new Loading("Loading overview...")
}
const downloaded = new UIEventSource<{ features: ChangeSetData[] }[]>([])
for (const filepath of paths) {
Utils.downloadJson(homeUrl + filepath).then(data => {
downloaded.data.push(data)
downloaded.ping()
})
}
return new VariableUiElement(downloaded.map(downloaded => {
const themeBreakdown = new Map<string, number>()
for (const feats of downloaded) {
console.log("Feats:", feats)
for (const feat of feats.features) {
const key = feat.properties.metadata.theme
const count = themeBreakdown.get(key) ?? 0
themeBreakdown.set(key, count + 1)
}
}
const keys = Array.from(themeBreakdown.keys())
const values = keys.map( k => themeBreakdown.get(k))
console.log(keys, values)
return new Combine([
"Got " + downloaded.length + " files out of " + paths.length,
new ChartJs({
type: "pie",
data: {
datasets: [{data: values}],
labels: keys
}
}).SetClass("w-1/3 h-full")
]).SetClass("block w-full h-full")
})).SetClass("block w-full h-full")
})).SetClass("block w-full h-full").AttachTo("maindiv")