// Interpolate returns the closest point to given distance within geometry.
// This geometry must be a LineString.
185174
func (g *Geometry) Interpolate(dist float64) (*Geometry, error) {
	return geomFromC("Interpolate", cGEOSInterpolate(g.g, C.double(dist)))
}
10214
func (p Point) Distance(b Point) s1.Angle {
	return p.Vector.Angle(b.Vector)
}
89583
func interpolationFuncCompact() ast.Function {
	return ast.Function{
		ArgTypes:   []ast.Type{ast.TypeList},
		ReturnType: ast.TypeList,
		Variadic:   false,
		Callback: func(args []interface{}) (interface{}, error) {
			inputList := args[0].([]ast.Variable)

			var outputList []string
			for _, val := range inputList {
				strVal, ok := val.Value.(string)
				if !ok {
					return nil, fmt.Errorf(
						"compact() may only be used with flat lists, this list contains elements of %s",
						val.Type.Printable())
				}
				if strVal == "" {
					continue
				}

				outputList = append(outputList, strVal)
			}
			return stringSliceToVariableValue(outputList), nil
		},
	}
}
99405
func interpolationFuncMax() ast.Function {
	return ast.Function{
		ArgTypes:     []ast.Type{ast.TypeFloat},
		ReturnType:   ast.TypeFloat,
		Variadic:     true,
		VariadicType: ast.TypeFloat,
		Callback: func(args []interface{}) (interface{}, error) {
			max := args[0].(float64)

			for i := 1; i < len(args); i++ {
				max = math.Max(max, args[i].(float64))
			}

			return max, nil
		},
	}
}
1023036
func interpolationFuncDistinct() ast.Function {
	return ast.Function{
		ArgTypes:     []ast.Type{ast.TypeList},
		ReturnType:   ast.TypeList,
		Variadic:     true,
		VariadicType: ast.TypeList,
		Callback: func(args []interface{}) (interface{}, error) {
			var list []string

			if len(args) != 1 {
				return nil, fmt.Errorf("accepts only one argument.")
			}

			if argument, ok := args[0].([]ast.Variable); ok {
				for _, element := range argument {
					if element.Type != ast.TypeString {
						return nil, fmt.Errorf(
							"only works for flat lists, this list contains elements of %s",
							element.Type.Printable())
					}
					list = appendIfMissing(list, element.Value.(string))
				}
			}

			return stringSliceToVariableValue(list), nil
		},
	}
}
620752
func interpolationFuncIndent() ast.Function {
	return ast.Function{
		ArgTypes:   []ast.Type{ast.TypeInt, ast.TypeString},
		ReturnType: ast.TypeString,
		Callback: func(args []interface{}) (interface{}, error) {
			spaces := args[0].(int)
			data := args[1].(string)
			pad := strings.Repeat(" ", spaces)
			return strings.Replace(data, "\n", "\n"+pad, -1), nil
		},
	}
}
1120899
func (ps PointSet) Bound() *Bound {
	if len(ps) == 0 {
		return NewBound(0, 0, 0, 0)
	}

	minX := math.Inf(1)
	minY := math.Inf(1)

	maxX := math.Inf(-1)
	maxY := math.Inf(-1)

	for _, v := range ps {
		minX = math.Min(minX, v.X())
		minY = math.Min(minY, v.Y())

		maxX = math.Max(maxX, v.X())
		maxY = math.Max(maxY, v.Y())
	}

	return NewBound(maxX, minX, maxY, minY)
}
1202466
func (p Point) DistanceTo(op *Point) float64 {
	dx := p.x - op.x
	dy := p.y - op.y
	return math.Sqrt(dx*dx + dy*dy)
}
112556
func ToInterval(ls orb.LineString, df orb.DistanceFunc, dist float64) orb.LineString {
	if dist <= 0 {
		return nil
	}

	// precomputes the total distance and intermediate distances
	total, dists := precomputeDistances(ls, df)

	totalPoints := int(total/dist) + 1
	ls, ret := resampleEdgeCases(ls, totalPoints)
	if ret {
		return ls
	}

	return resample(ls, dists, total, totalPoints)
}
123155
func InterpolateWith(resolver interpolate.VariableResolver) mapdecode.Option {
	return mapdecode.FieldHook(func(dest reflect.StructField, srcData reflect.Value) (reflect.Value, error) {
		shouldInterpolate := false

		options := strings.Split(dest.Tag.Get(_tagName), ",")[1:]
		for _, option := range options {
			if option == _interpolateOption {
				shouldInterpolate = true
				break
			}
		}

		if !shouldInterpolate {
			return srcData, nil
		}

		// Use Interface().(string) so that we handle the case where data is an
		// interface{} holding a string.
		v, ok := srcData.Interface().(string)
		if !ok {
			// Cannot interpolate non-string type. This shouldn't be an error
			// because an integer field may be marked as interpolatable and may
			// have received an integer as expected.
			return srcData, nil
		}

		s, err := interpolate.Parse(v)
		if err != nil {
			return srcData, fmt.Errorf("failed to parse %q for interpolation: %v", v, err)
		}

		newV, err := s.Render(resolver)
		if err != nil {
			return srcData, fmt.Errorf("failed to render %q with environment variables: %v", v, err)
		}

		return reflect.ValueOf(newV), nil
	})
}
743363
func interpolationFuncMap() ast.Function {
	return ast.Function{
		ArgTypes:     []ast.Type{},
		ReturnType:   ast.TypeMap,
		Variadic:     true,
		VariadicType: ast.TypeAny,
		Callback: func(args []interface{}) (interface{}, error) {
			outputMap := make(map[string]ast.Variable)

			if len(args)%2 != 0 {
				return nil, fmt.Errorf("requires an even number of arguments, got %d", len(args))
			}

			var firstType *ast.Type
			for i := 0; i < len(args); i += 2 {
				key, ok := args[i].(string)
				if !ok {
					return nil, fmt.Errorf("argument %d represents a key, so it must be a string", i+1)
				}
				val := args[i+1]
				variable, err := hil.InterfaceToVariable(val)
				if err != nil {
					return nil, err
				}
				// Enforce map type homogeneity
				if firstType == nil {
					firstType = &variable.Type
				} else if variable.Type != *firstType {
					return nil, fmt.Errorf("all map values must have the same type, got %s then %s", firstType.Printable(), variable.Type.Printable())
				}
				// Check for duplicate keys
				if _, ok := outputMap[key]; ok {
					return nil, fmt.Errorf("argument %d is a duplicate key: %q", i+1, key)
				}
				outputMap[key] = variable
			}

			return outputMap, nil
		},
	}
}
500785
func (c Cell) Distance(target Point) s1.ChordAngle {
	return c.distanceInternal(target, true)
}
71741
func interpolationFuncAbs() ast.Function {
	return ast.Function{
		ArgTypes:   []ast.Type{ast.TypeFloat},
		ReturnType: ast.TypeFloat,
		Callback: func(args []interface{}) (interface{}, error) {
			return math.Abs(args[0].(float64)), nil
		},
	}
}
74012
func interpolationFuncKeys(vs map[string]ast.Variable) ast.Function {
	return ast.Function{
		ArgTypes:   []ast.Type{ast.TypeMap},
		ReturnType: ast.TypeList,
		Callback: func(args []interface{}) (interface{}, error) {
			mapVar := args[0].(map[string]ast.Variable)
			keys := make([]string, 0)

			for k, _ := range mapVar {
				keys = append(keys, k)
			}

			sort.Strings(keys)

			// Keys are guaranteed to be strings
			return stringSliceToVariableValue(keys), nil
		},
	}
}
1324324
func interpolationFuncFlatten() ast.Function {
	return ast.Function{
		ArgTypes:   []ast.Type{ast.TypeList},
		ReturnType: ast.TypeList,
		Variadic:   false,
		Callback: func(args []interface{}) (interface{}, error) {
			inputList := args[0].([]ast.Variable)

			var outputList []ast.Variable
			return flattener(outputList, inputList), nil
		},
	}
}
1276669
func (l Line) Closest(v Vec) Vec {
	// between is a helper function which determines whether x is greater than min(a, b) and less than max(a, b)
	between := func(a, b, x float64) bool {
		min := math.Min(a, b)
		max := math.Max(a, b)
		return min < x && x < max
	}

	// Closest point will be on a line which perpendicular to this line.
	// If and only if the infinite perpendicular line intersects the segment.
	m, b := l.Formula()

	// Account for horizontal lines
	if m == 0 {
		x := v.X
		y := l.A.Y

		// check if the X coordinate of v is on the line
		if between(l.A.X, l.B.X, v.X) {
			return V(x, y)
		}

		// Otherwise get the closest endpoint
		if l.A.To(v).Len() < l.B.To(v).Len() {
			return l.A
		}
		return l.B
	}

	// Account for vertical lines
	if math.IsInf(math.Abs(m), 1) {
		x := l.A.X
		y := v.Y

		// check if the Y coordinate of v is on the line
		if between(l.A.Y, l.B.Y, v.Y) {
			return V(x, y)
		}

		// Otherwise get the closest endpoint
		if l.A.To(v).Len() < l.B.To(v).Len() {
			return l.A
		}
		return l.B
	}

	perpendicularM := -1 / m
	perpendicularB := v.Y - (perpendicularM * v.X)

	// Coordinates of intersect (of infinite lines)
	x := (perpendicularB - b) / (m - perpendicularM)
	y := m*x + b

	// Check if the point lies between the x and y bounds of the segment
	if !between(l.A.X, l.B.X, x) && !between(l.A.Y, l.B.Y, y) {
		// Not within bounding box
		toStart := v.To(l.A)
		toEnd := v.To(l.B)

		if toStart.Len() < toEnd.Len() {
			return l.A
		}
		return l.B
	}

	return V(x, y)
}
723446
func interpolationFuncLower() ast.Function {
	return ast.Function{
		ArgTypes:   []ast.Type{ast.TypeString},
		ReturnType: ast.TypeString,
		Callback: func(args []interface{}) (interface{}, error) {
			toLower := args[0].(string)
			return strings.ToLower(toLower), nil
		},
	}
}