Modul:Mapframe: Forskjell mellom sideversjoner

Fra Wikisida.no
Hopp til navigering Hopp til søk
(engelske navn i Thailand)
m (Én sideversjon ble importert)
 
(84 mellomliggende versjoner av 5 brukere er ikke vist)
Linje 4: Linje 4:
["Q17"] = "en", -- Japan
["Q17"] = "en", -- Japan
["Q79"] = "en", -- Egypt
["Q79"] = "en", -- Egypt
["Q115"] = "en", -- Etiopia
["Q148"] = "en", -- Kina
["Q148"] = "en", -- Kina
["Q230"] = "en", -- Georgia
["Q399"] = "en", -- Armenia
["Q423"] = "en", -- Nord-Korea
["Q423"] = "en", -- Nord-Korea
["Q424"] = "en", -- Kambodsja
["Q424"] = "en", -- Kambodsja
["Q668"] = "en", -- India
["Q668"] = "en", -- India
["Q711"] = "en", -- Mongolia
["Q794"] = "en", -- Iran
["Q794"] = "en", -- Iran
["Q796"] = "en", -- Irak
["Q796"] = "en", -- Irak
["Q801"] = "en", -- Israel
["Q810"] = "en", -- Jordan
["Q810"] = "en", -- Jordan
["Q819"] = "en", -- Laos
["Q819"] = "en", -- Laos
["Q822"] = "en", -- Libanon
["Q836"] = "en", -- Myanmar
["Q836"] = "en", -- Myanmar
["Q842"] = "en", -- Oman
["Q842"] = "en", -- Oman
Linje 20: Linje 26:
["Q865"] = "en", -- Republikken Kina - Taiwan
["Q865"] = "en", -- Republikken Kina - Taiwan
["Q869"] = "en", -- Thailand
["Q869"] = "en", -- Thailand
["Q878"] = "en", -- De forente arabiske emirater
["Q884"] = "en", -- Sør-Korea
["Q884"] = "en", -- Sør-Korea
["Q889"] = "en" -- Afghanistan
["Q889"] = "en", -- Afghanistan
["Q902"] = "en", -- Bangladesh
["Q917"] = "en", -- Bhutan
["Q986"] = "en", -- Eritrea
["Q23792"] = "en" -- Palestina
}
}




local p = {}
local p = {}

local legend = {}
local numLegend = 0
local maxLegend = 5

local bbox = {}
bbox.min = {}
bbox.max = {}
bbox.center = {}
bbox.dist = {}
bbox.txt = {"Koordinater funnet"}

autozoom = {
{ dist=2000,zoom=3},
{ dist=700,zoom=4},
{ dist=300,zoom=5},
{ dist=150,zoom=6},
{ dist=50,zoom=7},
{ dist=30,zoom=8},
{ dist=10,zoom=9},
{ dist=6,zoom=10},
{ dist=4,zoom=11},
}

local function hasLocalCoord()
local pageWikitext = mw.title.getCurrentTitle():getContent()
local treff = pageWikitext:match("{{[Kk]oord|[^}]+}}")
if treff then
local treffVis = treff:match("vis")
local treffTittel = treff:match("tittel")
local treffTekst = treff:match("tekst")
if treff and treffVis and treffTittel then
return treff
end
end
return nil
end


local function lonlat(args)
local function lonlat(args)
Linje 54: Linje 102:
end
end
return selectedClaim
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 allOkSnaks(entity,datatype)
local retur = {}
if entity.claims then
for propid,props in pairs(entity.claims) do
for idx,claim in ipairs(props) do
if claim.rank == 'preferred' or claim.rank == 'normal' then
local snak = claim.mainsnak
if snak.snaktype == "value" and snak.datatype == datatype then
local sn = {}
sn.snak = snak
sn.qu = claim.qualifiers
table.insert(retur,sn)
end
end
end
end
end
return retur
end

function dump(item)
return "<pre>" .. mw.text.jsonEncode(item, mw.text.JSON_PRETTY) .. "</pre>"
end


local function addBbox(entity)
for idx,sn in ipairs(allOkSnaks(entity,"globe-coordinate")) do
local snak = sn.snak
local val = snak.datavalue.value
local qu = sn.qu
local qutxt = ""
if qu and qu.P518 then
qutxt = " P518 " .. mw.wikibase.formatValues(qu.P518)
end
if not bbox.min.longitude or bbox.min.longitude > val.longitude then
bbox.min.longitude = val.longitude
end
if not bbox.min.latitude or bbox.min.latitude > val.latitude then
bbox.min.latitude = val.latitude
end
if not bbox.max.longitude or bbox.max.longitude < val.longitude then
bbox.max.longitude = val.longitude
end
if not bbox.max.latitude or bbox.max.latitude < val.latitude then
bbox.max.latitude = val.latitude
end
local txt = snak.property .. " " .. qutxt .. " " .. val.longitude .. " " .. val.latitude
table.insert(bbox.txt,txt)
end
if (bbox.min.longitude) then
bbox.center.longitude = (bbox.min.longitude + bbox.max.longitude)/2
bbox.center.latitude = (bbox.min.latitude + bbox.max.latitude)/2
bbox.dist.longitude = (bbox.max.longitude - bbox.min.longitude)
bbox.dist.latitude = (bbox.max.latitude - bbox.min.latitude)
bbox.haversine = HaversineDistance(
bbox.max.latitude,bbox.max.longitude,
bbox.min.latitude,bbox.min.longitude)
end
return

end
local function bboxlist(ids)
for ix,id in ipairs(ids) do
local entity = mw.wikibase.getEntity(id)
addBbox(entity)
end
end

-- From en:Module:Sandbox/Hellknowz/CoordDistance
function HaversineDistance(lat1,lon1,lat2,lon2)

local radius = 6371 -- km

local dlat = math.rad(lat2-lat1)
local dlon = math.rad(lon2-lon1)
local a = math.sin(dlat/2) * math.sin(dlat/2) + math.cos(math.rad(lat1)) * math.cos(math.rad(lat2)) * math.sin(dlon/2) * math.sin(dlon/2)
local c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
return radius * c

end

-- the distances need to be adjusted according to the size of the frame of the map
local function bboxzoom(factor)
for ix,v in ipairs(autozoom) do
if bbox.haversine and v.dist*factor < bbox.haversine then
return v.zoom
end
end
return 12
end
end


