Merge branch 'develop'

This commit is contained in:
Pieter Vander Vennet 2023-05-01 10:08:47 +02:00
commit 8f66e3d992
12 changed files with 344 additions and 128 deletions

View file

@ -1,9 +1,11 @@
# Integrating MapRoulette
[MapRoulette](https://www.maproulette.org/) is a website which has challenges. A challenge is a collection of _microtasks_, i.e. mapping
tasks which can be solved in a few minutes.
[MapRoulette](https://www.maproulette.org/) is a website which has challenges. A challenge is a collection of _microtasks_, i.e. mapping tasks which can be solved in a few minutes.
A perfect example of this is to setup such a challenge to e.g. import new points.
> [Important: always follow the import guidelines if you want to import data.](https://wiki.openstreetmap.org/wiki/Import/Guidelines)
A perfect example of this is to setup such a challenge to e.g. import new points. [Important: always follow the import guidelines if you want to import data.](https://wiki.openstreetmap.org/wiki/Import/Guidelines)
(Another approach to set up a guided import is to create a map note for every point with the [import helper](https://mapcomplete.osm.be/import_helper). This however litters the map notes and will upset mappers if used with to much points. However, this flow is easier to setup as no changes to theme files are needed, nor is a maproulette-account needed)
## The API

View file

@ -1,7 +1,7 @@
import { Utils } from "../Utils"
export default class Constants {
public static vNumber = "0.27.1"
public static vNumber = "0.27.2"
public static ImgurApiKey = "7070e7167f0a25a"
public static readonly mapillary_client_token_v4 =

View file

@ -1,17 +1,17 @@
import Svg from "../../Svg"
import Combine from "../Base/Combine"
import { SubtleButton } from "../Base/SubtleButton"
import {SubtleButton} from "../Base/SubtleButton"
import Translations from "../i18n/Translations"
import BaseUIElement from "../BaseUIElement"
import LayoutConfig, { LayoutInformation } from "../../Models/ThemeConfig/LayoutConfig"
import { ImmutableStore, Store, UIEventSource } from "../../Logic/UIEventSource"
import LayoutConfig, {LayoutInformation} from "../../Models/ThemeConfig/LayoutConfig"
import {ImmutableStore, Store, UIEventSource} from "../../Logic/UIEventSource"
import Loc from "../../Models/Loc"
import UserRelatedState from "../../Logic/State/UserRelatedState"
import { Utils } from "../../Utils"
import {Utils} from "../../Utils"
import Title from "../Base/Title"
import themeOverview from "../../assets/generated/theme_overview.json"
import { Translation } from "../i18n/Translation"
import { TextField } from "../Input/TextField"
import {Translation} from "../i18n/Translation"
import {TextField} from "../Input/TextField"
import Locale from "../i18n/Locale"
import SvelteUIElement from "../Base/SvelteUIElement"
import ThemesList from "./ThemesList.svelte"
@ -37,7 +37,7 @@ export default class MoreScreen extends Combine {
searchTerm = searchTerm.toLowerCase()
if (searchTerm === "personal") {
window.location.href = MoreScreen.createUrlFor(
{ id: "personal" },
{id: "personal"},
false,
state
).data
@ -59,13 +59,13 @@ export default class MoreScreen extends Combine {
(th) =>
th.hideFromOverview == false &&
th.id !== "personal" &&
MoreScreen.MatchesLayoutFunc(th)(searchTerm)
MoreScreen.MatchesLayout(th, searchTerm)
)
if (publicTheme !== undefined) {
window.location.href = MoreScreen.createUrlFor(publicTheme, false, state).data
}
const hiddenTheme = MoreScreen.officialThemes.find(
(th) => th.id !== "personal" && MoreScreen.MatchesLayoutFunc(th)(searchTerm)
(th) => th.id !== "personal" && MoreScreen.MatchesLayout(th, searchTerm)
)
if (hiddenTheme !== undefined) {
window.location.href = MoreScreen.createUrlFor(hiddenTheme, false, state).data
@ -109,6 +109,85 @@ export default class MoreScreen extends Combine {
])
}
/**
* Creates a button linking to the given theme
* @private
*/
public static createLinkButton(
state: {
locationControl?: UIEventSource<Loc>
layoutToUse?: LayoutConfig
},
layout: {
id: string
icon: string
title: any
shortDescription: any
definition?: any
mustHaveLanguage?: boolean
},
isCustom: boolean = false
): BaseUIElement {
const url = MoreScreen.createUrlFor(layout, isCustom, state)
let content = new Combine([
new Translation(
layout.title,
!isCustom && !layout.mustHaveLanguage ? "themes:" + layout.id + ".title" : undefined
),
new Translation(layout.shortDescription)?.SetClass("subtle") ?? "",
]).SetClass("overflow-hidden flex flex-col")
if (state.layoutToUse === undefined) {
// Currently on the index screen: we style the buttons equally large
content = new Combine([content]).SetClass("flex flex-col justify-center h-24")
}
return new SubtleButton(layout.icon, content, {url, newTab: false})
}
public static CreateProffessionalSerivesButton() {
const t = Translations.t.professional.indexPage
return new Combine([
new Title(t.hook, 4),
t.hookMore,
new SubtleButton(undefined, t.button, {url: "./professional.html"}),
]).SetClass("flex flex-col border border-gray-300 p-2 rounded-lg")
}
public static MatchesLayout(layout: {
id: string
title: any
shortDescription: any
keywords?: any[]
}, search: string): boolean {
if(search === undefined){
return true
}
search = search.toLocaleLowerCase()
if (search.length > 3 && layout.id.toLowerCase().indexOf(search) >= 0) {
return true
}
if(layout.id === "personal"){
return false
}
const entitiesToSearch = [
layout.shortDescription,
layout.title,
...(layout.keywords ?? []),
]
for (const entity of entitiesToSearch) {
if (entity === undefined) {
continue
}
const term = entity["*"] ?? entity[Locale.language.data]
if (term?.toLowerCase()?.indexOf(search) >= 0) {
return true
}
}
return false
}
private static createUrlFor(
layout: { id: string; definition?: string },
isCustom: boolean,
@ -164,79 +243,4 @@ export default class MoreScreen extends Combine {
}) ?? new ImmutableStore<string>(`${linkPrefix}`)
)
}
/**
* Creates a button linking to the given theme
* @private
*/
public static createLinkButton(
state: {
locationControl?: UIEventSource<Loc>
layoutToUse?: LayoutConfig
},
layout: {
id: string
icon: string
title: any
shortDescription: any
definition?: any
mustHaveLanguage?: boolean
},
isCustom: boolean = false
): BaseUIElement {
const url = MoreScreen.createUrlFor(layout, isCustom, state)
let content = new Combine([
new Translation(
layout.title,
!isCustom && !layout.mustHaveLanguage ? "themes:" + layout.id + ".title" : undefined
),
new Translation(layout.shortDescription)?.SetClass("subtle") ?? "",
]).SetClass("overflow-hidden flex flex-col")
if (state.layoutToUse === undefined) {
// Currently on the index screen: we style the buttons equally large
content = new Combine([content]).SetClass("flex flex-col justify-center h-24")
}
return new SubtleButton(layout.icon, content, { url, newTab: false })
}
public static CreateProffessionalSerivesButton() {
const t = Translations.t.professional.indexPage
return new Combine([
new Title(t.hook, 4),
t.hookMore,
new SubtleButton(undefined, t.button, { url: "./professional.html" }),
]).SetClass("flex flex-col border border-gray-300 p-2 rounded-lg")
}
private static MatchesLayoutFunc(layout: {
id: string
title: any
shortDescription: any
keywords?: any[]
}): (search: string) => boolean {
return (search: string) => {
search = search.toLocaleLowerCase()
if (layout.id.toLowerCase().indexOf(search) >= 0) {
return true
}
const entitiesToSearch = [
layout.shortDescription,
layout.title,
...(layout.keywords ?? []),
]
for (const entity of entitiesToSearch) {
if (entity === undefined) {
continue
}
const term = entity["*"] ?? entity[Locale.language.data]
if (term?.toLowerCase()?.indexOf(search) >= 0) {
return true
}
}
return false
}
}
}

View file

@ -9,6 +9,7 @@
import ProfessionalServicesButton from "./ProfessionalServicesButton.svelte"
import ThemeButton from "./ThemeButton.svelte"
import { LayoutInformation } from "../../Models/ThemeConfig/LayoutConfig"
import MoreScreen from "./MoreScreen";
export let search: UIEventSource<string>
export let themes: LayoutInformation[]
@ -18,26 +19,7 @@
export let hideThemes: boolean = true
// Filter theme based on search value
$: filteredThemes = themes.filter((theme) => {
if ($search === undefined || $search === "") return true
const srch = $search.toLocaleLowerCase()
if (theme.id.toLowerCase().indexOf(srch) >= 0) {
return true
}
const entitiesToSearch = [theme.shortDescription, theme.title, ...(theme.keywords ?? [])]
for (const entity of entitiesToSearch) {
if (entity === undefined) {
continue
}
const term = entity["*"] ?? entity[Locale.language.data]
if (term?.toLowerCase()?.indexOf(search) >= 0) {
return true
}
}
return false
})
$: filteredThemes = themes.filter((theme) => MoreScreen.MatchesLayout(theme, $search))
</script>
<section>

View file

@ -821,5 +821,46 @@
"render": "1"
}
}
],
"filter": [
"open_now",
{
"id": "sells_second-hand",
"options": [
{
"question": {
"en": "Sells second hand bicycles",
"de": "Verkauft gebrauchte Fahrräder",
"nl": "Verkoopt twedehands fietsen",
"it": "Vende biciclette usate"
},
"osmTags": {
"or": [
"service:bicycle:second_hand=yes",
"service:bicycle:second_hand=only"
]
}
}
]
},
{
"id": "offers_diy_repair",
"options": [
{
"question": {
"en": "Offers DIY bike repair",
"de": "Bietet Selbstreparatur an",
"nl": "Biedt doe-het-zelfreparaties aan",
"it": "Offre riparazioni fai da te"
},
"osmTags": {
"or": [
"service:bicycle:diy=yes",
"service:bicycle:diy=only"
]
}
}
]
}
]
}
}

