主要目的
计算每个出租车接客和送客地点与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!")
}