local function wdCoords(entity)
local function wdCoords(entity)
local wdlat,wdlon = nil,nil
local wdlat,wdlon = nil,nil
local category = ""
if entity.claims and entity.claims["P625"] then
if entity.claims and entity.claims["P625"] then
local claim = selectSingleClaim(entity.claims["P625"])
local claim = selectSingleClaim(entity.claims["P625"])
if claim.mainsnak.datavalue then
if claim and claim.mainsnak.datavalue then
local coord = claim.mainsnak.datavalue.value or nil
local coord = claim.mainsnak.datavalue.value or nil
wdlat = coord["latitude"] or nil
wdlat = coord["latitude"] or nil
wdlon = coord["longitude"] or nil
wdlon = coord["longitude"] or nil
end
end
end
end
return wdlat,wdlon
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:Sider med koordinater hentet fra P159]]"
end
end
end
end
return wdlat,wdlon,category
end
end


Linje 76: Linje 245:
local value = claim.mainsnak.datavalue.value or nil
local value = claim.mainsnak.datavalue.value or nil
if value then
if value then
local shape = {
local prop = {}
local shape = {
["type"] = "ExternalData",
["type"] = "ExternalData",
["service"] = "page",
["service"] = "page",
["title"] = value
["title"] = value,
["properties"] = prop
}
}
return shape
return shape
Linje 91: Linje 262:
if entity.claims and entity.claims["P17"] then
if entity.claims and entity.claims["P17"] then
local claim = selectSingleClaim(entity.claims["P17"])
local claim = selectSingleClaim(entity.claims["P17"])
if claim.mainsnak.datavalue then
if claim and claim.mainsnak.datavalue then
local value = claim.mainsnak.datavalue.value or nil
local value = claim.mainsnak.datavalue.value or nil
if value then
if value then
Linje 101: Linje 272:
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 117: Linje 288:
if description then
if description then
prop["description"] = description
prop["description"] = description
end
if symbol and title then
numLegend = numLegend + 1
prop["marker-symbol"] = tostring(numLegend)
table.insert(legend,title)
end
end
prop["marker-size"] = "small"
prop["marker-size"] = "small"
Linje 124: Linje 300:
end
end


local function geoline(id,stroke)
local function geoline(id,stroke,title)
local line = {
local line = {
["type"] = "ExternalData",
["type"] = "ExternalData",
Linje 131: Linje 307:
['properties'] = {
['properties'] = {
["stroke"] = stroke,
["stroke"] = stroke,
["stroke-width"]= 2
["stroke-width"] = 2,
["marker-size"] = "small",
--["marker-symbol"] = "-letter",
["title"] = title
}
}
}
}
Linje 144: Linje 323:
['properties'] = {
['properties'] = {
["stroke"] = stroke,
["stroke"] = stroke,
["stroke-width"]= 2,
["stroke-width"] = 2,
["fill"] = "#ff0000",
["fill-opacity"] = opacity or 0.1
["fill-opacity"] = opacity or 0.1
}
}
Linje 151: Linje 331:
end
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 includeProp(geojson,entity,prop)
local function showEnt(geojson,id,wdlat,wdlon,artikkel,description,stroke,title,opacity,createLink,method,symbol)
local text = title
if not entity or not prop or not entity.claims then
if createLink and text and link then
text = "[[" .. artikkel .. "|" .. title .. "]]"
end
local shape = nil
if method == "geoshape" then
shape = geoshape(id,stroke,opacity)
table.insert(geojson, shape)
local line = geoline(id,stroke,title)
table.insert(geojson, line)
if wdlat and wdlon then
local point = mappoint(wdlat,wdlon,text,description,symbol)
table.insert(geojson, point)
end
elseif method == "geomask" then
shape = geomask(id,stroke,opacity)
table.insert(geojson, shape)
end
return geojson
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)
if createLink and text and link then
text = "[[" .. link .. "|" .. text .. "]]"
end
local meth = method or "geoshape"
local bilde = nil
if entity.claims and entity.claims["P18"] then
local claim = selectSingleClaim(entity.claims["P18"])
if claim then
local snak = claim.mainsnak
if snak.snaktype == "value" then
bilde = snak.datavalue.value or nil
end
end
end
local description = nil
if createLink and bilde then
description = "[[File:" .. bilde .. "]]"
end
geojson = showEnt(geojson,id,wdlat,wdlon,link,description,stroke,text,opacity,createLink,meth,symbol)

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
return nil
end
end
local claims = entity.claims[prop] or nil
local entity = mw.wikibase.getEntity(id)
if not claims then
if not entity then
return nil
return nil
end
end
return showEntity(geojson,id,entity,stroke,nil,opacity,"createLink",method,symbol)
end
local stroke = "#880000"

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
for idx,claim in pairs(claims) do
local qualifiers = claim.qualifiers
local qualifiers = claim.qualifiers
Linje 171: Linje 437:
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
local symbol = nil
visEntity(geojson,id,stroke,0.1)
if usesymbol and numLegend < 99 then
symbol = "1"
end
visEntity(geojson,id,stroke,opacity,method,symbol)
count = count+1
end
end
end
end
Linje 178: Linje 450:
end
end


local function showEntity(geojson,id,entity,stroke,title,opacity,createLink)
local function includeLocation(geojson,entity)
if not entity or not entity.claims then
local wdlat,wdlon = wdCoords(entity)
return geojson
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
end
local claims = entity.claims["P131"] or entity.claims["P276"] or nil
local description = nil
if createLink then
if not claims then
return geojson
if entity.claims and entity.claims["P18"] then
end
local claim = selectSingleClaim(entity.claims["P18"])
qids = getcurrentqids(claims)
local image = claim.mainsnak.datavalue.value or nil
if image then
if #qids>1 then
bboxlist(qids)
description = "[[File:" .. image .. "]]"
end
end
end
end
local shape = geoshape(id,stroke,opacity)
local stroke = "#888888"
local opacity = 0.1
local shape = geomask(qids,stroke,opacity)
table.insert(geojson, shape)
table.insert(geojson, shape)
return geojson
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
end


local function includeProp(geojson,entity,prop)
-- Visualize an entity through boundary, marker with name of entity. geojson updated by showEntity
if not entity or not prop or not entity.claims then
local function visEntity(geojson,id,stroke,opacity)
if not id then
return nil
return nil
end
end
local entity = mw.wikibase.getEntity(id)
local claims = entity.claims[prop] or nil
if not entity then
if not claims then
return nil
return nil
end
end
return showEntity(geojson,id,entity,stroke,nil,opacity,"createLink")
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 .. idx .. " = " .. leg .. "<br/>"
end
if numLegend>maxLegend then
text = string.format([[
<div class="mw-collapsible mw-collapsed">
<div class="sentrert">%s nummererte markører</div>
<div class="mw-collapsible-content">%s</div>
</div>
]], numLegend, text)
end
if numLegend > 0 then
text = text .. "[[Kategori:Sider med kart med nummererte markører]]"
end
return text
end
end