View file

@ -2,7 +2,7 @@
"id": "maproulette_challenge",
"name": null,
"description": {
"en": "Layer showing tasks of a single MapRoulette challenge. This layer is intended to be reused and extended in themes; refer to the documentation on how to do this.",
"en": "Layer showing tasks of a single MapRoulette challenge. This layer is intended to be reused and extended in themes; refer to [the documentation](https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Integrating_Maproulette.md) on how to do this.",
"de": "Ebene mit Aufgaben einer einzelnen MapRoulette-Herausforderung. Diese Ebene soll in Themen wiederverwendet und erweitert werden; Informationen dazu finden Sie in der Dokumentation.",
"nl": "Laag met taken van een MapRoulette uitdaging"
},
@ -224,4 +224,4 @@
]
}
]
}
}

View file

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.1"
id="svg4"
sodipodi:docname="bicycle_broken.svg"
width="418.33188"
height="319.56787"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs8" />
<sodipodi:namedview
id="namedview6"
pagecolor="#505050"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:pageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="2.2345697"
inkscape:cx="187.50814"
inkscape:cy="207.87"
inkscape:window-width="1920"
inkscape:window-height="995"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<path
path-name="a"
unicode="á"
horiz-adv-x="661"
d="m 137.6798,122.2211 50.33597,-56.105359 -3.74261,-36.808647 -22.20084,-6.419782 c -6.22541,-1.800194 -4.84396,-6.865812 -3.04675,-13.0808814 1.7972,-6.215069 3.33253,-11.2361916 9.55793,-9.43600296 L 240.89058,21.279359 c 6.2151,1.797211 9.80947,8.301683 8.01227,14.516752 -1.8002,6.225415 -8.30863,9.798304 -14.52372,8.001093 l -25.84167,-7.472597 2.48283,24.171323 179.83228,52.00184 -0.75745,-30.282148 c -0.27489,-1.714133 -2.26124,-11.979526 -11.83856,-14.748985 l -27.05188,-7.822553 c -6.2151,-1.797211 -4.82426,-6.860115 -3.02705,-13.075184 1.7972,-6.215069 3.32584,-11.248329 9.54095,-9.451115 l 27.05188,7.822553 c 20.3564,5.88643 27.60616,24.805114 28.68044,35.056818 0.02,0.32804 0.7466,29.061174 1.68585,66.058404 0.0405,0.29229 0.0135,0.56504 0.0219,0.85925 0.4214,16.50693 0.87564,34.62656 1.32103,52.59726 1.17021,46.42161 1.84858,104.70155 1.84858,104.70155 0.15952,6.46883 -4.9564,11.84934 -11.42792,12.01817 -6.4755,0.14742 -11.84663,-4.96577 -12.01817,-11.42792 l -1.8111,-104.64124 -0.84004,-33.02327 -162.39534,89.54277 2.01077,36.24487 7.79114,2.25296 c 5.89801,1.70551 9.28865,7.8705 7.58314,13.76849 -1.70551,5.89799 -7.86316,9.30191 -13.76119,7.59639 l -30.96199,-8.95323 c -5.898,-1.70552 -9.29892,-7.87348 -7.59341,-13.77147 1.70551,-5.89799 7.87348,-9.29893 13.77147,-7.59342 l 2.47853,0.71672 -3.19278,-28.26901 -30.08761,-8.70039 C 158.12031,302.01549 101.38778,331.02765 46.967377,315.29098 -10.324959,298.72384 -14.69457,254.56599 31.079899,206.46822 7.6428176,153.49645 49.677348,91.225109 106.96949,107.79219 c 11.23971,3.25017 21.52202,8.19056 30.71031,14.42891 m 2.18406,32.66181 -42.514931,47.38493 63.776671,18.44221 c 2.68193,-24.39481 -5.4537,-48.24383 -21.26174,-65.82714 m -17.95755,-15.08239 c -6.51556,-4.06972 -13.67945,-7.33882 -21.41243,-9.57495 -44.919457,-12.98929 -72.121191,21.24655 -54.451356,81.56699 -45.92773542,50.06902 -37.4873844,68.08427 7.422655,81.07084 l -2e-5,-1e-5 C 95.493269,305.0166 139.286,283.12987 155.37714,243.46851 L 72.88667,219.61487 c -3.881034,-1.12227 -6.893527,-4.16885 -8.011983,-8.04215 -1.108138,-3.87031 -0.147194,-8.05824 2.551648,-11.05644 l 54.479975,-60.71576 m 33.61016,-2.36447 c 22.16511,23.53361 33.24273,56.4666 28.28868,89.83336 l 1.1e-4,-1.8e-4 21.31426,6.17382 -2.81434,-27.59849 -6.20968,-1.81595 c -5.8926,-1.72425 -9.33512,-7.67453 -7.69144,-13.28848 1.45758,-4.97042 6.3859,-8.01111 11.58641,-7.45474 l -8.74865,-85.662116 -35.72535,39.812776 m 72.89002,93.26803 163.15943,-89.95681 -0.0841,-3.6677 -177.89178,-51.440708 10.67047,104.538498 8.72367,2.55415 c 5.89259,1.72425 9.33512,7.67453 7.68846,13.29877 -1.64368,5.61396 -7.75161,8.77204 -13.64416,7.0477 l -0.43248,-0.12506 z"
id="path2"
sodipodi:nodetypes="cccssssssccccssssscccccccccccsssssscccscsccccccccsccscsccccsccccccccccccccsc" />
<g
inkscape:groupmode="layer"
id="layer1"
inkscape:label="Layer 1"
transform="translate(-17.636971,9.079318)" />
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View file

