Skip to content

Builder foundation work #182

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
Open

Conversation

rsned
Copy link
Collaborator

@rsned rsned commented May 19, 2025

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.

Copy link
Collaborator

@flwyd flwyd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change :: references to Go style.

s2/builder.go Outdated
@@ -33,3 +39,345 @@ const (
// when MaxEdgeDeviation is exceeded.
maxEdgeDeviationRatio = 1.1
)

// isFullPolygonPredicate is an interface for determining if Polygons are
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason this is the first thing in the file? The java version has it at the end, and it seems like a pretty minor part of the builder API.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A lot of it is just the order I bumped into it in the C++. Will massage the orderings.

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).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: misplaced closing paren

s2/builder.go Outdated
//
// TODO(rsned): Make the type public when Builder is ready.
type builder struct {
opts *builderOptions
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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))};"

// 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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change all-caps to Go identifiers here and below.

)

// graphOptions is only needed by Layer implementations. A layer is
// responsible for assembling an Graph of snapped edges into the
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/an (Graph)/a \1/

// DEFAULT: edgeTypeDirected
edgeType edgeType

// DEFAULT: degenerateEdgesKeep
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we make the default values the first iota value when declaring the constants?

// 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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we change the name so the default can be false, maybe disableVertexFiltering?


import "github.com/golang/geo/s1"

// polylineType Indicates whether polylines should be "paths" (which don't
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lower-case indicates

rsned added 5 commits May 28, 2025 16:57
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().
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants