Modul:Sandkasse/Haros/kart
Hopp til navigering
Hopp til søk
Dokumentasjon for denne modulen kan opprettes på Modul:Sandkasse/Haros/kart/dok
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 = {"dette er en test"} 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 function enkartlenke(treff) local treff1 = mw.text.split( treff, "}", true ) args = mw.text.split( treff1[1], "|", true ) return args end function kartlenker(geojson) local pageWikitext = mw.title.getCurrentTitle():getContent() for treff in pageWikitext:gmatch("{{kartlenke|[^}]+}}") do geojson = enkartlenke(geojson,treff) end return geojson 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 txt = propid .. " " .. idx .. " " .. claim.rank .. " " -- .. snak.snaktype -- table.insert(retur,txt) 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 -- 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 local function addBbox(entity) local retur = bbox.txt 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 .. " " .. entity.id .. " " .. mw.wikibase.label(entity.id) .. " ".. 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 --bbox.txt = retur return --bbox 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 local function bboxzoom() for ix,v in ipairs(autozoom) do if bbox.haversine and v.dist < 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,letter) 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 showEntity(geojson,id,entity,stroke,title,opacity,createLink,method,symbol,letter) 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"]) if claim then local image = claim.mainsnak.datavalue.value or nil if image then description = "[[File:" .. image .. "]]" end end end end local shape = nil if meth == "geoshape" then shape = geoshape(id,stroke,opacity) table.insert(geojson, shape) if wdlat and wdlon then local point = mappoint(wdlat,wdlon,text,description,symbol,letter) table.insert(geojson, point) end elseif meth == "geomask" then shape = geomask(id,stroke,opacity) table.insert(geojson, shape) elseif meth == "geoxxx" 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,letter) table.insert(geojson, point) end 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,letter) 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,letter) 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 then if useymbol == "1" and numLegend < 100 then symbol = "1" end if not usesymbol =="1" then symbol = usesymbol end 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) bboxlist(qids) 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,symbol) 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 local useprop = "1" if symbol then useprop = symbol end visClaims(geojson,claims,stroke,opacity,"geoshape",useprop) 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 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 p131 = args['p131'] local entity = mw.wikibase.getEntity(id) or mw.wikibase.getEntity(p131) or nil if not id and not p131 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["vis egenskap"] or args["include property"] or nil local includeElement = args["vis element"] or args["include element"] 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 mw.wikibase.label(p131) or "" local align = args["align"] or 'right' local lang = selectMapLanguage(entity) local json = args["json"] or nil local geojson = {} local stroke = "#ff0000" local title = nil local opacity = 0.1 --if includeProperty then --end if id then showEntity(geojson,id,entity,stroke,title,opacity) end if p131 then local stroke = "#888888" local opacity = 0.1 local shape = geomask(p131,stroke,opacity) table.insert(geojson, shape) end if args['marker'] and lat and lon then local point = mappoint(lat,lon) table.insert(geojson, point) end includeLocation(geojson,entity) opacity = 0.0 if includeElement then local els = mw.text.split( includeElement, ',', true ) for i,id in ipairs(els) do visEntity(geojson,mw.text.trim(id),stroke,opacity,"geoshape",1) end end if includeProperty then local props = mw.text.split( includeProperty, ',', true ) for i,pid in ipairs(props) do includeProp(geojson,entity,mw.text.trim(pid)) end 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: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 if json then return "<pre>" .. mw.text.jsonEncode(args, mw.text.JSON_PRETTY) .. "</pre>" .. "<pre>" .. mw.text.jsonEncode(geojson, mw.text.JSON_PRETTY) .. "</pre>" 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 if not args["vis egenskap"] then args["vis egenskap"] = argframe["vis egenskap"] or nil 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 function p.printEntity(frame) local id = "Q1538332" --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 function p.test(frame) local id = "Q1314643" --frame.args[1] local entity = mw.wikibase.getEntity(id) addBbox(entity) local txt = bbox local geojson = {} includeLocation(geojson,entity) --enkartlenke("{{kartlenke|qid=123|bokstav=A}}") --if txt then return "<pre>" .. mw.text.jsonEncode(bbox, mw.text.JSON_PRETTY) .. "</pre>" --end end return p