Modul:Sandkasse/Haros/kart

Fra Wikipedia, den frie encyklopedi
Hopp til navigering Hopp til søk


local math_mod = require( "Module:Math" )

local p = {}

function p.test1(frame)
	
	frame.args[1] = "Q585"
	return p.kart(frame)
end

function p.test2(frame)
	local id = "Q585"
	local lon=10.752777777778
	local lat = 59.911111111111
	local zoom = 9
	local width = 350

    return p.tegnKart(id,lon,lat)
end

function p.test(frame)
	local id = "Q110848"
	local args = {}
	key = 1
	args[key] = id
	frame.args = args

	return p.printEntity(frame)
end

function p.kart(frame)
	local id = frame.args[1]
	local entity = mw.wikibase.getEntity(id)
--	if id == 'Q50619' then
--		return "<pre>" .. mw.text.jsonEncode(frame.args, mw.text.JSON_PRETTY) .. "</pre>" 
--	end
	return map2(frame.args)
--	return ""
end

function lonlat(args)
	local newargs = args
	if not args["lat"] and not args["lon"] then
		if args["breddegrad"] and args["lengdegrad"] then
			newargs["lat"] = args["breddegrad"]
			newargs["lon"] = args["lengdegrad"]
		end
	end
	return newargs
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)
    args["width"] = 250
	local maptxt = map2(args,1)
	if not maptxt or maptxt =="" then
		return mapNoWikidata(args,1)
	end
	return maptxt
end
function mapNoWikidata(args,infoboks)
	local geojson = {}
	local zoom = args["zoom"] or nil
	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 250
	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 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 = ''
    if infobox then
    	mlink = '<br/>' .. mw.getCurrentFrame():extensionTag('maplink', mw.text.jsonEncode(geojson), linkargs)
    end
   	frameargs['text'] = text .. mlink
	return  mw.getCurrentFrame():extensionTag('mapframe', mw.text.jsonEncode(geojson), frameargs)

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
function map2(args,infobox)
	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 350
	end
	local height  = tonumber(args["height"]) or width
	if height == "full" then
		return ""
	end
	local zoom = args["zoom"] or nil
	local lat = args["latitude"] or args["lat"]
	local lon = args["longitude"] or args["lon"]
	local includeProperty = args["include property"] or nil
	local wdlat,wdlon = wdCoords(entity)
	if not lat or not lon then
		lat = wdlat
		lon = wdlon
    end
    if not lon or not lat then
    	return ""
    end
	local text = args["text"]  or mw.wikibase.label(id) or ""
	local align = args["align"]  or 'right'
	
	local geojson = {}
	local stroke = "#ff0000"
	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
	if includeProperty then
		includeProp(geojson,entity,includeProperty)
	end
	local frameargs = {
    		['height'] = height,
    		['width'] = width,
    		['align'] = align
    	}
    if zoom 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
    	}
    	if frameless then
    		frameargs['frameless'] = 'frameless'
    	end
    	local mlink = ''
    	if text then
    		if infobox then
    			mlink = '<br/>' .. mw.getCurrentFrame():extensionTag('maplink', mw.text.jsonEncode(geojson), linkargs)
    		end
    		frameargs['text'] = text .. mlink
    	end
	return  mw.getCurrentFrame():extensionTag('mapframe', mw.text.jsonEncode(geojson), frameargs)
	
--    return "<pre>" .. mw.text.jsonEncode(geojson, mw.text.JSON_PRETTY) .. "</pre>" 
end

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"
	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
			visEntity(geojson,id,stroke,0.1)
		end
	end

	return geojson
end

-- Visualize an entity through boundary, marker with name of entity. geojson updated by showEntity
function visEntity(geojson,id,stroke,opacity)
	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")
end
function showEntity(geojson,id,entity,stroke,title,opacity,createLink)
	local wdlat,wdlon = wdCoords(entity)
	local text = title  or mw.wikibase.label(id)
	local link = mw.wikibase.sitelink(id)
	if createLink and text and link then
		text = "[[" .. link .. "|" .. text .. "]]"
	end
	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 = 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)
		table.insert(geojson, point)
	end
    return geojson
end

function wdCoords(entity)
	local wdlat,wdlon = nil,nil
	if entity.claims and entity.claims["P625"] then
		local claim = selectSingleClaim(entity.claims["P625"])
	   	local coord = claim.mainsnak.datavalue.value or nil
   		wdlat = coord["latitude"] or nil
   		wdlon = coord["longitude"] or nil
   	end
	return wdlat,wdlon
end


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

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

function mappoint(latitude,longitude,title,description)
	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
    prop["marker-size"] = "small"
    point["properties"] = prop
    point["geometry"] = geo
    return point
end

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

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

function p.tegnKart(id,lon,lat,zoom,width,align,frameless)
	local geojson = {}
	local line = geoline(id,"#ff0000")
	table.insert(geojson, line)
	local shape = geoshape(id,"#ff0000")
	table.insert(geojson, shape)
	local point = mappoint(lat,lon)
	table.insert(geojson, point)
	local args = {
    		['height'] = width or 350,
    		['width'] = width or 350,
    		['align'] = align or 'center',
    		['latitude'] = lat,
    		['longitude'] = lon,
    		['zoom'] = zoom or 8
    	}
    	if frameless then
    		args['frameless'] = 'frameless'
    	end
	return mw.getCurrentFrame():extensionTag('mapframe', mw.text.jsonEncode(geojson), args)
	
end

function p.printEntity(frame)
	local id = frame.args[1]
	local entity = mw.wikibase.getEntity(id)
	if entity then return "<pre>" .. mw.text.jsonEncode(entity, mw.text.JSON_PRETTY) .. "</pre>" end
end

return p