Resample points that make up a line

12 ビュー (過去 30 日間)
newbie9
newbie9 2019 年 7 月 24 日
回答済み: newbie9 2019 年 7 月 24 日
My dataset consists of lines that are defined by "group_id" and "counter." Each group_id is one line, and the counter is the order of the points to build the line. x & y fields are the coordinates in UTM meters.
How can I resample the lines at a specific spacing (e.g., 200 meters)? I don't have the mapping toolbox.
Dataset example attached

採用された回答

newbie9
newbie9 2019 年 7 月 24 日
I solved this by [for each group_id] getting the distance between each counter_id. Then if the distance was less than the threshold, I used linspace to resample the points to make up the line. The distance check/resampling is in the function at the bottom of the script. The figure shows that the spacing has been resampled as expected.
datain = readtable('example_data.txt');
interval = 200;
% pre-allocate empty table
colnames = datain.Properties.VariableNames;
temptable = array2table(NaN(300*1000,length(colnames)));
temptable.Properties.VariableNames = colnames;
rownum = 1;
% descritize
for ii = 202 %min(datain.group_id):max(datain.group_id)
data_subset = datain(datain.group_id == ii,:);
[interpol_subset] = descritize(data_subset, interval);
rowA = rownum;
rowB = rownum + height(interpol_subset) -1;
temptable.group_id(rowA:rowB) = interpol_subset.group_id;
temptable.counter(rowA:rowB) = interpol_subset.counter;
temptable.x(rowA:rowB) = interpol_subset.x;
temptable.y(rowA:rowB) = interpol_subset.y;
rownum = rowB +1;
end
npts = sum(~isnan(temptable.x));
temptable = temptable(1:npts, :);
%%%%%%%%%%%%%%%%%%%%%%%%%%%
% make a plot for visual check
%%%%%%%%%%%%%%%%%%%%%%%%%%%
subplot(1,1,1)
for ii = 202 %min(datain.group_id):max(datain.group_id)
mytable = datain(datain.group_id == ii,:);
sortrows(mytable,'counter');
plot(mytable.x, mytable.y, 'black', 'DisplayName', 'Line')
hold on
end
box on
grid on
axis equal
ax = gca;
ax.XRuler.Exponent = 0;
ax.YRuler.Exponent = 0;
hold on
scatter(data_subset.x, data_subset.y, 'DisplayName', 'Original Spacing')
scatter(temptable.x, temptable.y, 14, 'filled', 'magenta', 'DisplayName', 'Resampled Spacing')
legend
%%%%%%%%%%%%%%%%%%%%%%%%%%%
% FUNCTION
%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [table_interpol] = descritize(datatable, stepsize)
% check inputs
check = istable(datatable);
if check ~= 1
error('--- data input to descritize function must be a table ---');
end
check = length(unique(datatable.group_id));
if check ~= 1
error('--- data input to descritize function must have only one group_id ---');
end
% pre-allocate empty table
cols = datatable.Properties.VariableNames;
temp = array2table(NaN(50*1000,length(cols)));
temp.Properties.VariableNames = cols;
rowcounter = 1;
% descritize the line
sortrows(datatable,'counter');
for jj = 1:max(datatable.counter)-1
ptA = [datatable.x(jj), datatable.y(jj)];
ptB = [datatable.x(jj+1), datatable.y(jj+1)];
dist = sqrt((ptB(1) - ptA(1))^2 + (ptB(2) - ptA(2))^2);
if dist > stepsize
npts_new = ceil(dist/stepsize)+1;
x_new = linspace(ptA(1), ptB(1), npts_new);
y_new = linspace(ptA(2), ptB(2), npts_new);
else
npts_new = 2;
x_new = [ptA(1), ptB(1)];
y_new = [ptA(2), ptB(2)];
end
x_new = x_new';
y_new = y_new';
rowA = rowcounter;
rowB = rowcounter + length(x_new) -1;
temp.x(rowA:rowB) = x_new;
temp.y(rowA:rowB) = y_new;
%rowcounter = rowB +1;
rowcounter = rowB; % do this to overwrite previous end, which is the next start
end
npts = sum(~isnan(temp.x));
groupid = ones(npts, 1) .* unique(datatable.group_id);
counterid = 1:1:npts;
counterid = counterid';
temp = temp(1:npts, :);
temp.group_id = groupid;
temp.counter = counterid;
table_interpol = temp;
end
Capture.JPG

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeRandom Number Generation についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by