Linje 227: Linje 513:
end
end
local point = mappoint(lat,lon)
local point = mappoint(lat,lon)
local width = tonumber(args["width"]) or 250
local width = tonumber(args["width"]) or 300
local height = tonumber(args["height"]) or width
local height = tonumber(args["height"]) or width
local text = args["text"] or ""
local text = args["text"] or ""
Linje 236: Linje 522:
['align'] = align
['align'] = align
}
}
if zoom then
if zoom and zoom ~= 'auto' then
frameargs['zoom'] = zoom
frameargs['zoom'] = zoom
frameargs['latitude'] = lat
frameargs['latitude'] = lat
Linje 260: Linje 546:
end
end


local function map2(args,infobox)
local function getIds(args)
local ids= {}
local id = args['id'] or args[1] or nil
if id == "" then
id = nil
end
if id ~= "" then
local ida = {}
for ident in mw.ustring.gmatch(id, 'Q%d+' ) do
local entity = mw.wikibase.getEntity(ident) or nil
local id1 = entity.id
local lab = mw.wikibase.label( id1 )
if lab then
ida[lab] = id1
end
table.insert(ids,id1)
end
for lab,id2 in pairs(ida) do
--table.insert(ids,id2)
end
--ids = mw.text.split( id, ',', true )
if #ids ~= 1 then
id = nil
end
end
--local entity = mw.wikibase.getEntity(id) or nil
--if not id then
-- if not entity then
-- return ""
-- end
-- id = entity.id
-- table.insert(ids, id)
--end
return ids
end

local function map2(args,infobox,visKoord)
local id = args['id'] or args[1] or nil
local id = args['id'] or args[1] or nil
if id == "" then
if id == "" then
Linje 272: Linje 594:
id = entity.id
id = entity.id
end
end
local out = args["out"] or nil
local width = args["width"] or nil
local width = args["width"] or nil
if width ~= "full" then
if width ~= "full" then
width = tonumber(args["width"]) or 350
width = tonumber(args["width"]) or 300
end
end
local height = tonumber(args["height"]) or width
local height = tonumber(args["height"]) or width
Linje 280: Linje 603:
return ""
return ""
end
end
addBbox(entity)
local zoom = args["zoom"] or 8
local zoom = args["zoom"] or 8
local lat = args["latitude"] or args["lat"]
local lat = args["latitude"] or args["lat"]
local lon = args["longitude"] or args["lon"]
local lon = args["longitude"] or args["lon"]
local includeProperty = args["include property"] or nil
local includeProperty = args["vis egenskap"] or args["include property"] or nil
local wdlat,wdlon = wdCoords(entity)
local wdlat,wdlon,coordcat = wdCoords(entity)
if not lat or not lon then
if not lat or not lon then
lat = wdlat
lat = wdlat
lon = wdlon
lon = wdlon
end
end
local centerLat = lat
local centerLon = lon
if not lon or not lat then
if not lon or not lat then
return ""
return "[[Kategori:Sider hvor kartmodul mangler koordinater]]"
end
end
local text = args["text"] or mw.wikibase.label(id) or ""
local text = args["text"] or mw.wikibase.label(id) or ""
Linje 308: Linje 635:
table.insert(geojson, point)
table.insert(geojson, point)
end
end
includeLocation(geojson,entity)
if includeProperty then
if includeProperty then
local props = mw.text.split( includeProperty, ',', true )
includeProp(geojson,entity,includeProperty)
for i,pid in ipairs(props) do
includeProp(geojson,entity,pid)
end
end
end
local frameargs = {
local frameargs = {
Linje 317: Linje 648:
['lang'] = lang
['lang'] = lang
}
}
if zoom then
if zoom and zoom == 'auto' then
centerLat = bbox.center.latitude
centerLon = bbox.center.longitude
local factor = width/300
zoom = bboxzoom(factor)
if visKoord == "debug" then
text = text .. " " .. dump(bbox) -- for debug
end
end
if zoom and zoom ~= 'auto' then
frameargs['zoom'] = zoom
frameargs['zoom'] = zoom
frameargs['latitude'] = lat
frameargs['latitude'] = centerLat
frameargs['longitude'] = lon
frameargs['longitude'] = centerLon
end
end

local linkargs = {
local linkargs = {
['height'] = height,
['height'] = height,
Linje 332: Linje 673:
['lang'] = lang
['lang'] = lang
}
}
if out == "geojson" then
return "<pre>" .. mw.text.jsonEncode(geojson, mw.text.JSON_PRETTY) .. "</pre>"
else
local mlink = ''
local mlink = ''
local klink = ''
local klink = ''
if text then
if text then
if infobox then
if infobox then
local koordmal = "[[Kategori:Sider 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)
-- 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'} }
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'
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/>'
.. makeLegend() .. text .. mlink .. klink
.. osmLink(entity) .. koordmal .. coordcat
end
end
frameargs['text'] = text .. mlink .. klink
frameargs['text'] = makeLegend() .. text .. mlink .. klink
end
end
return mw.getCurrentFrame():extensionTag('mapframe', mw.text.jsonEncode(geojson), frameargs)
return mw.getCurrentFrame():extensionTag('mapframe', mw.text.jsonEncode(geojson), frameargs)
end
-- return "<pre>" .. mw.text.jsonEncode(geojson, mw.text.JSON_PRETTY) .. "</pre>"
-- return "<pre>" .. mw.text.jsonEncode(geojson, mw.text.JSON_PRETTY) .. "</pre>"
end


