Interactive/zoomable Openstreetmap without mapping toolbox
Show older comments
Hi,
I created a function for a figure with an interactive high resolution Openstreetmap.
The problem is that the OSM is in grayscale and not original colored.
I think the problem is that the tiles are not loaded correctly. Maybe it is a wrong url or something like that.
Here is the function:
function interactiveWebmap(lat, lon, initialZoom)
% Initialize the figure and UI elements
fig = figure('Name', 'Interactive Webmap', 'NumberTitle', 'off', ...
'MenuBar', 'none', 'ToolBar', 'none', 'WindowButtonDownFcn', @mouseDownCallback, ...
'WindowScrollWheelFcn', @scrollWheelCallback, ...
'Position', [100, 100, 800, 600]); % Set a reasonable size for the figure
ax = axes('Parent', fig);
zoomLevel = initialZoom;
currentLat = lat;
currentLon = lon;
dragging = false;
startPos = [];
% Initial map load
updateMap(currentLat, currentLon, zoomLevel);
function scrollWheelCallback(~, event)
if event.VerticalScrollCount > 0
zoomOutCallback();
else
zoomInCallback();
end
end
function mouseDownCallback(~, ~)
% Set dragging to true and record the starting position
dragging = true;
startPos = get(fig, 'CurrentPoint');
% Set the WindowButtonMotionFcn and WindowButtonUpFcn callbacks
set(fig, 'WindowButtonMotionFcn', @mouseMoveCallback);
set(fig, 'WindowButtonUpFcn', @mouseUpCallback);
end
function mouseMoveCallback(~, ~)
% If dragging, update the map position
if dragging
currentPos = get(fig, 'CurrentPoint');
% Calculate movement delta in pixels
dx = (currentPos(1) - startPos(1)) * 0.01 / zoomLevel;
dy = (startPos(2) - currentPos(2)) * 0.01 / zoomLevel;
% Update latitude and longitude
currentLon = currentLon - dx;
currentLat = currentLat + dy;
% Update the map with new coordinates
updateMap(currentLat, currentLon, zoomLevel);
% Update start position
startPos = currentPos;
end
end
function mouseUpCallback(~, ~)
% Stop dragging
dragging = false;
set(fig, 'WindowButtonMotionFcn', '');
set(fig, 'WindowButtonUpFcn', '');
end
function zoomInCallback(~, ~)
if zoomLevel < 19
zoomLevel = zoomLevel + 1;
updateMap(currentLat, currentLon, zoomLevel);
end
end
function zoomOutCallback(~, ~)
if zoomLevel > 0
zoomLevel = zoomLevel - 1;
updateMap(currentLat, currentLon, zoomLevel);
end
end
function updateMap(lat, lon, zoom)
% Define the number of tiles to fetch for the current view
tilesPerSide = 3; % Fetch a 3x3 grid of tiles
[xtile, ytile] = latLonToTile(lat, lon, zoom);
% Preallocate the map image
mapImage = uint8(zeros(256 * tilesPerSide, 256 * tilesPerSide, 3));
% Fetch tiles and stitch them together
for x = 1:tilesPerSide
for y = 1:tilesPerSide
tileX = xtile + x - 2;
tileY = ytile + y - 2;
url = sprintf('https://tile.openstreetmap.org/%d/%d/%d.png', zoom, tileX, tileY);
try
% Fetch the tile image from the web
tileImage = imread(url);
% Ensure the tile is an RGB image
if size(tileImage, 3) == 1
tileImage = repmat(tileImage, [1, 1, 3]);
end
catch
warning('Failed to load tile: (%d, %d)', tileX, tileY);
% Use a white tile if failed to load
tileImage = 255 * ones(256, 256, 3, 'uint8');
end
% Compute the correct position for each tile in the final image
mapImage((y-1)*256+1:y*256, (x-1)*256+1:x*256, :) = tileImage;
end
end
% Display the map image
imshow(mapImage, 'Parent', ax);
title(ax, sprintf('OpenStreetMap\nLat: %.4f, Lon: %.4f, Zoom: %d', lat, lon, zoom));
end
function [xtile, ytile] = latLonToTile(lat, lon, zoom)
% Convert latitude and longitude to tile coordinates
n = 2^zoom;
xtile = floor((lon + 180) / 360 * n);
ytile = floor((1 - log(tan(deg2rad(lat)) + sec(deg2rad(lat))) / pi) / 2 * n);
end
function rad = deg2rad(deg)
% Convert degrees to radians
rad = deg * pi / 180;
end
function sec = sec(x)
% Compute the secant of x (1/cos(x))
sec = 1 ./ cos(x);
end
end
Example Berlin, Germany
interactiveWebmap(52.5200, 13.4050, 12);
Maybe you are able to help me.
Thank you.
Accepted Answer
More Answers (0)
Categories
Find more on Manage Products in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
