Modul:Mapframe: Forskjell mellom sideversjoner

Fra Wikisida.no
Hopp til navigering Hopp til søk
(bedret beskyttelse av koordinater fra P159)
(Nummererte markører)
Linje 37: Linje 37:


local p = {}
local p = {}

local legend = {}
local numLegend = 0


local function hasLocalCoord()
local function hasLocalCoord()
Linje 148: Linje 151:
end
end


local function mappoint(latitude,longitude,title,description)
local function mappoint(latitude,longitude,title,description,symbol)
local point = {}
local point = {}
point["type"] = "Feature"
point["type"] = "Feature"
Linje 164: Linje 167:
if description then
if description then
prop["description"] = description
prop["description"] = description
end
if symbol then
prop["marker-symbol"] = symbol
table.insert(legend,title)
end
end
prop["marker-size"] = "small"
prop["marker-size"] = "small"
Linje 214: Linje 221:




local function showEntity(geojson,id,entity,stroke,title,opacity,createLink,method)
local function showEntity(geojson,id,entity,stroke,title,opacity,createLink,method,symbol)
local wdlat,wdlon = wdCoords(entity)
local wdlat,wdlon = wdCoords(entity)
local text = title or mw.wikibase.label(id)
local text = title or mw.wikibase.label(id)
Linje 239: Linje 246:
table.insert(geojson, line)
table.insert(geojson, line)
if wdlat and wdlon then
if wdlat and wdlon then
local point = mappoint(wdlat,wdlon,text,description)
local point = mappoint(wdlat,wdlon,text,description,symbol)
table.insert(geojson, point)
table.insert(geojson, point)
end
end
Linje 250: Linje 257:


-- Visualize an entity through boundary, marker with name of entity. geojson updated by showEntity
-- Visualize an entity through boundary, marker with name of entity. geojson updated by showEntity
local function visEntity(geojson,id,stroke,opacity,method)
local function visEntity(geojson,id,stroke,opacity,method,symbol)
if not id then
if not id then
return nil
return nil
Linje 258: Linje 265:
return nil
return nil
end
end
return showEntity(geojson,id,entity,stroke,nil,opacity,"createLink",method)
return showEntity(geojson,id,entity,stroke,nil,opacity,"createLink",method,symbol)
end
end


Linje 282: Linje 289:
end
end


local function visClaims(geojson,claims,stroke,opacity,method)
local function visClaims(geojson,claims,stroke,opacity,method,usesymbol)
local count = 0
for idx,claim in pairs(claims) do
for idx,claim in pairs(claims) do
local qualifiers = claim.qualifiers
local qualifiers = claim.qualifiers
Linje 292: Linje 300:
if not endtime then
if not endtime then
local id = claim.mainsnak.datavalue.value['id'] or nil
local id = claim.mainsnak.datavalue.value['id'] or nil
numLegend = numLegend + 1
visEntity(geojson,id,stroke,opacity,method)
local symbol = nil
if usesymbol and numLegend < 100 then
symbol = tostring(numLegend)
end
visEntity(geojson,id,stroke,opacity,method,symbol)
end
end
end
end
Linje 326: Linje 339:
local stroke = "#880000"
local stroke = "#880000"
local opacity = 0.1
local opacity = 0.1
visClaims(geojson,claims,stroke,opacity,"geoshape")
visClaims(geojson,claims,stroke,opacity,"geoshape","bruk symbol")


return geojson
return geojson
end

local function makeLegend()
local text = ""
for idx,leg in ipairs(legend) do
text = text .. "<br/>".. idx .. " = " .. leg
end
if numLegend>3 then
text = string.format([[
<div class="mw-collapsible mw-collapsed">
<div class="sentrert">%s markører</div>
<div class="mw-collapsible-content">%s</div>
</div>
]], numLegend, text)
text = text .. "[[Kategori:Artikler med kart med nummererte markører]]"
end
return text
end
end


Linje 464: Linje 494:
end
end
frameargs['frameless'] = 'frameless'
frameargs['frameless'] = 'frameless'
return mw.getCurrentFrame():extensionTag('mapframe', mw.text.jsonEncode(geojson), frameargs) .. '<br/>' .. text .. mlink .. klink
return mw.getCurrentFrame():extensionTag('mapframe', mw.text.jsonEncode(geojson), frameargs) .. '<br/>'
.. text .. mlink .. makeLegend() .. klink
.. osmLink(entity) .. koordmal .. coordcat
.. osmLink(entity) .. koordmal .. coordcat
end
end
frameargs['text'] = text .. mlink .. klink
frameargs['text'] = text .. mlink .. klink .. makeLegend()
end
end
return mw.getCurrentFrame():extensionTag('mapframe', mw.text.jsonEncode(geojson), frameargs)
return mw.getCurrentFrame():extensionTag('mapframe', mw.text.jsonEncode(geojson), frameargs)