local function maptest(args,infobox,visKoord)
local ids = getIds(args)
local id = ids[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 out = args["out"] or nil
local width = args["width"] or nil
if width ~= "full" then
width = tonumber(args["width"]) or 300
end
local height = tonumber(args["height"]) or width
if height == "full" then
return ""
end
for idx,ident in ipairs(ids) do
local entity = mw.wikibase.getEntity(ident) or nil
addBbox(entity)
end
local zoom = args["zoom"] or 8
local zoomadd = args["zoomadd"] or 0
local lat = args["latitude"] or args["lat"]
local lon = args["longitude"] or args["lon"]
local includeProperty = args["vis egenskap"] or args["include property"] or nil
local wdlat,wdlon,coordcat = wdCoords(entity)
if not lat or not lon then
lat = wdlat
lon = wdlon
end
local centerLat = lat
local centerLon = lon
if #ids<2 and (not lon or not lat) then
return "[[Kategori:Sider 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
for idx,ident in ipairs(ids) do
local entity = mw.wikibase.getEntity(ident) or nil
local symbol = nil
if numLegend < 99 then
symbol = "1"
end
visEntity(geojson,ident,stroke,opacity,"geoshape",symbol)
--showEntity(geojson,ident,entity,stroke,title,opacity)
end

if args['marker'] and lat and lon then
local point = mappoint(lat,lon)
table.insert(geojson, point)
end
includeLocation(geojson,entity)
if includeProperty then
local props = mw.text.split( includeProperty, ',', true )
for i,pid in ipairs(props) do
includeProp(geojson,entity,pid)
end
end
local frameargs = {
['height'] = height,
['width'] = width,
['align'] = align,
['lang'] = lang
}
if zoom and zoom == 'auto' then
centerLat = bbox.center.latitude
centerLon = bbox.center.longitude
local factor = width/300
zoom = tostring(tonumber(bboxzoom(factor))+tonumber(zoomadd))
if visKoord == "debug" then
text = text .. " " .. dump(bbox) -- for debug
end
end
if zoom and zoom ~= 'auto' then
frameargs['zoom'] = zoom
frameargs['latitude'] = centerLat
frameargs['longitude'] = centerLon
end
local linkargs = {
['height'] = height,
['width'] = width,
['align'] = align,
['latitude'] = lat,
['longitude'] = lon,
['zoom'] = zoom or 8,
['lang'] = lang
}
if out == "geojson" then
return "<pre>" .. mw.text.jsonEncode(geojson, mw.text.JSON_PRETTY) .. "</pre>"
else
local mlink = ''
local klink = ''
if text then
if infobox then
local koordmal = "[[Kategori:Sider 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/>'
.. makeLegend() .. text .. mlink .. klink
.. osmLink(entity) .. koordmal .. coordcat
end
frameargs['text'] = text .. "<br />(test)<br />" ..makeLegend() .. mlink .. klink
end
return mw.getCurrentFrame():extensionTag('mapframe', mw.text.jsonEncode(geojson), frameargs)
end
end
end


Linje 352: Linje 843:
local args = lonlat(mw.getCurrentFrame():getParent().args)
local args = lonlat(mw.getCurrentFrame():getParent().args)
local argframe = mw.getCurrentFrame().args
local argframe = mw.getCurrentFrame().args
local vis = argframe["vis"] or ""
local vis = args["vis"] or argframe["vis"] or ""
if vis == "nei" then
if vis == "nei" then
return ""
return ""
end
end
args["width"] = args["width"] or argframe["width"] or 250
args["width"] = args["width"] or argframe["width"] or 300
args["zoom"] = tonumber(args["zoom"]) or tonumber(argframe["zoom"]) or 8
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
if not args["vis egenskap"] then
args["vis egenskap"] = argframe["vis egenskap"] or nil
end
args[1] = ""
args[1] = ""
args["align"] = "center"
args["align"] = "center"
if argframe["karttest"] == "ja" then
local maptxt = map2(args,1)
return maptest(args)
end

local maptxt = map2(args,1,vis)
if not maptxt or maptxt =="" then
if not maptxt or maptxt =="" then
return mapNoWikidata(args,1)
return mapNoWikidata(args,1)
end
end
return maptxt
return maptxt
end

function mapkilde(args)
local pageWikitext = mw.title.getCurrentTitle():getContent()
local kartid = args["kartid"] or ""

local regtxt = "{{[Kk]artlenke|[^}]+}}"
local txt = kartid

for kartmal in mw.ustring.gmatch(pageWikitext, regtxt ) do
local aa = {}
local xxx = mw.text.split(kartmal, '|', true )
for j,pkval in ipairs(xxx) do
local pk = mw.text.split(pkval, '=', true )
aa[pk[1]] = pk[2]
end
if aa["kartid"] and mw.ustring.find(aa["kartid"], kartid ) then

txt = txt .. "<br/>" .. kartmal
end
end
local argmap = {}
argmap["zoom"] = "auto"
argmap["id"] = txt
return maptest(argmap)
-- return nil

--return txt
end

local regtxtid = "Q%d+"
local regtxtpoint = "Point%(.*%)"
local regtxtlink = "https://no.wikipedia.org/wiki/.*>" -- <https://no.wikipedia.org/wiki/Vikeholmen_fyr>
local regtxtimg = "commons:.*"

local function gsparqlid(txt)
for ident in mw.ustring.gmatch(txt, regtxtid ) do
return ident
end
return nil
end

local function gsparqltxt(txt,regtxt,lstart,lend)
if not txt then return nil end
for ix, txt1 in ipairs(txt ) do
for txt2 in mw.ustring.gmatch(txt1, regtxt ) do
local len = mw.ustring.len( txt2 )
return mw.ustring.sub( txt2, lstart, len-lend )
--return mw.text.split(p, '[ ,]', false )
end
end
return nil
end

local function gsparqlpos(txt)
local p = gsparqltxt(txt,regtxtpoint,7,1)
if P then
return mw.text.split(p, '[ ,]', false )
end
return nil
end

local function gsparqlimg(txt)
return gsparqltxt(txt,regtxtimg,9,0)
end

local function gsparqlpos2(txt)
if not txt then return nil end
for ix, txt1 in ipairs(txt ) do
for postxt in mw.ustring.gmatch(txt1, regtxtpoint ) do
local len = mw.ustring.len( postxt )
local p = mw.ustring.sub( postxt, 7, len-1 )
return mw.text.split(p, '[ ,]', false )
end
end
return nil
end

local function gsparqllink(txt)
if not txt then return nil end
for postxt in mw.ustring.gmatch(txt, regtxtlink ) do
local len = mw.ustring.len( postxt )
return mw.ustring.sub( postxt, 31, len-1 )
--return mw.text.split(p, '[ ,]', false )
end
return nil
end

local log = ""

function gsparqlLine(geojson,line,ix)
local g = {}
local g2 = {}
local xxx = mw.text.split(line, ' ', true )
local id = gsparqlid(xxx[1])
local pos = gsparqlpos2(xxx)
local link = gsparqllink(line)
local img = gsparqlimg(xxx) or ""
if id and pos then
g["ix"] = ix
g["xxx"] = xxx
g["id"] = id
g["name"] = xxx[2]
local title = xxx[2]
--title = gsparqllink(line)
--local link = nil -- mw.wikibase.label(id)
if title and link then
title = "[[" .. link .. "|" .. title .. "]]"
end
g["pos"] = pos
local description = nil
if xxx[3] and (img and img ~= "") then
local lang = mw.language.getContentLanguage()
description = lang:ucfirst( xxx[3]) .. "[[File:" .. img .. "]]"
end
local artikkel = nil
local stroke = "#880000"
local opacity = 0.1
local symbol = "1"
log = g
--local marker = mappoint(tonumber(pos[1]),tonumber(pos[2]),title,bilde,symbol)
showEnt(geojson,id,tonumber(pos[2]),tonumber(pos[1]),artikkel,description,stroke,title,opacity,true,"geoshape",symbol)
--table.insert(geojson,marker)
end
return geojson
end
function gsparqlLines(geojson,sparql)
local lines = mw.text.split(sparql, '\n', true )
for ix,line in ipairs(lines) do
geojson = gsparqlLine(geojson,line,ix)
end
return geojson
end

function mapsparql(args)
local sparql =
--"wd:Q12316978 Vikeholmen fyr Point(5.27605 59.1408) commons:Vikaholmen, Karmøy - S-1602U1 114.jpg <https://no.wikipedia.org/wiki/Vikeholmen_fyr>"--
args["id"] or "wd:Q281492 Birtevatn Point(7.94993 59.04772)"

local geojson = {}
geojson = gsparqlLines(geojson,sparql)
if true then
frameargs = {}
frameargs["width"] = "600"
frameargs["height"] = "600"
frameargs['text'] = makeLegend() --.. text --.. mlink .. klink
return mw.getCurrentFrame():extensionTag('mapframe', mw.text.jsonEncode(geojson), frameargs) --.. '<br/>'
-- .. makeLegend() -- .. text .. mlink .. klink
-- .. osmLink(entity) .. koordmal .. coordcat
end
return "<pre>" .. mw.text.jsonEncode(geojson, mw.text.JSON_PRETTY) .. "</pre>"
.. "<br />" .. "<pre>" .. mw.text.jsonEncode(log, mw.text.JSON_PRETTY) .. "</pre>"
.. "<br />" .. makeLegend()
end


local function gjsonpos(txt)
local len = mw.ustring.len(txt)
local p = mw.ustring.sub( txt, 7, len-1 )
return mw.text.split(p, '[ ,]', false )
end

function gsparqlJson(geojson,line,ix)
local point = line["loc"]
if false then
geojson[ix] = point
return geojson
end
local pos = gjsonpos(point)
local qid = gsparqlid(line["item"])
local artikkel = nil
local description = line["itemDescription"]
local stroke = "#880000"
local opacity = 0.1
local symbol = "1"
local title = line["itemLabel"]
showEnt(geojson,qid,tonumber(pos[2]),tonumber(pos[1]),artikkel,description,stroke,title,opacity,true,"geoshape",symbol)

return geojson
end

function mapjson2(json)
local geojson = {}
for ix,line in ipairs(json) do
geojson = gsparqlJson(geojson,line,ix)
end
if true then
frameargs = {}
frameargs["width"] = "600"
frameargs["height"] = "600"
frameargs['text'] = makeLegend() --.. text --.. mlink .. klink
return mw.getCurrentFrame():extensionTag('mapframe', mw.text.jsonEncode(geojson), frameargs) --.. '<br/>'
-- .. makeLegend() -- .. text .. mlink .. klink
-- .. osmLink(entity) .. koordmal .. coordcat
end
end

function jsonfilter(json,type,val)
local json2 = {}
for ix,line in ipairs(json) do
if line[type] and ( gsparqlid(line[type]) == gsparqlid(val) ) then
table.insert(json2, line)
end
end

return json2
end

function mapjson(args)
local a = args["json"]
local b = mw.text.jsonDecode(a)
local c = {"Q2245","Q2272"}
local maps = ""
for ix,cc in ipairs(c) do
local d = jsonfilter(b,"adm",cc)
maps = maps .. mapjson2(d)
legend = {}
numLegend = 0
end
return maps
-- local c = mw.text.decode(a,true)
-- return dump(geojson)
end
end


function p.map(frame)
function p.map(frame)
-- return "<pre>" .. mw.text.jsonEncode(frame:getParent().args, mw.text.JSON_PRETTY) .. "</pre>"
-- return "<pre>" .. mw.text.jsonEncode(frame:getParent().args, mw.text.JSON_PRETTY) .. "</pre>"
return map2(mw.getCurrentFrame():getParent().args)
local args = mw.getCurrentFrame():getParent().args
if args["karttest"] == "ja" then
return maptest(args)
end
if args["test"] == "ja" then
return maptest(args)
end
if args["test"] == "test" then
return mapsparql(args)
end
if args["test"] == "kilde" then
return mapkilde(args)
end
if args["test"] == "json" then
return mapjson(args)
end

return map2(args)
end
end



Siste sideversjon per 5. jan. 2025 kl. 18: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 maxLegend = 5

local bbox = {}
bbox.min = {}
bbox.max = {}
bbox.center = {}
bbox.dist = {}
bbox.txt = {"Koordinater funnet"}

autozoom = {
	{ dist=2000,zoom=3}, 
	{ dist=700,zoom=4}, 
	{ dist=300,zoom=5}, 
	{ dist=150,zoom=6}, 
	{ dist=50,zoom=7}, 
	{ dist=30,zoom=8}, 
	{ dist=10,zoom=9}, 
	{ dist=6,zoom=10}, 
	{ dist=4,zoom=11}, 
}

local function hasLocalCoord()
	local pageWikitext = mw.title.getCurrentTitle():getContent()
	local treff = pageWikitext:match("{{[Kk]oord|[^}]+}}")
	if treff then
		local treffVis = treff:match("vis")
		local treffTittel = treff:match("tittel")
		local treffTekst = treff:match("tekst")
		if treff and treffVis and treffTittel then 
			return treff
		end
	end
	return nil
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 allOkSnaks(entity,datatype)
	local retur = {}
	if entity.claims then
		for propid,props in pairs(entity.claims) do
			for idx,claim in ipairs(props) do
				if claim.rank == 'preferred' or claim.rank == 'normal' then
					local snak = claim.mainsnak
					if snak.snaktype == "value" and snak.datatype == datatype then
						local sn = {}
						sn.snak = snak
						sn.qu = claim.qualifiers
						table.insert(retur,sn)
					end
				end
			end
		end
	end
	return retur
end

function dump(item)
	return "<pre>" .. mw.text.jsonEncode(item, mw.text.JSON_PRETTY) .. "</pre>"
end


local function addBbox(entity)
	for idx,sn in ipairs(allOkSnaks(entity,"globe-coordinate")) do
		local snak = sn.snak
		local val = snak.datavalue.value
		local qu = sn.qu
		local qutxt = ""
		if qu and qu.P518 then
			qutxt = " P518 " .. mw.wikibase.formatValues(qu.P518)
		end
		if not bbox.min.longitude or bbox.min.longitude > val.longitude then
			bbox.min.longitude = val.longitude
		end
		if not bbox.min.latitude or bbox.min.latitude > val.latitude then
			bbox.min.latitude = val.latitude
		end
		if not bbox.max.longitude or bbox.max.longitude < val.longitude then
			bbox.max.longitude = val.longitude
		end
		if not bbox.max.latitude or bbox.max.latitude < val.latitude then
			bbox.max.latitude = val.latitude
		end
		local txt = snak.property .. " " .. qutxt .. " " .. val.longitude .. " " .. val.latitude
		table.insert(bbox.txt,txt)
	end
	if (bbox.min.longitude) then
		bbox.center.longitude = (bbox.min.longitude + bbox.max.longitude)/2
		bbox.center.latitude = (bbox.min.latitude + bbox.max.latitude)/2
		bbox.dist.longitude = (bbox.max.longitude - bbox.min.longitude)
		bbox.dist.latitude = (bbox.max.latitude - bbox.min.latitude)
		bbox.haversine = HaversineDistance(
			bbox.max.latitude,bbox.max.longitude,
			bbox.min.latitude,bbox.min.longitude)
    end
	return 

end
local function bboxlist(ids)
	for ix,id in ipairs(ids) do
		local entity = mw.wikibase.getEntity(id)
		addBbox(entity)
	end
end

-- From en:Module:Sandbox/Hellknowz/CoordDistance
function HaversineDistance(lat1,lon1,lat2,lon2)

    local radius = 6371 -- km

    local dlat = math.rad(lat2-lat1)
    local dlon = math.rad(lon2-lon1)
    local a = math.sin(dlat/2) * math.sin(dlat/2) + math.cos(math.rad(lat1)) * math.cos(math.rad(lat2)) * math.sin(dlon/2) * math.sin(dlon/2)
    local c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
    return radius * c

end

-- the distances need to be adjusted according to the size of the frame of the map
local function bboxzoom(factor)
	for ix,v in ipairs(autozoom) do
		if bbox.haversine  and v.dist*factor < bbox.haversine then
			return v.zoom
		end
	end
	return 12
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:Sider 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 prop = {}
			local shape = {
	       	["type"] = "ExternalData",
			["service"] = "page",
			["title"] =  value,
			["properties"] = prop
		}
		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 and title then
		numLegend = numLegend + 1
		prop["marker-symbol"] = tostring(numLegend)
		table.insert(legend,title)
    end
    prop["marker-size"] = "small"
    point["properties"] = prop
    point["geometry"] = geo
    return point
end

local function geoline(id,stroke,title)
	local line = {
		["type"] = "ExternalData",
		["service"] = "geoline",
		["ids"] =  id,
        ['properties'] = {
        	["stroke"] = stroke,
        	["stroke-width"] = 2,
        	["marker-size"] = "small",
        	--["marker-symbol"] = "-letter",
        	["title"] = title
        }
     }
     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 showEnt(geojson,id,wdlat,wdlon,artikkel,description,stroke,title,opacity,createLink,method,symbol)
	local text = title
	if createLink and text and link then
		text = "[[" .. artikkel .. "|" .. title .. "]]"
	end
	local shape = nil
	if method == "geoshape" then
		shape = geoshape(id,stroke,opacity)
		table.insert(geojson, shape)
		local line = geoline(id,stroke,title)
		table.insert(geojson, line)
		if wdlat and wdlon then
    		local point = mappoint(wdlat,wdlon,text,description,symbol)
			table.insert(geojson, point)
		end
	elseif method == "geomask" then
		shape = geomask(id,stroke,opacity)
		table.insert(geojson, shape)
	end
	return geojson
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)
	if createLink and text and link then
		text = "[[" .. link .. "|" .. text .. "]]"
	end
	local meth = method or "geoshape"
	local bilde = nil
	if entity.claims and entity.claims["P18"] then
		local claim = selectSingleClaim(entity.claims["P18"])
		if claim then
			local snak = claim.mainsnak
			if snak.snaktype == "value" then
   				bilde = snak.datavalue.value or nil
   			end
		end
	end
	local description = nil
	if createLink and bilde then
		description = "[[File:" .. bilde .. "]]"
	end
	geojson = showEnt(geojson,id,wdlat,wdlon,link,description,stroke,text,opacity,createLink,meth,symbol)

	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
			local symbol = nil
			if usesymbol and numLegend < 99 then
				symbol = "1"
			end
			visEntity(geojson,id,stroke,opacity,method,symbol)
			count = count+1
			
		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)
	if #qids>1 then
		bboxlist(qids)
	end
	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  .. idx .. " = " .. leg .. "<br/>"
	end
	if numLegend>maxLegend then
    	text = string.format([[
				<div class="mw-collapsible mw-collapsed">
					<div class="sentrert">%s nummererte markører</div>
					<div class="mw-collapsible-content">%s</div>
				</div>
			]], numLegend, text)
	end
	if numLegend > 0 then
		text = text .. "[[Kategori:Sider 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 300
	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 getIds(args)
	local ids= {}
	local id = args['id'] or args[1] or nil	
	if id == "" then
		id = nil
	end
	if id ~= "" then
		local ida = {}
		for ident in mw.ustring.gmatch(id, 'Q%d+' )  do
			local entity = mw.wikibase.getEntity(ident) or nil
			local id1 = entity.id
			local lab = mw.wikibase.label( id1 )
			if lab then
				ida[lab] = id1
			end
			table.insert(ids,id1)
		end
		for lab,id2 in pairs(ida) do
			--table.insert(ids,id2)
		end
		--ids = mw.text.split( id, ',', true )
		if #ids ~= 1 then
			id = nil
		end
	end
	--local entity = mw.wikibase.getEntity(id) or nil
	--if not id then
	--	if not entity then
	--		return ""
	--	end
	--	id = entity.id
	--	table.insert(ids, id)
	--end
	return ids
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 out = args["out"] or nil
	local width = args["width"] or nil
	if width ~= "full" then
		width = tonumber(args["width"]) or 300
	end
	local height  = tonumber(args["height"]) or width
	if height == "full" then
		return ""
	end
	addBbox(entity)
	
	local zoom = args["zoom"] or 8
	local lat = args["latitude"] or args["lat"]
	local lon = args["longitude"] or args["lon"]
	local includeProperty = args["vis egenskap"]  or args["include property"] or nil
	local wdlat,wdlon,coordcat = wdCoords(entity)
	if not lat or not lon then
		lat = wdlat
		lon = wdlon
	end
	local centerLat = lat
	local centerLon = lon
    if not lon or not lat then
    	return "[[Kategori:Sider 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
		local props = mw.text.split( includeProperty, ',', true )
		for i,pid in ipairs(props) do
			includeProp(geojson,entity,pid)
		end
	end
	local frameargs = {
    		['height'] = height,
    		['width'] = width,
    		['align'] = align,
    		['lang'] = lang
    	}
	if zoom and zoom == 'auto' then
  	
    	centerLat = bbox.center.latitude
    	centerLon = bbox.center.longitude
    	local factor = width/300
    	zoom = bboxzoom(factor)
    	if visKoord == "debug" then
    		text = text .. " " .. dump(bbox)   -- for debug
    	end
	end
    if zoom and zoom ~= 'auto' then
   	
    	frameargs['zoom'] = zoom
    	frameargs['latitude'] = centerLat
    	frameargs['longitude'] = centerLon
    end
	local linkargs = {
    		['height'] = height,
    		['width'] = width,
    		['align'] = align,
    		['latitude'] = lat,
    		['longitude'] = lon,
    		['zoom'] = zoom or 8,
    		['lang'] = lang
    	}
    if out == "geojson" then
    	return "<pre>" .. mw.text.jsonEncode(geojson, mw.text.JSON_PRETTY) .. "</pre>"
    else
    	local mlink = ''
        local klink = ''
     	if text then
    		if infobox then
    			local koordmal = "[[Kategori:Sider 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/>'
    			.. makeLegend() .. text .. mlink .. klink
    			.. osmLink(entity) .. koordmal .. coordcat
    		end
    		frameargs['text'] = makeLegend() .. text .. mlink .. klink
    	end
	return  mw.getCurrentFrame():extensionTag('mapframe', mw.text.jsonEncode(geojson), frameargs)
	end
