2022-02-04 01:05:35 +01:00
import { Conversion } from "./Conversion"
2022-01-14 13:58:37 +01:00
import LayerConfig from "../LayerConfig"
import { LayerConfigJson } from "../Json/LayerConfigJson"
import Translations from "../../../UI/i18n/Translations"
2022-01-21 01:57:16 +01:00
import PointRenderingConfigJson from "../Json/PointRenderingConfigJson"
2022-05-01 22:58:59 +02:00
import { Translation , TypedTranslation } from "../../../UI/i18n/Translation"
2022-01-14 13:58:37 +01:00
2022-01-21 01:57:16 +01:00
export default class CreateNoteImportLayer extends Conversion < LayerConfigJson , LayerConfigJson > {
/ * *
* A closed note is included if it is less then 'n' - days closed
* @private
* /
private readonly _includeClosedNotesDays : number
2022-01-14 13:58:37 +01:00
2022-01-26 21:40:38 +01:00
constructor ( includeClosedNotesDays = 0 ) {
2022-01-14 13:58:37 +01:00
super (
[
"Advanced conversion which deducts a layer showing all notes that are 'importable' (i.e. a note that contains a link to some MapComplete theme, with hash '#import')." ,
"The import buttons and matches will be based on the presets of the given theme" ,
2022-07-18 02:00:32 +02:00
] . join ( "\n\n" ) ,
[ ] ,
"CreateNoteImportLayer"
)
2022-01-21 01:57:16 +01:00
this . _includeClosedNotesDays = includeClosedNotesDays
2022-01-14 13:58:37 +01:00
}
2022-02-10 23:16:14 +01:00
convert ( layerJson : LayerConfigJson , context : string ) : { result : LayerConfigJson } {
2022-01-14 13:58:37 +01:00
const t = Translations . t . importLayer
2022-01-26 21:40:38 +01:00
2022-01-21 01:57:16 +01:00
/ * *
* The note itself will contain ` tags=k=v;k=v;k=v;...
* This must be matched with a regex .
* This is a simple JSON - object as how it ' ll be put into the layerConfigJson directly
* /
2022-01-26 21:40:38 +01:00
const isShownIfAny : any [ ] = [ ]
2022-01-21 01:57:16 +01:00
const layer = new LayerConfig ( layerJson , "while constructing a note-import layer" )
for ( const preset of layer . presets ) {
const mustMatchAll = [ ]
for ( const tag of preset . tags ) {
const key = tag . key
const value = tag . value
2022-01-26 21:40:38 +01:00
const condition = "_tags~(^|.*;)" + key + "=" + value + "($|;.*)"
2022-01-21 01:57:16 +01:00
mustMatchAll . push ( condition )
}
2022-01-26 21:40:38 +01:00
isShownIfAny . push ( { and : mustMatchAll } )
2022-01-21 01:57:16 +01:00
}
2022-01-26 21:40:38 +01:00
const pointRenderings = ( layerJson . mapRendering ? ? [ ] ) . filter (
( r ) = > r !== null && r [ "location" ] !== undefined
)
const firstRender = < PointRenderingConfigJson > pointRenderings [ 0 ]
2022-07-18 02:00:32 +02:00
if ( firstRender === undefined ) {
throw ` Layer ${ layerJson . id } does not have a pointRendering: ` + context
2022-02-04 00:44:09 +01:00
}
2022-01-25 21:55:51 +01:00
const title = layer . presets [ 0 ] . title
2022-01-26 21:40:38 +01:00
2022-01-21 01:57:16 +01:00
const importButton = { }
{
2022-07-18 02:00:32 +02:00
const translations = trs ( t . importButton , {
layerId : layer.id ,
title : layer.presets [ 0 ] . title ,
} )
2022-01-21 01:57:16 +01:00
for ( const key in translations ) {
2022-07-18 02:00:32 +02:00
if ( key !== "_context" ) {
2022-05-01 22:58:59 +02:00
importButton [ key ] = "{" + translations [ key ] + "}"
2022-07-18 02:00:32 +02:00
} else {
2022-05-01 22:58:59 +02:00
importButton [ key ] = translations [ key ]
}
2022-01-26 21:40:38 +01:00
}
2022-01-21 01:57:16 +01:00
}
2022-01-26 21:40:38 +01:00
function embed ( prefix , translation : Translation , postfix ) {
2022-01-25 21:55:51 +01:00
const result = { }
for ( const language in translation . translations ) {
2022-01-26 21:40:38 +01:00
result [ language ] = prefix + translation . translations [ language ] + postfix
2022-01-25 21:55:51 +01:00
}
2022-05-01 22:58:59 +02:00
result [ "_context" ] = translation . context
2022-01-25 21:55:51 +01:00
return result
}
2022-07-18 02:00:32 +02:00
function tr ( translation : Translation ) {
return { . . . translation . translations , _context : translation.context }
2022-05-01 22:58:59 +02:00
}
2022-07-18 02:00:32 +02:00
function trs < T > ( translation : TypedTranslation < T > , subs : T ) : object {
2022-05-01 22:58:59 +02:00
return { . . . translation . Subs ( subs ) . translations , _context : translation.context }
}
2022-01-26 21:40:38 +01:00
const result : LayerConfigJson = {
id : "note_import_" + layer . id ,
2022-01-21 01:57:16 +01:00
// By disabling the name, the import-layers won't pollute the filter view "name": t.layerName.Subs({title: layer.title.render}).translations,
2022-07-18 02:00:32 +02:00
description : trs ( t . description , { title : layer.title.render } ) ,
2022-01-14 13:58:37 +01:00
source : {
osmTags : {
and : [ "id~*" ] ,
} ,
2022-01-26 21:40:38 +01:00
geoJson :
"https://api.openstreetmap.org/api/0.6/notes.json?limit=10000&closed=" +
this . _includeClosedNotesDays +
"&bbox={x_min},{y_min},{x_max},{y_max}" ,
2022-01-21 01:57:16 +01:00
geoJsonZoomLevel : 10 ,
2022-01-14 13:58:37 +01:00
maxCacheAge : 0 ,
} ,
2022-01-26 20:47:08 +01:00
minzoom : Math.min ( 12 , layerJson . minzoom - 2 ) ,
2022-01-14 13:58:37 +01:00
title : {
2022-07-18 02:00:32 +02:00
render : trs ( t . popupTitle , { title } ) ,
2022-01-14 13:58:37 +01:00
} ,
calculatedTags : [
2022-01-21 01:57:16 +01:00
"_first_comment=feat.get('comments')[0].text.toLowerCase()" ,
2022-02-08 02:22:36 +01:00
"_trigger_index=(() => {const lines = feat.properties['_first_comment'].split('\\n'); const matchesMapCompleteURL = lines.map(l => l.match(\".*https://mapcomplete.osm.be/\\([a-zA-Z_-]+\\)\\(.html\\)?.*#import\")); const matchedIndexes = matchesMapCompleteURL.map((doesMatch, i) => [doesMatch !== null, i]).filter(v => v[0]).map(v => v[1]); return matchedIndexes[0] })()" ,
2022-01-21 01:57:16 +01:00
"_comments_count=feat.get('comments').length" ,
2022-01-25 21:55:51 +01:00
"_intro=(() => {const lines = feat.get('comments')[0].text.split('\\n'); lines.splice(feat.get('_trigger_index')-1, lines.length); return lines.filter(l => l !== '').join('<br/>');})()" ,
2022-05-07 17:53:59 +02:00
"_tags=(() => {let lines = feat.get('comments')[0].text.split('\\n').map(l => l.trim()); lines.splice(0, feat.get('_trigger_index') + 1); lines = lines.filter(l => l != ''); return lines.join(';');})()" ,
2022-01-14 13:58:37 +01:00
] ,
isShown : {
2022-07-18 02:00:32 +02:00
and : [ "_trigger_index~*" , { or : isShownIfAny } ] ,
2022-01-14 13:58:37 +01:00
} ,
titleIcons : [
{
render : "<a href='https://openstreetmap.org/note/{id}' target='_blank'><img src='./assets/svg/osm-logo-us.svg'></a>" ,
} ,
] ,
tagRenderings : [
{
id : "Intro" ,
2022-03-10 23:20:50 +01:00
render : "{_intro}" ,
2022-01-14 13:58:37 +01:00
} ,
2022-01-21 01:57:16 +01:00
{
id : "conversation" ,
render : "{visualize_note_comments(comments,1)}" ,
condition : "_comments_count>1" ,
} ,
2022-01-14 13:58:37 +01:00
{
id : "import" ,
2022-01-21 01:57:16 +01:00
render : importButton ,
condition : "closed_at=" ,
2022-01-14 13:58:37 +01:00
} ,
{
id : "close_note_" ,
2022-01-25 21:55:51 +01:00
render : embed (
2022-03-10 23:20:50 +01:00
"{close_note(" ,
t . notFound . Subs ( { title } ) ,
", ./assets/svg/close.svg, id, This feature does not exist, 18)}"
) ,
2022-01-21 01:57:16 +01:00
condition : "closed_at=" ,
2022-01-14 13:58:37 +01:00
} ,
{
id : "close_note_mapped" ,
2022-03-10 23:20:50 +01:00
render : embed (
"{close_note(" ,
t . alreadyMapped . Subs ( { title } ) ,
", ./assets/svg/duplicate.svg, id, Already mapped, 18)}"
) ,
2022-01-21 01:57:16 +01:00
condition : "closed_at=" ,
} ,
{
id : "handled" ,
2022-05-01 22:58:59 +02:00
render : tr ( t . importHandled ) ,
2022-01-21 01:57:16 +01:00
condition : "closed_at~*" ,
2022-01-14 13:58:37 +01:00
} ,
{
id : "comment" ,
render : "{add_note_comment()}" ,
} ,
{
id : "add_image" ,
render : "{add_image_to_note()}" ,
2022-05-06 12:41:24 +02:00
} ,
{
2022-07-18 02:00:32 +02:00
id : "nearby_images" ,
2022-05-06 12:41:24 +02:00
render : tr ( t . nearbyImagesIntro ) ,
2022-01-14 13:58:37 +01:00
} ,
] ,
mapRendering : [
{
location : [ "point" ] ,
icon : {
2022-01-21 01:57:16 +01:00
render : "circle:white;help:black" ,
2022-01-26 21:40:38 +01:00
mappings : [
{
if : { or : [ "closed_at~*" , "_imported=yes" ] } ,
then : "circle:white;checkmark:black" ,
2022-01-21 01:57:16 +01:00
} ,
2022-09-08 21:40:48 +02:00
] ,
2022-01-14 13:58:37 +01:00
} ,
2022-01-21 01:57:16 +01:00
iconSize : "40,40,center" ,
2022-01-14 13:58:37 +01:00
} ,
] ,
}
2022-01-26 21:40:38 +01:00
2022-01-14 13:58:37 +01:00
return {
2022-02-10 23:16:14 +01:00
result ,
2022-01-14 13:58:37 +01:00
}
}
}