Thursday, August 6, 2026

Matlab: An example Map script

% Created by LI Xu
% Version 1.0
% August 6, 2026


% If you have any question about this code,
% please do not hesitate to contact me via E-mail: 
% jeremy456@163.com

% Blog:
% http://blog.sciencenet.cn/u/lixujeremy
% http://lixuworld.blogspot.com/


clear;
clc;
close all;

timebegin=tic;
cur_data=date;
cur_time=fix(clock);
str1=sprintf('%s %.2d:%.2d:%.2d', cur_data, cur_time(4), cur_time(5), cur_time(6)); 
fprintf('Time Begin: ');
fprintf(str1);
fprintf('\n');



% Define the Google Street Map tile URL
% name = 'google_streets';
name='streets';
% url = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/${z}/${y}/${x}';
% url = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/${z}/${y}/${x}';
% url = 'https://mt1.google.com/vt/lyrs=m&x=${x}&y=${y}&z=${z}&style=p.v:off|s.t:3|s.e:l|p.v:on';
% 
% url = 'https://mt1.google.com/vt/lyrs=m&x=${x}&y=${y}&z=${z}&style=p.v:off|s.t:3|s.e:l|p.v:on';
% url = 'https://mt1.google.com/vt/lyrs=m&x=${x}&y=${y}&z=${z}';
% url = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Physical_Map/MapServer/tile/${z}/${y}/${x}';
% attribution = 'Map data ©2026 Google';
% url = 'https://cartodb-basemaps-a.global.ssl.fastly.net/light_all/${z}/${x}/${y}.png';
% url = 'https://cartodb-basemaps-a.global.ssl.fastly.net/dark_all/${z}/${x}/${y}.png';
% name = 'carto_voyager';
% attribution = '© OpenStreetMap contributors, © CARTO';
% url = 'https://cartodb-basemaps-a.global.ssl.fastly.net/rastertiles/voyager/${z}/${x}/${y}.png';
% 
% 
% % Add it to your MATLAB basemap list
% addCustomBasemap(name, url, 'Attribution', attribution);

% url = 'https://server.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/${z}/${y}/${x}';
% url = 'https://server.arcgisonline.com/ArcGIS/rest/services/Specialty/NatGeo_World_Map/MapServer/tile/${z}/${y}/${x}';
% url = 'https://cartodb-basemaps-a.global.ssl.fastly.net/rastertiles/voyager/${z}/${x}/${y}.png';
attribution = '© OpenStreetMap contributors, © CARTO';

url = 'https://mt1.google.com/vt/lyrs=s&x=${x}&y=${y}&z=${z}';
addCustomBasemap(name, url, 'Attribution', attribution);
% addCustomBasemap(name, url, 'Attribution', 'Sources: Esri, National Geographic, Garmin');
% url = 'https://stamen-tiles.a.ssl.fastly.net/toner/${z}/${x}/${y}.png';
% addCustomBasemap('stamen_toner', url, 'Attribution', 'Map tiles by Stamen Design, CC BY 3.0');

% Create geographic axes with OpenStreetMap basemap
figure;
gx = geoaxes('Basemap', name);
set(gcf, 'OuterPosition', get(0, 'ScreenSize'));
f = gcf;

% Define custom latitude/longitude range (Winnipeg-centered)
% latRange = [49.76, 50.01];
% lonRange = [-97.45, -96.9];
latRange = [49.79+0.005+0.009, 49.82-0.0068];
lonRange = [-97.15+0.008, -97.13+0.004];
% Calculate aspect ratio for exact limits without expansion
mean_lat = mean(latRange);
cos_factor = cosd(mean_lat);
ar = diff(latRange) / (diff(lonRange) * cos_factor);  % Required height/width for axes

% Set up resize function to maintain aspect and exact limits
gx.Units = 'pixels';
f.Units = 'pixels';
f.SizeChangedFcn = @(~, ~) myresizefcn(gx, f, ar, latRange, lonRange);
myresizefcn(gx, f, ar, latRange, lonRange);
% Rotate the whole map figure visually
view(gx, 2);
% rotate3d(f, 'on');
% % rotate3d(gx, 'on');
% gx.View = [30 90];


gx.Grid = 'off';
gx.TickDir = 'none';
gx.LatitudeLabel.String = '';
gx.LongitudeLabel.String = '';
gx.FontSize = 0.01;


% dat=cell2mat(dat);
% lats=dat(:, 1);
% lons=dat(:, 2);
% nums=dat(:, 3);
% hold on;
% for i = 1:length(lats)
%     % Draw Circle
%     plot(gx, lats(i), lons(i), 'bo', 'MarkerSize', 18, 'MarkerFaceColor', 'y');
%     % Draw Number
%     text(gx, lats(i), lons(i), num2str(nums(i)), ...
%         'HorizontalAlignment', 'center', 'VerticalAlignment', 'middle', 'Color', 'blue', 'FontWeight','bold', 'FontSize', 15);
% end

% 49.81155561273022, -97.13142673818446
plot(gx, 49.81155561273022, -97.13142673818446, 'pentagram', 'MarkerSize', 20, 'MarkerFaceColor', 'blue');


hold off;

gx.Grid = 'off';
gx.TickDir = 'none';
gx.LatitudeLabel.String = '';
gx.LongitudeLabel.String = '';
gx.FontSize = 0.01;

% dim = [0.1 0.83 0.8 0.1]; % Position at the top center
% str = 'Campus Water Fountain Map';
% 
% hAnn = annotation('textbox', dim, 'String', str, ...
%     'EdgeColor', 'none', ...         % No border
%     'HorizontalAlignment', 'center', ...
%     'VerticalAlignment', 'middle', ...
%     'FontSize', 25, ...
%     'FontWeight', 'bold', ...
%     'Color', 'white', ...
%     'Interpreter', 'none');

pause(3);
otname='kunakmap_vector';
export_fig(otname, '-png', '-painters', '-r300');
close all;



fprintf('Time Begin: ');
fprintf(str1);
fprintf('\n');
cur_data=date;
cur_time=fix(clock);
str2=sprintf('%s %.2d:%.2d:%.2d', cur_data, cur_time(4), cur_time(5), cur_time(6)); 
fprintf('Time End: ');
disp(str2);
timespan=toc(timebegin);
fprintf('Time Span: %.4f s\n', timespan);



disp('************************************************************');

function myresizefcn(gx, f, ar, latlim, lonlim)
    if (f.Position(4) / f.Position(3)) < ar
        % Figure is wide: constrain by height
        gx.Position(4) = f.Position(4) * 0.8;
        gx.Position(3) = gx.Position(4) / ar;
        % Center
        gx.Position(1) = (f.Position(3) - gx.Position(3)) / 2 + f.Position(1);
        gx.Position(2) = (f.Position(4) - gx.Position(4)) / 2 + f.Position(2);
    else
        % Figure is tall: constrain by width
        gx.Position(3) = f.Position(3) * 0.8;
        gx.Position(4) = gx.Position(3) * ar;
        % Center
        gx.Position(1) = (f.Position(3) - gx.Position(3)) / 2 + f.Position(1);
        gx.Position(2) = (f.Position(4) - gx.Position(4)) / 2 + f.Position(2);
    end
    % Re-apply limits to maintain exact range
    geolimits(gx, latlim, lonlim);
end