--    return "<pre>" .. mw.text.jsonEncode(geojson, mw.text.JSON_PRETTY) .. "</pre>" 
end


local function maptest(args,infobox,visKoord)
	local ids = getIds(args)
	local id = ids[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 out = args["out"] or nil
	local width = args["width"] or nil
	if width ~= "full" then
		width = tonumber(args["width"]) or 300
	end
	local height  = tonumber(args["height"]) or width
	if height == "full" then
		return ""
	end
	
	for idx,ident in ipairs(ids) do
		local entity = mw.wikibase.getEntity(ident) or nil
		addBbox(entity)
	end
	local zoom = args["zoom"] or 8
	local zoomadd = args["zoomadd"] or 0
	local lat = args["latitude"] or args["lat"]
	local lon = args["longitude"] or args["lon"]
	local includeProperty = args["vis egenskap"]  or args["include property"] or nil
	local wdlat,wdlon,coordcat = wdCoords(entity)
	if not lat or not lon then
		lat = wdlat
		lon = wdlon
	end
	local centerLat = lat
	local centerLon = lon
    if #ids<2 and (not lon or not lat) then
    	return "[[Kategori:Sider 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
	for idx,ident in ipairs(ids) do
		local entity = mw.wikibase.getEntity(ident) or nil
		local symbol = nil
		if numLegend < 99 then
				symbol = "1"
			end
		visEntity(geojson,ident,stroke,opacity,"geoshape",symbol)
		--showEntity(geojson,ident,entity,stroke,title,opacity)
	end

	
	if args['marker'] and lat and lon then
    	local point = mappoint(lat,lon)
		table.insert(geojson, point)
	end
	includeLocation(geojson,entity)
	if includeProperty then
		local props = mw.text.split( includeProperty, ',', true )
		for i,pid in ipairs(props) do
			includeProp(geojson,entity,pid)
		end
	end
	local frameargs = {
    		['height'] = height,
    		['width'] = width,
    		['align'] = align,
    		['lang'] = lang
    	}
	if zoom and zoom == 'auto' then
  	
    	centerLat = bbox.center.latitude
    	centerLon = bbox.center.longitude
    	local factor = width/300
    	zoom = tostring(tonumber(bboxzoom(factor))+tonumber(zoomadd))
    	if visKoord == "debug" then
    		text = text .. " " .. dump(bbox)   -- for debug
    	end
	end
    if zoom and zoom ~= 'auto' then
   	
    	frameargs['zoom'] = zoom
    	frameargs['latitude'] = centerLat
    	frameargs['longitude'] = centerLon
    end
	local linkargs = {
    		['height'] = height,
    		['width'] = width,
    		['align'] = align,
    		['latitude'] = lat,
    		['longitude'] = lon,
    		['zoom'] = zoom or 8,
    		['lang'] = lang
    	}
    if out == "geojson" then
    	return "<pre>" .. mw.text.jsonEncode(geojson, mw.text.JSON_PRETTY) .. "</pre>"
    else
    	local mlink = ''
        local klink = ''
     	if text then
    		if infobox then
    			local koordmal = "[[Kategori:Sider 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/>'
    			.. makeLegend() .. text .. mlink .. klink
    			.. osmLink(entity) .. koordmal .. coordcat
    		end
    		frameargs['text'] = text ..  "<br />(test)<br />" ..makeLegend() ..  mlink .. klink
    	end
		return  mw.getCurrentFrame():extensionTag('mapframe', mw.text.jsonEncode(geojson), frameargs)
	end
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 300
    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
	if not args["vis egenskap"] then
		args["vis egenskap"] = argframe["vis egenskap"] or nil
	end
    args[1] = ""
    args["align"] = "center"
    if argframe["karttest"] == "ja" then
		return maptest(args)
	end

	local maptxt = map2(args,1,vis)
	if not maptxt or maptxt =="" then
		return mapNoWikidata(args,1)
	end
	return maptxt
end

function mapkilde(args)
	local pageWikitext = mw.title.getCurrentTitle():getContent()
	local kartid = args["kartid"] or ""

	local regtxt = "{{[Kk]artlenke|[^}]+}}"
	local txt = kartid

	for kartmal in mw.ustring.gmatch(pageWikitext, regtxt )  do
		local aa = {}
		local xxx = mw.text.split(kartmal, '|', true )
		for j,pkval in ipairs(xxx) do
			local pk = mw.text.split(pkval, '=', true )
		
			aa[pk[1]] = pk[2]
		end
		if aa["kartid"] and mw.ustring.find(aa["kartid"], kartid ) then

		txt = txt .. "<br/>" .. kartmal
		end
	end
	local argmap = {}
	argmap["zoom"] = "auto"
	argmap["id"] = txt
	return maptest(argmap)
--	return nil

	--return txt
end

local regtxtid = "Q%d+"
local regtxtpoint = "Point%(.*%)"
local regtxtlink = "https://no.wikipedia.org/wiki/.*>" -- <https://no.wikipedia.org/wiki/Vikeholmen_fyr>
local regtxtimg = "commons:.*"

local function gsparqlid(txt)
	for ident in mw.ustring.gmatch(txt, regtxtid )  do
		return ident
	end
	return nil
end

local function gsparqltxt(txt,regtxt,lstart,lend)
	if not txt then return nil end
	for ix, txt1 in ipairs(txt )  do
		for txt2 in mw.ustring.gmatch(txt1, regtxt )  do
			local len = mw.ustring.len( txt2 )
			return mw.ustring.sub( txt2, lstart, len-lend )
			--return mw.text.split(p, '[ ,]', false )
		end
	end
	return nil
end

local function gsparqlpos(txt)
	local p = gsparqltxt(txt,regtxtpoint,7,1)
	if P then
		return mw.text.split(p, '[ ,]', false )
	end
	return nil
end

local function gsparqlimg(txt)
	return gsparqltxt(txt,regtxtimg,9,0)
end

local function gsparqlpos2(txt)
	if not txt then return nil end
	for ix, txt1 in ipairs(txt )  do
		for postxt in mw.ustring.gmatch(txt1, regtxtpoint )  do
			local len = mw.ustring.len( postxt )
			local p = mw.ustring.sub( postxt, 7, len-1 )
			return mw.text.split(p, '[ ,]', false )
		end
	end
	return nil
end

local function gsparqllink(txt)
	if not txt then return nil end
	for postxt in mw.ustring.gmatch(txt, regtxtlink )  do
		local len = mw.ustring.len( postxt )
		return mw.ustring.sub( postxt, 31, len-1 )
		--return mw.text.split(p, '[ ,]', false )
	end
	return nil
end

local log = ""

function gsparqlLine(geojson,line,ix)
	local g = {}
	local g2 = {}
	local xxx = mw.text.split(line, '	', true )
	local id = gsparqlid(xxx[1])
	local pos = gsparqlpos2(xxx)
	local link = gsparqllink(line)
	local img = gsparqlimg(xxx) or ""
	if id and pos then
		g["ix"] = ix
		
		g["xxx"] = xxx
		g["id"] = id
		g["name"] = xxx[2]
		local title = xxx[2]
		--title = gsparqllink(line)
		--local link = nil -- mw.wikibase.label(id)
		if title and link then
			title = "[[" .. link .. "|" .. title .. "]]"
		end
		g["pos"] = pos
		local description = nil
		if xxx[3] and (img and img ~= "") then
			local lang = mw.language.getContentLanguage()
			description = lang:ucfirst( xxx[3]) .. "[[File:" .. img .. "]]"
		end
		local artikkel = nil
		local stroke = "#880000"
		local opacity = 0.1
		local symbol = "1"
		log = g
		--local marker = mappoint(tonumber(pos[1]),tonumber(pos[2]),title,bilde,symbol)
		showEnt(geojson,id,tonumber(pos[2]),tonumber(pos[1]),artikkel,description,stroke,title,opacity,true,"geoshape",symbol)
		--table.insert(geojson,marker)
	end
	return geojson
end
function gsparqlLines(geojson,sparql)
	local lines = mw.text.split(sparql, '\n', true )
	for ix,line in ipairs(lines) do
		geojson = gsparqlLine(geojson,line,ix)
	end
	return geojson
end

function mapsparql(args)
	local sparql = 
	--"wd:Q12316978	Vikeholmen fyr	Point(5.27605 59.1408)	commons:Vikaholmen, Karmøy - S-1602U1 114.jpg	<https://no.wikipedia.org/wiki/Vikeholmen_fyr>"--
	args["id"] or "wd:Q281492	Birtevatn	Point(7.94993 59.04772)"

	local geojson = {}
	geojson = gsparqlLines(geojson,sparql)
	if true then
		frameargs = {}
		frameargs["width"] = "600"
		frameargs["height"] = "600"
		frameargs['text'] = makeLegend() --.. text --.. mlink .. klink
	    			return  mw.getCurrentFrame():extensionTag('mapframe', mw.text.jsonEncode(geojson), frameargs) --.. '<br/>'
    		--	.. makeLegend()  -- .. text .. mlink .. klink
    		--	.. osmLink(entity) .. koordmal .. coordcat
	end
	return "<pre>" .. mw.text.jsonEncode(geojson, mw.text.JSON_PRETTY) .. "</pre>"
	.. "<br />" .. "<pre>" .. mw.text.jsonEncode(log, mw.text.JSON_PRETTY) .. "</pre>"
	.. "<br />" .. makeLegend()
end


local function gjsonpos(txt)
	local len = mw.ustring.len(txt)
	local p =  mw.ustring.sub( txt, 7, len-1 )
	return mw.text.split(p, '[ ,]', false )
end

function gsparqlJson(geojson,line,ix)
	local point = line["loc"]
	if false then
		geojson[ix] = point
		return geojson
	end
	local pos = gjsonpos(point)
	local qid = gsparqlid(line["item"])
	local artikkel = nil
	local description = line["itemDescription"]
	local stroke = "#880000"
	local opacity = 0.1
	local symbol = "1"
	local title = line["itemLabel"]
	showEnt(geojson,qid,tonumber(pos[2]),tonumber(pos[1]),artikkel,description,stroke,title,opacity,true,"geoshape",symbol)

	return geojson
end

function mapjson2(json)
	local geojson = {}
	for ix,line in ipairs(json) do
		geojson = gsparqlJson(geojson,line,ix)
	end
	if true then
		frameargs = {}
		frameargs["width"] = "600"
		frameargs["height"] = "600"
		frameargs['text'] = makeLegend() --.. text --.. mlink .. klink
	    			return  mw.getCurrentFrame():extensionTag('mapframe', mw.text.jsonEncode(geojson), frameargs) --.. '<br/>'
    		--	.. makeLegend()  -- .. text .. mlink .. klink
    		--	.. osmLink(entity) .. koordmal .. coordcat
	end
end

function jsonfilter(json,type,val)
	local json2 = {}
	for ix,line in ipairs(json) do
		if line[type] and ( gsparqlid(line[type]) == gsparqlid(val) ) then
			
			table.insert(json2, line)
		end
	end

	return json2
end

function mapjson(args)
	local a = args["json"]
	local b = mw.text.jsonDecode(a)
	local c = {"Q2245","Q2272"}
	local maps = ""
	for ix,cc in ipairs(c) do
		local d = jsonfilter(b,"adm",cc)
		maps = maps .. mapjson2(d)
		legend = {}
		numLegend = 0
	end
	return maps
--	local c = mw.text.decode(a,true)
--	return dump(geojson)
end

function p.map(frame)
--	return "<pre>" .. mw.text.jsonEncode(frame:getParent().args, mw.text.JSON_PRETTY) .. "</pre>"
	local args = mw.getCurrentFrame():getParent().args
	if args["karttest"] == "ja" then
		return maptest(args)
	end
	if args["test"] == "ja" then
		return maptest(args)
	end
	if args["test"] == "test" then
		return mapsparql(args)
	end
	if args["test"] == "kilde" then
		return mapkilde(args)
	end
	if args["test"] == "json" then
		return mapjson(args)
	end

	return map2(args)
end

return p