


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

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));