Sideversjonen fra 3. mar. 2022 kl. 19:20

Denne modulen benyttes av kartmalen {{Kart}}. Se dokumentasjonssiden til denne malen for bruk og instruksjoner.


local math_mod = require( "Module:Math" )

local useLanguage = {
	["Q17"] = "en",     -- Japan
	["Q79"] = "en",     -- Egypt
	["Q115"] = "en",    -- Etiopia
	["Q148"] = "en",    -- Kina
	["Q230"] = "en",    -- Georgia
	["Q399"] = "en",    -- Armenia
	["Q423"] = "en",    -- Nord-Korea
	["Q424"] = "en",    -- Kambodsja
	["Q668"] = "en",    -- India
	["Q711"] = "en",    -- Mongolia
	["Q794"] = "en",    -- Iran
	["Q796"] = "en",    -- Irak
	["Q801"] = "en",    -- Israel
	["Q810"] = "en",    -- Jordan
	["Q819"] = "en",    -- Laos
	["Q822"] = "en",    -- Libanon
	["Q836"] = "en",    -- Myanmar
	["Q842"] = "en",    -- Oman
	["Q843"] = "en",    -- Pakistan
	["Q846"] = "en",    -- Qatar
	["Q851"] = "en",    -- Saudi-Arabia
	["Q858"] = "en",    -- Syria
	["Q865"] = "en",    -- Republikken Kina - Taiwan
	["Q869"] = "en",    -- Thailand
	["Q878"] = "en",    -- De forente arabiske emirater
	["Q884"] = "en",    -- Sør-Korea
	["Q889"] = "en",    -- Afghanistan
	["Q902"] = "en",    -- Bangladesh
	["Q917"] = "en",    -- Bhutan
	["Q986"] = "en",    -- Eritrea
	["Q23792"] = "en"     -- Palestina
}


local p = {}

local legend = {}
local numLegend = 0

local function hasLocalCoord()
	local pageWikitext = mw.title.getCurrentTitle():getContent()
	local treff = pageWikitext:match("{{[Kk]oord|[^}]+}}")
	return treff	
end

local function lonlat(args)
	local newargs = args
	if not args["lat"] and not args["lon"] then
		if args["breddegrad"] and args["lengdegrad"] then
			newargs["lat"] = tonumber(args["breddegrad"]) or nil
			newargs["lon"] = tonumber(args["lengdegrad"]) or nil
		end
	end
	return newargs
end

local function selectSingleClaim(claims)
	if not claims then
		return nil
	end
	local selectedClaim = nil
	for idx,claim in pairs(claims) do
		if claim.rank == 'preferred' then
			return claim
		end
		if claim.rank == 'normal' then
			if not selectedClaim then
				selectedClaim = claim
			end
		end
	end
	return selectedClaim
end

local function osmLink(entity)
	local osm = ""
	local osmval = entity:getBestStatements("P402")
	if osmval and osmval[1] and osmval[1].mainsnak["datavalue"] then
		local osmid = osmval[1].mainsnak["datavalue"].value or ""
		if osmid and osmid ~= "" then
			--osm = "<br/> vis på [https://www.openstreetmap.org/relation/" .. osmid .. " OSM]"
			osm = "[[Kategori:Sider hvor Wikidata har lenker til OpenStreetMap relation]]"
		end
	end
	return osm
end

local function wdCoords(entity)
	local wdlat,wdlon = nil,nil
	local category = ""
	if entity.claims and entity.claims["P625"] then
		local claim = selectSingleClaim(entity.claims["P625"])
		if claim and claim.mainsnak.datavalue then
			local coord = claim.mainsnak.datavalue.value or nil
			wdlat = coord["latitude"] or nil
			wdlon = coord["longitude"] or nil
		end
	end
	if not wdlat then
		if entity.claims and entity.claims["P159"] then
			local claim = selectSingleClaim(entity.claims["P159"])
			if claim and claim.qualifiers then
				local qual = claim.qualifiers["P625"]
				if qual and  qual[1] and qual[1].datavalue then
					local coord = qual[1].datavalue.value or nil
					wdlat = coord["latitude"] or nil
					wdlon = coord["longitude"] or nil
				end
				if wdlat then
					category = "[[Kategori:Artikler med koordinater hentet fra P159]]"
				end
			end
		end
	end
	return wdlat,wdlon,category
end


local function wdGeoShape(entity)
	local shape = nil
	if entity.claims and entity.claims["P3896"] then
		local claim = selectSingleClaim(entity.claims["P3896"])
		local value = claim.mainsnak.datavalue.value or nil
		if value then
	       local shape = {
	       	["type"] = "ExternalData",
			["service"] = "page",
			["title"] =  value
		}
		return shape
		end
	end
	return nil
end

local function selectMapLanguage(entity)
	local lang = "local"
	if entity.claims and entity.claims["P17"] then
		local claim = selectSingleClaim(entity.claims["P17"])
		if claim and claim.mainsnak.datavalue then
		    local value = claim.mainsnak.datavalue.value or nil
		    if value then
			    lang = useLanguage[value["id"]] or "local"
			end
		end
	end
	return lang
end

local function mappoint(latitude,longitude,title,description,symbol)
	local point = {}
    point["type"] = "Feature"
    local geo = {}
    geo["type"] = "Point"
	local pos = {}
    geo["coordinates"] = pos
    -- ensure the coordinates are not too long for the geojson
    geo["coordinates"][1] = math_mod._round( longitude, 6 )
    geo["coordinates"][2] = math_mod._round( latitude, 6 )
    local prop = {}
    if title then
    	prop["title"] = title
    end
    if description then
    	prop["description"] = description
    end
    if symbol then
    	prop["marker-symbol"] = symbol
    	table.insert(legend,title)
    end
    prop["marker-size"] = "small"
    point["properties"] = prop
    point["geometry"] = geo
    return point
end

local function geoline(id,stroke)
	local line = {
		["type"] = "ExternalData",
		["service"] = "geoline",
		["ids"] =  id,
        ['properties'] = {
        	["stroke"] = stroke,
        	["stroke-width"] = 2
        }
     }
     return line
end

local function geoshape(id,stroke,opacity)
	local line = {
		["type"] = "ExternalData",
		["service"] = "geoshape",
		["ids"] =  id,
        ['properties'] = {
        	["stroke"] = stroke,
        	["stroke-width"] = 2,
        	["fill"] = "#ff0000",
        	["fill-opacity"] = opacity or 0.1
        }
     }
     return line
end

local function geomask(id,stroke,opacity)
	local line = {
		["type"] = "ExternalData",
		["service"] = "geomask",
		["ids"] =  id,
        ['properties'] = {
        	["stroke"] = stroke,
        	["stroke-width"] = 1,
        	["fill-opacity"] = opacity or 0.05
        }
     }
     return line
end


local function showEntity(geojson,id,entity,stroke,title,opacity,createLink,method,symbol)
	local wdlat,wdlon = wdCoords(entity)
	local text = title  or mw.wikibase.label(id)
	local link = mw.wikibase.sitelink(id)
	local meth = method or "geoshape"
	if createLink and text and link then
		text = "[[" .. link .. "|" .. text .. "]]"
	end
	local description = nil
	if createLink then
		if entity.claims and entity.claims["P18"] then
			local claim = selectSingleClaim(entity.claims["P18"])
	   		local image = claim.mainsnak.datavalue.value or nil
			if image then
				description = "[[File:" .. image .. "]]"
			end
		end
	end
	local shape = nil
	if meth == "geoshape" then
		shape = geoshape(id,stroke,opacity)
		table.insert(geojson, shape)
		local line = geoline(id,stroke)
		table.insert(geojson, line)
		if wdlat and wdlon then
    		local point = mappoint(wdlat,wdlon,text,description,symbol)
			table.insert(geojson, point)
		end
	elseif meth == "geomask" then
		shape = geomask(id,stroke,opacity)
		table.insert(geojson, shape)
	end
    return geojson
end

-- Visualize an entity through boundary, marker with name of entity. geojson updated by showEntity
local function visEntity(geojson,id,stroke,opacity,method,symbol)
	if not id then
		return nil
	end
	local entity = mw.wikibase.getEntity(id)
	if not entity then
		return nil
	end
	return showEntity(geojson,id,entity,stroke,nil,opacity,"createLink",method,symbol)
end

local function getcurrentqids(claims)
	local qids = {}
	for idx,claim in pairs(claims) do
		local qualifiers = claim.qualifiers
		local endtime = nil
		if qualifiers then
			endtime = claim.qualifiers["P582"] or nil
		end
		-- todo: Test on end time simplified. This assumes that all end times are in the past
		if not endtime then
			if claim.mainsnak and claim.mainsnak.datavalue and claim.mainsnak.datavalue.value then
				local qid = claim.mainsnak.datavalue.value['id'] or nil
				if qid then
					table.insert(qids, qid)
				end
			end
		end
	end
	return qids
end

local function visClaims(geojson,claims,stroke,opacity,method,usesymbol)
	local count = 0
	for idx,claim in pairs(claims) do
		local qualifiers = claim.qualifiers
		local endtime = nil
		if qualifiers then
			endtime = claim.qualifiers["P582"] or nil
		end
		-- todo: Test on end time simplified. This assumes that all end times are in the past
		if not endtime then
			local id = claim.mainsnak.datavalue.value['id'] or nil
			numLegend = numLegend + 1
			local symbol = nil
			if usesymbol and numLegend < 100 then
				symbol = tostring(numLegend)
			end
			visEntity(geojson,id,stroke,opacity,method,symbol)
		end
	end

	return geojson
end

local function includeLocation(geojson,entity)
	if not entity or not entity.claims then
		return geojson
	end
	local claims = entity.claims["P131"] or entity.claims["P276"] or nil
	if not claims then
		return geojson
	end	
	qids = getcurrentqids(claims)
	local stroke = "#888888"
	local opacity = 0.1
	local shape = geomask(qids,stroke,opacity)
	table.insert(geojson, shape)
	return geojson
end

local function includeProp(geojson,entity,prop)
	if not entity or not prop or not entity.claims then
		return nil
	end
	local claims = entity.claims[prop] or nil
	if not claims then
		return nil
	end
	
	local stroke = "#880000"
	local opacity = 0.1
	visClaims(geojson,claims,stroke,opacity,"geoshape","bruk symbol")

	return geojson
end

local function makeLegend()
	local text = ""
	for idx,leg in ipairs(legend) do
		text = text  .. "<br/>".. idx .. " = " .. leg
	end
	if numLegend>3 then
    	text = string.format([[
				<div class="mw-collapsible mw-collapsed">
					<div class="sentrert">%s markører</div>
					<div class="mw-collapsible-content">%s</div>
				</div>
			]], numLegend, text)
		text = text .. "[[Kategori:Artikler med kart med nummererte markører]]"
	end
	return text
end

local function mapNoWikidata(args,infoboks)
	local geojson = {}
	local zoom = args["zoom"] or 8
	local lat = args["latitude"] or args["lat"]
	local lon = args["longitude"] or args["lon"]
	if not lat or not lon then
		return ""
	end
    local point = mappoint(lat,lon)
	local width = tonumber(args["width"]) or 290
	local height  = tonumber(args["height"]) or width
	local text = args["text"]  or ""
	table.insert(geojson, point)
	local frameargs = {
    		['height'] = height,
    		['width'] = width,
    		['align'] = align
    		}
    if zoom and zoom ~= 'auto' then
    	frameargs['zoom'] = zoom
    	frameargs['latitude'] = lat
    	frameargs['longitude'] = lon
    end
	local linkargs = {
    		['height'] = height,
    		['width'] = width,
    		['align'] = align,
    		['latitude'] = lat,
    		['longitude'] = lon,
    		['zoom'] = zoom or 8
    	}
    local mlink = ''
    local klink = ''
    if infobox then
--    	mlink = '<br/>' .. mw.getCurrentFrame():extensionTag('maplink', mw.text.jsonEncode(geojson), linkargs)
    	klink = '<br/>' .. mw.getCurrentFrame():expandTemplate{title='koord',args = { lat, lon, vis='tekst'} }
    end
   	frameargs['text'] = text .. mlink .. klink
	return  mw.getCurrentFrame():extensionTag('mapframe', mw.text.jsonEncode(geojson), frameargs)

end

