add sauna theme #2382

Merged
pietervdvn merged 15 commits from Osmwithspace/MapComplete:sauna into develop 2025-07-04 16:42:46 +00:00
Collaborator

#2376

Opening a pull request on MapComplete

Hey! Thanks for opening a pull request on Mapcomplete! This probably means you want to add a new theme - if so, please
follow the checklist below. If this pull request is for some other issue, please ignore the template.

Adding your new theme

Thanks for taking the time to create your theme and to add it to the main repository!

To making merging smooth, please make sure that each of the following conditions is met:

  • The codebase is GPL-licensed. By opening a pull request, the new theme will be GPL too
  • All images are included in the pull request and no images are loaded from an external service (e.g. Wikipedia)
  • The guidelines on how to make your own theme
    are read and followed
#2376 Opening a pull request on MapComplete ===================================== Hey! Thanks for opening a pull request on Mapcomplete! This probably means you want to add a new theme - if so, please follow the checklist below. If this pull request is for some other issue, please ignore the template. Adding your new theme --------------------- Thanks for taking the time to create your theme and to add it to the main repository! To making merging smooth, please make sure that each of the following conditions is met: - [x] The codebase is GPL-licensed. By opening a pull request, the new theme will be GPL too - [x] All images are included in the pull request and no images are loaded from an external service (e.g. Wikipedia) - [x] The [guidelines on how to make your own theme](https://source.mapcomplete.org/MapComplete/MapComplete/src/branch/master/Docs/Making_Your_Own_Theme.md) are read and followed
add sauna theme
Some checks failed
/ deploy_on_hosted (pull_request) Failing after 4m22s
718472de4f
@ -0,0 +20,4 @@
"opening_hours",
{
"id": "charge_cost_rewritten",
"rewrite": {
Owner

Wow, you are using a 'rewrite'-block. That is pretty neat

Wow, you are using a 'rewrite'-block. That is pretty neat
Osmwithspace marked this conversation as resolved
@ -0,0 +98,4 @@
"source": {
"osmTags": {
"and": [
"leisure~.*sauna.*",
Owner

The 'source' is a bit weird. First of all, leisure~.*sauna.* will give all items which have a substring sauna in the leisure key.

Second, it seems like you are only selecting sauna's which have at least some item missing. This means that someone might add a sauna, fill out all details close MC. Upon reopening MC, the sauna they added will not show up again, as all information is known. This will cause them to add it again and to loose confidence in MapComplete, as "the data that they contributed dissappeared".

Keep in mind that MapComplete is not a todo app like streetcomplete, but also a 'browse OSM data'-app.

The 'source' is a bit weird. First of all, `leisure~.*sauna.*` will give all items which have a substring `sauna` in the leisure key. Second, it seems like you are _only_ selecting sauna's which have at least some item _missing_. This means that someone might add a sauna, fill out all details close MC. Upon reopening MC, the sauna they added will not show up again, as all information is known. This will cause them to add it again and to loose confidence in MapComplete, as "the data that they contributed dissappeared". Keep in mind that MapComplete is _not_ a todo app like streetcomplete, but also a 'browse OSM data'-app.
Author
Collaborator

The 'source' is a bit weird. First of all, leisure~.*sauna.* will give all items which have a substring sauna in the leisure key.

It's a very rare case, but I want to cover leisure=water_park;sauna for example.

Second, it seems like you are only selecting sauna's which have at least some item missing.

No, it's the other way around. leisure=sauna unfortunately has the problem that it's not clear whether it's a single sauna as part of a sauna area or an entire sauna area. Since I only want to display entire sauna areas, I filter in the sauna layer by opening_hours, website or phone.

This will cause them to add it again

Therefore, I want to prevent the addition of POIs in this theme.

I know that's not quite clean, but I think it's an acceptable way of dealing with the current situation.

> The 'source' is a bit weird. First of all, `leisure~.*sauna.*` will give all items which have a substring `sauna` in the leisure key. It's a very rare case, but I want to cover `leisure=water_park;sauna` for example. > Second, it seems like you are _only_ selecting sauna's which have at least some item _missing_. No, it's the other way around. `leisure=sauna` unfortunately has the problem that it's not clear whether it's a single sauna as part of a sauna area or an entire sauna area. Since I only want to display entire sauna areas, I filter in the `sauna` layer by `opening_hours`, `website` or `phone`. > This will cause them to add it again Therefore, I want to prevent the addition of POIs in this theme. I know that's not quite clean, but I think it's an acceptable way of dealing with the current situation.
Owner

It's a very rare case, but I want to cover leisure=water_park;sauna for example.

There were 5 leisure=water_park;sauna in OSM, I did retag them all. It happens that, when I make a theme, I do some initial data cleanup first too.

Since I only want to display entire sauna areas, I filter in the sauna layer by opening_hours, website or phone.

Hmm, this is an interesting case. Your approach ain't foolproof, as someone might have tagged it on both the 'area' and the individual sauna parts.

Maybe an approach with loading the outlines of swimming pool facilities, water parks, ... too and then removing sauna's within such amenity (with some metatagging) might work. Could you link a few examples?

Also: how do we deal with private sauna's in someones backyard?

Therefore, I want to prevent the addition of POIs in this theme.

Oh, I didn't catch that. The MapComplete paradigm is to allow addition as much as possible too. Otherwise, I'll have an issue pretty soon stating "cannot add new sauna" ;)
So, I can exceptionally allow this, but only if all else fails.

> It's a very rare case, but I want to cover leisure=water_park;sauna for example. There were 5 `leisure=water_park;sauna` in OSM, I did retag them all. It happens that, when I make a theme, I do some initial data cleanup first too. > Since I only want to display entire sauna areas, I filter in the sauna layer by opening_hours, website or phone. Hmm, this is an interesting case. Your approach ain't foolproof, as someone might have tagged it on both the 'area' and the individual sauna parts. Maybe an approach with loading the outlines of swimming pool facilities, water parks, ... too and then removing sauna's _within_ such amenity (with some metatagging) might work. Could you link a few examples? Also: how do we deal with private sauna's in someones backyard? > Therefore, I want to prevent the addition of POIs in this theme. Oh, I didn't catch that. The MapComplete paradigm is to allow addition as much as possible too. Otherwise, I'll have an issue pretty soon stating "cannot add new sauna" ;) So, I can exceptionally allow this, but only if all else fails.
Author
Collaborator

Maybe an approach with loading the outlines of swimming pool facilities, water parks, ... too and then removing sauna's within such amenity (with some metatagging) might work. Could you link a few examples?

For this I would need your help.
Here is an interesting example: https://www.openstreetmap.org/node/673997403

Also: how do we deal with private sauna's in someones backyard?

In the sauna_at_leisure layer I have an access question and then I exclude private ones. I could do this in the sauna layer as well.

The MapComplete paradigm is to allow addition as much as possible too.

I don't know how we could do this so that it's foolproof.

> Maybe an approach with loading the outlines of swimming pool facilities, water parks, ... too and then removing sauna's _within_ such amenity (with some metatagging) might work. Could you link a few examples? For this I would need your help. Here is an interesting example: https://www.openstreetmap.org/node/673997403 > Also: how do we deal with private sauna's in someones backyard? In the sauna_at_leisure layer I have an access question and then I exclude private ones. I could do this in the sauna layer as well. > The MapComplete paradigm is to allow addition as much as possible too. I don't know how we could do this so that it's foolproof.
Owner

The first step is to creata a layer with sport facilities and load it in the theme.
Then, use the calculatedTags-feature - especially enclosing features in the sauna layer. You will be able to detect if it is within a swimming pool.

The last step is to use an (on by default) filter to hide them, or to steal information (e.g. opening hours) from the enclosing features.

The first step is to creata a layer with sport facilities and load it in the theme. Then, use the [calculatedTags-feature](https://source.mapcomplete.org/MapComplete/MapComplete/src/branch/develop/Docs/CalculatedTags.md) - especially [enclosing features](https://source.mapcomplete.org/MapComplete/MapComplete/src/branch/develop/Docs/CalculatedTags.md#enclosingfeatures) in the sauna layer. You will be able to detect if it is within a swimming pool. The last step is to use an (on by default) filter to hide them, or to steal information (e.g. opening hours) from the enclosing features.
@ -0,0 +120,4 @@
"render": {
"en": "{name}"
}
}
Owner

Please, also add an allowMove block. These aren't added by default in Studio, but it is required for official themes. It is also what caused the build to fail.

The simplest way is to add "allowMove": true

Please, also add an `allowMove` block. These aren't added by default in Studio, but it is required for official themes. It is also what caused the build to fail. The simplest way is to add `"allowMove": true`
Osmwithspace marked this conversation as resolved
@ -0,0 +86,4 @@
]
},
"contact",
"defibrillator.defibrillator-fixme"
Owner

You are reusing the 'fixme' for 'defibrillators'. This results in a question 'are there any other things you want to say about this defibrillator ?'. That is pretty confusing as this is about sauna's...

In general, I try to not use 'fixme' as it burdens more experienced mappers and tends to make that users just restate some facts that are already captured in a tag.

You are reusing the 'fixme' for 'defibrillators'. This results in a question 'are there any other things you want to say about this *defibrillator* ?'. That is pretty confusing as this is about sauna's... In general, I try to not use 'fixme' as it burdens more experienced mappers and tends to make that users just restate some facts that are already captured in a tag.
Author
Collaborator

You are reusing the 'fixme' for 'defibrillators'. This results in a question 'are there any other things you want to say about this defibrillator ?'. That is pretty confusing as this is about sauna's...

As far as i see, the sentences are not specific for defibrillators.

In general, I try to not use 'fixme' as it burdens more experienced mappers and tends to make that users just restate some facts that are already captured in a tag.

In fact, I'm not entirely happy with it either. I wanted to offer a way to make low-threshold posts/comments when you have reached the functional limits of the theme.

> You are reusing the 'fixme' for 'defibrillators'. This results in a question 'are there any other things you want to say about this _defibrillator_ ?'. That is pretty confusing as this is about sauna's... As far as i see, the [sentences](https://source.mapcomplete.org/MapComplete/MapComplete/src/commit/5515114be95bd442d682c01818e0fcd48507c455/assets/layers/defibrillator/defibrillator.json#L688-L718) are not specific for defibrillators. > In general, I try to not use 'fixme' as it burdens more experienced mappers and tends to make that users just restate some facts that are already captured in a tag. In fact, I'm not entirely happy with it either. I wanted to offer a way to make low-threshold posts/comments when you have reached the functional limits of the theme.
Owner

As far as i see, the sentences are not specific for defibrillators.

The dutch (nl) one is ;)
In any case, it is a bad habit of reusing this tagrendering from an unrelated layer. I propose you move the "fixme" into the "questions/questions.json"-file (and drop the dutch text). Then, you can reuse it.

