Conversation
Fix comments. Remove outdate maxEdgeDeviation methods. Add TODOs for a few more things to be done. Update some of the inline constant values to match the C++ values. (sqrt(2)/13 --> 0.548, etc. Remove removed methods from test.
Convert the first of the nested types from S2Builer::Graph to Go adding some unit tests.
flwyd
left a comment
There was a problem hiding this comment.
Thanks for tackling this!
s2/builder.go
Outdated
| // (including the case where there are no edges at all), then the layer | ||
| // implementation calls the given predicate to determine whether the polygon | ||
| // is empty or full except for those degeneracies. The predicate is given | ||
| // an S2Builder::Graph containing the output edges, but note that in general |
There was a problem hiding this comment.
Change :: references to Go style.
s2/builder.go
Outdated
| // or E7 lat/lng coordinates) while preserving the input topology and with | ||
| // guaranteed error bounds. | ||
| // | ||
| // 3. Simplifying geometry (e.g. for indexing, display, or storage). |
There was a problem hiding this comment.
Go doc lists need indentation before the number (this one's missing a space).
s2/builder.go
Outdated
| // builder.StartLayer(NewPolygonLayer(output)) | ||
| // builder.AddPolygon(input); | ||
| // if err := builder.Build(); err != nil { | ||
| // fmt.Printf("error building: %v\n"), err |
There was a problem hiding this comment.
Nit: misplaced closing paren
s2/builder.go
Outdated
| // | ||
| // TODO(rsned): Make the type public when Builder is ready. | ||
| type builder struct { | ||
| opts *builderOptions |
There was a problem hiding this comment.
I recognize that the C++ and Java implementations also have a mutable Options member, but this seems like a weird use of the builder pattern. Someone could change state of the options part way through using the Builder, which seems like it would make reasoning about the semantic guarantees more difficult.
It also seems kind of odd that there's a builderOptions type, but also a lot of option-like fields in the builder itself. Does the builder need to hang on to the builderOptions that was used in init, or are the derived fields sufficient?
There was a problem hiding this comment.
There seems to be only a couple places that read from it within Builder so making it non-mutable seems reasonable.
The primary use case from C++ is passing in the default options, or creating an options with an explicit snap function a la "S2Builder builder{S2Builder::Options(S2CellIdSnapFunction(snap_level))};"
s2/builder_graph_options.go
Outdated
| // to consist of four edges (two duplicate edges and their siblings), since | ||
| // only two of these four edges will be used in the final output. | ||
| // | ||
| // Furthermore, since the options REQUIRE and CREATE guarantee that all |
There was a problem hiding this comment.
Change all-caps to Go identifiers here and below.
s2/builder_graph_options.go
Outdated
| ) | ||
|
|
||
| // graphOptions is only needed by Layer implementations. A layer is | ||
| // responsible for assembling an Graph of snapped edges into the |
s2/builder_graph_options.go
Outdated
| // DEFAULT: edgeTypeDirected | ||
| edgeType edgeType | ||
|
|
||
| // DEFAULT: degenerateEdgesKeep |
There was a problem hiding this comment.
Could we make the default values the first iota value when declaring the constants?
There was a problem hiding this comment.
I've reordered all the builder enums to have the first iota value be the expected default option.
s2/builder_graph_options.go
Outdated
| // the graph passed to this layer will contain the full set of vertices. | ||
| // (This is not recommended when the number of layers could be large.) | ||
| // | ||
| // DEFAULT: true |
There was a problem hiding this comment.
Could we change the name so the default can be false, maybe disableVertexFiltering?
s2/builder_options.go
Outdated
|
|
||
| import "github.com/golang/geo/s1" | ||
|
|
||
| // polylineType Indicates whether polylines should be "paths" (which don't |
Rename edge {int, int} to graphEdge to reduce confusablilty with Shape's Edge{point, point}
In Run, fix a couple of logic errors with (x&1)+1.
Don't fail on the first error encountered in run, keep processing edges and return any/the last error encountered to follow C++'s Run().
… builder-foundations
Move the enums and option types back into their main file. (graph_options-> graph) Re-order enums to ensure the default value is first in the iota list. Rename builder variables to get rid of the CA suffix. Clean up some comments
Incorporate the comments missing on builder and graph from the Java classes. Spelling fixes.
flwyd
left a comment
There was a problem hiding this comment.
Sorry for the delayed review. FYI, I'll be OOO next week.
Since the types are package-private, let me know if there are comments you'd prefer to address after submitting this first round.
| // | ||
| // TODO(rsned): Consider pulling out the methods that are helper functions for | ||
| // Layer implementations (such as getDirectedLoops) into a builder_graph_util.go. | ||
| type graph struct { |
There was a problem hiding this comment.
In C++ this is S2Builder::Graph and in Java it's S2BuilderGraph. Does this function as a general-purpose graph, or should this be s2.BuilderGraph?
| numVertices int32 | ||
| // The vertices in this Graph. The index of a Vertex in this list is its VertexID. | ||
| vertices []Point | ||
| // The graphEdges in this Graph. The index of a graphEdge in this list is the EdgeID. |
There was a problem hiding this comment.
The constructor documentation in C++/Java wants this to be lexicographically sorted.
| } | ||
|
|
||
| // newGraph returns a new graph instance initialized with the given data. | ||
| func newGraph(opts *graphOptions, |
There was a problem hiding this comment.
Is this going to get additional logic, or would it be sufficient for callers to just initialize the struct?
| // edge pairs in several possible ways (e.g. discarding or creating them). | ||
| // The output is suitable for passing to the newGraph method. | ||
| // | ||
| // If options.edgeType == EdgeTypeUndirected, then all input edges |
There was a problem hiding this comment.
s/options/opts/ here and below.
| // centers, E7 lat/lng points on the sphere, or simply a subset of the | ||
| // input vertices), rather than being limited to an integer grid. | ||
| // | ||
| // Here are some of its other features: |
There was a problem hiding this comment.
The Java version also has some documentation about edge labels that might be worth including.
| } | ||
|
|
||
| // maxVertexID is the maximum possible vertex ID, used as a sentinel value. | ||
| const maxVertexID = int32(^uint32(0) >> 1) |
There was a problem hiding this comment.
I'm not great with bit fiddling; is this the same as math.MaxInt32?
|
|
||
| // stableLessThan compares two graphEdges for stable sorting. | ||
| // It uses the graphEdge IDs as a tiebreaker to ensure a stable sort. | ||
| func stableLessThan(a, b graphEdge, aID, bID int32) bool { |
There was a problem hiding this comment.
Might want a type-specific name to avoid package-level collisions.
|
|
||
| // graphEdge is a tuple of edge IDs. | ||
| type graphEdge struct { | ||
| first, second int32 |
There was a problem hiding this comment.
Optional: I wonder if type edgeID int32 would make things more readable, or if it would just make it harder to match the other implementations.
| func (ep *graphEdgeProcessor) handleDegenerateEdge(edge graphEdge, outBegin, outEnd int, nOut, nIn, inBegin, in int) error { | ||
| // This is a degenerate edge. | ||
| if nOut != nIn { | ||
| return errors.New("inconsistent number of degenerate edges") |
There was a problem hiding this comment.
Is it worth including the counts?
| // This makes it easier to write algorithms that gather the output graphs | ||
| // from several layers and process them all at once (such as | ||
| // closedSetNormalizer). | ||
| Build(g *graph) (bool, error) |
There was a problem hiding this comment.
Document the meaning of the returned boolean.
Add the types in the builder system (graph, layer, various options and enums). The types are all set as package private for now so no one can use them until they are ready.
Add all the comments and documentation for the above.
Add Builder::Graph's EdgeProcessor embedded type and tests.
Next up will be working through Graphs other types like PolylineBuilder and its various methods.