ferddle has asked for the wisdom of the Perl Monks concerning the following question:

This should be an easy question but I have hit a brick wall with my code. I greatly appreciate any response...

I work extensively with GoogleEarth files that contain both points and polygons. I have assigned two arrays for each X and Y coordinate for the points file. The arrays look something like this:

For the following coordinates:(-12, -83),(0, 34),(23, -76)

@pnt_x_values = (-12, 0, 23)

@pnt_y_values = (-83, 34, -76)

I would like to find any points that lie within any of the polygons. I have stripped the polygon file into four arrays. Each consecutive element of each array contains the minimum and maximum values for the x and y coordinates for each polygon.

The sample below uses three (rectangular) polygons:

@poly_x_min = (-13, 45, 22)

@poly_x_max = (-11, 49, 24)

@poly_y_min = (-82, 33, -2)

@poly_y_max = (-84, 35, -6)

In other words, the first point coordinate lies within the first polygon. ie:

$poly_x_min[0] <= $pnt_x_values[0] <= $poly_x_max[0]

and

$poly_y_min[0] <= $pnt_y_values[0] <= $poly_y_max[0]

(In the file, there is no nice correlation between indexes like this.)

I have posted a horrible illustration here

If you have any ideas, on how to get perl to evaluate each point against each polygon in this manner, I would greatly appreciate it.

Replies are listed 'Best First'.
Re: Is a point in a polygon?
by sandboxed (Sexton) on Apr 30, 2008 at 08:46 UTC

    Hi Ferddle,

    First of all, I think that the question is nice but there's something missing: some code. People will help you kindly with any perl-related question there, but they will not do the homework for you, of course! ;).

    Just try to update your question and put your code as clean as possible. Perhaps people will be able to help you (it looks more like an algorithm problem). Just for some help, check which kind of iterative structure fits you more.

    Looking by google you will find things like this: algorithm polygon -> Determining Whether A Point Is Inside A Complex Polygon

    Hope it helps!
    Sandboxed

Re: Is a point in a polygon?
by grizzley (Chaplain) on Apr 30, 2008 at 08:50 UTC

    Where's the problem? You wrote already condition, now write

    for $pid (0..$num_of_points-1) { for $polyid (0..$num_of_polygons-1) { 'do something' if <your condition> } }
    and that's it.

    Maybe there is a problem with speed? Or really great number of data? Some sorting would help here? Please write more info if you need more help.

Re: Is a point in a polygon?
by BrowserUk (Patriarch) on Apr 30, 2008 at 13:12 UTC

    If you have large numbers of point to look up and/or large numbers of polygons to match against, then you may find Re: Speeding up ... (O(N) determination of point in polygon regardless of complexity) of interest. It demonstrates a method of O(1) lookup (per point) regardless of how many polygons you are matching against. Well, up to 4 billion polygons.

    That is, to lookup any 2D point and determine which of upto 2**32 polyons it is in, takes one memory read.

    In that case it was finding the zipcode for a grid reference anywhere in the US. Which doesn't sound too dissimilar to the sketchy details you've given. It's quite simple to program and very fast.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Is a point in a polygon?
by apl (Monsignor) on Apr 30, 2008 at 09:41 UTC
    You're more likely to get help from people with domain-specific skills if you used a relevant title. "Easy question" isn't going to attract any geometers on the board; "Finding points within polygons" might.
Re: Is a point in a polygon?
by Anonymous Monk on Apr 30, 2008 at 08:33 UTC
Re: Is a point in a polygon?
by GrandFather (Saint) on Apr 30, 2008 at 09:54 UTC

    You speak of points and polygons but give 3d sample data and a 2d illustration. You mention GoogleEarth files which implies geographic data which implies spherical coordinates. I'm confused! What is it that you are really dealing with? If it is spherical data then the math is a pile more "fun" than if you are really dealing with 2d data, or even with 3d data.


    Perl is environmentally friendly - it saves trees

      No, this is not 3d sample. Look at names of structures:

      @pnt_x_values = (-12, 0, 23) @pnt_y_values = (-83, 34, -76)
      In the first table x coordinates of points are stored, in the second - y coords. And for polygons 1st table stores x min coordinates, 2nd table stores x max coords, and so on.

      Yes, it is funny and (in some cases) unconvenient way of storing 2d data...

        Doh!

        The following code may be of interest:

        use strict; use warnings; my @pnt_x_values = (-12, 0, 23); my @pnt_y_values = (-83, 34, -76); my @poly_x_min = (-13, 45, 22); my @poly_x_max = (-11, 49, 24); my @poly_y_min = (-82, 33, -2); my @poly_y_max = (-84, 35, -6); for my $polyI (0 .. $#poly_x_min) { my $x1 = $poly_x_min[$polyI]; my $x2 = $poly_x_max[$polyI]; my $y1 = $poly_y_min[$polyI]; my $y2 = $poly_y_max[$polyI]; my @poly = map {{x => $_->[0], y =>$_->[1]}} ([$x1, $y1], [$x2, $y1], [$x2, $y2], [$x1, $y2]); for my $pi (0 .. $#pnt_x_values) { my %point = (x => $pnt_x_values[$pi], y => $pnt_y_values[$pi]) +; next unless PointInPoly (\%point, \@poly); print 'Point ' . ($pi + 1) . ' inside poly ' . (1 + $polyI) . +"\n"; } } sub PointInPoly { my ($point, $poly) = @_; my $wCount = 0; for my $i (0 .. $#$poly - 1, -1) { # edge from$poly->[$i] to$poly->[$i + 1] if ($poly->[$i]{y} <= $point->{y}) { # start y <= $P->{y} if ($poly->[$i + 1]->{y} > $point->{y}) { # an upward crossing if (isLeft ($poly->[$i], $poly->[$i + 1], $point) > 0) + { # $P left of edge ++$wCount; # have a valid up intersect } } } else { # start y > $P->{y} (no test needed) if ($poly->[$i + 1]->{y} <= $point->{y}) { # a downward crossing if (isLeft ($poly->[$i], $poly->[$i + 1], $point) < 0) + { # $P right of edge --$wCount; # have a valid down intersect } } } } return $wCount; } sub isLeft { my ($P0, $P1, $P2) = @_; return ($P1->{x} - $P0->{x}) * ($P2->{y} - $P0->{y}) - ($P2->{x} - $P0->{x}) * ($P1->{y} - $P0->{y}); }

        Prints:

        Point 1 inside poly 1

        Perl is environmentally friendly - it saves trees
Re: Is a point in a polygon?
by Anonymous Monk on Apr 30, 2008 at 08:37 UTC
    Aren't you looking for something Geo-