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 CenterFile Exchange에서 Random Number Generation에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by