In fact, I'm not entirely happy with it either. I wanted to offer a way to make low-threshold posts/comments when you have reached the functional limits of the theme.

Then maybe note=* or description=* is more fitting? Anyway, fixme=* is acceptable as well if you insist. Related: #1678

Those free text fields are also quite good indicators of what the functional limits are and serve as great inspiration for new questions.

> As far as i see, the sentences are not specific for defibrillators. The dutch (`nl`) one is ;) In any case, it is a bad habit of reusing this tagrendering from an unrelated layer. I propose you move the "fixme" into the "questions/questions.json"-file (and drop the dutch text). Then, you can reuse it. > In fact, I'm not entirely happy with it either. I wanted to offer a way to make low-threshold posts/comments when you have reached the functional limits of the theme. Then maybe `note=*` or `description=*` is more fitting? Anyway, `fixme=*` is acceptable as well if you insist. Related: #1678 Those free text fields are also quite good indicators of what the functional limits are and serve as great inspiration for new questions.
Author
Collaborator

I propose you move the "fixme" into the "questions/questions.json"-file (and drop the dutch text). Then, you can reuse it.

I moved it MapComplete/MapComplete@c7ec2e6cab

> I propose you move the "fixme" into the "questions/questions.json"-file (and drop the dutch text). Then, you can reuse it. I moved it https://source.mapcomplete.org/MapComplete/MapComplete/commit/c7ec2e6cab35127ffceb52861f262c22b3ea7798
Osmwithspace marked this conversation as resolved
Owner

