How to assign point to multiple circles

6 visualizaciones (últimos 30 días)
012786534
012786534 el 11 de Feb. de 2020
Comentada: 012786534 el 14 de Feb. de 2020
Hi,
I have small script to assign points to circles. However, when a point falls into overlapping circles, then I want it to be assigned to the circle with the nearest center. In other words, a point can only be assigned to one circle. That last part is giving me a problem. Otherwise no more than 2 circles can overlap and if a point fall outside all the circles then it is not assigned anything.
Please note that I dont have any packages.
Thoughts ?
% Positions of points
lat = [47.5, 45.5, 46.5, 46.6, 47.8, 45.7, 44]';
lon = [-63.5, -61.5, -62.5, -62.4, -63.6, -61.7, -59.9]';
pts_positions = table(lat, lon);
% Center of circles
lat = [47, 45, 43]';
lon = [-63, -61, -59]';
name = {'A'; 'B'; 'C'};
circles_positions = table(name,lat, lon);
angles = linspace(0, 2*pi, 720);
radius = 2;
% Assign points to circles
for i = 1:height(circles_positions)
j = circles_positions(i, 1);
x = radius * cos(angles) + circles_positions.lon(i);
y = radius * sin(angles) + circles_positions.lat(i);
mask = pts_positions.lat > min(y) & pts_positions.lon < max(y) & ...
pts_positions.lon > min(x) & pts_positions.lon < max(x);
pts_positions.circle_name(mask) = table2cell(j(1,1));
end

Respuesta aceptada

Adam Danz
Adam Danz el 11 de Feb. de 2020
Editada: Adam Danz el 11 de Feb. de 2020
The first block of code below identifies which circle center is closest to each pts_positions using pdist2(). It then assigns the circle name from circles_positions to each row in pts_positions.
% Positions of points
lat = [47.5, 45.5, 46.5, 46.6, 47.8, 45.7, 44]';
lon = [-63.5, -61.5, -62.5, -62.4, -63.6, -61.7, -59.9]';
pts_positions = table(lat, lon);
% Center of circles
lat = [47, 45, 43]'; % I recommend you use different variable names here to avoid confusion.
lon = [-63, -61, -59]'; % I recommend you use different variable names here to avoid confusion.
name = {'A'; 'B'; 'C'};
circles_positions = table(name,lat, lon);
% angles = linspace(0, 2*pi, 720); % no longer needed
radius = 2;
% Determine which circle center is closest to each coordinate.
% distToCircCenters(i,j) is the distance between pts(i) and cirlces(j)
distToCircCenters = pdist2(pts_positions{:,:}, circles_positions{:,{'lat','lon'}});
% closestCircIdx is a positive integer identifying which circle in circles_positions is closest
[~, closestCircIdx] = min(distToCircCenters, [], 2);
% Assign circle name
pts_positions.circle_name = circles_positions.name(closestCircIdx);
The block of code below plots the results using rounded rectangles. The circles are color coded and the (lon,lat) points are color coded to show which circle they belong to.
% Plot the circles (this uses rounded rectangles)
nCircles = numel(circles_positions.lat);
plotCircFcn = @(x,y,r)rectangle('Position',[x-r,y-r,r*2,r*2],'Curvature',[1,1]);
clf()
hold on
axis equal
box on
recHand = arrayfun(@(i)plotCircFcn(circles_positions.lon(i),circles_positions.lat(i),radius),1:nCircles);
% Color the circles and mark the centers
circColors = [jet(nCircles), repmat(0.5,nCircles,1)]; % color and transparency (undocumented)
set(recHand, {'FaceColor'}, mat2cell(circColors, ones(size(circColors,1),1), size(circColors,2)) )
plot(circles_positions.lon, circles_positions.lat, 'k*')
% Plot the lat and lon points color coding which circle they belong to
scatter(pts_positions.lon, pts_positions.lat, 90, circColors(closestCircIdx,1:3), 'filled', 'MarkerEdgeColor', 'k')
  3 comentarios
Adam Danz
Adam Danz el 12 de Feb. de 2020
Editada: Adam Danz el 13 de Feb. de 2020
I added an additional (lon,lat) coordinates that is out of bounds for all circles. The points that are out of bounds will be colored black.
% Positions of points
lat = [47.5, 45.5, 46.5, 46.6, 47.8, 45.7, 44, 47.5]';
lon = [-63.5, -61.5, -62.5, -62.4, -63.6, -61.7, -59.9, -60.5]';
pts_positions = table(lat, lon);
% Center of circles
lat = [47, 45, 43]'; % I recommend you use different variable names here to avoid confusion.
lon = [-63, -61, -59]'; % I recommend you use different variable names here to avoid confusion.
name = {'A'; 'B'; 'C'};
circles_positions = table(name,lat, lon);
angles = linspace(0, 2*pi, 720);
radius = 2;
% Determine which circle center is closest to each coordinate.
% distToCircCenters(i,j) is the distance between pts(i) and cirlces(j)
distToCircCenters = pdist2(pts_positions{:,:}, circles_positions{:,{'lat','lon'}});
% If points are outside of circle, replace distance with NaN
nCircles = numel(circles_positions.lat);
distToCircCenters(distToCircCenters > radius) = NaN;
distToCircCenters(:, nCircles+1) = inf;
% closestCircIdx is a positive integer identifying which circle in circles_positions is closest
[~, closestCircIdx] = min(distToCircCenters, [], 2);
% Assign circle name
circNames = [circles_positions.name; 'None'];
pts_positions.circle_name = circNames(closestCircIdx);
% Plot the circles (this uses rounded rectangles)
plotCircFcn = @(x,y,r)rectangle('Position',[x-r,y-r,r*2,r*2],'Curvature',[1,1]);
clf()
hold on
axis equal
box on
recHand = arrayfun(@(i)plotCircFcn(circles_positions.lon(i),circles_positions.lat(i),radius),1:nCircles);
% Color the circles and mark the centers
circColors = [jet(nCircles), repmat(0.5,nCircles,1)]; % color and transparency (undocumented)
set(recHand, {'FaceColor'}, mat2cell(circColors, ones(size(circColors,1),1), size(circColors,2)) )
plot(circles_positions.lon, circles_positions.lat, 'k*')
% Plot the lat and lon points color codeing which circle they belong to
circColors2 = [circColors; [0 0 0 circColors(1,end)]];
scatter(pts_positions.lon, pts_positions.lat, 90, circColors2(closestCircIdx,1:3), 'filled', 'MarkerEdgeColor', 'k')
012786534
012786534 el 14 de Feb. de 2020
Thank you Adam, I really appreciate your help.

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Geographic Plots en Help Center y File Exchange.

Etiquetas

Community Treasure Hunt

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

Start Hunting!

Translated by