GO语言 - GOOGLE MAPS API:判断指定点是否在多边形或折线内部或附近
Hey there! Since you already know how to handle this in JavaScript, translating the logic to Go will feel familiar once you see the idiomatic implementations. Let’s break down both the point-in-polygon (inside/outside) check and proximity (nearby) check for lines/polygons step by step.
The go-to method here is the ray casting algorithm: cast a horizontal ray from the point to the right, count how many times it crosses the polygon’s edges. An odd count means the point is inside; even means outside.
Here’s a clean Go implementation:
package main import "math" type Point struct { X, Y float64 } // IsPointInPolygon checks if a point lies inside a polygon (vertices ordered clockwise or counter-clockwise) func IsPointInPolygon(p Point, polygon []Point) bool { inside := false n := len(polygon) for i := 0; i < n; i++ { j := (i + 1) % n pi := polygon[i] pj := polygon[j] // Check if point's y falls within the edge's y-range, then if it's left of the ray-edge intersection ((pi.Y > p.Y) != (pj.Y > p.Y)) && (p.X < (pj.X-pi.X)*(p.Y-pi.Y)/(pj.Y-pi.Y)+pi.X) { inside = !inside } } return inside }
Quick notes:
- Pass your polygon as a slice of
Pointstructs, with vertices ordered consistently (clockwise or counter-clockwise). - The
(i+1)%ntrick automatically connects the last vertex back to the first for closed polygons.
To check if a point is "nearby" a polygon or polyline, calculate the shortest distance from the point to any edge of the shape, then compare it to your threshold (e.g., 5 units).
First, a helper to calculate distance from a point to a line segment:
// PointToSegmentDistance returns the shortest distance from point p to segment ab func PointToSegmentDistance(p, a, b Point) float64 { abX := b.X - a.X abY := b.Y - a.Y apX := p.X - a.X apY := p.Y - a.Y dot := apX*abX + apY*abY lenSq := abX*abX + abY*abY var t float64 if lenSq == 0 { // a and b are the same point—return distance to a return math.Hypot(p.X-a.X, p.Y-a.Y) } // Clamp t to [0,1] to stay within the segment bounds t = math.Max(0, math.Min(1, dot/lenSq)) // Find closest point on the segment closestX := a.X + t*abX closestY := a.Y + t*abY return math.Hypot(p.X-closestX, p.Y-closestY) } // IsPointNearPolygon checks if a point is within a threshold distance of any polygon edge func IsPointNearPolygon(p Point, polygon []Point, threshold float64) bool { n := len(polygon) for i := 0; i < n; i++ { j := (i + 1) % n dist := PointToSegmentDistance(p, polygon[i], polygon[j]) if dist <= threshold { return true } } return false }
This works for both closed polygons and open polylines—for polylines, you can skip the modulo if you don’t want to connect the last vertex back to the first, but it won’t break anything if you leave it in.
Let’s put it all together with a quick test:
func main() { // Define a square polygon square := []Point{ {X: 0, Y: 0}, {X: 10, Y: 0}, {X: 10, Y: 10}, {X: 0, Y: 10}, } insidePoint := Point{X: 5, Y: 5} println("Inside square:", IsPointInPolygon(insidePoint, square)) // true outsidePoint := Point{X: 15, Y: 5} println("Outside square:", IsPointInPolygon(outsidePoint, square)) // false nearPoint := Point{X: 12, Y: 5} println("Near square (threshold 2):", IsPointNearPolygon(nearPoint, square, 2)) // true println("Near square (threshold 1):", IsPointNearPolygon(nearPoint, square, 1)) // false }
内容的提问来源于stack exchange,提问作者Thiện Lý

