function h=m_names(file,varargin) % M_NAMES puts names of places on m_maps (toolbox M_NAMEBOX) % When a M_MAP of any projection or scale has been made, M_NAMES puts % names from the m_name-database in their right place. % % h = m_names(file) % % file = optional string of filename (w/path) to a special map-name % database-file (default is the main base) % varargin = Text property/value pairs. Give if uniform property for all % names is wanted, regardless of the name's property-values % set in database. The adjustable properties are % FontName, FontWeight, FontAngle and Color. % % h = handles to all name text-objects available. % % The names might not be placed perfectly, but M_NAMES initiates M_MOVETEXT, % with which you can choose any name with a mouseclick on it, move and % change it with the key-controls of M_MOVETEXT. M_NAMES also makes a % listbox where you can choose names from all available names in the area, % including the invisible ones (those too small for M_NAMES' size-limit). % More names can easily be added with M_NEWNAME('name'), or with keypress % 'n' (see M_MOVETEXT), and names can be saved to the default database or a % separate base just for a particular map. % % CUSTOMIZATION: % The path and name of the main m_name-database (M_NAMEBASE), should be % edited in this file (M_NAMES.M). Below the help section there is a % customization section you can edit. There is also a minimum font-size for % the names to show on map, that might have to be set right for your system. % % PROVIDED BASES: % cities606.mat : 606 cities worldwide. The names will be placed in % the middle of the cities' positions, so a change of % horizontal- or vertical alignment might be a good % idea. In addition the original pinpoint-positions are % stored in the third column of the names' UserData, in % case You want some marks on the map. % m_name_political.mat: A base of country and capitol names. NOT TESTED! % % See also M_MOVETEXT M_NEWNAME M_SAVENAME M_MAP M_NAMEBOX M_NAME_DEMO % ECURVE (for drawing and saving of lines and arrows on map, % like ocean currents, travel routes, etc.) %Time-stamp: %File: global MAP_VAR_LIST MAP_VAR_LIST.name.handles_all=[]; % handles on all names in the area MAP_VAR_LIST.name.handles=[]; % handles on visible names MAP_VAR_LIST.name.boxhandle=[]; % handle on the listbox of all names %%%% CUSTOMIZATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% MAP_VAR_LIST.name.base='~/matlab/m_namebox/m_namebase'; % main mapname base limit=5; % fontsize lower limit %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% error(nargchk(0,9,nargin)); % check inputs if exist('MAP_VAR_LIST'), limits=[MAP_VAR_LIST.longs MAP_VAR_LIST.lats]; else error('You must create an M_MAP (M_PROJ) first!'); end if nargin<1 | isempty(file), file=MAP_VAR_LIST.name.base; else MAP_VAR_LIST.name.base=file; end wrong=0; whatodo='Continue'; % Check for database. if exist([file,'.mat'])==2 % If databasefile exists eval([ 'load ',file]); % load it. if ~exist('m_name') % If no 'm_name' inside, ERROR, wrong=[ 'Missing m_name-data in ',upper(file),'.MAT. ']; else for i=1:length(m_name) % else lon(i,:)=m_name(i).UserData(1,1:2); % assign to lat(i,:)=m_name(i).UserData(2,1:2); % temporary variables end end else wrong=[ 'No such file: ',upper(file),'.MAT. ']; end if wrong, error([wrong,'Use M_SAVENAME to create new database!']); end % Turn off the interfering 'clickability' of patches on map set(findobj(get(gca,'children'),'type','patch'),'HitTest','off'); %ho=findobj(get(gca,'children'),'tag','m_gshhs_c'); % choose only names inside or near the limits-area find(limits(1)<=lon(:,2) & lon(:,1)<=limits(2) & limits(3)<=lat(:,2) & lat(:,1)<=limits(4)); m_name=m_name(ans); % to speed up plotting and later moving of objects set(gcf,'RendererMode','manual','Renderer','painters',... 'PaperPositionMode','auto'); % to get the text printed right % loop through ALL NAMES and PLACE them for i=1:length(m_name) this_name=m_name(i); % Assign temporary structural name=cellstr(this_name.String(:)'); % Get String (the name) UData=getfield(this_name,'UserData'); % Get UserData (positions) if size(UData)~=[2 2] | ~isreal(UData) ... % CHECK THE DATA (robust) | (~ischar(name)&~iscell(name)) | isempty(char(name)) fprintf(1,'Irregularity found in database-name number %d !\n',i); break; % Skip to next if wrong. end [x,y]=m_ll2xy(UData(1,1:2),UData(2,1:2)); % Convert to x/y-koordinates if diff(x) < 0 % Prevent names being x=fliplr(x);y=fliplr(y); % plotted upside down end % (diff(x) always positive) rot=atan2(diff(y),diff(x))*180/pi; % Find rotation MAP_VAR_LIST.name.handles_all(i)=... % Plot text in figure text(x(1)+diff(x)/2,y(1)+diff(y)/2, ... name, ... 'Rotation',rot, ... 'HorizontalAlignment','center', ... 'VerticalAlignment','middle', ... 'Visible','off', ... 'Tag','m_name', ... 'UserData',UData, ... 'FontName',getfield(this_name,'FontName'), ... 'FontWeight',getfield(this_name,'FontWeight'), ... 'FontAngle',getfield(this_name,'FontAngle'), ... 'Color',getfield(this_name,'Color')); % Set the fontsize right and decide leng=sqrt(diff(x)^2+diff(y)^2); % which names to be visible setfontsize(MAP_VAR_LIST.name.handles_all(i),leng,limit); % MAP_VAR_LIST.name.handles=[MAP_VAR_LIST.name.handles ans]; end % Check for and set strmatch('fontname',lower(varargin)); % UNIFORM PROPERTIES if any(ans),set(MAP_VAR_LIST.name.handles_all,'FontName',varargin{ans+1});end strmatch('fontweight',lower(varargin)); if any(ans),set(MAP_VAR_LIST.name.handles_all,'FontWeight',varargin{ans+1});end strmatch('fontangle',lower(varargin)); if any(ans),set(MAP_VAR_LIST.name.handles_all,'FontAngle',varargin{ans+1});end strmatch('color',lower(varargin)); if any(ans),set(MAP_VAR_LIST.name.handles_all,'Color',varargin{ans+1});end h=MAP_VAR_LIST.name.handles_all; % assign outargument handles if ~isempty(h) % LISTBOX-UICONTROL created for MAP_VAR_LIST.name.boxhandle = ... % choosing between all name objects uicontrol('Style','listbox', ... 'String',getnamelist(h), ... 'Position',[0 0 200 100], ... 'BackgroundColor',[1 1 1],... 'Tag','m_listbox',... 'Callback','m_movetext;', ... 'buttonDownFcn','m_movetext;', ... 'TooltipString', ... 'All the names available in your area (incl. hidden)'); % % 'buttonDownFcn','set(MAP_VAR_LIST.name.boxhandle,''enable'',''on'')',... % % uicontrol('Style','popup', ... % 'String',getnamelist(h), ... % 'Position',[0 0 200 20], ... % 'Tag','m_listbox',... % 'Callback','m_movetext;', ... % 'TooltipString', ... % 'All the names available in your area (incl. hidden)'); if isempty(MAP_VAR_LIST.name.handles) % If no visible names, fobj=MAP_VAR_LIST.name.handles_all(1);% choose first invisible name, else % or else fobj=MAP_VAR_LIST.name.handles(1); % choose visible name, end % to set as current object: set(gcf,'CurrentObject',fobj,'KeypressFcn',''); end figure(gcf); m_movetext; % Start M_MOVETEXT % to display it's helpdialog % ------------------------------------------------------------ function h_visible=setfontsize(h,len,limit) % squeezes name between points fsize=3; tlen=0; h_visible=[]; while tlen < len% & fsize < 19 % choose fontsize fsize=fsize+1; set(h,'Fontsize',fsize); rot=get(h,'rotation'); % find rotation set(h,'rotation',0); % rotate into horizontal get(h,'Extent');tlen=ans(3); % find textlength set(h,'rotation',rot); % rotate back in place end if fsize >= limit % if large enough, make visible set(h,'Visible','on'); % (set minimum size here) h_visible=h; end % ------------------------------------------------------------ function list=getnamelist(h) % GETNAMELIST makes string from object's cellstring-array 'String' for i = 1:length(h) lis=''; str=cellstr(get(h(i),'String')); for j=1:length(str) lis=strcat(lis,str(j),{ ' '}); end list(i,1)=cellstr(char(lis)); % strip away trailing spaces end