theres not a way of getting images through roblox http service so you would need to make a webserver like an api so it returns the decoded pixels there, but i’ve made one myself so if you want feel free to use it.
the way it works is with POST requests, You need to give it the Tile Coodinates, Zoom and Resolution.
My api will return an array of colors, heights and water pixels (The heights are already decoded).
local httpService = game:GetService("HttpService")
function deg2num(lon, lat, zoom)
local n = 2 ^ zoom
local lon_deg = tonumber(lon)
local lat_rad = math.rad(lat)
local xtile = math.floor(n * ((lon_deg + 180) / 360))
local ytile = math.floor(n * (1 - (math.log(math.tan(lat_rad) + (1 / math.cos(lat_rad))) / math.pi)) / 2)
return xtile, ytile
end
function num2deg(x, y, z)
local n = 2 ^ z
local lon_deg = x / n * 360.0 - 180.0
local lat_rad = math.atan(math.sinh(math.pi * (1 - 2 * y / n)))
local lat_deg = lat_rad * 180.0 / math.pi
return lon_deg, lat_deg
end
local url = "https://roearthserver01.pythonanywhere.com/Terrain/v2" -- My API Url
local latitude, longitude = 46.19842278192789, -122.19063690278452 -- The location you want to get the data of
local zoom = 12
local x, y = deg2num(longitude, latitude, zoom) -- Get X and Y Tiles
local resolution = 256 -- Resolution should be within a range of (2 - 256)
-- The PostAsync() method with my API needs to always have this order: (TileX, TileY, Zoom, Resolution)
local data = httpService:JSONDecode(
httpService:PostAsync(url, httpService:JSONEncode({x, y, zoom, resolution}))
)
local heights = data.heights
local colors = data.colors
-- Print the pixel (1, 1) and (256, 256) in the decoded heightmap image
-- The decoded heightmap image has a range of (1 - Resolution), In this case is (1 - 256), Remember its using 1 - indexing like lua
print(heights[`{1},{1}`])
print(heights[`{256},{256}`])
If you want to visualize it then heres a code for it, Just be careful with the resolution since it might lag a LOT your studio, And i also recommend doing it on a new studio place.
local httpService = game:GetService("HttpService")
function deg2num(lon, lat, zoom)
local n = 2 ^ zoom
local lon_deg = tonumber(lon)
local lat_rad = math.rad(lat)
local xtile = math.floor(n * ((lon_deg + 180) / 360))
local ytile = math.floor(n * (1 - (math.log(math.tan(lat_rad) + (1 / math.cos(lat_rad))) / math.pi)) / 2)
return xtile, ytile
end
function num2deg(x, y, z)
local n = 2 ^ z
local lon_deg = x / n * 360.0 - 180.0
local lat_rad = math.atan(math.sinh(math.pi * (1 - 2 * y / n)))
local lat_deg = lat_rad * 180.0 / math.pi
return lon_deg, lat_deg
end
local url = "https://roearthserver01.pythonanywhere.com/Terrain/v2" -- My API Url
local latitude, longitude = 46.19842278192789, -122.19063690278452 -- The location you want to get the data of
local zoom = 14
local x, y = deg2num(longitude, latitude, zoom) -- Get X and Y Tiles
local resolution = 64 -- Resolution should be within a range of (2 - 256)
-- The PostAsync() method with my API needs to always have this order: (TileX, TileY, Zoom, Resolution)
local data = httpService:JSONDecode(
httpService:PostAsync(url, httpService:JSONEncode({x, y, zoom, resolution}))
)
local heights = data.heights
local colors = data.colors
local metersPerPixel = (156543 / math.pow(2, zoom) * 256) / resolution -- the distance between each pixel in meters
local scale = 3.57 -- roblox units to meters
for y = 1, resolution - 1 do
for x = 1, resolution - 1 do
local point00 = Instance.new("Attachment")
point00.WorldPosition = Vector3.new(x * metersPerPixel, heights[`{x},{y}`], y * metersPerPixel) * scale
local point10 = Instance.new("Attachment")
point10.WorldPosition = Vector3.new((x + 1) * metersPerPixel, heights[`{x + 1},{y}`], y * metersPerPixel) * scale
local point01 = Instance.new("Attachment")
point01.WorldPosition = Vector3.new(x * metersPerPixel, heights[`{x},{y + 1}`], (y + 1) * metersPerPixel) * scale
local point11 = Instance.new("Attachment")
point11.WorldPosition = Vector3.new((x + 1) * metersPerPixel, heights[`{x + 1},{y + 1}`], (y + 1) * metersPerPixel) * scale
local rod0 = Instance.new("RodConstraint")
rod0.Attachment0 = point00
rod0.Attachment1 = point01
rod0.Thickness = scale * 10
rod0.Visible = true
rod0.Length = (rod0.Attachment1.WorldPosition - rod0.Attachment0.WorldPosition).Magnitude
local rod1 = Instance.new("RodConstraint")
rod1.Attachment0 = point00
rod1.Attachment1 = point01
rod1.Thickness = scale * 10
rod1.Visible = true
rod1.Length = (rod1.Attachment1.WorldPosition - rod1.Attachment0.WorldPosition).Magnitude
local rod2 = Instance.new("RodConstraint")
rod2.Attachment0 = point00
rod2.Attachment1 = point11
rod2.Thickness = scale * 10
rod2.Visible = true
rod2.Length = (rod2.Attachment1.WorldPosition - rod2.Attachment0.WorldPosition).Magnitude
local rod3 = Instance.new("RodConstraint")
rod3.Attachment0 = point01
rod3.Attachment1 = point11
rod3.Thickness = scale * 10
rod3.Visible = true
rod3.Length = (rod3.Attachment1.WorldPosition - rod3.Attachment0.WorldPosition).Magnitude
local rod4 = Instance.new("RodConstraint")
rod4.Attachment0 = point10
rod4.Attachment1 = point11
rod4.Thickness = scale * 10
rod4.Visible = true
rod4.Length = (rod4.Attachment1.WorldPosition - rod4.Attachment0.WorldPosition).Magnitude
rod4.Parent = workspace.Terrain
point00.Parent = workspace.Terrain
point10.Parent = workspace.Terrain
point01.Parent = workspace.Terrain
point11.Parent = workspace.Terrain
rod0.Parent = workspace.Terrain
rod1.Parent = workspace.Terrain
rod2.Parent = workspace.Terrain
rod3.Parent = workspace.Terrain
end
task.wait()
end
task.wait(30)
workspace.Terrain:ClearAllChildren()