Git Product home page Git Product logo

geo's People

Contributors

domob1812 avatar dsymonds avatar gofz avatar keijak avatar lascap avatar nes1983 avatar rsned avatar sambeckman avatar sandesh247 avatar shishberg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

geo's Issues

[question] distance between points

I'm loving the library, really well put together!

I'd like to find the distance in meters between two points.

What did I try:

a: = s2.PointFromLatLng()
b: = s2.PointFromLatLng()
distance := a.Distance(b) // <- how do i convert this to mm/m/km

Not even sure if I'm using the correct methods.

Inconsistent result using RegionCoverer over Loop

I've come up with some results using the CellUnion method of RegionCoverer which are unexpected to me. I've created this gist to reproduce what I'm observing.

I'm basically comparing the cells covered by a Polyline containing 3 points and a Loop which is defined using the same 3 points. Using a RegionCoverer, it identifies 3 cells for the Polyline but returns an empty list of cells in the case of the Loop.

I've done some digging and although the FastCovering call identifies the same initial candidates in both cases, Loop's IntersectsCell method results in a "Disjoint" CellRelation for each of the 4 identified candidates.

I would have expected similar cells returning for both geometries or at least a non empty slice in the case of the Loop.

Typo on testcase output

It seems that VertexNeighbors should be CommonAncestorLevel.

geo/s2/cellid_test.go

Lines 544 to 546 in ff7962d

if got, ok := test.ci.CommonAncestorLevel(test.other); ok != test.wantOk || got != test.want {
t.Errorf("CellID(%v).VertexNeighbors(%v) = %d, %t; want %d, %t", test.ci, test.other, got, ok, test.want, test.wantOk)
}

polylines match

Hi,
what is the recommended way to find two polylines (intersecting each other) are in same direction.
Is there any function written for it?

Polygon Intetersection didn't work for triangle and rectangle

So I use S2.Polygon Intersects methods.

My points as a triangle and another rectangle (when drawing) have no intersection. However, the intersect methods will return true.

I put all the points inside of s2.Point and construct loop using list of s2.point and construct polygon using list of loop. Could some one tell me if I use them wrong or if the algorithm has some problems.

S2: Regioncoverer slightly intersecting another face doesn't cover whole region

I created a regioncoverer from a rectangle as following:

var regionCoverer s2.RegionCoverer

regionCoverer.MaxCells = 10000
regionCoverer.MinLevel = 7
regionCoverer.MaxLevel = 7

topleft := s2.LatLngFromDegrees(72.0000064, -141.0000000)
topright := s2.LatLngFromDegrees(72.0000064, -55.6152420)
bottomleft := s2.LatLngFromDegrees(41.9017143, -141.0000000)
bottomright := s2.LatLngFromDegrees(41.9017143, -55.6152420)

rect = s2.Rect{}
rect = rect.AddPoint(bottomleft)
rect = rect.AddPoint(bottomright)
rect = rect.AddPoint(topright)
rect = rect.AddPoint(topleft)

covering := regionCoverer.Covering(s2.Region(rect))

The result is not 100% what I was expecting. A cellUnion of CellID's covering the whole rectangle should be the result but the small part of the rectangle that lies on a different face does not get any cellID's returned for it. I visualized all cell's in QGIS so that you can see what I mean:

Image of  regioncoverer error

The part where it looks like somebody took a bite out of it lies on a different face (face 4 vs. face 2).

Slightly lowering the bottomleft and bottomright latitude solves the problem.

math/bits benchmarks

Hey all. I recently opened a pull request that removed some of the redundancies with Go 1.9's math/bits package. Addressing some of the feedback there, I've written a few benchmarks to demonstrate that there is indeed a performance improvement to be had by moving to this implementation.

https://github.com/topos-ai/go-s2bits

