Modul:Vatten OSM
Utseende
Dokumentation [visa] [redigera] [historik] [rensa sidcachen]
Detta är en modul för att visa vattendrag på OpenStreetMap-kartor baserat på Wikidata.
För att ett vattendrag ska visas krävs 1) att det finns en "relation" för vattendraget på OpenStreetMap samt 2) att den relationen har ett angivit Wikidata-id. För mer information vad ovanstående innebär se Wikipedia:Kartor och den information som länkas därifrån.
Hur modellen fungerar
[redigera wikitext]Modulen
- .. går igenom alla biflöde (P974) och visar dem (om inte maxlevel är satt så att biflöden på aktuell "nivå" inte visas). Den anropar därefter det ursprungliga funktionsanropet men med det vattendraget istället (d.v.s. funktionen är rekursiv) för att följa biflöden till biflöden o.s.v.
- .. går igenom alla sjöar längs vattendraget (P469) och vattendragets källa (P885) och visar dem (om inte lakes är satt till falskt). Den kontroller att de är sjöar och inte något annat (t.ex. förekommer det att bergskedjor är satta som vattendragets källa (P885). Den försöker sedan följa alla tillflöde (P200) till sjön och visa dem och deras biflöden. Om sjön har gränsar till (P47) eller har del(ar) (P527) som också är sjöar fortsätter moduler och utföra denna punkten även för dem.
- .. ser om flodbäcken (P4614) finns och om den i sin tur har en geografisk form (P3896). Ifall den finns och basin inte är satt till falskt kommer den att visas
Användbara parametrar (som sätts för varje artikel)
[redigera wikitext]- deny: lista på wikidataobjekt som modulen ska ignorera. Det kan t.ex. gälla kanaler som annars risker att koppla samman vattendrag som inte naturligt hör samman (och därigenom skapa biflöden som inte finns).
- basin: om vattendragets avrinningsområde ska visas (om en karta för det finns inlagd)
- lakes: om sjöar ska visas
- maxlevel: hur många "nivåer" av biflöden som modulen ska visa. Om den inte är satt visas alla biflöden och deras biflöden rekursivt. Om den är satt till 1 visas bara biflöden, är den satt till 2 visas även biflöden till biflöden o.s.v. I vissa fall (eller om flera kartor visas) kan det finnas så många biflöden och/eller sjöar inlagda att programvaran inte klarar av att visa alla. I det fallet är det motiverat att sätta en maxnivå.
- zoom: zoom-nivå för kartan. Normalt behöver detta inte fyllas i då programvaran som visar kartor på Wikipedia sköter det automatiskt (så att allt visas på bild och fyller ut bilden så bra som möjligt), men i vissa fall kan det vara praktiskt att sätta den själv (för att t.ex. bara visa en del av ett objekt).
- longitude: sätt longitud för kartans centrum, som för zoom behöver du vanligen inte sätta denna
- latitude: sätt latitud för kartans centrum, som för zoom behöver du vanligen inte sätta denna
- align: sätt justering för kartan
Inställningar (som är gemensamma för alla artiklar för en viss språkversion av Wikipedia
[redigera wikitext]I början av modulen finns ett antal inställningar (raderna som börjar med "settings"), dessa är:
- settings.width: bredden på kartan
- settings.height: höjden på kartan
- settings.paths.width.main: tjockleken på linjen för (huvud)vattendraget
- settings.paths.width.tributary: tjockleken på linjen för biflöden
- settings.paths.colour.main: färg på linjen för (huvud)vattendraget
- settings.paths.colour.tributary: färg på linjen för biflöden
- settings.areas.width: tjockleken på linjen runt sjöar
local wd = require( 'Modul:Referenshantering' )
p={}
localisation={}
localisation.txtTributary='med biflöden '
localisation.templates={}
localisation.templates.txtColour='Färg'
localisation.templates.txtMap='maplink'
localisation.arguments={}
localisation.arguments.frame={}
localisation.arguments.frame.text='ram'
localisation.arguments.frame.width='rambredd'
localisation.arguments.frame.height='ramhöjd'
localisation.arguments.line={}
localisation.arguments.line.text='linje'
localisation.arguments.line.colour='linjefärg'
localisation.arguments.line.width='linjetjocklek'
localisation.arguments.form={}
localisation.arguments.form.text='form'
localisation.arguments.form.colour=localisation.arguments.line.colour
localisation.arguments.form.width=localisation.arguments.line.width
localisation.arguments._type='typ'
localisation.arguments._title='titel'
localisation.arguments._raw='rå'
localisation.arguments.zoom='zoom'
localisation.arguments.from='från'
localisation.txtYes='ja'
settings={}
settings.width=250
settings.height=250
settings.paths={}
settings.paths.width={}
settings.paths.width.main=5
settings.paths.width.tributary=1
settings.paths.width.tributary_secondary=1
settings.paths.colour={}
settings.paths.colour.main='#000080' --'#9090FF'
settings.paths.colour.tributary='#000080'
settings.paths.colour.tributary_secondary='#000080'
settings.areas={}
settings.areas.width=1
local iRiver=1
local myArgs={};
local iCounter=1
local denylist={}
local allrivers={}
local allakes={}
local riverdatabase={}
local basinsdatabase={}
local lakedatabase={}
local denyassource={Q46831=true,Q3958626=true,Q3777462=true,Q2074737=true}
-- bergskedje, alpine section, alpine group, kommun i Spanien
function bHasArgument(args,txtName)
-- Check for the presence of 'hydropower'
for _, arg in pairs(args) do
if arg == txtName then
-- Do something if 'hydropower' is found
return true
end
end
return false
end
p.addQueriedLocations=function (qid,iInstanceOf,txtIcon,txtIconSize,txtIconColour)
txtQuery="SELECT DISTINCT ?id ?geo ?idLabel (concat('[[',?idLabel,']]') as ?title) WHERE { ?id wdt:P31 ?type; wdt:P625 ?geo. SERVICE wikibase:label { bd:serviceParam wikibase:language 'sv, en'. ?id rdfs:label ?idLabel. ?type rdfs:label ?typeLabel. } ?id wdt:P206 wd:" .. qid .. ". ?id wdt:P31 wd:" .. iInstanceOf .. "}"
return p.addContent ("{" .. p.addArgument("type","ExternalData") .. " ," .. p.addArgument("service","geopoint") .. " ," ..p.addArgument("query",txtQuery) .. " , \"properties\":{"..p.addArgument("marker-size",txtIconSize) .. " ," .. p.addArgument("marker-color",txtIconColour) .. " ," .. p.addArgument("marker-symbol",txtIcon) .. "} }" )
end
p.addQueriedAreas=function (qid,iInstanceOf,iWidth,txtColour,fOpacity)
txtQuery="SELECT DISTINCT ?id ?geo ?idLabel (concat('[[',?idLabel,']]') as ?title) ('" .. txtColour .. "' as ?fill) WHERE { ?id wdt:P31 ?type; wdt:P625 ?geo. SERVICE wikibase:label { bd:serviceParam wikibase:language 'sv, en'. ?id rdfs:label ?idLabel. ?type rdfs:label ?typeLabel. } ?id wdt:P206 wd:" .. qid .. ". ?id wdt:P31 wd:" .. iInstanceOf .. "}"
return p.addContent ("{" .. p.addArgument("type","ExternalData") .. " ," .. p.addArgument("service","geoshape") .. " ," ..p.addArgument("query",txtQuery) .. " , \"properties\":{"..p.addArgumentNoQuote("stroke-width",iWidth) .. " ," .. p.addArgument("stroke",txtColour) .. " ," .. p.addArgumentNoQuote("fill-opacity",fOpacity) .. "} }" )
end
p.addNatureReserves=function (qid)
return p.addQueriedAreas(qid,"Q179049",1,"#008000",0.2)
end
p.addHydropower=function (qid)
return p.addQueriedLocations(qid,"Q15911738","dam","small","#0000AA")
end
p.addBattles=function (qid)
return p.addQueriedLocations(qid,"Q178561","historic","small","#8B4513")
end
p.addTowns=function (qid)
return p.addQueriedLocations(qid,"Q515","city","small","#800000") .. p.addQueriedLocations(qid,"Q3957","city","small","#800000")
end
p.addVillages=function (qid)
return p.addQueriedLocations(qid,"Q532","home","small","#008000")
end
p.data=function(frame,bTributaries)
many=false
if (frame.args['id']) then
if (string.find(frame.args['id'], ",")) then
mw.log("hittat")
mw.log(frame.args['id'])
ids=p.split(frame.args['id'],",")
many=true
else
mw.log("ensam")
id=frame.args['id']
end
else
id=mw.wikibase.getEntityIdForCurrentPage()
end
if (frame.args['deny']) then
denylist=p.split(frame.args['deny'],",")
end
if (frame.args['basin']) then
bBasin=frame.args['basin'] == "true"
else
bBasin=true
end
if (frame.args['lakes']) then
bLakes=frame.args['lakes'] == "true"
else
bLakes=true
end
if (bTributaries==nil) then
bTributaries=true -- Default value
end
if (many) then
for key, value in pairs( ids ) do
p.addRiver(key,0,bTributaries)
end
else
p.addRiver(id,0,bTributaries)
end
return tprint(riverdatabase) .. tprint(lakedatabase) .. tprint(denylist)
end
p.show=function (frame)
myArgs={}
if (frame.args['height']) then
iHeight=frame.args['height']
else
iHeight=250
end
if (frame.args['width']) then
iWidth=frame.args['width']
else
iWidth=250
end
if (frame.args['maxlevel']) then
bHasMaxLevel=true
iMaxLevel=tonumber(frame.args['maxlevel'])
else
bHasMaxLevel=false
end
if (frame.args['zoom']) then
myArgs['zoom']=frame.args['zoom']
end
if (frame.args['longitude']) then
myArgs['longitude']=frame.args['longitude']
end
if (frame.args['latitude']) then
myArgs['latitude']=frame.args['latitude']
end
if (frame.args['align']) then
myArgs['align']=frame.args['align']
end
if (frame.args['zoom']) then
myArgs['zoom']=frame.args['zoom']
end
if (frame.args['tributaries']) then
bTributaries=frame.args['tributaries'] == "true"
else
bTributaries=true
end
p.data(frame,bTributaries)
p.iItems=0
myArgs['height']=iHeight
myArgs['width']=iWidth
local txtContent=''
for key, valueRiver in pairs( riverdatabase ) do
if (valueRiver.level==0) then
iThickness=settings.paths.width.main
end
if (valueRiver.level==1) then
iThickness=settings.paths.width.tributary
end
if (valueRiver.level>1) then
iThickness=settings.paths.width.tributary_secondary
end
txtContent= txtContent..p.addLineWD(valueRiver.id,settings.paths.colour.tributary_secondary,iThickness,valueRiver.name)
if (bHasArgument(frame.args,'hydropower') or bHasArgument(frame.args,'all')) then
txtContent=txtContent .. p.addHydropower(valueRiver.id)
end
if (bHasArgument(frame.args,'battles') or bHasArgument(frame.args,'all')) then
txtContent=txtContent .. p.addBattles(valueRiver.id)
end
if (bHasArgument(frame.args,'towns') or bHasArgument(frame.args,'all')) then
txtContent=txtContent .. p.addTowns(valueRiver.id)
end
if (bHasArgument(frame.args,'villages') or bHasArgument(frame.args,'all')) then
txtContent=txtContent .. p.addVillages(valueRiver.id)
end
if (bHasArgument(frame.args,'naturereserves') or bHasArgument(frame.args,'all')) then
txtContent=txtContent .. p.addNatureReserves(valueRiver.id)
end
end
if (bLakes) then
for keyLake, valueLake in pairs( lakedatabase ) do
txtContent= txtContent..p.addAreaWD(valueLake.id,settings.paths.colour.main,settings.areas.width,valueLake.name)
end
end
if (bBasin) then
for keyBasin, valueBasin in pairs( basinsdatabase ) do
txtContent=txtContent .. p.addAreaCommons(keyBasin,"#FFFF00","10","0.1")
end
end
if (frame.args['inverse']) then
txtContent=txtContent .. p.addInverse(frame.args['inverse'],'#FFFFFF',1,'#000000',0.9,3)
end
if (txtContent) then
txtContent="["..txtContent.."]"
end
return frame:extensionTag{ name = 'mapframe', content = txtContent, args = myArgs }
end
p.addArgument=function(txtLabel,txtValue)
if (txtValue) then return "\"" .. txtLabel .. "\"" .. ":" .. "\"" .. txtValue .. "\"" end
end
p.addArgumentNoQuote=function(txtLabel,txtValue)
return "\"" .. txtLabel .. "\"" .. ":" .. txtValue
end
p.addContent=function(txt)
if (p.iItems>0) then
txtConnect=","
else
txtConnect=" "
end
p.iItems=p.iItems+1
return txtConnect .. txt
end
p.addLineWD=function(qid,txtColour,iWidth,txtTitle)
return p.addContent ("{" .. p.addArgument("type","ExternalData") .. " ," .. p.addArgument("service","geoline") .. " ," ..p.addArgument("ids",qid) .. " , \"properties\":{"..p.addArgument("title",txtTitle) .. " ," .. p.addArgument("stroke",txtColour) .. " ," .. p.addArgumentNoQuote("stroke-width",iWidth) .. "} }" )
end
p.addAreaWD=function(qid,txtColour,iWidth,txtTitle)
if (txtTitle) then
return p.addContent ("{" .. p.addArgument("type","ExternalData") .. " ," .. p.addArgument("service","geoshape") .. " ," ..p.addArgument("ids",qid) .. " , \"properties\":{"..p.addArgument("title",txtTitle) .. " ," .. p.addArgument("stroke",txtColour) .. " ," .. p.addArgumentNoQuote("stroke-width",iWidth) .. "} }")
else
return p.addContent ("{" .. p.addArgument("type","ExternalData") .. " ," .. p.addArgument("service","geoshape") .. " ," ..p.addArgument("ids",qid) .. " , \"properties\":{"..p.addArgument("stroke",txtColour) .. " ," .. p.addArgumentNoQuote("stroke-width",iWidth) .. "} }")
end
end
p.addAreaCommons=function(txtFilename,txtColour,iWidth,fOpacity)
return p.addContent("{" .. p.addArgument("type","ExternalData") .. " ," .. p.addArgument("service","page") .. " ," ..p.addArgument("title",txtFilename) .. " , \"properties\":{"..p.addArgument("stroke",txtColour) .. " ," .. p.addArgumentNoQuote("stroke-width",iWidth) .. " ," ..p.addArgumentNoQuote("fill-opacity",fOpacity) .. "} }")
end
p.addLineWD=function(qid,txtColour,iWidth,txtTitle)
if (txtTitle) then
return p.addContent ("{" .. p.addArgument("type","ExternalData") .. " ," .. p.addArgument("service","geoline") .. " ," ..p.addArgument("ids",qid) .. " , \"properties\":{"..p.addArgument("title",txtTitle) .. " ," .. p.addArgument("stroke",txtColour) .. " ," .. p.addArgumentNoQuote("stroke-width",iWidth) .. "} }" )
else
return p.addContent ("{" .. p.addArgument("type","ExternalData") .. " ," .. p.addArgument("service","geoline") .. " ," ..p.addArgument("ids",qid) .. " , \"properties\":{"..p.addArgument("stroke",txtColour) .. " ," .. p.addArgumentNoQuote("stroke-width",iWidth) .. "} }" )
end
end
p.addInverse=function(qid,txtFillColour,fFillOpacity,txtStrokeColour,fStrokeOpacity,iWidth)
return p.addContent ("{" .. p.addArgument("type","ExternalData") .. " ," .. p.addArgument("service","geomask") .. " ," ..p.addArgument("ids",qid) .. " , \"properties\":{"..p.addArgument("fill",txtFillColour) .. " ," .. p.addArgumentNoQuote("fill-opacity",fFillOpacity) .. " ," .. p.addArgument("stroke",txtStrokeColour) .. " ," .. p.addArgumentNoQuote("stroke-opacitity",fStrokeOpacity) .. " ," .. p.addArgumentNoQuote("stroke-width",iWidth) .. "} }" )
end
p.show2=function (frame)
return p.show(frame)
end
p.addLake=function(qid,iLevel)
if (qid and ((not bHasMaxLevel) or (iLevel<=iMaxLevel)) and (not denylist[qid]) and p.isAllowed(qid)) then
if not allakes[qid] then
local item={}
item.id=qid
item.name=mw.wikibase.getLabel(qid)
table.insert(lakedatabase,item)
allakes[qid]=true
local entityTributary=mw.wikibase.getBestStatements(qid, 'P200' )
for key, value in pairs( entityTributary ) do
local qidTributary=read(value,'id')
if (p.isLake(qidTributary)) then
p.addLake(qidTributary,iLevel)
else
p.addRiver(qidTributary,iLevel+1,true)
end
end
local entityPart=mw.wikibase.getBestStatements(qid, 'P527' )
for key, value in pairs( entityPart ) do
qidPart=read(value,'id')
if (p.isLake(qidPart)) then
p.addLake(qidPart,iLevel)
end
end
local entityBorders=mw.wikibase.getBestStatements(qid, 'P47' )
for key, value in pairs( entityBorders ) do
qidBorder=read(value,'id')
if (p.isLake(qidBorder)) then
p.addLake(qidBorder,iLevel)
end
end
end
end
end
p.isAllowed=function(qid)
local entity=mw.wikibase.getBestStatements(qid, 'P31' )
for key, value in pairs( entity ) do
id=read(value,'id')
if (denyassource[id]) then
return false
end
end
return true
end
p.isLake=function(qid)
if (not qid) then return false end
local entity=mw.wikibase.getBestStatements(qid, 'P31' )
for key, value in pairs( entity ) do
id=read(value,'id')
if (id=='Q23397') or (id=='Q104093746') then
return true
end
end
return false
end
p.addRiver=function(qid,iLevel,bTributaries)
local level=iLevel
if qid and ((not allrivers[qid]) and ((not bHasMaxLevel) or (iLevel<=iMaxLevel)) and (not denylist[qid])) then
local item={}
item.id=qid
item.level=level
item.name=mw.wikibase.getLabel(qid)
table.insert(riverdatabase,item)
allrivers[qid]=true
if (bTributaries) then
-- Tributaries directly from the river
local entityTributary=mw.wikibase.getBestStatements(qid, 'P974' )
local id
for key, value in pairs( entityTributary ) do
id=read(value,'id')
if not allrivers[id] then
tblRiver=p.addRiver(id,level+1,bTributaries)
end
end
if (bLakes) then
-- Tributaries via the river's source (assuming it is a lake)
local entitySources=mw.wikibase.getBestStatements(qid, 'P885' )
for keyLake, valueLake in pairs( entitySources ) do
local id=read(valueLake,'id')
if (p.isLake(id)) then
p.addLake(id,level)
end
end
-- Tributaries via lakes the river pass by
local entityLakes=mw.wikibase.getBestStatements(qid, 'P469' )
for keyLake, valueLake in pairs( entityLakes ) do
local iLake=read(valueLake,'id')
p.addLake(iLake,level)
end
end
end
if (bBasin) then
iBasin=readFirstStatementId(qid,'P4614')
if (iBasin) then
statements=mw.wikibase.getBestStatements(iBasin,'P3896')
if not(next(statements)==nil) then
if not(statements[1]==nil) then
local txtBasin=statements[1].mainsnak.datavalue.value
local newtxt=txtBasin:gsub("^Data:%s*", "")
if not(basinsdatabase[newtxt]) then basinsdatabase[newtxt]=true end
-- table.insert(basinsdatabase,newtxt)
end
end
end
end
end
end
--[=====[
--]=====]
-- Funktion från https://stackoverflow.com/questions/41942289/display-contents-of-tables-in-lua
function tprint (tbl, indent)
if not indent then indent = 0 end
local toprint = string.rep(" ", indent) .. "{\r\n"
indent = indent + 2
for k, v in pairs(tbl) do
toprint = toprint .. string.rep(" ", indent)
if (type(k) == "number") then
toprint = toprint .. "[" .. k .. "] = "
elseif (type(k) == "string") then
toprint = toprint .. k .. "= "
end
if (type(v) == "number") then
toprint = toprint .. v .. ",\r\n"
elseif (type(v) == "string") then
toprint = toprint .. "\"" .. v .. "\",\r\n"
elseif (type(v) == "table") then
toprint = toprint .. tprint(v, indent + 2) .. ",\r\n"
else
toprint = toprint .. "\"" .. tostring(v) .. "\",\r\n"
end
end
toprint = toprint .. string.rep(" ", indent-2) .. "}"
return toprint
end
-- Function to split a string by a delimiter (by chatgpt)
p.split=function(inputStr, delimiter)
local result = {}
for match in (inputStr .. delimiter):gmatch("(.-)" .. delimiter) do
-- table.insert(result, match)
result[match]=true
end
return result
end
return p