Home > utilities > read_kml.m

read_kml

PURPOSE ^

READ_KML reads a Google Earth kml file into Matlab

SYNOPSIS ^

function [lat,lon,z] = read_kml(fileName)

DESCRIPTION ^

READ_KML reads a Google Earth kml file into Matlab
 Reads in lat,lon,z from a simple path file.

  All the data in the data file must EITHER be on one line, for example:
   -73.6513,40.4551,0 -73.3905,40.5214,0 -73.0589,40.5956,0
 OR each point must be on its own line, for example:
   -73.237171, 40.627311, 0.0 
   -73.242945, 40.626360, 0.0 

  I have tried to make this code as robust as possible, but it may still
  crash if there is a space in the wrong place in the data file.

 Example:
   [lat,lon,z] = read_kml('test.kml');

 where test.kml looks like:
 <?xml version="1.0" encoding="UTF-8"?>
 <kml xmlns="http://earth.google.com/kml/2.1">
 <Placemark>
     <name>test_length</name>
     <description>junk</description>
     <LineString>
         <tessellate>1</tessellate>
         <coordinates>
 -73.65138440596144,40.45517368645169,0 -73.39056199144957,40.52146569128411,0 -73.05890757388369,40.59561213913959,0 -72.80519929505505,40.66961872411046,0 -72.61180114704385,40.72997510603909,0 -72.43718187249095,40.77509309196679,0 </coordinates>
     </LineString>
 </Placemark>
 </kml>
 afarris@usgs.gov 2006 November

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [lat,lon,z] = read_kml(fileName)
0002 %READ_KML reads a Google Earth kml file into Matlab
0003 % Reads in lat,lon,z from a simple path file.
0004 %
0005 %  All the data in the data file must EITHER be on one line, for example:
0006 %   -73.6513,40.4551,0 -73.3905,40.5214,0 -73.0589,40.5956,0
0007 % OR each point must be on its own line, for example:
0008 %   -73.237171, 40.627311, 0.0
0009 %   -73.242945, 40.626360, 0.0
0010 %
0011 %  I have tried to make this code as robust as possible, but it may still
0012 %  crash if there is a space in the wrong place in the data file.
0013 %
0014 % Example:
0015 %   [lat,lon,z] = read_kml('test.kml');
0016 %
0017 % where test.kml looks like:
0018 % <?xml version="1.0" encoding="UTF-8"?>
0019 % <kml xmlns="http://earth.google.com/kml/2.1">
0020 % <Placemark>
0021 %     <name>test_length</name>
0022 %     <description>junk</description>
0023 %     <LineString>
0024 %         <tessellate>1</tessellate>
0025 %         <coordinates>
0026 % -73.65138440596144,40.45517368645169,0 -73.39056199144957,40.52146569128411,0 -73.05890757388369,40.59561213913959,0 -72.80519929505505,40.66961872411046,0 -72.61180114704385,40.72997510603909,0 -72.43718187249095,40.77509309196679,0 </coordinates>
0027 %     </LineString>
0028 % </Placemark>
0029 % </kml>
0030 % afarris@usgs.gov 2006 November
0031 
0032 %% open the data file and find the beginning of the data
0033 fid=fopen(fileName);
0034 if fid < 0
0035     error('could not find file')
0036 end
0037 done=0;
0038 while done == 0
0039     junk = fgetl(fid);
0040     f=findstr(junk,'<coordinates>');
0041     if isempty(f) == 0
0042         done = 1;
0043     end
0044 end
0045 ar = 1;
0046 % junk either ends with the word '<coordinates>' OR
0047 % some data follows the word '<coordinates>'
0048 if (f + 13) >= length(junk)  
0049     % no data on this line
0050     % done2 is set to zero so the next loop will read the data
0051     done2 = 0;
0052 else
0053     % there is some data in this line following '<coordinates>'
0054     clear f2
0055     f2=findstr(junk,'</coordinates>');
0056     if isempty(f2) == 0
0057         %all data is on this line
0058         alldata{ar} = junk(f+13:f2-1);
0059         % done2 is set to one because the next loop does not need to run
0060         done2 = 1;
0061     else
0062         % only some data is on this line
0063         alldata{ar} = junk(f+13:end);
0064         ar = ar + 1;
0065         % done2 is set to zero so the next loop will read the rest of the data
0066         done2 = 0;
0067     end
0068 end
0069 
0070 %% Read in the data
0071 while done2 == 0
0072     % read in line from data file
0073     junk = fgetl(fid);
0074     f=findstr(junk,'</coordinates>');
0075     if isempty(f) == 1 
0076         % no ending signal, just add this data to the rest
0077         alldata{ar} = junk;
0078         ar = ar + 1;
0079     else
0080         % ending signal is present
0081         if f < 20
0082             % </coordinates> is in the begining of the line, ergo no data
0083             % on this line; just end the loop
0084             done2 = 1;
0085         else 
0086             % the ending signal (</coordinates>) is present: remove it,
0087             % add data to the rest and signal the end of the loop
0088             f2 = strfind(junk,'</coordinates>');
0089             alldata{ar} = junk(1:f2-1);
0090             ar = ar + 1;
0091             done2 = 1;
0092         end
0093     end
0094 end
0095 
0096 %% get the data into neat vectors
0097 % either all the data is on one line, or each point is on its own line
0098 f = strfind(alldata{1}(:)',',');
0099 if length(f) > 2
0100     % more than one coordinate on each line, this is hard b/c there is no
0101     % comma between points (just commans between lon and lat, and between
0102     % lat and z)  ie;  -70.0000,42.0000,0 -70.1000,40.10000,0 -70.2,....
0103     %
0104     %  I have to divide the string into Latitude, Longitude and Z values
0105     % using the locations of both commas and spaces.
0106     %
0107     % turn alldata into regular vector so it is easier to work with
0108     data = cell2mat(alldata);
0109     % now find all commas
0110     fComma = strfind(data, ',');
0111     % find all spaces
0112     fSpace = strfind(data,' ');
0113     a=1;
0114     fC = 1;
0115     % have to do first point seperately b/c line may not begin with a space
0116     lon(a) = str2num(data(1:fComma(fC)-1));
0117     lat(a) = str2num(data(fComma(fC)+1:fComma(fC+1)-1));
0118     z(a) = str2num(data(fComma(fC+1)+1:fSpace(1)-1));
0119     a=a+1;
0120     fS=1;
0121     % go thru all the points in the line
0122     for fC = 3: 2: length(fComma)
0123         lon(a) = str2num(data(fSpace(fS)+1:fComma(fC)-1));
0124         lat(a) = str2num(data(fComma(fC)+1:fComma(fC+1)-1));
0125         if fS  < length(fSpace)
0126             z(a) = str2num(data(fComma(fC+1)+1:fSpace(fS+1)-1 ));
0127         else
0128             % have to handle last point seperatly b/c line may not end with
0129             % a space
0130             z(a) = str2num(data(fComma(fC+1)+1:end ));
0131         end
0132         a=a+1;
0133         fS=fS+1;
0134     end
0135  else
0136     %each point is on its own line
0137     for i = 1 : size(alldata,2)
0138         fComma = strfind(alldata{i}(:)',',');
0139         lon(i) = str2num(alldata{i}(1:fComma(1)-1));
0140         lat(i) = str2num(alldata{i}(fComma(1)+1:fComma(2)-1));
0141         z(i) = str2num(alldata{i}(fComma(2)*1:end));
0142     end
0143  end
0144 
0145 fclose(fid);
0146 [a,b]=size(lat);
0147 lat=reshape(lat,max(a,b),min(a,b));
0148 lon=reshape(lon,max(a,b),min(a,b));
0149 z=reshape(z,max(a,b),min(a,b));

Generated on Wed 20-Feb-2019 16:06:01 by m2html © 2005