local function map2(args,infobox,visKoord)
	local id = args['id'] or args[1] or nil
	if id == "" then
		id = nil
	end
	local entity = mw.wikibase.getEntity(id) or nil
	if not id then
		if not entity then
			return ""
		end
		id = entity.id
	end
	local width = args["width"] or nil
	if width ~= "full" then
		width = tonumber(args["width"]) or 290
	end
	local height  = tonumber(args["height"]) or width
	if height == "full" then
		return ""
	end
	local zoom = args["zoom"] or 8
	local lat = args["latitude"] or args["lat"]
	local lon = args["longitude"] or args["lon"]
	local includeProperty = args["include property"] or nil
	local wdlat,wdlon,coordcat = wdCoords(entity)
	if not lat or not lon then
		lat = wdlat
		lon = wdlon
    end
    if not lon or not lat then
    	return "[[Kategori:Artikler hvor kartmodul mangler koordinater]]"
    end
	local text = args["text"]  or mw.wikibase.label(id) or ""
	local align = args["align"]  or 'right'
	local lang = selectMapLanguage(entity) 
	
	local geojson = {}
	local stroke = "#ff0000"
	local title = nil
	local opacity = 0.1
	if includeProperty then
		opacity = 0.0
	end
	showEntity(geojson,id,entity,stroke,title,opacity)
	if args['marker'] and lat and lon then
    	local point = mappoint(lat,lon)
		table.insert(geojson, point)
	end
	includeLocation(geojson,entity)
	if includeProperty then
		includeProp(geojson,entity,includeProperty)
	end
	local frameargs = {
    		['height'] = height,
    		['width'] = width,
    		['align'] = align,
    		['lang'] = lang
    	}
    if zoom and zoom ~= 'auto' then
    	frameargs['zoom'] = zoom
    	frameargs['latitude'] = lat
    	frameargs['longitude'] = lon
    end
	if zoom and zoom == 'auto' then
		zoom = nil
	end
	local linkargs = {
    		['height'] = height,
    		['width'] = width,
    		['align'] = align,
    		['latitude'] = lat,
    		['longitude'] = lon,
    		['zoom'] = zoom or 8,
    		['lang'] = lang
    	}
    	local mlink = ''
        local klink = ''
     	if text then
    		if infobox then
    			local koordmal = "[[Kategori:Artikler med lokal koord mal til tittelfelt]]"
    			if not hasLocalCoord() then
    				visKoord = "tittel"
    				koordmal = ""
    			end
--    			mlink = '<br/>' .. mw.getCurrentFrame():extensionTag('maplink', mw.text.jsonEncode(geojson), linkargs)
                if visKoord and visKoord == 'tittel' then
    	            klink = '<br/>' .. mw.getCurrentFrame():expandTemplate{title='koord',args = { lat, lon , vis='tekst,tittel'} }
    	        else
    	            klink = '<br/>' .. mw.getCurrentFrame():expandTemplate{title='koord',args = { lat, lon , vis='tekst'} }
    	        end
    			frameargs['frameless'] = 'frameless'
    			return  mw.getCurrentFrame():extensionTag('mapframe', mw.text.jsonEncode(geojson), frameargs) .. '<br/>'
    			.. text .. mlink .. makeLegend() .. klink
    			.. osmLink(entity) .. koordmal .. coordcat
    		end
    		frameargs['text'] = text .. mlink .. klink .. makeLegend()
    	end
	return  mw.getCurrentFrame():extensionTag('mapframe', mw.text.jsonEncode(geojson), frameargs)
	
--    return "<pre>" .. mw.text.jsonEncode(geojson, mw.text.JSON_PRETTY) .. "</pre>" 
end

function p.infoboxLocation(frame)
--	return "<pre>" .. mw.text.jsonEncode(frame:getParent().args, mw.text.JSON_PRETTY) .. "</pre>"
    local args = lonlat(mw.getCurrentFrame():getParent().args)
    local argframe = mw.getCurrentFrame().args
    local vis = args["vis"] or argframe["vis"] or ""
    if vis == "nei" then
    	return ""
    end
    args["width"] = args["width"] or argframe["width"] or 290
    local zoom = args["zoom"] or argframe["zoom"] or nil
    if zoom and zoom ~= 'auto' then
	    args["zoom"] = tonumber(args["zoom"]) or tonumber(argframe["zoom"]) or 8
	else 
		if not zoom then
			args["zoom"] = 8
		else
			args["zoom"] = 'auto'
		end
	end
    args[1] = ""
    args["align"] = "center"
	local maptxt = map2(args,1,vis)
	if not maptxt or maptxt =="" then
		return mapNoWikidata(args,1)
	end
	return maptxt
end

function p.map(frame)
--	return "<pre>" .. mw.text.jsonEncode(frame:getParent().args, mw.text.JSON_PRETTY) .. "</pre>"
	return map2(mw.getCurrentFrame():getParent().args)
end

return p