mirror of https://github.com/tidwall/tile38.git
point match on interior hole, fixes #241
This commit is contained in:
parent
02fa605dc4
commit
5b5e589be3
|
@ -17,6 +17,11 @@ func (p Point) Inside(exterior Polygon, holes []Polygon) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
// Inside detects if a rect intersects another polygon
|
||||
func (r Rect) Inside(exterior Polygon, holes []Polygon) bool {
|
||||
return r.Polygon().Inside(exterior, holes)
|
||||
}
|
||||
|
||||
// Inside returns true if shape is inside of exterior and not in a hole.
|
||||
func (shape Polygon) Inside(exterior Polygon, holes []Polygon) bool {
|
||||
var ok bool
|
||||
|
|
|
@ -5,6 +5,11 @@ func (p Point) Intersects(exterior Polygon, holes []Polygon) bool {
|
|||
return p.Inside(exterior, holes)
|
||||
}
|
||||
|
||||
// Intersects detects if a rect intersects another polygon
|
||||
func (r Rect) Intersects(exterior Polygon, holes []Polygon) bool {
|
||||
return r.Polygon().Inside(exterior, holes)
|
||||
}
|
||||
|
||||
// Intersects detects if a polygon intersects another polygon
|
||||
func (shape Polygon) Intersects(exterior Polygon, holes []Polygon) bool {
|
||||
return shape.doesIntersects(false, exterior, holes)
|
||||
|
|
|
@ -62,6 +62,17 @@ type Rect struct {
|
|||
Min, Max Point
|
||||
}
|
||||
|
||||
// Polygon returns a polygon for the rect
|
||||
func (r Rect) Polygon() Polygon {
|
||||
p := Polygon(make([]Point, 5))
|
||||
p[0] = Point{X: r.Min.X, Y: r.Max.Y}
|
||||
p[1] = Point{X: r.Max.X, Y: r.Max.Y}
|
||||
p[2] = Point{X: r.Max.X, Y: r.Min.Y}
|
||||
p[3] = Point{X: r.Min.X, Y: r.Min.Y}
|
||||
p[4] = Point{X: r.Min.X, Y: r.Max.Y}
|
||||
return p
|
||||
}
|
||||
|
||||
// Rect returns the bounding box rectangle for the polygon
|
||||
func (p Polygon) Rect() Rect {
|
||||
var bbox Rect
|
||||
|
|
|
@ -97,7 +97,15 @@ func (g Polygon) WithinBBox(bbox BBox) bool {
|
|||
if len(g.Coordinates) == 0 {
|
||||
return false
|
||||
}
|
||||
return polyPositions(g.Coordinates[0]).InsideRect(rectBBox(bbox))
|
||||
rbbox := rectBBox(bbox)
|
||||
ext, holes := polyExteriorHoles(g.Coordinates)
|
||||
if len(holes) > 0 {
|
||||
if rbbox.Max == rbbox.Min {
|
||||
return rbbox.Min.Inside(ext, holes)
|
||||
}
|
||||
return rbbox.Inside(ext, holes)
|
||||
}
|
||||
return ext.InsideRect(rectBBox(bbox))
|
||||
}
|
||||
|
||||
// IntersectsBBox detects if the object intersects a bbox.
|
||||
|
@ -108,7 +116,15 @@ func (g Polygon) IntersectsBBox(bbox BBox) bool {
|
|||
if len(g.Coordinates) == 0 {
|
||||
return false
|
||||
}
|
||||
return polyPositions(g.Coordinates[0]).IntersectsRect(rectBBox(bbox))
|
||||
rbbox := rectBBox(bbox)
|
||||
ext, holes := polyExteriorHoles(g.Coordinates)
|
||||
if len(holes) > 0 {
|
||||
if rbbox.Max == rbbox.Min {
|
||||
return rbbox.Min.Intersects(ext, holes)
|
||||
}
|
||||
return rbbox.Intersects(ext, holes)
|
||||
}
|
||||
return ext.IntersectsRect(rectBBox(bbox))
|
||||
}
|
||||
|
||||
// Within detects if the object is fully contained inside another object.
|
||||
|
|
|
@ -246,3 +246,55 @@ func TestPolygonIntersectsBBox(t *testing.T) {
|
|||
t.Fatal("!")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIssue241(t *testing.T) {
|
||||
g, _ := ObjectJSON(`{
|
||||
"type": "Polygon",
|
||||
"coordinates": [
|
||||
[
|
||||
[2.2571754455566406, 48.84472294197522],
|
||||
[2.252626419067383, 48.8473212003792],
|
||||
[2.2455883026123047, 48.847660093710566],
|
||||
[2.2386789321899414, 48.846022088028505],
|
||||
[2.2353315353393555, 48.842152792889486],
|
||||
[2.235288619995117, 48.83966724854628],
|
||||
[2.236189842224121, 48.836870863722986],
|
||||
[2.240910530090332, 48.83461104476972],
|
||||
[2.2461462020874023, 48.8343568087582],
|
||||
[2.2527122497558594, 48.83540199299912],
|
||||
[2.2573471069335938, 48.837746516162916],
|
||||
[2.259106636047363, 48.84003443899817],
|
||||
[2.259106636047363, 48.84302835299516],
|
||||
[2.2571754455566406, 48.84472294197522]
|
||||
],
|
||||
[
|
||||
[2.2546112537384033, 48.84285183001222],
|
||||
[2.254890203475952, 48.842774159702614],
|
||||
[2.255094051361084, 48.84197626682054],
|
||||
[2.2551369667053223, 48.84108656596295],
|
||||
[2.254589796066284, 48.8398649668164],
|
||||
[2.2528302669525146, 48.83974492367404],
|
||||
[2.2515535354614253, 48.839942641637556],
|
||||
[2.2512423992156982, 48.84047223948045],
|
||||
[2.2509634494781494, 48.841891534086436],
|
||||
[2.2513389587402344, 48.84261881872204],
|
||||
[2.2546112537384033, 48.84285183001222]
|
||||
]
|
||||
]
|
||||
}`)
|
||||
p1, _ := ObjectJSON(`{"type":"Point","coordinates":[2.253119945526123,48.841404318083505]}`)
|
||||
if g.Intersects(p1) {
|
||||
t.Fatalf("expected %v, got %v", false, g.Intersects(p1))
|
||||
}
|
||||
if g.Within(p1) {
|
||||
t.Fatalf("expected %v, got %v", false, g.Within(p1))
|
||||
}
|
||||
p2, _ := ObjectJSON(`{"type":"Point","coordinates":[2.2564244270324703,48.83788774899389]}`)
|
||||
if !g.Intersects(p2) {
|
||||
t.Fatalf("expected %v, got %v", true, g.Intersects(p2))
|
||||
}
|
||||
if !g.Within(p2) {
|
||||
t.Fatalf("expected %v, got %v", false, g.Within(p2))
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue