根据经纬度数据计算空间距离-Go语言实现

主要目的
计算每个出租车接客和送客地点与15个银行的距离,对于满足距离小于等于97m条件的银行和出租车接/送客信息实现匹配。

1、银行所在地点的经纬度

在这里插入图片描述

2、出租车接/送客地点的经纬度

在这里插入图片描述

3、距离计算并统计

package main

import (
	"encoding/csv"
	"fmt"
	"io"
	"log"
	"math"
	"os"
	"strconv"
)

func Distance_list(fileName string) {
	// 定义一个字符串数组,保存接客计算结果
	result_index1 := []string{}
	result_name1 := []string{}
	// 定义一个字符串数组,保存送客计算结果
	result_index2 := []string{}
	result_name2 := []string{}
	// fmt.Println(result)
	data_bank_name := [15]string{"Bank of America(investment banking)", "Barclays(Investment Bank)", "BNY Mellon (headquarters)", "Citigroup(global markets)", "Credit Suisse", "Deutsche Bank", "Deutsche Bank(securities)", "Goldman Sachs(headquarters)", "JPMorgan Chase (investment banking)", "JPMorgan Chase(headquarters)", "Morgan Stanley(headquarters)", "Morgan Stanley(investment management)", "RBC Capital Markets ", "UBS(USA)Inc(Private wealth management)", "BNY Mellon (headquarters) (2014/6)"}
	// 经度
	data_bank_lon := [15]float64{-73.984167, -73.9853352, -74.0126052, -74.011036, -73.986556, -73.9725, -74.0105799, -74.014444, -73.977089, -73.9754, -73.985678, -73.980556, -74.0169804, -73.9763302, -74.015556}
	// 纬度
	data_bank_lat := [15]float64{40.755278, 40.76052, 40.7069034, 40.720685, 40.741556, 40.7578, 40.7062295, 40.714722, 40.755585, 40.7558, 40.760386, 40.754722, 40.7139824, 40.756043, 40.713056}
	//将经纬度数据保存为数组
	pick_lon := []float64{}
	pick_lat := []float64{}
	drop_lon := []float64{}
	drop_lat := []float64{}
	//准备读取文件
	fs, err := os.Open(fileName)
	if err != nil {
		log.Fatalf("can not open the file, err is %+v", err)
	}
	defer fs.Close()
	r := csv.NewReader(fs)
	//针对大文件,一行一行的读取文件
	for {
		row, err := r.Read()
		if err != nil && err != io.EOF {
			log.Fatalf("can not read, err is %+v", err)
		}
		if err == io.EOF {
			break
		}
		lon1, _ := strconv.ParseFloat(row[0], 64)
		pick_lon = append(pick_lon, lon1)
		// fmt.Println(lat1)
		lat1, _ := strconv.ParseFloat(row[1], 64)
		pick_lat = append(pick_lat, lat1)

		lon2, _ := strconv.ParseFloat(row[2], 64)
		drop_lon = append(drop_lon, lon2)
		// fmt.Println(lat1)
		lat2, _ := strconv.ParseFloat(row[3], 64)
		drop_lat = append(drop_lat, lat2)
	}
	// 遍历循环计算距离-接客
	var i, j int
	// 计算距离
	for i = 0; i < len(pick_lon); i++ {
		for j = 0; j < 15; j++ {
			//转化为弧度(rad)
			const EARTH_RADIUS = 6378137  // 6378137(地球赤道半径:m)
			rad := math.Pi / 180.0
			// 1 、先获取银行的经纬度
			lon := float64(data_bank_lon[j])*rad
			lat := float64(data_bank_lat[j])*rad
			if lon < 0 {
				lon = math.Pi*2 - math.Abs(lon)
			}
			if lat > 0 {
				lat = math.Pi/2 - math.Abs(lat)
			}
			// 2、获取接客经纬度
			lon1 := pick_lon[i] * rad
			lat1 := pick_lat[i] * rad
			if lon1 < 0 {
				lon1 = math.Pi*2 - math.Abs(lon1)
			}
			if lat1 > 0 {
				lat1 = math.Pi/2 - math.Abs(lat1)
			}
			// 3、获取送客经纬度
			lon2 := drop_lon[i] * rad
			lat2 := drop_lat[i] * rad
			if lon2 < 0 {
				lon2 = math.Pi*2 - math.Abs(lon2)
			}
			if lat2 > 0 {
				lat2 = math.Pi/2 - math.Abs(lat2)
			}
			// 4、换算
			x := EARTH_RADIUS * math.Cos(lon) * math.Sin(lat)
			y := EARTH_RADIUS * math.Sin(lon) * math.Sin(lat)
			z := EARTH_RADIUS * math.Cos(lat)
			x1 := EARTH_RADIUS * math.Cos(lon1) * math.Sin(lat1)
			y1 := EARTH_RADIUS * math.Sin(lon1) * math.Sin(lat1)
			z1 := EARTH_RADIUS * math.Cos(lat1)
			x2 := EARTH_RADIUS * math.Cos(lon2) * math.Sin(lat2)
			y2 := EARTH_RADIUS * math.Sin(lon2) * math.Sin(lat2)
			z2 := EARTH_RADIUS * math.Cos(lat2)
			// 5、求距离
			// 接客距离
			d1 := math.Sqrt((x1-x)*(x1-x) + (y1-y)*(y1-y) + (z1-z)*(z1-z))
			theta1 := math.Acos((EARTH_RADIUS*EARTH_RADIUS + EARTH_RADIUS*EARTH_RADIUS - d1*d1) / (2 * EARTH_RADIUS * EARTH_RADIUS))
			distance1 := theta1 * EARTH_RADIUS
			if distance1 <= 96.56064 {
				result_index1 = append(result_index1, strconv.Itoa(i))
				result_name1 = append(result_name1, data_bank_name[j])
			}
			// 送客距离
			d2 := math.Sqrt((x2-x)*(x2-x) + (y2-y)*(y2-y) + (z2-z)*(z2-z))
			theta2 := math.Acos((EARTH_RADIUS*EARTH_RADIUS + EARTH_RADIUS*EARTH_RADIUS - d2*d2) / (2 * EARTH_RADIUS * EARTH_RADIUS))
			distance2 := theta2 * EARTH_RADIUS
			if distance2 <= 96.56064 {
				result_index2 = append(result_index2, strconv.Itoa(i))
				result_name2 = append(result_name2, data_bank_name[j])
			}
		}
	}
	// 1、将接客信息存入文件
	path1 := "C:\\Users\\JunLiu\\Desktop\\数据分析\\香港中文大学商学院\\3-taxi\\pickup bank\\2016-06.csv"  //待更新
	//os.O_WRONLY | os.O_CREATE
	file1, err := os.OpenFile(path1, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666)
	if err != nil {
		fmt.Println("file open error:", err)
		return
	}
	defer file1.Close()
	//使用缓存方式写入
	writer1 := csv.NewWriter(file1)
	//写入表头
	head1 := []string{"index", "name"}  
	writer1.Write(head1)
	writer1.Flush()
	for i=0; i < len(result_index1); i++ {
		var d1 = []string{result_index1[i], result_name1[i]}
		writer1.Write(d1)
	}
	//将缓存中数据刷新到文本中
	writer1.Flush()
	fmt.Println("writedown_1 !!!")

	// 2、将送客信息存入文件
	path2 := "C:\\Users\\JunLiu\\Desktop\\数据分析\\香港中文大学商学院\\3-taxi\\dropoff bank\\2016-06.csv"  //待更新
	//os.O_WRONLY | os.O_CREATE
	file2, err := os.OpenFile(path2, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666)
	if err != nil {
		fmt.Println("file open error:", err)
		return
	}
	defer file2.Close()
	//使用缓存方式写入
	writer2 := csv.NewWriter(file2)
	//写入表头
	head2 := []string{"index", "name"}  
	writer2.Write(head2)
	writer2.Flush()
	for i=0; i < len(result_index2); i++ {
		var d2 = []string{result_index2[i], result_name2[i]}
		writer2.Write(d2)
	}
	//将缓存中数据刷新到文本中
	writer2.Flush()
	fmt.Println("writedown_2 !!!")
}

func main() {
	// 读取文件
	filePath := "C:\\Users\\JunLiu\\Desktop\\数据分析\\香港中文大学商学院\\3-taxi\\taxi_latlon\\2016-06.csv"    //待处理
	// runtime.GOMAXPROCS(4)         // 核心数 8
	fmt.Printf("start!\n")
	Distance_list(filePath)
	fmt.Printf("finish!")
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值