@ -19,6 +19,14 @@
"https://github.com/streetcomplete/StreetComplete/blob/master/res/graphics/recycling%20icons/beverage_cartons.svg"
]
},
{
"path": "bicycles.svg",
"license": "CC0",
"authors": [
"Antwerpenize Bike Font"
],
"sources": []
},
{
"path": "cans.svg",
"license": "CC-BY-SA",
@ -113,6 +121,14 @@
"https://openclipart.org/detail/175842/basic-light-bulb"
]
},
{
"path": "needles.svg",
"license": "CC0",
"authors": [],
"sources": [
"https://svgsilh.com/image/1294131.html"
]
},
{
"path": "newspaper.svg",
"license": "CC-BY-SA",

View file

@ -0,0 +1,41 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="1280.000000pt" height="1254.000000pt" viewBox="0 0 1280.000000 1254.000000"
preserveAspectRatio="xMidYMid meet">
<metadata>
Created by potrace 1.15, written by Peter Selinger 2001-2017
</metadata>
<g transform="translate(0.000000,1254.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M8952 12530 c-98 -21 -186 -91 -234 -189 -18 -37 -22 -63 -23 -131 0
-154 -25 -123 519 -668 l481 -482 -853 -853 -852 -852 -667 666 c-761 758
-706 714 -873 714 -85 0 -101 -3 -154 -29 -76 -37 -140 -101 -174 -174 -24
-50 -27 -70 -27 -157 0 -171 -24 -140 561 -726 l505 -505 -738 -730 c-406
-401 -1453 -1435 -2328 -2298 -875 -863 -1736 -1715 -1914 -1892 l-325 -322
118 -884 c64 -485 119 -892 121 -903 4 -16 -218 -242 -1040 -1064 -574 -575
-1044 -1046 -1042 -1046 1 -1 138 23 305 54 l303 57 877 876 877 877 840 -130
c462 -71 850 -129 862 -129 21 0 226 202 4233 4159 1125 1111 1115 1101 1125
1101 6 0 230 -220 500 -490 562 -563 540 -545 700 -545 77 0 98 4 147 27 79
37 142 98 181 177 29 60 32 73 32 161 -1 164 36 119 -717 869 -362 360 -658
659 -658 665 0 6 381 392 847 858 l848 848 480 -478 c543 -542 524 -526 670
-527 102 0 171 31 244 110 82 91 107 214 67 335 -18 53 -83 120 -1785 1823
-1565 1567 -1773 1771 -1826 1797 -67 33 -146 44 -213 30z m1211 -3632 c-467
-467 -852 -848 -858 -848 -5 0 -234 224 -507 497 l-498 498 852 852 853 853
502 -502 503 -503 -847 -847z m-1425 -1324 c204 -204 372 -376 372 -381 0 -12
-392 -401 -2740 -2718 -1108 -1094 -2108 -2081 -2222 -2194 l-208 -205 -707
108 c-390 59 -710 110 -712 112 -8 7 -191 1399 -189 1429 3 25 92 118 547 568
l545 537 311 -309 c204 -204 323 -315 347 -326 111 -46 235 23 254 141 13 85
5 95 -334 437 l-317 317 90 91 c50 50 139 136 198 191 l108 101 307 -306 c204
-203 319 -311 344 -322 111 -46 235 23 254 141 13 85 5 96 -332 434 l-314 315
195 195 195 195 308 -307 c169 -168 321 -313 339 -322 49 -24 119 -21 169 9
73 43 106 123 84 206 -10 39 -48 80 -323 357 l-312 312 195 195 195 195 310
-309 c170 -171 323 -315 338 -320 143 -54 286 74 247 220 -10 39 -48 80 -321
354 l-309 310 195 195 195 195 308 -307 c169 -169 320 -312 335 -318 143 -53
286 75 247 221 -10 39 -48 81 -320 354 l-308 310 197 192 197 192 300 -300
c164 -165 312 -307 328 -316 46 -24 145 -14 188 19 67 51 91 154 54 228 -10
19 -152 169 -315 333 l-296 298 260 254 260 253 445 -441 c245 -243 613 -609
818 -813z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View file

@ -273,6 +273,15 @@
]
},
"then": "circle:white;./assets/layers/waste_disposal/waste_disposal.svg"
},
{
"if": {
"and": [
"_waste_amount=1",
"recycling:needles=yes"
]
},
"then": "circle:white;./assets/layers/recycling/needles.svg"
}
]
},
@ -475,6 +484,24 @@
]
},
"then": "circle:white;./assets/layers/waste_disposal/waste_disposal.svg"
},
{
"if": {
"and": [
"_waste_amount>1",
"recycling:needles=yes"
]
},
"then": "circle:white;./assets/layers/recycling/needles.svg"
},
{
"if": {
"and": [
"_waste_amount>1",
"recycling:bicycles=yes"
]
},
"then": "circle:white;./assets/layers/recycling/bicycles.svg"
}
]
}
@ -576,6 +603,20 @@
"recycling:small_electrical_appliances=",
"recycling:waste="
]
},
{
"if": "recycling_type=pickup_point",
"then": {
"en": "This is a pickup point. The waste material is placed here without placing it in a dedicated container.",
"nl": "Dit is een verzamelplaats zonder container waar het afval later opgepikt wordt."
}
},
{
"if": "recycling_type=dump",
"then": {
"en": "This is a dump where the waste material is stacked.",
"nl": "Dit is een afvalhoop waar het afvalmateriaal bovenop elkaar gestapeld wordt."
}
}
]
},
@ -1024,6 +1065,10 @@
"de": "Nadeln können hier recycelt werden",
"it": "Aghi e oggetti appuntiti",
"ca": "Aquí es poden reciclar agulles"
},
"icon": {
"path": "./assets/layers/recycling/needles.svg",
"class": "medium"
}
},
{
@ -1041,6 +1086,18 @@
"class": "medium"
},
"hideInAnswer": "recycling_type=container"
},
{
"if": "recycling:bicycles=yes",
"ifnot": "recycling:bicycles=",
"then": {
"en": "Bicycles can be recycled here",
"nl": "Fietsen (en fietswrakken) kunnen hier gerecycled worden"
},
"icon": {
"path": "./assets/layers/recycling/bicycles.svg",
"class": "medium"
}
}
]
},
@ -1338,7 +1395,7 @@
"it": "Riciclo di rottami metallici",
"ca": "Reciclatge de ferralla"
},
"osmTags": "recycling:printer_cartridges=yes"
"osmTags": "recycling:scrap_metal=yes"
},
{
"question": {
@ -1349,16 +1406,6 @@
"it": "Riciclo di piccoli elettrodomestici",
"ca": "Reciclatge de petits electrodomèstics"
},
"osmTags": "recycling:scrap_metal=yes"
},
{
"question": {
"en": "Recycling of residual waste",
"nl": "Recycling van restafval",
"de": "Recycling von Restabfällen",
"it": "Riciclo di secco",
"ca": "Reciclatge del rebuig"
},
"osmTags": {
"or": [
"recycling:small_appliances=yes",
@ -1375,6 +1422,20 @@
"ca": "Reciclatge del rebuig"
},
"osmTags": "recycling:waste=yes"
},
{
"question": {
"en": "Recycling of printer cartridges",
"nl": "Recycling van inktpatronen"
},
"osmTags": "recycling:printer_cartridges=yes"
},
{
"question": {
"en": "Recycling of bicycles",
"nl": "Recycling van fietsen"
},
"osmTags": "recycling:bicycles=yes"
}
]
},
@ -1409,4 +1470,4 @@
"enableRelocation": true,
"enableImproveAccuracy": true
}
}
}

