Skip to content

Instantly share code, notes, and snippets.

@adamochayon
Last active July 8, 2020 15:58
Show Gist options
  • Save adamochayon/c0387c831515981acdc414b71510d025 to your computer and use it in GitHub Desktop.
Save adamochayon/c0387c831515981acdc414b71510d025 to your computer and use it in GitHub Desktop.
func (api *SearchApi) BuildBoundingBox(
ctx context.Context,
query *search.SearchQuery,
) (bbox *GeoBoundingBox, err error) {
queries := buildSubQueries(query)
boundingBoxes, err = api.getSubBoundingBoxes(ctx, queries)
if err != nil {
return nil, err
}
bbox = api.mergeAndFitBoundingBoxes(ctx, boundingBoxes, query)
return
}
func (api *SearchApi) getSubBoundingBoxes(
ctx context.Context,
queries []SearchQuery,
) (boundingBoxes []*GeoBoundingBox, err error) {
funcs := make([]goutils.GenericFunction, len(queries))
boundingBoxes = make([]*GeoBoundingBox, len(queries))
calculateBoundingBoxForQuery := func(i int, query SearchQuery) func() error {
return func() error {
// First, check cache to see if we can save a network request
if bbox, found := api.Cache.Get(query.Name); found {
boundingBoxes[i] = bbox.(*GeoBoundingBox)
return nil
}
// Otherwise, proceed to perform request
results, err := api.callMapSearch(ctx, query)
if err != nil {
return err
}
if bbox := calculateBoundingBox(results); bbox != nil {
api.Cache.SetDefault(query.Name, bbox)
boundingBoxes[i] = bbox
}
return nil
}
}
for i, query := range queries {
funcs[i] = calculateBoundingBoxForQuery(i, query)
}
// Build all bounding boxes concurrently!
if err = RunAsync(funcs...); err != nil {
return nil, err
}
return
}
func calculateBoundingBox(
mapSearchResults *search.MapSearchResults,
) *GeoBoundingBox {
clusters := cleanClusters(mapSearchResults.GetClusters())
clusters = pruneOutliers(ctx, clusters)
return getClustersBoundingBox(clusters)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment