Přeskočit na obsah

Modul:Distance

Z Wikicest

Dokumentaci tohoto modulu lze vytvořit na stránce Modul:Distance/Dokumentace

local p = {}

local R = 6371

local function deg2rad(deg) return deg * math.pi / 180 end

local function distance(lat1, lon1, lat2, lon2)
    local dlat = deg2rad(lat2 - lat1)
    local dlon = deg2rad(lon2 - lon1)
    lat1 = deg2rad(lat1)
    lat2 = deg2rad(lat2)
    local a = math.sin(dlat/2)^2 + math.cos(lat1)*math.cos(lat2)*math.sin(dlon/2)^2
    local c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
    return R * c
end

local function bearing(lat1, lon1, lat2, lon2)
    lat1 = deg2rad(lat1)
    lat2 = deg2rad(lat2)
    local dlon = deg2rad(lon2 - lon1)
    local y = math.sin(dlon) * math.cos(lat2)
    local x = math.cos(lat1)*math.sin(lat2) - math.sin(lat1)*math.cos(lat2)*math.cos(dlon)
    local brng = math.atan2(y, x)
    return (brng * 180 / math.pi + 360) % 360
end

local function direction(brng)
    local dirs = {
        "severně","severovýchodně","východně","jihovýchodně",
        "jižně","jihozápadně","západně","severozápadně"
    }
    local idx = math.floor((brng + 22.5) / 45) % 8 + 1
    return dirs[idx]
end

local function getCoords(qid)
    local snak = mw.wikibase.getBestStatements(qid, 'P625')[1]
    if snak and snak.mainsnak and snak.mainsnak.datavalue then
        local val = snak.mainsnak.datavalue.value
        return val.latitude, val.longitude
    end
    return nil, nil
end

function p.distance(frame)
    -- QID current article
    local qid1 = mw.wikibase.getEntityIdForCurrentPage()
    if not qid1 then return "Článek není napojen na Wikidata" end

    -- Parameter: name of destination
    local title = frame.args[1]
    if not title then return "Chybí cíl" end

    local qid2 = mw.wikibase.getEntityIdForTitle(title) -- try title as article
    if not qid2 then
    	if mw.wikibase.getEntity(title) then
    		qid2 = title -- title is QID
    	else
    		return "Neplatný cíl"
    	end
    end

    local lat1, lon1 = getCoords(qid1)
    local lat2, lon2 = getCoords(qid2)
    if not lat1 or not lat2 then return "Souřadnice nejsou dostupné" end

    -- check parameter reverse
    local reverse = frame.args.reverse
    if reverse and (reverse == "1" or reverse == "yes" or reverse == "true") then
        lat1, lon1, lat2, lon2 = lat2, lon2, lat1, lon1
    end
    
    local dist = math.floor(distance(lat1, lon1, lat2, lon2) + 0.5)
    local dir = direction(bearing(lat1, lon1, lat2, lon2))

    return dist .. " km " .. dir
end

return p