mirror of
				https://github.com/go-gitea/gitea
				synced 2025-10-26 17:08:25 +00:00 
			
		
		
		
	* Improve issue indexer * Fix new issue sqlite bug * Different test indexer paths for each db * Add integration indexer paths to make clean
		
			
				
	
	
		
			99 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			99 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| //  Copyright (c) 2017 Couchbase, Inc.
 | |
| //
 | |
| // 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 geo
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"math"
 | |
| 	"strconv"
 | |
| 	"strings"
 | |
| )
 | |
| 
 | |
| type distanceUnit struct {
 | |
| 	conv     float64
 | |
| 	suffixes []string
 | |
| }
 | |
| 
 | |
| var inch = distanceUnit{0.0254, []string{"in", "inch"}}
 | |
| var yard = distanceUnit{0.9144, []string{"yd", "yards"}}
 | |
| var feet = distanceUnit{0.3048, []string{"ft", "feet"}}
 | |
| var kilom = distanceUnit{1000, []string{"km", "kilometers"}}
 | |
| var nauticalm = distanceUnit{1852.0, []string{"nm", "nauticalmiles"}}
 | |
| var millim = distanceUnit{0.001, []string{"mm", "millimeters"}}
 | |
| var centim = distanceUnit{0.01, []string{"cm", "centimeters"}}
 | |
| var miles = distanceUnit{1609.344, []string{"mi", "miles"}}
 | |
| var meters = distanceUnit{1, []string{"m", "meters"}}
 | |
| 
 | |
| var distanceUnits = []*distanceUnit{
 | |
| 	&inch, &yard, &feet, &kilom, &nauticalm, &millim, ¢im, &miles, &meters,
 | |
| }
 | |
| 
 | |
| // ParseDistance attempts to parse a distance string and return distance in
 | |
| // meters.  Example formats supported:
 | |
| // "5in" "5inch" "7yd" "7yards" "9ft" "9feet" "11km" "11kilometers"
 | |
| // "3nm" "3nauticalmiles" "13mm" "13millimeters" "15cm" "15centimeters"
 | |
| // "17mi" "17miles" "19m" "19meters"
 | |
| // If the unit cannot be determined, the entire string is parsed and the
 | |
| // unit of meters is assumed.
 | |
| // If the number portion cannot be parsed, 0 and the parse error are returned.
 | |
| func ParseDistance(d string) (float64, error) {
 | |
| 	for _, unit := range distanceUnits {
 | |
| 		for _, unitSuffix := range unit.suffixes {
 | |
| 			if strings.HasSuffix(d, unitSuffix) {
 | |
| 				parsedNum, err := strconv.ParseFloat(d[0:len(d)-len(unitSuffix)], 64)
 | |
| 				if err != nil {
 | |
| 					return 0, err
 | |
| 				}
 | |
| 				return parsedNum * unit.conv, nil
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	// no unit matched, try assuming meters?
 | |
| 	parsedNum, err := strconv.ParseFloat(d, 64)
 | |
| 	if err != nil {
 | |
| 		return 0, err
 | |
| 	}
 | |
| 	return parsedNum, nil
 | |
| }
 | |
| 
 | |
| // ParseDistanceUnit attempts to parse a distance unit and return the
 | |
| // multiplier for converting this to meters.  If the unit cannot be parsed
 | |
| // then 0 and the error message is returned.
 | |
| func ParseDistanceUnit(u string) (float64, error) {
 | |
| 	for _, unit := range distanceUnits {
 | |
| 		for _, unitSuffix := range unit.suffixes {
 | |
| 			if u == unitSuffix {
 | |
| 				return unit.conv, nil
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	return 0, fmt.Errorf("unknown distance unit: %s", u)
 | |
| }
 | |
| 
 | |
| // Haversin computes the distance between two points.
 | |
| // This implemenation uses the sloppy math implemenations which trade off
 | |
| // accuracy for performance.  The distance returned is in kilometers.
 | |
| func Haversin(lon1, lat1, lon2, lat2 float64) float64 {
 | |
| 	x1 := lat1 * degreesToRadian
 | |
| 	x2 := lat2 * degreesToRadian
 | |
| 	h1 := 1 - cos(x1-x2)
 | |
| 	h2 := 1 - cos((lon1-lon2)*degreesToRadian)
 | |
| 	h := (h1 + cos(x1)*cos(x2)*h2) / 2
 | |
| 	avgLat := (x1 + x2) / 2
 | |
| 	diameter := earthDiameter(avgLat)
 | |
| 
 | |
| 	return diameter * asin(math.Min(1, math.Sqrt(h)))
 | |
| }
 |