Hoppa till innehållet

Modul:Vatten OSM

Från Wikipedia

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 har en "relation" skapat på OpenStreetMap samt 2) att den relationen har ett angivit Wikidata-id. För mer information se Wikipedia:Kartor och de länkar som länkas där.

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 (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)
	local bTributaries,bBasin
	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
	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
	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
			-- 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
		
		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

--[=====[ 
--]=====]


-- 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