【问题标题】:Determine distance from coastline in Matlab在 Matlab 中确定与海岸线的距离
【发布时间】:2010-08-26 14:34:48
【问题描述】:

在 MATLAB 中,我有一组表示美国位置的纬度和经度对。我需要确定到最近海岸线的距离。

我认为 MATLAB 有一个内置的美国纬度/经度点数据库。如何访问和使用它?

还有关于如何有效地确定距离的任何建议?

更新:后续问题:Determine center of bins when using meshm

【问题讨论】:

    标签: matlab distance latitude-longitude


    【解决方案1】:

    由于我无法访问 Mapping Toolbox,这对于解决这个问题来说是理想的,我想出了一个独立于任何工具箱的解决方案,包括 Image Processing Toolbox

    Steve Eddins 有一个image processing blog at The MathWorks,去年他在其中发表了一系列非常酷的帖子,专门讨论使用数字高程图。具体来说,他指出了从哪里获取它们以及如何加载和处理它们。以下是相关的博文:

    使用此 DEM 数据,您可以找出海洋边缘所在位置的纬度和经度,找出从内陆地图点到最近这些沿海点的距离,然后进行精美的可视化。我使用函数FILTER2通过与海洋掩码的卷积来帮助找到海洋的边缘,并使用计算方程great-circle distances来获得沿地球表面的地图点之间的距离。

    使用上述博客文章中的一些示例代码,我得出以下结论:

    %# Load the DEM data:
    
    data_size = [6000 10800 1];  %# The data has 1 band.
    precision = 'int16=>int16';  %# Read 16-bit signed integers into a int16 array.
    header_bytes = 0;
    interleave = 'bsq';          %# Band sequential. Not critical for 1 band.
    byte_order = 'ieee-le';
    E = multibandread('e10g',data_size,precision,...        %# Load tile E
                      header_bytes,interleave,byte_order);
    F = multibandread('f10g',data_size,precision,...        %# Load tile F
                      header_bytes,interleave,byte_order);
    dem = [E F];  %# The digital elevation map for tile E and F
    clear E F;    %# Clear E and F (they are huge!)
    
    %# Crop the DEM data and get the ranges of latitudes and longitudes:
    
    [r,c] = size(dem);      %# Size of DEM
    rIndex = [1 4000];      %# Row range of DEM to keep
    cIndex = [6000 14500];  %# Column range of DEM to keep
    dem = dem(rIndex(1):rIndex(2),cIndex(1):cIndex(2));  %# Crop the DEM
    latRange = (50/r).*(r-rIndex+0.5);     %# Range of pixel center latitudes
    longRange = (-180/c).*(c-cIndex+0.5);  %# Range of pixel center longitudes
    
    %# Find the edge points of the ocean:
    
    ocean_mask = dem == -500;        %# The ocean is labeled as -500 on the DEM
    kernel = [0 1 0; 1 1 1; 0 1 0];  %# Convolution kernel
    [latIndex,longIndex] = ...       %# Find indices of points on ocean edge
      find(filter2(kernel,~ocean_mask) & ocean_mask);
    coastLat = latRange(1)+diff(latRange).*...     %# Convert indices to
               (latIndex-1)./diff(rIndex);         %#   latitude values
    coastLong = longRange(1)+diff(longRange).*...  %# Convert indices to
                (longIndex-1)./diff(cIndex);       %#   longitude values
    
    %# Find the distance to the nearest coastline for a set of map points:
    
    lat = [39.1407 35 45];        %# Inland latitude points (in degrees)
    long = [-84.5012 -100 -110];  %# Inland longitude points (in degrees)
    nPoints = numel(lat);         %# Number of map points
    scale = pi/180;               %# Scale to convert degrees to radians
    radiusEarth = 3958.76;        %# Average radius of Earth, in miles
    distanceToCoast = zeros(1,nPoints);   %# Preallocate distance measure
    coastIndex = zeros(1,nPoints);        %# Preallocate a coastal point index
    for iPoint = 1:nPoints                %# Loop over map points
      rho = cos(scale.*lat(iPoint)).*...  %# Compute central angles from map
            cos(scale.*coastLat).*...     %#   point to all coastal points
            cos(scale.*(coastLong-long(iPoint)))+...
            sin(scale.*lat(iPoint)).*...
            sin(scale.*coastLat);
      d = radiusEarth.*acos(rho);         %# Compute great-circle distances
      [distanceToCoast(iPoint),coastIndex(iPoint)] = min(d);  %# Find minimum
    end
    
    %# Visualize the data:
    
    image(longRange,latRange,dem,'CDataMapping','scaled');  %# Display the DEM
    set(gca,'DataAspectRatio',[1 1 1],'YDir','normal',...   %# Modify some axes
        'XLim',longRange,'YLim',fliplr(latRange));          %#   properties
    colormap([0 0.8 0.8; hot]);  %# Add a cyan color to the "hot" colormap
    xlabel('Longitude');         %# Label the x axis
    ylabel('Latitude');          %# Label the y axis
    hold on;                     %# Add to the plot
    plot([long; coastLong(coastIndex).'],...    %'# Plot the inland points and
         [lat; coastLat(coastIndex).'],...      %'#   nearest coastal points
         'wo-');
    str = strcat(num2str(distanceToCoast.',...  %'# Make text for the distances
                         '%0.1f'),{' miles'});
    text(long,lat,str,'Color','w','VerticalAlignment','bottom');  %# Plot the text
    

    这是结果图:

    我想这让我距离最近的“海洋”海岸线近 400 英里(实际上,它可能是Intracoastal Waterway)。

    【讨论】:

    • 你是一个在没有Matlab工具箱的情况下解决问题的坚定人,我向你致敬
    • 你怎么知道如何计算 latRange 和 longRange。我现在使用 Alaskan NOAA DEM 数据集(50-90N、90-180N),但无法获得正确的 latRange 和 longRange。你从哪里得到 0.5 或 50/r 或 -180/c 的?我修改了 data_size 参数以说明 A 标题,但仍然丢失
    • 我目前正在使用:latRange = (40/r).*(r-rIndex+0.5) + 50;longRange = (-90/c).*(c-cIndex+0.5)-90; 他们很接近,但我没有信心:(
    • @Elpezmuerto:我的示例使用瓷砖 E 和 F。这些瓷砖一起跨越 0-50N、0-180W。这就是 50/r-180/c 比例因子的来源。对于您使用图块 A 的示例,它们将分别为 40/r-90/c0.5 的因子在那里,以便计算从第一个像素的中心到最后一个像素的中心的坐标范围。 coastLatcoastLong 中的坐标也是在像素中心计算的。
    【解决方案2】:
    load coast; 
    axesm('mercator'); 
    plotm(lat,long)
    

    在与coast.mat 相同的目录中还有其他数据集可能更有用。

    然后我会找到到数据集中所有点的距离,然后取最短距离。这将假设美国以外的海岸线是可以接受的答案。您将需要使用距离函数,因为欧几里得几何在这里不适用。

    【讨论】:

    • 这些文件和函数在 Mapping Toolbox 中吗?
    • 是的,这些是映射工具箱。正要编辑答案以反映这一点,但你已经抓住了我!
    • 我必须做 plotm(long,lat) 才能让北站起来。
    • @Marc,这很奇怪。我又试了一次,我的方法向北上升了。
    • @Marc,我用了plotm(lat,long),North 起来了
    【解决方案3】:

    Gnovice 的回答很好,对未来很有用,但我不需要那么高的保真度,也不想花费额外的时间从像素距离转换为纬度/经度距离。以 MatlabDoug 的回答,我编写了以下脚本:

    % Get Data  
    coast = load('coast.mat');
    locations = load('locations.mat');
    
    % Preallocate  
    coast_indexes = nan(size(locations.lat));
    distancefromcoast = nan(size(locations.lat));
    
    % Find distance and corresponding coastal point  
    for i=1:1:numel(locations.lat)  
        [dist, az] = distance(locations.lat(i), locations.long(i), coast.lat, coast.long);
        [distancefromcoast(i),coast_indexes(i)] = min(dist);
    end
    

    【讨论】:

    • 您可以使用MIN 的第二个输出来获取您的索引:[distancefromcoast(i),coast_indexes(i)] = min(dist);
    • 如果您想在没有映射工具箱的情况下计算测地线距离,请使用mathworks.com/matlabcentral/fileexchange/39108 中的 geoddistance。这比距离更准确,甚至适用于几乎对映点(与距离不同)。
    猜你喜欢
    • 2019-01-21
    • 1970-01-01
    • 1970-01-01
    • 2014-02-13
    • 1970-01-01
    • 2015-02-26
    • 2016-02-13
    • 1970-01-01
    • 2015-04-20
    相关资源
    最近更新 更多