matlab,python写kml文件
O、matlab与google_earth相关的一些工具
1. google earth toolbox
大量好用的工具函数
https://ww2.mathworks.cn/matlabcentral/fileexchange/12954-google-earth-toolbox
2. kml2struct
读取kml文件,将kml内容以struct的形式,在matlab里展现:
https://ww2.mathworks.cn/matlabcentral/fileexchange/35642-kml2struct
一、matlab自带函数 写kml文件
0.准备知识
(1)kmlwrite( ) 函数
(2)geoshape( )函数
(3)kmlwriteline()函数
(4)kmlwritepolygon()函数
(5)kmlwritepoint()函数
(6)shapewrite()函数
matlab 写.shp文件
1.写点文件
(1)情景:如下所示,给出若干个点的经纬度坐标,调用相关函数,设置kml文件格式:
(2)geoshape默认是 线 (line):
LAT=[52.17101310,52.08006661,51.77114935,51.86161181];
LON=[126.55621819,127.06011254,126.91212965,126.41155862];
filename = 'D:\test_001_point.kml';
shape = geoshape(LAT,LON);
shape.Geometry = 'point';
kmlwrite(filename,shape,'Color','red');
结果展示:
2.写线文件
(1)绿线的轨迹走向和所给的点的经纬度顺序相对应
% 写线文件
LAT=[52.17101310,52.08006661,51.77114935,51.86161181];
LON=[126.55621819,127.06011254,126.91212965,126.41155862];
filename = 'D:\test_001_line.kml';
shape = geoshape(LAT,LON);
shape.Geometry = 'line'; % 可不要,因为geoshape默认属性为线
kmlwrite(filename,shape,'Color','green','width',2);
3.写多边形文件
(1)写多边形文件,给出点的经纬度要形成一个闭环,即第一个点和最后一个点是同一个点
(2)写多边形文件,顺时针给出点的经纬度,表示的是多边形的内部;逆时针给出点的经纬度,表示的是多边形的外部!
% 写多边形文件
LAT=[52.17101310,52.08006661,51.77114935,51.86161181,52.17101310];
LON=[126.55621819,127.06011254,126.91212965,126.41155862,126.55621819];
filename = 'D:\test_001_polygon.kml';
shape = geoshape(LAT,LON);
shape.Geometry = 'polygon';
kmlwrite(filename,shape,'Color','yellow','width',2,'AltitudeMode', 'clampToGround','Name', 'Rectangle');
%'AltitudeMode', 'clampToGround' 忽略高度值,将特征设置在地面上。这是不指定高度值时的默认解释。
%'Name', 'Rectangle' 设置多边形的名称
%一个多个polygon的kml文件生成
cp_polygon_name={};
for i=1:size(candidate_lat_1,1)
polygon_candidate(i) = geoshape([candidate_lat_1(i),candidate_lat_2(i),candidate_lat_3(i),candidate_lat_4(i),candidate_lat_1(i)], [candidate_lon_1(i),candidate_lon_2(i),candidate_lon_3(i),candidate_lon_4(i),candidate_lon_1(i)]);
cp_polygon_name(i)=cellstr(['cp_',num2str(i)]);
end
filename='H:\cp_library\zy3_test_area2\GLAD30\GLAD30_cp_polygon.kml'
kmlwrite(filename,polygon_candidate,'Color','yellow','width',2,'AltitudeMode', 'clampToGround','Name', cp_polygon_name);
二、直接写kml文件
1.阅读了解kml文件
(1)最详细的学习博客:包括点,点描述,叠层,线,多边形
https://blog.csdn.net/alzhuzhu/article/details/52163572
(2)另外一个博客
https://blog.csdn.net/onlymydreams_mfc/article/details/81840232
2.实践写kml文件
(1)实践类博客
http://blog.sina.com.cn/s/blog_6b1c80b30102xtqa.html
python写kml文件
见: https://blog.csdn.net/weixin_43955546/article/details/123486605
3. matlab读取kml文件(点文件)
函数来源:https://ww2.mathworks.cn/matlabcentral/fileexchange/13026-read_kml
function [x,y,z] = read_kml(fileName)
% READ_KML Reads in (x,y,z) from a GoogleEarth kml file.
%
% I have tried to make this code as robust as possible, but it may crash
% or give unexpected resutls if the file is not formatted exactly as
% expected.
%
% Example:
% [x,y,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 2016March09, now can read mulitple sets of coordinates
% afarris@usgs.gov 2006November
%% open the data file and find the beginning of the data
fid=fopen(fileName);
if fid < 0
error('could not find file')
end
% This loop reads the data file one line at a time. If if finds the word
% <coordinates>, it knows there is data until it reads the word
% </coordinates>. After loading this data, it keeps reading the file,
% looking for another instance of <coordinates> until it finds the word
% </kml> which signals that the end of the file has been reached.
% Some files have all the data on one line, others have newline charecters
% in various points in the file. I hope this code that works in all cases.
done=0;
endoffile = 0;
ar = 1;
while endoffile == 0
while done == 0
junk = fgetl(fid);
f = strfind(junk,'<coordinates>');
ff = strfind(junk,'</kml>');
if ~isempty(f)
done = 1;
elseif ~isempty(ff)
endoffile = 1;
done = 1;
end
end
if endoffile
break
end
% 'junk' either ends with the word '<coordinates>' OR
% some data follows the word '<coordinates>'
if (f + 13) >= length(junk)
% no data on this line
% done2 is set to zero so the next loop will read the data
done2 = 0;
else
% there is some data in this line following '<coordinates>'
clear f2
f2 = strfind(junk,'</coordinates>');
if ~isempty(f2)
%all data is on this line
% there may be multiple sets of data on this one line
% I read them all
for i = 1 : size(f2,2)
alldata{ar} = junk(f(i)+13:f2(i)-1);
% I add in whitespace b/c sometimes it is missing
alldata{ar+1} = ' ';
ar = ar+2;
end
% done2 is set to one because the next loop does not need to run
done2 = 1;
else
% only some data is on this line
alldata{ar} = junk(f+13:end);
% I add in whitespace b/c sometimes it is missing
alldata{ar+1} = ' ';
ar = ar+2;
% done2 is set to zero so the next loop will read the rest of the data
done2 = 0;
end
% check to see if at end of the file
ff = strfind(junk,'</kml>');
if ~isempty(ff)
% no more data
endoffile = 1;
break
else
% need to keep looking for more data
done = 0;
end
end
% If not all the data was on the line with the word <coordiate>,
% read in the data
while done2 == 0
% read in line from data file
junk = fgetl(fid);
f = strfind(junk,'</coordinates>');
if isempty(f) == 1
% no ending signal, just add this data to the rest
alldata{ar} = junk;
ar = ar + 1;
else
% ending signal is present
done = 0;
if f < 20
% </coordinates> is in the begining of the line, ergo no data
% on this line; just end the loop
done2 = 1;
else
% the ending signal (</coordinates>) is present: remove it,
% add data to the rest and signal the end of the loop
f2 = strfind(junk,'</coordinates>');
alldata{ar} = junk(1:f2-1);
ar = ar + 1;
done2 = 1;
disp('done with line')
end
end
% check to see if at end of the file
ff = strfind(junk,'</kml>');
if ~isempty(ff)
% no more data
endoffile = 1;
break
else
% need to keep looking for more data
done = 0;
end
end
end
fclose(fid);
%% get the data into neat vectors
% I have to divide the string into X, Y and Z values.
%
% This is hard b/c there is no comma between points
% (just commans between x and y, and between
% y and z) ie; -70.0000,42.0000,0 -70.1000,40.10000,0 -70.2,....
%
% I used to do this by finding commas and spaces, now I use
% 'strsplit'! Thank you Matlab!
% 'alldata' is one huge cell
% turn alldata into regular vector so it is easier to work with
data = cell2mat(alldata);
% data is one huge string, split it so there is seperate element for each number
C = strsplit(data,{',',' '});
% sometimes first and/or last element in C is empty, this causes problems
len = size(C,2);
if isempty(C{1}) && isempty(C{end})
D = C(2:len-1);
elseif isempty(C{1}) && ~isempty(C{end})
D = C(2:end);
elseif isempty(C{end}) && ~isempty(C{1})
D = C(1:len-1);
end
% There has GOT to be a better way to split C into 3 variables!
a = 1;
for i = 1 : 3: length(D)-2
x(a,1) = str2double(D{i});
a=a+1;
end
a=1;
for i = 2 : 3: length(D)-1
y(a,1) = str2double(D{i});
a=a+1;
end
a=1;
for i = 3 : 3: length(D)
z(a,1) = str2double(D{i});
a=a+1;
end