Resample points that make up a line

조회 수: 9 (최근 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개)

Community Treasure Hunt

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

Start Hunting!

Translated by