[ {"name": "a point in the middle of a square", "args": [{"lat": 5, "lng": 5}, [{"lat": 0, "lng": 0}, {"lat": 0, "lng": 10}, {"lat": 10, "lng": 10}, {"lat": 10, "lng": 0}]], "expect": true}, {"name": "a point east of the square", "args": [{"lat": 5, "lng": 15}, [{"lat": 0, "lng": 0}, {"lat": 0, "lng": 10}, {"lat": 10, "lng": 10}, {"lat": 10, "lng": 0}]], "expect": false}, {"name": "a point on the bottom edge counts as inside", "args": [{"lat": 0, "lng": 5}, [{"lat": 0, "lng": 0}, {"lat": 0, "lng": 10}, {"lat": 10, "lng": 10}, {"lat": 10, "lng": 0}]], "expect": true}, {"name": "a point on the east edge counts as inside (plain ray casting says outside here)", "args": [{"lat": 5, "lng": 10}, [{"lat": 0, "lng": 0}, {"lat": 0, "lng": 10}, {"lat": 10, "lng": 10}, {"lat": 10, "lng": 0}]], "expect": true}, {"name": "a vertex counts as inside", "args": [{"lat": 10, "lng": 10}, [{"lat": 0, "lng": 0}, {"lat": 0, "lng": 10}, {"lat": 10, "lng": 10}, {"lat": 10, "lng": 0}]], "expect": true}, {"name": "on the line extending an edge but beyond the corner is outside", "args": [{"lat": 0, "lng": 15}, [{"lat": 0, "lng": 0}, {"lat": 0, "lng": 10}, {"lat": 10, "lng": 10}, {"lat": 10, "lng": 0}]], "expect": false}, {"name": "a closed ring (last vertex repeats the first) gives the same answer", "args": [{"lat": 5, "lng": 5}, [{"lat": 0, "lng": 0}, {"lat": 0, "lng": 10}, {"lat": 10, "lng": 10}, {"lat": 10, "lng": 0}, {"lat": 0, "lng": 0}]], "expect": true}, {"name": "clockwise and anticlockwise rings agree", "args": [{"lat": 5, "lng": 5}, [{"lat": 10, "lng": 0}, {"lat": 10, "lng": 10}, {"lat": 0, "lng": 10}, {"lat": 0, "lng": 0}]], "expect": true}, {"name": "concave U shape: a point in the notch is outside", "args": [{"lat": 5, "lng": 5}, [{"lat": 0, "lng": 0}, {"lat": 0, "lng": 10}, {"lat": 10, "lng": 10}, {"lat": 10, "lng": 7}, {"lat": 3, "lng": 7}, {"lat": 3, "lng": 3}, {"lat": 10, "lng": 3}, {"lat": 10, "lng": 0}]], "expect": false}, {"name": "concave U shape: a point in the left arm is inside", "args": [{"lat": 5, "lng": 1}, [{"lat": 0, "lng": 0}, {"lat": 0, "lng": 10}, {"lat": 10, "lng": 10}, {"lat": 10, "lng": 7}, {"lat": 3, "lng": 7}, {"lat": 3, "lng": 3}, {"lat": 10, "lng": 3}, {"lat": 10, "lng": 0}]], "expect": true}, {"name": "concave U shape: a point in the base under the notch is inside", "args": [{"lat": 2, "lng": 5}, [{"lat": 0, "lng": 0}, {"lat": 0, "lng": 10}, {"lat": 10, "lng": 10}, {"lat": 10, "lng": 7}, {"lat": 3, "lng": 7}, {"lat": 3, "lng": 3}, {"lat": 10, "lng": 3}, {"lat": 10, "lng": 0}]], "expect": true}, {"name": "concave U shape: the inner corner of the notch is on the boundary", "args": [{"lat": 3, "lng": 5}, [{"lat": 0, "lng": 0}, {"lat": 0, "lng": 10}, {"lat": 10, "lng": 10}, {"lat": 10, "lng": 7}, {"lat": 3, "lng": 7}, {"lat": 3, "lng": 3}, {"lat": 10, "lng": 3}, {"lat": 10, "lng": 0}]], "expect": true}, {"name": "a ray through a vertex of a diamond counts the crossing once: inside", "args": [{"lat": 5, "lng": 2}, [{"lat": 0, "lng": 5}, {"lat": 5, "lng": 10}, {"lat": 10, "lng": 5}, {"lat": 5, "lng": 0}]], "expect": true}, {"name": "a ray through a vertex of a diamond counts the crossing once: outside", "args": [{"lat": 5, "lng": -1}, [{"lat": 0, "lng": 5}, {"lat": 5, "lng": 10}, {"lat": 10, "lng": 5}, {"lat": 5, "lng": 0}]], "expect": false}, {"name": "a small triangle over London, point inside", "args": [{"lat": 51.52, "lng": -0.1}, [{"lat": 51.5, "lng": -0.2}, {"lat": 51.6, "lng": -0.1}, {"lat": 51.5, "lng": 0.0}]], "expect": true}, {"name": "a small triangle over London, point outside near the apex", "args": [{"lat": 51.59, "lng": -0.15}, [{"lat": 51.5, "lng": -0.2}, {"lat": 51.6, "lng": -0.1}, {"lat": 51.5, "lng": 0.0}]], "expect": false}, {"name": "two vertices are not a polygon", "args": [{"lat": 0, "lng": 0}, [{"lat": 0, "lng": 0}, {"lat": 1, "lng": 1}]], "expectError": "a polygon needs at least 3 distinct vertices"}, {"name": "repeated vertices do not count twice", "args": [{"lat": 0, "lng": 0}, [{"lat": 0, "lng": 0}, {"lat": 0, "lng": 0}, {"lat": 1, "lng": 1}, {"lat": 0, "lng": 0}]], "expectError": "a polygon needs at least 3 distinct vertices"}, {"name": "a vertex latitude out of range is an error", "args": [{"lat": 0, "lng": 0}, [{"lat": 0, "lng": 0}, {"lat": 91, "lng": 0}, {"lat": 0, "lng": 1}]], "expectError": "latitude must be between -90 and 90 degrees"}, {"name": "a point longitude out of range is an error", "args": [{"lat": 0, "lng": 200}, [{"lat": 0, "lng": 0}, {"lat": 0, "lng": 10}, {"lat": 10, "lng": 10}, {"lat": 10, "lng": 0}]], "expectError": "longitude must be between -180 and 180 degrees"} ]