Skip to content
Open
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module github.com/golang/geo
module github.com/marco709394/geo

go 1.12
27 changes: 25 additions & 2 deletions s2/contains_point_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,32 @@ func (q *ContainsPointQuery) Contains(p Point) bool {

cell := q.iter.IndexCell()
for _, clipped := range cell.shapes {
if q.shapeContains(clipped, q.iter.Center(), p) {
if q.shapeContains(clipped, q.iter.Center(), p) &&
q.index.Shape(clipped.shapeID) != nil {
return true
}
}
return false
}

// Contains reports whether any shape in the queries index contains the point p
// under the queries vertex model (Open, SemiOpen, or Closed).
func (q *ContainsPointQuery) ContainingShapeIds(p Point) []int32 {
ids := make([]int32, 0)
if !q.iter.LocatePoint(p) {
return ids
}

cell := q.iter.IndexCell()
for _, clipped := range cell.shapes {
if q.shapeContains(clipped, q.iter.Center(), p) &&
q.index.Shape(clipped.shapeID) != nil {
ids = append(ids, clipped.shapeID)
}
}
return ids
}

// shapeContains reports whether the clippedShape from the iterator's center position contains
// the given point.
func (q *ContainsPointQuery) shapeContains(clipped *clippedShape, center, p Point) bool {
Expand All @@ -92,6 +111,10 @@ func (q *ContainsPointQuery) shapeContains(clipped *clippedShape, center, p Poin
}

shape := q.index.Shape(clipped.shapeID)
if shape == nil {
return false
}

if shape.Dimension() != 2 {
// Points and polylines can be ignored unless the vertex model is Closed.
if q.model != VertexModelClosed {
Expand Down Expand Up @@ -187,4 +210,4 @@ func (q *ContainsPointQuery) ContainingShapes(p Point) []Shape {

// TODO(roberts): Remaining methods from C++
// type edgeVisitorFunc func(shape ShapeEdge) bool
// func (q *ContainsPointQuery) visitIncidentEdges(p Point, v edgeVisitorFunc) bool
// func (q *ContainsPointQuery) VisitIncidentEdges(p Point, v edgeVisitorFunc) bool
18 changes: 18 additions & 0 deletions s2/polyline.go
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,24 @@ func (p *Polyline) Interpolate(fraction float64) (Point, int) {
return (*p)[len(*p)-1], len(*p)
}

func (p *Polyline) UnInterpolate(target Point) (float64, int) {
point, vertex := p.Project(target)
if vertex == len(*p) {
return 1, vertex
}

var length, totalLength s1.Angle
for i := 1; i < len(*p); i++ {
totalLength += (*p)[i-1].Distance((*p)[i])
if i < vertex {
length = totalLength
} else if i == vertex {
length += point.Distance((*p)[i-1])
}
}
return float64(length / totalLength), vertex
}

// TODO(roberts): Differences from C++.
// UnInterpolate
// NearlyCoversPolyline
Expand Down
34 changes: 25 additions & 9 deletions s2/shapeindex.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ const (
IteratorBegin ShapeIndexIteratorPos = iota
// IteratorEnd specifies the iterator should be positioned at the end of the index.
IteratorEnd
// IteratorUnpositioned specifies the iterator position is not changed.
IteratorUnpositioned
)

// ShapeIndexIterator is an iterator that provides low-level access to
Expand Down Expand Up @@ -223,6 +225,7 @@ func NewShapeIndexIterator(index *ShapeIndex, pos ...ShapeIndexIteratorPos) *Sha
s.Begin()
case IteratorEnd:
s.End()
case IteratorUnpositioned:
default:
panic("unknown ShapeIndexIteratorPos value")
}
Expand Down Expand Up @@ -535,7 +538,14 @@ func (t *tracker) restoreStateBefore(limitShapeID int32) {

// lowerBound returns the shapeID of the first entry x where x >= shapeID.
func (t *tracker) lowerBound(shapeID int32) int32 {
panic("not implemented")
pos := 0
for _, id := range t.shapeIDs {
if id >= shapeID {
break
}
pos++
}
return int32(pos)
}

// removedShape represents a set of edges from the given shape that is queued for removal.
Expand Down Expand Up @@ -737,9 +747,15 @@ func (s *ShapeIndex) Remove(shape Shape) {
// The index updates itself lazily because it is much more efficient to
// process additions and removals in batches.
id := s.idForShape(shape)
if id < 0 {
return
}
s.RemoveById(id)
}

// If the shape wasn't found, it's already been removed or was not in the index.
if s.shapes[id] == nil {
func (s *ShapeIndex) RemoveById(id int32) {
shape, exist := s.shapes[id]
if !exist {
return
}

Expand All @@ -757,7 +773,7 @@ func (s *ShapeIndex) Remove(shape Shape) {
shapeID: id,
hasInterior: shape.Dimension() == 2,
containsTrackerOrigin: shape.ReferencePoint().Contained,
edges: make([]Edge, numEdges),
edges: make([]Edge, numEdges),
}

for e := 0; e < numEdges; e++ {
Expand Down Expand Up @@ -824,7 +840,7 @@ func (s *ShapeIndex) applyUpdatesInternal() {
s.removeShapeInternal(p, allEdges, t)
}

for id := s.pendingAdditionsPos; id < int32(len(s.shapes)); id++ {
for id := s.pendingAdditionsPos; id < s.nextID; id++ {
s.addShapeInternal(id, allEdges, t)
}

Expand All @@ -833,7 +849,7 @@ func (s *ShapeIndex) applyUpdatesInternal() {
}

s.pendingRemovals = s.pendingRemovals[:0]
s.pendingAdditionsPos = int32(len(s.shapes))
s.pendingAdditionsPos = s.nextID
// It is the caller's responsibility to update the index status.
}

Expand Down Expand Up @@ -952,7 +968,7 @@ func (s *ShapeIndex) shrinkToFit(pcell *PaddedCell, bound r2.Rect) CellID {
if !s.isFirstUpdate() && shrunkID != pcell.CellID() {
// Don't shrink any smaller than the existing index cells, since we need
// to combine the new edges with those cells.
iter := s.Iterator()
iter := NewShapeIndexIterator(s, IteratorUnpositioned)
if iter.LocateCellID(shrunkID) == Indexed {
shrunkID = iter.CellID()
}
Expand Down Expand Up @@ -1006,7 +1022,7 @@ func (s *ShapeIndex) updateEdges(pcell *PaddedCell, edges []*clippedEdge, t *tra
// There may be existing index cells contained inside pcell. If we
// encounter such a cell, we need to combine the edges being updated with
// the existing cell contents by absorbing the cell.
iter := s.Iterator()
iter := NewShapeIndexIterator(s, IteratorUnpositioned)
r := iter.LocateCellID(pcell.id)
if r == Disjoint {
disjointFromIndex = true
Expand Down Expand Up @@ -1189,7 +1205,7 @@ func (s *ShapeIndex) makeIndexCell(p *PaddedCell, edges []*clippedEdge, t *track
eshapeID := int32(s.Len())
cshapeID := eshapeID // Sentinels

if eNext != len(edges) {
if eNext < len(edges) {
eshapeID = edges[eNext].faceEdge.shapeID
}
if cNextIdx < len(cshapeIDs) {
Expand Down