goos: darwin
goarch: amd64
pkg: github.com/topos-ai/go-s2bits
BenchmarkS2CellIDLevel/30-4         	2000000000	         1.03 ns/op
BenchmarkS2CellIDLevel/29-4         	2000000000	         1.04 ns/op
BenchmarkS2CellIDLevel/28-4         	2000000000	         1.05 ns/op
BenchmarkS2CellIDLevel/27-4         	2000000000	         1.05 ns/op
BenchmarkS2CellIDLevel/26-4         	2000000000	         1.04 ns/op
BenchmarkS2CellIDLevel/25-4         	2000000000	         1.04 ns/op
BenchmarkS2CellIDLevel/24-4         	2000000000	         1.04 ns/op
BenchmarkS2CellIDLevel/23-4         	2000000000	         1.04 ns/op
BenchmarkS2CellIDLevel/22-4         	2000000000	         1.04 ns/op
BenchmarkS2CellIDLevel/21-4         	2000000000	         1.04 ns/op
BenchmarkS2CellIDLevel/20-4         	2000000000	         1.04 ns/op
BenchmarkS2CellIDLevel/19-4         	2000000000	         1.04 ns/op
BenchmarkS2CellIDLevel/18-4         	2000000000	         1.04 ns/op
BenchmarkS2CellIDLevel/17-4         	2000000000	         1.04 ns/op
BenchmarkS2CellIDLevel/16-4         	2000000000	         1.03 ns/op
BenchmarkS2CellIDLevel/15-4         	2000000000	         1.04 ns/op
BenchmarkS2CellIDLevel/14-4         	2000000000	         1.04 ns/op
BenchmarkS2CellIDLevel/13-4         	2000000000	         1.04 ns/op
BenchmarkS2CellIDLevel/12-4         	2000000000	         1.05 ns/op
BenchmarkS2CellIDLevel/11-4         	2000000000	         1.03 ns/op
BenchmarkS2CellIDLevel/10-4         	2000000000	         1.03 ns/op
BenchmarkS2CellIDLevel/9-4          	2000000000	         1.04 ns/op
BenchmarkS2CellIDLevel/8-4          	2000000000	         1.05 ns/op
BenchmarkS2CellIDLevel/7-4          	2000000000	         1.03 ns/op
BenchmarkS2CellIDLevel/6-4          	2000000000	         1.03 ns/op
BenchmarkS2CellIDLevel/5-4          	2000000000	         1.04 ns/op
BenchmarkS2CellIDLevel/4-4          	2000000000	         1.02 ns/op
BenchmarkS2CellIDLevel/3-4          	2000000000	         1.02 ns/op
BenchmarkS2CellIDLevel/2-4          	2000000000	         1.03 ns/op
BenchmarkS2CellIDLevel/1-4          	2000000000	         1.03 ns/op
BenchmarkS2CellIDLevel/0-4          	2000000000	         1.04 ns/op
BenchmarkCellIDLevel/30-4           	2000000000	         0.35 ns/op
BenchmarkCellIDLevel/29-4           	2000000000	         0.36 ns/op
BenchmarkCellIDLevel/28-4           	2000000000	         0.34 ns/op
BenchmarkCellIDLevel/27-4           	2000000000	         0.34 ns/op
BenchmarkCellIDLevel/26-4           	2000000000	         0.35 ns/op
BenchmarkCellIDLevel/25-4           	2000000000	         0.35 ns/op
BenchmarkCellIDLevel/24-4           	2000000000	         0.34 ns/op
BenchmarkCellIDLevel/23-4           	2000000000	         0.35 ns/op
BenchmarkCellIDLevel/22-4           	2000000000	         0.34 ns/op
BenchmarkCellIDLevel/21-4           	2000000000	         0.35 ns/op
BenchmarkCellIDLevel/20-4           	2000000000	         0.35 ns/op
BenchmarkCellIDLevel/19-4           	2000000000	         0.35 ns/op
BenchmarkCellIDLevel/18-4           	2000000000	         0.34 ns/op
BenchmarkCellIDLevel/17-4           	2000000000	         0.35 ns/op
BenchmarkCellIDLevel/16-4           	2000000000	         0.34 ns/op
BenchmarkCellIDLevel/15-4           	2000000000	         0.34 ns/op
BenchmarkCellIDLevel/14-4           	2000000000	         0.35 ns/op
BenchmarkCellIDLevel/13-4           	2000000000	         0.34 ns/op
BenchmarkCellIDLevel/12-4           	2000000000	         0.35 ns/op
BenchmarkCellIDLevel/11-4           	2000000000	         0.35 ns/op
BenchmarkCellIDLevel/10-4           	2000000000	         0.34 ns/op
BenchmarkCellIDLevel/9-4            	2000000000	         0.35 ns/op
BenchmarkCellIDLevel/8-4            	2000000000	         0.34 ns/op
BenchmarkCellIDLevel/7-4            	2000000000	         0.35 ns/op
BenchmarkCellIDLevel/6-4            	2000000000	         0.34 ns/op
BenchmarkCellIDLevel/5-4            	2000000000	         0.35 ns/op
BenchmarkCellIDLevel/4-4            	2000000000	         0.35 ns/op
BenchmarkCellIDLevel/3-4            	2000000000	         0.34 ns/op
BenchmarkCellIDLevel/2-4            	2000000000	         0.35 ns/op
BenchmarkCellIDLevel/1-4            	2000000000	         0.35 ns/op
BenchmarkCellIDLevel/0-4            	2000000000	         0.35 ns/op
PASS
ok  	github.com/topos-ai/go-s2bits	90.225s

Understanding that the maintainers of this library want to continue to support Go 1.8, I'm adding this as an issue that can be referenced in the future.

Thanks!

returned cap from CapBound for Polyline is too big

Hi,
i have case that performance using CapBound is in times slower compared to suggested replacement.

func (p *Polyline) CapBound() Cap {

Please change from

// CapBound returns the bounding Cap for this Polyline.
func (p *Polyline) CapBound() Cap {
	return p.RectBound().CapBound()
}

to

// CapBound returns the bounding Cap for this Polyline.
func (p *Polyline) CapBound() Cap {
	c := s2.EmptyCap()
	for _, v := range *p {
		c.AddPoint(v)
	}
	return c
}

Question: Overflow converting `CellID.Pos()` to float64 is possible?

Hi

I have to convert the latlongs of a polyline into list of s2CellId Pos(uint64) and store the POS() value in redis as sorted set(which needs value as float64)
Now I am a bit afraid of overflow while converting POS from uint64 to float64 because below code overflows -

	numUint64 := math.MaxUint64
	numFloat64 := float64(numUint64)

However, the documentation of CellID.Pos() confirms the range as [0,2^posBits-1].
If we calculate, posBits = 2<<maxLevel + 1, given maxLevel = 30 below code works fine without overflow.

        posBits := (2<<30+1) - 1
	floatEq := float64(posBits)

Now, is it safe to say CellID.Pos() conversion to float64 will never overflow?

Polyline intersection

As already highlighted in #44 - there are quite a few C++ boolean functions missing from this port. e.g. one that I was looking at right now was Polyline intersecting another Polyline(and others soon)

I see the following:

// TODO(roberts): Differences from C++.
// Suffix
// Interpolate/UnInterpolate
// Intersects(Polyline) --> One I am interested in 

Do we have a list of all remaining tasks? Is anyone actively working on them? Or, is there any rough timeline of when we plan to add these features? :)

SimpleCrossing: differences from C++ tests

I noticed a difference in the expected behavior of SimpleCrossing between the C++ and Go version of this library.

C++ test is here: https://code.google.com/p/s2-geometry-library/source/browse/geometry/s2edgeutil_test.cc#85
Go test: https://github.com/golang/geo/blob/master/s2/edgeutil_test.go#L48

The C++ test expects true while the go code expects false. I noticed similar behavior with the same test while trying to implement and test RobustCrossing.

Is this a bug in the go library or a change in behavior at edge conditions in the RobustSign function?

The go test for RobustCrossing here: https://github.com/rlmcpherson/geo/blob/master/s2/edgeutil_test.go#L233

ShapeIndex Questions

Hello @rsned
Are all index query-methods thread safe?
Is it possible to add a method to force build of an index? Can I make a pull request?

Inconsistency in ContainsPoint implementation from f65fe01

Commit f65fe01 added several method implementations to s2's Loop structure, such that it now fully implements the Region interface. This commit also included a modification to Loop's ContainsPoint method, splitting the implementation into cases by number of vertices in the Loop. This implementation change introduced situations where results returned by ContainsPoint and bruteForceContainsPoint may disagree.

The method bruteForceContainsPoint is equivalent to the ContainsPoint implementation from previous commits. In new versions, bruteForceContainsPoint is only invoked if the Loop has less than 32 vertices. I'll provide a bit more discussion about isolating the issue, and the bottom of this message contains a test case which shows that bruteForceContainsPoint may sometimes disagree with the new implementation of ContainsPoint.

The precise issue with ContainsPoint appears to be a false negative. It occurs when using the LocatePoint method of an iterator. To recreate the error reporting, consider the following code snippet adapted from the implementation of ContainsPoint

/// ^^^^ omitted code ^^^^^

// For small loops, and during initial construction, it is faster to just
// check all the crossing.
const maxBruteForceVertices = 32
if len(l.vertices) < maxBruteForceVertices || l.index == nil {
	return l.bruteForceContainsPoint(p)
}

// Otherwise, look up the point in the index.
it := l.index.Iterator()
if !it.LocatePoint(p) {
	//>>>>>>> begin added code
	if l.bruteForceContainsPoint(p) {
		// Error reporting can go here:
		// bruteForceContainsPoint would return true, but if
		// we are at this point in the function, then
		// LocatePoint would have caused a false result
	}
	//>>>>>> end of added code
	return false
}
return l.iteratorContainsPoint(it, p)

/// vvv code continues below vvv

This is how I was able to isolate the issue. I added similar print/error checking statements to the line

return l.iteratorContainsPoint(it, p)

but I encountered no situations where this caused an error.

As promised, here is a test case which can be added to loop_test.go to provide a failure. Some remarks

  • The vectors look pretty lamentable; they were extracted with a crude print/panic statement inserted as suggested in the snippet above, and the error occurred at some point in the code where the points in the loop had already been normalized to unit length.
  • This example was originally 41 lines long, but I commented some out to make the example smaller while allowing the test to still fail. Of course it is still very unwieldy, and it may be possible to isolate the issue to a more manageable size by (temporarily) writing a separate "contains point"-esque method for Loop which avoids the call to bruteForceContainsPoint, regardless of the loop size.
     func TestLoopAgreesBrute(t *testing.T) {
     	failLoop := LoopFromPoints([]Point{
     		Point{r3.Vector{0.165641708683984922867438, -0.682335499717461102520133, 0.712026045990996392376360}},
     		Point{r3.Vector{0.166979327473334382414549, -0.682904418669755708393154, 0.711167673026464219887544}},
     		Point{r3.Vector{0.170033862370230215432798, -0.684512796839880532928646, 0.708894009432937788339757}},
     		Point{r3.Vector{0.173220846601894046257186, -0.686324802909040188048095, 0.706365913117550037192416}},
     		Point{r3.Vector{0.174132592687058745939410, -0.685648723780406754713113, 0.706798180347390614386427}},
     		Point{r3.Vector{0.174311093817664880534224, -0.685348749932649936589257, 0.707045071786688406056953}},
     		Point{r3.Vector{0.174788277726536822598291, -0.684972450974164481785067, 0.707291877074688768445299}},
     		Point{r3.Vector{0.175010683840933378707660, -0.684597055988098723844359, 0.707600262488615072697939}},
     		Point{r3.Vector{0.178440325586863041129604, -0.682113826909010900756414, 0.709140167628373951913545}},
     		Point{r3.Vector{0.178421498442325326960756, -0.681798846893779120215129, 0.709447743859904389474025}},
     		Point{r3.Vector{0.177363651320893683793756, -0.680666029071524625315703, 0.710799473872992471079613}},
     		Point{r3.Vector{0.178797103397320800155512, -0.679841802240863102291257, 0.711229020599288497272994}},
     		Point{r3.Vector{0.179208354282632764675753, -0.679476714451123453564207, 0.711474356722725964630172}},
     		Point{r3.Vector{0.179160846488811170695854, -0.679296586466655694103167, 0.711658301925974789980955}},
     		Point{r3.Vector{0.177754755617451076776803, -0.677801803870706653931677, 0.713433922325674485520608}},
     		Point{r3.Vector{0.177407707407642972752271, -0.677442089150445014844593, 0.713861836211913458605238}},
     		Point{r3.Vector{0.177198812539136635324510, -0.677367964597019756034513, 0.713984048401930637695045}},
     		Point{r3.Vector{0.176713912637369380265184, -0.677687776492058135957564, 0.713800721962119077979025}},
     		Point{r3.Vector{0.175562077462614568590382, -0.678115763127744464178193, 0.713678477155285651001293}},
     		Point{r3.Vector{0.174399255619088117130744, -0.678994258659042504433501, 0.713128106547179396734748}},
     		Point{r3.Vector{0.173303962271755457313915, -0.679403082290932269771133, 0.713005742217052929099452}},
     		Point{r3.Vector{0.173112863740829431291601, -0.679644400955237593109359, 0.712822154999159129928898}},
     		Point{r3.Vector{0.173070942545166334136653, -0.679975956971311856769091, 0.712516067739862535290740}},
     		Point{r3.Vector{0.172611481966008672994661, -0.680156883220664032485558, 0.712454834007777759730118}},
     		Point{r3.Vector{0.172375750124909493665726, -0.680473171917579389145203, 0.712209844827564220182126}},
     		Point{r3.Vector{0.172406271752544054676193, -0.680593659565949526957240, 0.712087317692862931117759}},
     		Point{r3.Vector{0.172036150809872556699531, -0.680879570099696906915199, 0.711903486320564882205986}},
     		Point{r3.Vector{0.170830245913837386328993, -0.680606447647954415636207, 0.712454834007777759730118}},
     		Point{r3.Vector{0.170650943370862256953657, -0.680394989174694653222275, 0.712699736377530812525549}},
     		Point{r3.Vector{0.170055147795025896062526, -0.680031099872446809229132, 0.713189280566303929198568}},
     		Point{r3.Vector{0.169624646201347706320206, -0.680074463704104847927567, 0.713250449154181564992427}},
     		Point{r3.Vector{0.168510702717778293457940, -0.679902327040342591146782, 0.713678477155285651001293}},
     		// Point{r3.Vector{0.167012134825664543269497, -0.680207855705349917485592, 0.713739602276421192250666}},
     		// Point{r3.Vector{0.166730147144508150658382, -0.680341156537279445615241, 0.713678477155285651001293}},
     		// Point{r3.Vector{0.166537056793038762414483, -0.680580777692820770852222, 0.713495069183906371890203}},
     		// Point{r3.Vector{0.166566405708508558092262, -0.680958101605218635299366, 0.713128106547179396734748}},
     		// Point{r3.Vector{0.166046269466772172807012, -0.681149171530156971599013, 0.713066927097273817182099}},
     		// Point{r3.Vector{0.165986282410054197811178, -0.681419936158346062349267, 0.712822154999159129928898}},
     		// Point{r3.Vector{0.165539070261747467416313, -0.681912696549804686618756, 0.712454834007777759730118}},
     		// Point{r3.Vector{0.165464015353066290492379, -0.682122818382738138609511, 0.712271100259466050097501}},
     		// Point{r3.Vector{0.165641708683984922867438, -0.682335499717461102520133, 0.712026045990996392376360}},
     	})
     
     	failPt := Point{r3.Vector{0.171317369856565732133546, -0.681796830037278533964695, 0.711198594864013489136312}}
     
     	if failLoop.ContainsPoint(failPt) != failLoop.bruteForceContainsPoint(failPt) {
     		t.Errorf("ContainsPoint should coincide with bruteForceContainsPoint")
     	}
     
     }

