diff options
Diffstat (limited to 'vendor/github.com/golang/geo/s2/query_options.go')
-rw-r--r-- | vendor/github.com/golang/geo/s2/query_options.go | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/vendor/github.com/golang/geo/s2/query_options.go b/vendor/github.com/golang/geo/s2/query_options.go new file mode 100644 index 000000000..9b7e38d62 --- /dev/null +++ b/vendor/github.com/golang/geo/s2/query_options.go @@ -0,0 +1,196 @@ +// Copyright 2019 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package s2 + +import ( + "math" + + "github.com/golang/geo/s1" +) + +const maxQueryResults = math.MaxInt32 + +// queryOptions represents the set of all configurable parameters used by all of +// the Query types. Most of these fields have non-zero defaults, so initialization +// is handled within each Query type. All of the exported methods accept user +// supplied sets of options to set or adjust as necessary. +// +// Several of the defaults depend on the distance interface type being used +// (e.g. minDistance, maxDistance, etc.) +// +// If a user sets an option value that a given query type doesn't use, it is ignored. +type queryOptions struct { + // maxResults specifies that at most MaxResults edges should be returned. + // This must be at least 1. + // + // The default value is to return all results. + maxResults int + + // distanceLimit specifies that only edges whose distance to the target is + // within this distance should be returned. + // + // Note that edges whose distance is exactly equal to this are + // not returned. In most cases this doesn't matter (since distances are + // not computed exactly in the first place), but if such edges are needed + // then you can retrieve them by specifying the distance as the next + // largest representable distance. i.e. distanceLimit.Successor(). + // + // The default value is the infinity value, such that all results will be + // returned. + distanceLimit s1.ChordAngle + + // maxError specifies that edges up to MaxError further away than the true + // closest edges may be substituted in the result set, as long as such + // edges satisfy all the remaining search criteria (such as DistanceLimit). + // This option only has an effect if MaxResults is also specified; + // otherwise all edges closer than MaxDistance will always be returned. + // + // Note that this does not affect how the distance between edges is + // computed; it simply gives the algorithm permission to stop the search + // early as soon as the best possible improvement drops below MaxError. + // + // This can be used to implement distance predicates efficiently. For + // example, to determine whether the minimum distance is less than D, set + // MaxResults == 1 and MaxDistance == MaxError == D. This causes + // the algorithm to terminate as soon as it finds any edge whose distance + // is less than D, rather than continuing to search for an edge that is + // even closer. + // + // The default value is zero. + maxError s1.ChordAngle + + // includeInteriors specifies that polygon interiors should be included + // when measuring distances. In other words, polygons that contain the target + // should have a distance of zero. (For targets consisting of multiple connected + // components, the distance is zero if any component is contained.) This + // is indicated in the results by returning a (ShapeID, EdgeID) pair + // with EdgeID == -1, i.e. this value denotes the polygons's interior. + // + // Note that for efficiency, any polygon that intersects the target may or + // may not have an EdgeID == -1 result. Such results are optional + // because in that case the distance to the polygon is already zero. + // + // The default value is true. + includeInteriors bool + + // specifies that distances should be computed by examining every edge + // rather than using the ShapeIndex. + // + // TODO(roberts): When optimized is implemented, update the default to false. + // The default value is true. + useBruteForce bool + + // region specifies that results must intersect the given Region. + // + // Note that if you want to set the region to a disc around a target + // point, it is faster to use a PointTarget with distanceLimit set + // instead. You can also set a distance limit and also require that results + // lie within a given rectangle. + // + // The default is nil (no region limits). + region Region +} + +// UseBruteForce sets or disables the use of brute force in a query. +func (q *queryOptions) UseBruteForce(x bool) *queryOptions { + q.useBruteForce = x + return q +} + +// IncludeInteriors specifies whether polygon interiors should be +// included when measuring distances. +func (q *queryOptions) IncludeInteriors(x bool) *queryOptions { + q.includeInteriors = x + return q +} + +// MaxError specifies that edges up to dist away than the true +// matching edges may be substituted in the result set, as long as such +// edges satisfy all the remaining search criteria (such as DistanceLimit). +// This option only has an effect if MaxResults is also specified; +// otherwise all edges closer than MaxDistance will always be returned. +func (q *queryOptions) MaxError(x s1.ChordAngle) *queryOptions { + q.maxError = x + return q +} + +// MaxResults specifies that at most MaxResults edges should be returned. +// This must be at least 1. +func (q *queryOptions) MaxResults(x int) *queryOptions { + // TODO(roberts): What should be done if the value is <= 0? + q.maxResults = int(x) + return q +} + +// DistanceLimit specifies that only edges whose distance to the target is +// within, this distance should be returned. Edges whose distance is equal +// are not returned. +// +// To include values that are equal, specify the limit with the next largest +// representable distance such as limit.Successor(), or set the option with +// Furthest/ClosestInclusiveDistanceLimit. +func (q *queryOptions) DistanceLimit(x s1.ChordAngle) *queryOptions { + q.distanceLimit = x + return q +} + +// ClosestInclusiveDistanceLimit sets the distance limit such that results whose +// distance is exactly equal to the limit are also returned. +func (q *queryOptions) ClosestInclusiveDistanceLimit(limit s1.ChordAngle) *queryOptions { + q.distanceLimit = limit.Successor() + return q +} + +// FurthestInclusiveDistanceLimit sets the distance limit such that results whose +// distance is exactly equal to the limit are also returned. +func (q *queryOptions) FurthestInclusiveDistanceLimit(limit s1.ChordAngle) *queryOptions { + q.distanceLimit = limit.Predecessor() + return q +} + +// ClosestConservativeDistanceLimit sets the distance limit such that results +// also incorporates the error in distance calculations. This ensures that all +// edges whose true distance is less than or equal to limit will be returned +// (along with some edges whose true distance is slightly greater). +// +// Algorithms that need to do exact distance comparisons can use this +// option to find a set of candidate edges that can then be filtered +// further (e.g., using CompareDistance). +func (q *queryOptions) ClosestConservativeDistanceLimit(limit s1.ChordAngle) *queryOptions { + q.distanceLimit = limit.Expanded(minUpdateDistanceMaxError(limit)) + return q +} + +// FurthestConservativeDistanceLimit sets the distance limit such that results +// also incorporates the error in distance calculations. This ensures that all +// edges whose true distance is greater than or equal to limit will be returned +// (along with some edges whose true distance is slightly less). +func (q *queryOptions) FurthestConservativeDistanceLimit(limit s1.ChordAngle) *queryOptions { + q.distanceLimit = limit.Expanded(-minUpdateDistanceMaxError(limit)) + return q +} + +// newQueryOptions returns a set of options using the given distance type +// with the proper default values. +func newQueryOptions(d distance) *queryOptions { + return &queryOptions{ + maxResults: maxQueryResults, + distanceLimit: d.infinity().chordAngle(), + maxError: 0, + includeInteriors: true, + useBruteForce: false, + region: nil, + } +} |