I will review the 'sauna-at-amenity'-layer on, but might, in the meantime, also work on some code to make this type of question reuse easier (i.e. to automatically 'prefix' every key)

I will review the 'sauna-at-amenity'-layer on, but might, in the meantime, also work on some code to make this type of question reuse easier (i.e. to automatically 'prefix' every key)
add "allowMove": true
Some checks failed
/ deploy_on_hosted (pull_request) Failing after 4m33s
b06f937c5b
Owner

Another small issue (which causes the build to block) is that sauna_at_leisure should be in its own directory in layers/sauna_at_leisure

Another small issue (which causes the build to block) is that `sauna_at_leisure` should be in its own directory in `layers/sauna_at_leisure`
Owner

I've created a new way to reuse tagRenderings where you can set a prefix. It can be used as following:

{
  "builtin": "sauna.*",
  "override": {
    "condition":{"and"+: "sauna=yes"}
  }
  "prefix": "sauna"
  }

This will import all questions from the sauna layer and modify all keys to have sauna: in front of it. The only thing you still need to create is a question if there is a sauna.

Again; highly experimental!

I've created a new way to reuse tagRenderings where you can set a prefix. It can be used as following: ```json { "builtin": "sauna.*", "override": { "condition":{"and"+: "sauna=yes"} } "prefix": "sauna" } ``` This will import _all_ questions from the sauna layer and modify all keys to have `sauna:` in front of it. The only thing you still need to create is a question _if_ there is a sauna. Again; highly experimental!
leisure=sauna
Some checks failed
/ deploy_on_hosted (pull_request) Has been cancelled
522c4e8b8c
Merge branch 'develop' into sauna
Some checks failed
/ deploy_on_hosted (pull_request) Failing after 4m53s
eabf72d121
Merge branch 'develop' into sauna
Some checks failed
/ deploy_on_hosted (pull_request) Failing after 3m9s
3ada645335
move "fixme" into "questions/questions.json"
Some checks failed
/ deploy_on_hosted (pull_request) Failing after 3m47s
c7ec2e6cab
move sauna_at_leisure to own directory
Some checks failed
/ deploy_on_hosted (pull_request) Failing after 3m13s
fe43c41d30
Fix: fix sauna theme
All checks were successful
/ deploy_on_hosted (push) Successful in 22m47s
/ deploy_on_hosted (pull_request) Successful in 18m0s
ccbbba5628

Congratulations! This PR been successfully built and has been deployed. It is (temporarily) available on https://builds.mapcomplete.org/2382

Congratulations! This PR been successfully built and has been deployed. It is (temporarily) available on https://builds.mapcomplete.org/2382
Owner

Allright, I've finally had the time to pick this up again and to have a look.

First of all, I've made a few tweaks and pushed it to your repo to have the build working. Furhtermore, I think I've also found a solution to your previous problem and a hole in the tagging. AFAIK, there are a few ways that sauna's can appear in the world:

  • Standalone sauna cabins
  • Sauna's as part of a sports centre
  • Sauna's as part of a hotel, fitness_centre, campsite
  • Sauna's as part of a wellness business (aka SPA), sometimes where the sauna is the main part.

IMHO, we were struggling earlier because we conflate the first (the physical sauna) and the last (the sauna as wellness amenity) concepts. I've had a look at some "sauna" near me (in Ghent), most of them are wellness salons also offering services as massages, silent room, a small swimming pool, jacuzzi, steam bath, bed&breakfast...

The other sauna=yes is in a large, public swimming pool.

Allright, I've finally had the time to pick this up again and to have a look. First of all, I've made a few tweaks and pushed it to your repo to have the build working. Furhtermore, I think I've also found a solution to your previous problem and a hole in the tagging. AFAIK, there are a few ways that sauna's can appear in the world: - Standalone sauna cabins - Sauna's as part of a sports centre - Sauna's as part of a hotel, fitness_centre, campsite - Sauna's as part of a wellness business (aka SPA), sometimes where the sauna is the main part. IMHO, we were struggling earlier because we conflate the first (the physical sauna) and the last (the sauna as wellness amenity) concepts. I've had a look at some "sauna" near me (in Ghent), most of them are wellness salons also offering services as massages, silent room, a small swimming pool, jacuzzi, steam bath, bed&breakfast... The other sauna=yes is in a large, public swimming pool.
Owner

