Module:HLFan/Autostraßenabfrage

From OpenStreetMap Wiki
Jump to navigation Jump to search
[Create] Documentation
local p = {}
local bit32 = require("bit32")

local keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"

local function lzw_encode(data)
    local dict = {}
    local out = {}
    local currChar
    local phrase = data:sub(1, 1)
    local code = 256
    local i = 1
    while i <= #data do
        currChar = data:sub(i + 1, i + 1)
        if dict[phrase .. currChar] then
            phrase = phrase .. currChar
        else
            table.insert(out, #phrase > 1 and dict[phrase] or phrase:byte())
            dict[phrase .. currChar] = code
            code = code + 1
            phrase = currChar
        end
        i = i + 1
    end
    return out
end

local function utf8_encode(bytesArr)
    local utf = {}
    for i = 1, #bytesArr do
        local c = bytesArr[i]
        if c < 128 then
            table.insert(utf, c)
        elseif c < 2048 then
            table.insert(utf, bit32.bor(bit32.rshift(c, 6), 192))
            table.insert(utf, bit32.bor(bit32.band(c, 63), 128))
        else
            table.insert(utf, bit32.bor(bit32.rshift(c, 12), 224))
            table.insert(utf, bit32.bor(bit32.band(bit32.rshift(c, 6), 63), 128))
            table.insert(utf, bit32.bor(bit32.band(c, 63), 128))
        end
    end
    return utf
end

local function base64_encode(inputArr)
    local output = ""
    local i = 1
    while i <= #inputArr do
        local chr1 = inputArr[i] or 0
        local chr2 = inputArr[i + 1] or 0
        local chr3 = inputArr[i + 2] or 0

        local enc1 = bit32.rshift(chr1, 2)
        local enc2 = bit32.bor(bit32.lshift(bit32.band(chr1, 3), 4), bit32.rshift(chr2, 4))
        local enc3 = bit32.bor(bit32.lshift(bit32.band(chr2, 15), 2), bit32.rshift(chr3, 6))
        local enc4 = bit32.band(chr3, 63)

        if i + 1 > #inputArr then
            enc3, enc4 = 64, 64
        elseif i + 2 > #inputArr then
            enc4 = 64
        end

        output = output ..
                 keyStr:sub(enc1 + 1, enc1 + 1) ..
                 keyStr:sub(enc2 + 1, enc2 + 1) ..
                 keyStr:sub(enc3 + 1, enc3 + 1) ..
                 keyStr:sub(enc4 + 1, enc4 + 1)

        i = i + 3
    end
    return output
end

local function makeQuery(area, target)
    target = target or ''
    return 'way[highway~"motorway|trunk|primary"](' .. area .. ')' .. target .. ';'
end

local function getAreas(wikitext)
    local areas = {}
    for s in wikitext:gmatch('[%d.,;]+') do
    	if #s >= 20 then
    		table.insert(areas, makeQuery('around:100' .. s:gsub('([%d.]+),([%d.]+);?', ',%2,%1')))
        end
    end
    return areas
end

local function getQuery()
	local title = mw.title.new("Austria/Liste Autostraßen")
    local wikitext = title:getContent()
    local areas = getAreas(wikitext)
	
    local outFilter = [[
way.r[highway=trunk];
way.r[highway=trunk_link];
way.s[highway=motorway];
way.s[highway=motorway_link];
way.s[highway=primary];
way.s[highway=primary_link];
]]
    return [[
[out:json];
area(id:3600016239)->.a;
]] .. makeQuery('area.a', '->.g') .. '\n(\n' .. table.concat(areas, '\n') .. [[

)->.s;
(.g; - .s;)->.r;
(
]] .. outFilter .. ');\nout geom;'
end

function p.generateQuery(frame)
    return getQuery()
end

function p.generateUrl(frame)
    return 'https://overpass-turbo.eu?q=' .. base64_encode(utf8_encode(lzw_encode(getQuery())))
end

return p