I have a following problem and I will try to explain it. I have a huge, political world map. I want to get a shape of selected country (in example Ghana, Nepal or Poland). How can I do that?
-
2that depends on how the data comprising your world map looks – Timothy Groote Jul 09 '14 at 12:56
-
@TimothyGroote this is the map I want to use in my project. It will be a little smaller of course: http://www.afranko.net/wp-content/uploads/2013/11/a55e78db0c82c787f8ae074fe2cd0c73.png – Jan Bońkowski Jul 09 '14 at 12:58
-
So it's just a bitmap, and doesn't actually contain any of the data you need to tell which country is which? – Timothy Groote Jul 09 '14 at 13:06
-
1You need to provide a bit more information first. Which of the linked images are you using? Could it be either? Do you need to detect the country shape using image analysis techniques or do you have/can use more information? Have you tried anything so far? – OnABauer Jul 10 '14 at 07:17
-
@OnABauer I currently don't use any image, but yes, it could be either. I'd like to define my own shapes from point to point (in example, I'd like to define France, Germany, Netherlands and Spain as Western Europe, Norway, Finland and Sweden as Scandinavia etc). I haven't tried any solution for my problem, but I thought I can solve it in the way I wrote - if I can define rectangle, how can I define any shape when I am having some points? – Jan Bońkowski Jul 10 '14 at 18:16
1 Answers
It depends what other information you are able to provide in advance. From your question and comments it sounds like you plan to predefine your shapes so the problem isn't too difficult. If you define each region by a set of points it's just a matter of checking if the selection (presumably a mouse click or similar) is within a polygon. There are a number of ways to do this. I think I've used one of the answers to the following question:
Something like:
public static bool IsInPolygon(Point[] poly, Point clickedPoint)
{
if (poly.Length < 3)
{
return false;
}
Point p1, p2;
bool inside = false;
Point oldPoint = new Point(poly[poly.Length - 1].X, poly[poly.Length - 1].Y);
for (int i = 0; i < poly.Length; i++)
{
Point newPoint = new Point(poly[i].X, poly[i].Y);
if (newPoint.X > oldPoint.X)
{
p1 = oldPoint;
p2 = newPoint;
}
else
{
p1 = newPoint;
p2 = oldPoint;
}
if ((newPoint.X < clickedPoint.X) == (clickedPoint.X <= oldPoint.X)
&& (clickedPoint.Y - (long)p1.Y) * (p2.X - p1.X) < (p2.Y - (long)p1.Y) *(clickedPoint.X - p1.X))
{
inside = !inside;
}
oldPoint = newPoint;
}
return inside;
}
I haven't tested the above code so I'd make sure to test it properly if you use it.
If you can't predefine the shapes then you'll probably have to use some sort of analysis method to pick out the shapes. If you use a clean map with solid lines it won't be too difficult. Any kind of flood fill algorithm should be able to pick out individual countries (obviously you'd have to deal with special cases like when a country is made of two distinct regions). From there getting a set of points from each shape can be done using a simple marching squares algorithm. If desired, you can then reduce the number of points depending on the level of accuracy you need.