Don't Swallow Error on Loop Validity

Ran into an issue with a degenerate loop yesterday and found myself having to edit source code to show me useful errors for what was causing it to be invalid. Seems like there's a perfectly reasonable place to return a useful error here rather than swallow it, wonder if this is something that can be looked at?

geo/s2/loop.go

Line 207 in a852329

func (l *Loop) IsValid() bool {

Deadlock during call to ShapeIndex.Iterator()

This is the call chain for (s *ShapeIndex)

Call to s.Iterator
--> s.maybeApplyUpdates()
  --> Acquires s.mu.Lock()
    --> s.applyUpdatesInternal()
      --> s.updateFaceEdges()
        --> s.skipCellRange()
          --> s.updateEdges()
            --> s.Iterator()
              --> s.maybeApplyUpdates()
                --> Tries to acquire s.mu.Lock() --> DEADLOCK

I'm using version v0.0.0-20200319012246-673a6f80352d

stuv_test.go: dead test code

There's dead test code on stuv_test.go [1]

siRandom and tiRandom is initialized to zero, siRandom > maxSiTi || tiRandom > maxSiTi is always false, therefore siRandom and tiRandom will be always zero for the testcase.

Here's simple fix.

siRandom = uint64(maxSiTi)
tiRansom = uint64(maxSiTi)

geo/s2/stuv_test.go

Lines 273 to 278 in d6335c7

var siRandom, tiRandom uint64
mask := -1 << uint64(maxLevel-level)
for siRandom > maxSiTi || tiRandom > maxSiTi {
siRandom = uint64(randomUint32() & uint32(mask))
tiRandom = uint64(randomUint32() & uint32(mask))
}

CellUnion.Intersects gives incorrect results

Currently, CellUnion.Intersects is implemented in terms of CellUnion.ContainsCellID. It should be implemented in terms of CellUnion.IntersectsCellID, as it is in the C++ library. With the current implementation, the method gives wrong results.

Loop edge self intersection not detected

From the s2geometry.io docs (emphasis mine):

Loops are not allowed to have any duplicate vertices (whether adjacent or not), and non-adjacent edges are not allowed to intersect. Loops must have at least 3 vertices (except for the “empty” and “full” loops discussed below). These restrictions make it possible to implement exact polygon-polygon containment and intersection tests very efficiently. See S2Builder if your data does not meet these requirements.

Whereas running this sample code does not return an error although the second and last (i.e. implicit) edges intersect

package main

import (
	"log"
	"github.com/golang/geo/s2"
)

func main() {
	vertices := [][]float64{{0, 0}, {0, 1}, {1, 0}, {1, 1}}
	pnts := []s2.Point{}
	for _, v := range vertices {
		ll := s2.LatLngFromDegrees(v[1], v[0])
		pnts = append(pnts, s2.PointFromLatLng(ll))
	}
	loop := s2.LoopFromPoints(pnts)
	err := loop.Validate()
	if err != nil {
		log.Printf("loop validate: %v", err)
	} else {
		log.Printf("all ok")
	}
}

Is this the expected behavior?

Inverted Loops don't contain expected Points

This issue might just be me not understanding the semantics of this library's Loop.Invert function, but my expectation is that a Loop which doesn't contain a Point p should then contain p when it is .Invert'ed. This is not currently the case in this library.

I've put together a small playground demonstrating this behaviour below:

https://play.golang.org/p/1touvyS49sE

NewClosestEdgeQuery problem

Hello @rsned

I use your golang package for finding the nearest polygon from geo point & i try to make it following this:

index := s2.NewShapeIndex()

// More than 4000 polygons of cities added to index
// ...

q := s2.NewClosestEdgeQuery(index, s2.NewClosestEdgeQueryOptions().MaxResults(1).IncludeInteriors(true))
target := s2.NewMinDistanceToPointTarget(s2.PointFromLatLng(s2.LatLngFromDegrees(40.853544, -73.099544)))
res := q.FindEdges(target)

I've got a problem, the method's implementation time is about 30 sec which is quite slow.
Maybe i did smth wrong or it is an expected result?
if I exactly did smth wrong, could you please tell me how to realize it in a right way?

Implement Polygon.Intersection

Since it seems acceptable to use this space to indicate interest in specific features, I would like to request polygon intersections. The Go language currently lacks a high quality library for boolean operations on geographic features, and having one would help me out greatly. (I am one of the maintainers of a low-to-medium quality library.) I greatly appreciate all the work that has happened so far to port this library to Go.

I have a question about code

In cellid.go ,faceIJOrientation() ,

if ci.lsb()&0x1111111111111110 != 0 {
, I do not understand why we should add this judgment -- ci.lsb()&0x1111111111111110 != 0 ? I think faceIJOrientation and cellIDFromFaceIJ reverse each other, but faceIJOrientation have one more calculation of orientation than cellIDFromFaceIJ . Can you help me answer my doubts , why add 504 line's judgment ? (I think for a long time, really did not figure out here)

cell containment discrepancy

There isn't agreement between the Cell, Loop, and Polygon implementations of ContainsCell as required by the Region interface.

testRegions := []s2.Region{
	cell, // s2.Cell
	s2.LoopFromCell(cell),
	s2.PolygonFromCell(cell),
}

for _, region := range testRegions {
	fmt.Println(region.ContainsCell(cell))
}

// true
// false
// false

I don't know whether or not this is intentional, but the discrepancy seems related to whether or not regions can be said to contain cells with which they share an edge.

Coverer.CellUnion(Point) can have multiple cells?

In S2, in some cases, a Coverer.CellUnion() of a Point can contain two cells. Is that the correct behavior? If so, what's the story?

Example:

package main

import (
	"fmt"

	"github.com/golang/geo/s2"
)

func main() {
	var (
		level   = 7
		coverer = s2.RegionCoverer{
			MinLevel: level,
			MaxLevel: level,
		}
		ll    = s2.LatLng{Lat: -0.8248776721189366, Lng: -2.038611228784389}
		p     = s2.PointFromLatLng(ll)
		union = coverer.CellUnion(p)
	)
	fmt.Println(len(union))
}

At the playground.

Radian == 57.2957795 ?

Hello,

I am encountering a confusing issue. s1.Radian is clearly defined as 1, but when I print it from within a program it equals 57.2957795 and s1.Degree equals 1.

Any ideas what the issue could be, or what I'm misunderstanding here?

$ cat example.go 
package main

import(
"fmt"
"github.com/golang/geo/s1"
)

func main() {
fmt.Println(s1.Radian)
}

$ go mod init example
go: creating new go.mod: module example

$ go run example.go 
go: finding module for package github.com/golang/geo/s1
go: found github.com/golang/geo/s1 in github.com/golang/geo v0.0.0-20200319012246-673a6f80352d
57.2957795

$ go version
go version go1.14.2 linux/amd64

Thanks!

Polygon and RegionCoverer not working

Hello

I created a polygon/triangle by using LoopFromPoints() and PolygonFromLoops() with 1 loop and tried to get the cells by using RegionCoverer() and SimpleRegionCovering(). Unfortunately it isn't working, the result: 6.3 Mio. level 13 cells. Expected result: 2

It works fine by using 3 polylines though.

The check polygon.ContainsPoint() fails as well for a given point, which should be inside the polygon.

It seems the problem is similar to #29.

I'm using go1.11 on MacOS 10.14.3.

Regards
Alex

Loop.Intersects gives incorrect results

I have two geojson objects
Polygon 1:
[[[-74.93335056304832,39.283340980346445],
[-74.93335056305031,40.30000217770297],
[-75.91667795181374,40.30000217770097],
[-75.91667795181175,40.28334098034444],
[-74.93335056304832,39.283340980346445]]]
Polygon 2:
[[[-74.3122237229173, 39.9541747627284],
[-74.1955570274039, 40.0833414585103],
[-74.5497238128233, 40.1958414684098],
[-74.7163905245327, 40.0583414352459],
[-74.8663905578957, 39.8208413826612],
[-74.4163904122584,39.7708413884741],
[-74.3122237229173, 39.9541747627284]]]

I converted [][][]float64 array to Loop using Function:
func convertFloatListToPolygon(floatList [][][]float64) *s2.Loop {
points := floatList[0]
pointList := make([]s2.Point, 0)
for _, point := range points {
s2Point := s2.PointFromLatLng(
s2.LatLng{
Lat:s1.Angle(point[1]), Lng:s1.Angle(point[0]), }) pointList = append(pointList, s2Point) } return s2.LoopFromPoints(pointList) }`

poly = convertFloatListToPolygon(p1)
comparedPoly = convertFloatListToPolygon(p2)
poly.Intersects(comparedPoly)

The results is true. However, when I draw those two polygon in geojson.io, it's not intersected.

Could someone tell me if I use function wrong or there is a bug in intersection?

Strange results

Hi,

just realized that LatLngFromDegrees does not convert argumens:

package main
import (
    "fmt"
    "github.com/golang/geo/s2"
    "github.com/golang/geo/s1"
)

func main() {
    fmt.Println(  s1.Degree, float64(s1.Degree), s2.LatLngFromDegrees(1, 1))  
}

result:

1.0000000 0.017453292519943295 [1.0000000, 1.0000000]

go version
go version go1.6 linux/amd64

go compiled from source

Support for Polygon Contains and Intersects method

I wanted to check if its possible to add support for Contains/Intersects for Polygon. Since the library doesn't yet support those methods for Polygon/MultiPolygon we just use the outer s2.Loop and do Intersects/Contains using that. That is error prone because it ignores the holes in the polygon.

If it's not very complicated then I could try porting them over from the C++ library and send over a PR?

Is the `.id()` equivalent in s2geometry-node equivalent to `.pos()`

I'm trying to use this package for a project over s2geometry-node

Which has this:

var origin = new s2.S2CellId(new s2.S2LatLng(lat, lng)).parent(15);
var walk = [origin.id()];

Which does this: https://github.com/billyriantono/s2geometry-node/blob/master/API.md#cellidid---number

I'm trying to achieve similar results by doing:

ll := s2.LatLngFromDegrees(location.Latitude, location.Longitude)
cid := s2.CellIDFromLatLng(ll).Parent(15)
cid.Pos()

Status and what's missing.

Hej Devs,
I am wondering what are the plans for this repo.

I'd be more than willing to collaborate and bring it up (feature wise to the c++ lib), but I'd love some guidance :D

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.