public boolean isWithin(final long px, final long py) {
        int wn = 0; // the winding number counter

        // loop through all edges of the polygon
        final int iLast = points.size() - 1;
        final Point p0 = points.get(isClosed ? iLast : 0);
        long p0x = p0.x; // need to use long to avoid overflow in products
        long p0y = p0.y;

        for (int i = isClosed ? 0 : 1; i <= iLast; i++) { // edge from v[i] to v[i+1]
            final Point p1 = points.get(i);

            final long p1x = p1.x;
            final long p1y = p1.y;

            if (isOnLine(px, py, p0x, p0y, p1x, p1y)) {
                return true;
            }

            final long intersect = (p1x - p0x) * (py - p0y) - (px - p0x) * (p1y - p0y);
            if (p0y <= py) {  // start y <= p.y
                // an upward crossing, p left of edge
                // have a valid up intersect
                if (p1y > py && intersect > 0) {
                    ++wn;
                }
            } else { // start y > p.y (no test needed)
                // a downward crossing, p right of edge
                // have a valid down intersect
                if (p1y <= py && intersect < 0) {
                    --wn;
                }
            }
            p0x = p1x;
            p0y = p1y;
        }
        return wn != 0;
    }
winding number test for a point in a polygon

@param px longitude of the point to check
@param py latitude of the point to check
@return a boolean whether the point is within the polygon or not.
main/src/main/java/cgeo/geocaching/brouter/core/OsmNogoPolygon.java