matlab,python 读 ,写kml文件(点,线,多边形)

13 篇文章 1 订阅


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


  • 2
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值