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-07-18 02:00:32 +02:00
2022-01-14 13:58:37 +01:00
}
] ,
"mapRendering" : [
{
"location" : [
2022-01-21 03:57:49 +01:00
"point"
2022-01-14 13:58:37 +01:00
] ,
"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-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
} ;
}
}