golang / geo Goto Github PK
View Code? Open in Web Editor NEWS2 geometry library in Go
License: Apache License 2.0
S2 geometry library in Go
License: Apache License 2.0
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.
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.
It seems that VertexNeighbors
should be CommonAncestorLevel
.
Lines 544 to 546 in ff7962d
Cell.Edge returns edge from vertex 3 to vertex 0 if k >= 3, documentation claim:
edge from vertex k to vertex k+1 (mod 4)
switch should be switch k%4 {
or switch k&0x03 {
https://github.com/golang/geo/blob/master/s2/cell.go#L78
Hi,
what is the recommended way to find two polylines (intersecting each other) are in same direction.
Is there any function written for it?
Line 25 in f41920e
E7 of 3.1 Degree is
31000000, not
310000000
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.
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:
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.
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!
Hi,
i have case that performance using CapBound is in times slower compared to suggested replacement.
Line 91 in fb250ae
// 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
}
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)
CellID.Pos()
conversion to float64
will never overflow?Its fixed there : a9db021
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? :)
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
➜ Downloads go version
go version go1.9 linux/amd64
Some of our tests which call regionCoverer.Covering
on a s2.Loop
are returning different results (different cells in CellUnion) after upgrading to go 1.9
.
This is where the call is made from https://github.com/dgraph-io/dgraph/blob/master/types/s2index.go#L208
Has there been some change in Go v1.9 which could have caused this change?
The function computes the correct vertex index for loops that represent holes but returns the vertex at the original index.
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?
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
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")
}
}
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?
Line 207 in a852329
Calling .Invert
on a polygon and then calling .ContainsPoint
causes a panic (at least, when initiated using PolygonFromLoops
with a list of loops containing a single RegularLoop
, I haven't tested other ways of initiating polygons).
There is a comment[1] says that epsilon math.Nextafter(0, 1)
can handle 1-bit floating point rounding error for each endpoint, but it doesn't. math.Nextafter(1,2)-1
does handle 1-bit rounding errors.
Here's a demo: https://play.golang.org/p/F78ciwSUoI
[1] https://github.com/golang/geo/blob/master/s1/interval.go#L293-L294
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
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)
Lines 273 to 278 in d6335c7
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.
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?
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:
After read the document, I had not found the function which count the distance between two point. Can some one tell me? Thanks
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?
I'm really interested in the S2 library for go. Based on some blog posts I have been playing with some code at https://github.com/OpenCoreData/ocdGarden/blob/master/s2test/main.go
Been making more questions than progress it seems. :)
Is there a Google Group or a slack channel or something where people can go to get help with the S2 Golang library?
cellID := s2.CellIDFromToken("c004")
cell := s2.CellFromCellID(cellID)
cell.RectBound() # panic: runtime error: index out of range [6] with length 6
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.
In cellid.go ,faceIJOrientation() ,
Line 504 in e2863f6
I think its better using epsilon
instead of constant literal 1e-14
.
Line 177 in 5747e98
In the test file https://github.com/golang/geo/blob/master/s2/polyline_test.go#L152, it defines the polyline like shown in the image:
coordinates are: "0:0, 0:1, -1:2, 0:3, 0:4, 1:4, 2:4.5, 3:4, 3.5:4, 4:4"
Even with tolerance 3 degrees, we get only the first and last:
{
have: polyStr,
tolerance: 3.0,
want: []int{0, 9},
},
In my understanding the angles are way bigger than 5 degrees?
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.
then, why not define:
func SimpleCrossing(a, b, c, d Point) bool {
return CrossingSign(a,b,c,d) == Cross
}
for backward compatibility ?
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.
Is there a world in which we can merge https://github.com/davidreynolds/gos2? It adds RegionCoverer, completes the implementation of Region
on Cap
, CellUnion
, and Rect
. It's well tested and I am currently using it in production with no problems.
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!
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
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?
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
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?
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()
There is a duplicated testcase on ChordAngle. I doubt there might be a mistake while porting source code.
Lines 43 to 44 in 5747e98
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
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.