Board index » delphi » Point in polygon = place in country

Point in polygon = place in country

I am planning an application involving an interactive map of the world
which requires identifying the country under the cursor.

I think I have an idea of a viable and efficient algorithm for this. A
slight complication is that in general countries may lie inside each
other. For example Lesotho lies entirely within South Africa.

My map data structure would thus include a (dynamic) array of points
for each country, an index for it, and a smallest bounding rectangle
for it, easily computed on the fly as I read the points. First I
iterate through my list of countries looking for bounding rectangle
hits using very simple code. Very often (most cases) I will only get
one such hit (or no hits if I am at sea), in which case I have nothing
further to do. In the case I have two or more such hits I must return
and test for polygonal hits withing those bounding rectangles: if I
get a hit I compute the area of the bounding rectangle. If I only get
one polygonal hit I am done, while if I get more (i.e. country within
a country) I select the one with the smallest bounding rectangle area
(I'm not sure if that takes care of pathological cases, but it will do
for my application).

To perform my polygonal hit I propose to use the Windows PtInRgn
function I've recently discovered. I've been successful in using this
function but my problem is I'm not sure I'm using it efficiently and
this where I would much appreciate help. I know nothing about Windows
programming and the Windows reference is very coy about what an HRgn
actually is, although I have managed to fathom they are very large -
typically several kilobytes for a random triangle on the screen.

Specifically I appreciate the need to DeleteObject to free resources
after performing PtInRgn. But do I need to SelectObject as well after
CreatePolygonRgn? Also from what I can make out of the documentation I
am supposed to restore the last selected object of HRgn type. But I
have no idea of what that would be before I perform my first polygon
hit test or how I could get hold it. I have to be clear I'm doing this
right because the build up in wasted resources could be huge in a
session with my application.

Help greatly appreciated: we are alone in this wide world, else I
would ask colleagues.

sincerely,

William Boyd

 

Re:Point in polygon = place in country


"William Reid Boyd" <Boyd.Will...@wanadoo.fr> wrote in message
news:3a9c658e.15263402@newsgroups.borland.com...

Quote
> I am planning an application involving an interactive map of the world
> which requires identifying the country under the cursor.
...
> Help greatly appreciated: we are alone in this wide world, else I
> would ask colleagues.

I think I would use an in-memory bitmap mask where each country
was colored uniquely -- easy with a pf24bit bitmap.   From a
mouse move event over the displayed bitmap, you can lookup
the corresponding pixel on the in-memory mask.

If you use a pf24bit mask, you would have 256 possible
values for each of the red, green and blue components.
You could use one of the components to give the
country index directly, and perhaps use the other
components for various groupings if desired.

--
efg     e...@efg2.com     Earl F. Glynn, Overland Park, KS  USA

efg's Computer Lab:  http://www.efg2.com/Lab
Mirror:  http://homepages.borland.com/efg2lab/Default.htm

Re:Point in polygon = place in country


I have a similar mechanism in a program

I would use ptInRect first to cut down on your region creation ( each
country to have a bounding rectangle)

Speed wise it seems fine, I use a 333 msecond timer to delay testing ( move
mouse, reset timer)

KevanB

Re:Point in polygon = place in country


On Tue, 27 Feb 2001 21:04:27 -0600, "Earl F. Glynn"

Quote
<EarlGl...@att.net> wrote:
>I think I would use an in-memory bitmap mask where each country
>was colored uniquely -- easy with a pf24bit bitmap.  

Thanks for this. I'll have a think about it, although I expect to be
working with metafiles (sorry, should have mentioned that).

William Boyd

Re:Point in polygon = place in country


Quote
On Wed, 28 Feb 2001 09:57:02 -0000, "KevanB" <ke...@aulic.org> wrote:

Thanks for these.

Quote
>I would use ptInRect first to cut down on your region creation

I hadn't noticed ptInRect, which I expect is faster than code I could
write: I'll certainly test the bounding rectangle first.

Quote
>I use a 333 msecond timer to delay testing ( move
>mouse, reset timer)

I'll follow you.

William Boyd;

Re:Point in polygon = place in country


Quote
>My map data structure would thus include a (dynamic) array of points
>for each country, an index for it, and a smallest bounding rectangle
>for it, easily computed on the fly as I read the points. First I
>iterate through my list of countries looking for bounding rectangle
>hits using very simple code. Very often (most cases) I will only get
>one such hit (or no hits if I am at sea), in which case I have nothing
>further to do. In the case I have two or more such hits I must return
>and test for polygonal hits withing those bounding rectangles: if I
>get a hit I compute the area of the bounding rectangle. If I only get
>one polygonal hit I am done, while if I get more (i.e. country within
>a country) I select the one with the smallest bounding rectangle area
>(I'm not sure if that takes care of pathological cases, but it will do
>for my application).

      I am expecting to tackle a similar but simpler problem in the
not too distant future.  What I'm planning to do is make an offscreen
drawing of the image, but with the colors different--item #1 will be
drawn in color 1 and so on.  When the user clicks a point, I'll look
at the offscreen image and see what color it is at that point.  No
searching needed, no hassles with curves, no hassles with overlap
(although that's not an issue for you.)

Re:Point in polygon = place in country


Hi,

I have done this using the component HotImage.
It works just fine.

Anders

"William Reid Boyd" <Boyd.Will...@wanadoo.fr> skrev i meddelandet
news:3a9c658e.15263402@newsgroups.borland.com...

Quote
> I am planning an application involving an interactive map of the world
> which requires identifying the country under the cursor.

> I think I have an idea of a viable and efficient algorithm for this. A
> slight complication is that in general countries may lie inside each
> other. For example Lesotho lies entirely within South Africa.

> My map data structure would thus include a (dynamic) array of points
> for each country, an index for it, and a smallest bounding rectangle
> for it, easily computed on the fly as I read the points. First I
> iterate through my list of countries looking for bounding rectangle
> hits using very simple code. Very often (most cases) I will only get
> one such hit (or no hits if I am at sea), in which case I have nothing
> further to do. In the case I have two or more such hits I must return
> and test for polygonal hits withing those bounding rectangles: if I
> get a hit I compute the area of the bounding rectangle. If I only get
> one polygonal hit I am done, while if I get more (i.e. country within
> a country) I select the one with the smallest bounding rectangle area
> (I'm not sure if that takes care of pathological cases, but it will do
> for my application).

> To perform my polygonal hit I propose to use the Windows PtInRgn
> function I've recently discovered. I've been successful in using this
> function but my problem is I'm not sure I'm using it efficiently and
> this where I would much appreciate help. I know nothing about Windows
> programming and the Windows reference is very coy about what an HRgn
> actually is, although I have managed to fathom they are very large -
> typically several kilobytes for a random triangle on the screen.

> Specifically I appreciate the need to DeleteObject to free resources
> after performing PtInRgn. But do I need to SelectObject as well after
> CreatePolygonRgn? Also from what I can make out of the documentation I
> am supposed to restore the last selected object of HRgn type. But I
> have no idea of what that would be before I perform my first polygon
> hit test or how I could get hold it. I have to be clear I'm doing this
> right because the build up in wasted resources could be huge in a
> session with my application.

> Help greatly appreciated: we are alone in this wide world, else I
> would ask colleagues.

> sincerely,

> William Boyd

Re:Point in polygon = place in country


Hi William,

There is a PointInPolygon function I have written on Earl Glynn's site.

Look under Point In Polygon at:
http://www.efg2.com/Lab/Library/Delphi/Graphics/Math.htm

I use it for the same purpose as you (maps). It does not use Windows
regions, just a simple geometrical algorithm.

I use it notably to display the name of the country or region in a hint
window when the mouse moves over it. For that use it seems quite fast and
accurate.

I'd be happy to have your feedback if you use it.

Thrse

Re:Point in polygon = place in country


Thrse

I will also have a look, creating regions is all fine and dandy, but Im all
for a faster method <g>

KevanB

Re:Point in polygon = place in country


Quote
> I hadn't noticed ptInRect, which I expect is faster than code I could
> write:

[Just babbeling]

Probably not.  ptInRect is pretty simple, and if you needed
speed, and had to do a lot of them, makes for a *great*
argument for the need for adding back support for inline
expanded functions in Delphi's Pascal front end.

Re:Point in polygon = place in country


Quote
On Thu, 1 Mar 2001 14:30:46 -0000, "KevanB" <ke...@aulic.org> wrote:

>Thrse

>I will also have a look, creating regions is all fine and dandy, but Im all
>for a faster method <g>

>KevanB

Browsing through a search in the newsgroups for PtInPolygon I found a
reference to a Microsoft Knowledge Base document which gives a C
routine for doing this without scanning regions: the algorithm is a
parity count thing on ray crossings, not quite what the human eye does
spose. I'll translate that into Delphi and put it up on a strictly
caveat emptor basis on mynhome pages and report back some time. I'll
also look into iability of my own first thought of using some stuff in
complex variable maths.

My thanks to all who responded.

William Boyd

Thanks to all for responding

Re:Point in polygon = place in country


| Browsing through a search in the newsgroups for PtInPolygon I found a
| reference to a Microsoft Knowledge Base document which gives a C
| routine for doing this without scanning regions: the algorithm is a
| parity count thing on ray crossings, not quite what the human eye does
| spose. I'll translate that into Delphi and put it up on a strictly
| caveat emptor basis on mynhome pages and report back some time. I'll
| also look into iability of my own first thought of using some stuff in
| complex variable maths.

I didn't realize you were looking for the point in poly algorithm
Check out Joseph Rourke
He fixed James Sedgewick algorithm

http://cs.smith.edu/~orourke/books/ftp.html

Garry Kernan

Other Threads