Allright, I had another go at this PR, I think I've figured out how to handle this:

  1. I have refactored 'sauna_at_leisure' to contain all relevant information about only the sauna part (thus: no contact info, no opening hours, ...). This layer can be reused in other layers with sauna_at_leisure.sauna_grouped to have a dropdown with those questions, with sauna_at_leisure.sauna_expanded to get the questions directly or as standalone layer in a theme, in which case it'll show just the block for everything that has sauna=yes.
  2. The sauna-layer has those expanded questions + contact info etc, as you had it earlier
  3. I have added the sauna_at_leisure.sauna_grouped block to other layers (e.g. tourism_accomodation which includes hotels, sports_centre and beauty_shops)
  4. and mixed all of them into the sauna theme!

This way we can show sauna information on all supported categories (and have a fallback), yet without the need to whip up a 'wellness-salon' type.

There are still a few loose ends, e.g. a beauty salon tagged as 'sauna' cannot be corrected by the end user (and the distinction between 'massage salon', beauty salon, sauna, ... is often hard to make in the first place anyway)

Allright, I had another go at this PR, I think I've figured out how to handle this: 1. I have refactored 'sauna_at_leisure' to contain all relevant information about only the sauna part (thus: no contact info, no opening hours, ...). This layer can be reused in other layers with `sauna_at_leisure.sauna_grouped` to have a dropdown with those questions, with `sauna_at_leisure.sauna_expanded` to get the questions directly or as standalone layer in a theme, in which case it'll show just the block for everything that has `sauna=yes`. 2. The `sauna`-layer has those expanded questions + contact info etc, as you had it earlier 3. I have added the `sauna_at_leisure.sauna_grouped` block to _other_ layers (e.g. tourism_accomodation which includes hotels, sports_centre and beauty_shops) 4. and mixed all of them into the sauna theme! This way we can show sauna information on all supported categories (and have a fallback), yet without the need to whip up a 'wellness-salon' type. There are still a few loose ends, e.g. a beauty salon tagged as 'sauna' cannot be corrected by the end user (and the distinction between 'massage salon', beauty salon, sauna, ... is often hard to make in the first place anyway)
Merge branch 'develop' into sauna
All checks were successful
/ deploy_on_hosted (pull_request) Successful in 18m16s
/ deploy_on_hosted (push) Successful in 18m29s
70a6808b5e

Congratulations! This PR been successfully built and has been deployed. It is (temporarily) available on https://builds.mapcomplete.org/2382

Congratulations! This PR been successfully built and has been deployed. It is (temporarily) available on https://builds.mapcomplete.org/2382
pietervdvn merged commit e97adedd6a into develop 2025-07-04 16:42:46 +00:00
pietervdvn deleted branch sauna 2025-07-04 16:42:58 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
3 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
MapComplete/MapComplete!2382
No description provided.