View file

@ -0,0 +1,24 @@
import Script from "./Script";
import {TagUtils} from "../Logic/Tags/TagUtils";
import {And} from "../Logic/Tags/And";
import Constants from "../Models/Constants";
import {ImmutableStore} from "../Logic/UIEventSource";
import {BBox} from "../Logic/BBox";
import {Overpass} from "../Logic/Osm/Overpass";
const fs = require("fs")
class DownloadFromOverpass extends Script {
constructor() {
super("Downloads data from openstreetmap, will save this as 'export.geojson'. All arguments will be interpreted as key=value pairs");
}
async main(args: string[]): Promise<void> {
const tags = new And(args.map(k => TagUtils.Tag(k)))
const overpass = new Overpass(tags,[], Constants.defaultOverpassUrls[0], new ImmutableStore(500))
const [data, _] = await overpass.queryGeoJson(BBox.global)
fs.writeFileSync("export.geojson", JSON.stringify(data), "utf8")
console.log("Written", data.features.length,"entries")
}
}
new DownloadFromOverpass().run()

View file

@ -28,7 +28,7 @@ export default class GenerateImageAnalysis extends Script {
tag,
[],
"https://overpass.kumi.systems/api/interpreter",
new ImmutableStore(180),
new ImmutableStore(500),
undefined,
false
)
@ -110,10 +110,10 @@ export default class GenerateImageAnalysis extends Script {
const msg = `${i}/${
allImages.size
} downloaded: ${d},skipped: ${s}, failed: ${f}, running: ${runningSecs}sec, ETA: ${estimatedActualMinutes}:${
} downloaded: ${d},skipped: ${s}, failed: ${f}, running: ${Math.floor(runningSecs)}sec, ETA: ${estimatedActualMinutes}:${
estimatedActualSeconds % 60
}`
ScriptUtils.erasableLog(msg)
ScriptUtils.erasableLog( " ", msg)
if (downloaded) {
d++
} else {
@ -227,10 +227,10 @@ export default class GenerateImageAnalysis extends Script {
}
async main(args: string[]): Promise<void> {
const datapath = args[0] ?? "../MapComplete-data/ImageLicenseInfo"
const datapath = args[0] ?? "../../git/MapComplete-data/ImageLicenseInfo"
await this.downloadData(datapath)
//await this.downloadMetadata(datapath)
await this.downloadMetadata(datapath)
this.analyze(datapath)
}
}