CREATE TABLE polys (
id INTEGER PRIMARY KEY,
xmin REAL,
ymin REAL,
xmax REAL,
ymax REAL,
name TEXT,
n INTEGER,
ar_x TEXT,
ar_y TEXT
)
CREATE TABLE points (
id INTEGER PRIMARY KEY,
x REAL,
y REAL,
name TEXT
)
CREATE INDEX ix_polys ON polys (xmin, ymin, xmax, ymax)
CREATE INDEX ix_points ON points (x, y)
####
SELECT py.name, py.n, py.ar_x, py.ar_y, pt.id, pt.x, pt.y
FROM polys py JOIN points pt ON
(py.xmin < pt.x AND py.ymin < pt.y AND py.xmax > pt.x AND py.ymax > pt.y)
WHERE py.id = ?
##
##
UPDATE points SET name = ? WHERE id IN (?)
##
##
sub _pointIsInPolygon {
my ($a_point, $n, $a_x, $a_y) = @_;
# point coords
my ($x, $y) = ($a_point->[0], $a_point->[1]);
# poly coords
# $n is the number of points in polygon.
my @x = @$a_x; # Even indices: x-coordinates.
my @y = @$a_y; # Odd indices: y-coordinates.
my ($i, $j); # Indices.
my $side = 0; # 0 = outside, 1 = inside.
for ($i = 0, $j = $n - 1 ; $i < $n; $j = $i++) {
if (
(
# If the y is between the (y-) borders ...
(($y[$i] <= $y) && ($y < $y[$j])) ||
(($y[$j] <= $y) && ($y < $y[$i]))
)
and
# ...the (x,y) to infinity line crosses the edge
# from the ith point to the jth point...
($x
<
($x[$j] - $x[$i] ) *
($y - $y[$i]) / ($y[$j] - $y[$i]) + $x[$i] )) {
$side = not $side; # Jump the fence.
}
}
return $side ? 1 : 0;
}
##
##
>perl test_point_in_poly.pl
5000.10000.15000.20000.25000.30000.35000.40000.45000.50000.55000.60000.65000.70000.75000.80000.85000.90000.95000.100000.
processed 100000 polys, updated 2948276 points
Total time: 8451 wallclock secs (6340.54 usr + 200.52 sys = 6541.06 CPU)