Last active
February 19, 2017 20:20
-
-
Save gnsx/8552aa63d139e14e7150e3939f6b3b39 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"gocsv" | |
"os" | |
"math" | |
"time" | |
"strconv" | |
"encoding/json" | |
"runtime" | |
"sync" | |
) | |
func check(e error) { | |
if e != nil { | |
panic(e) | |
} | |
} | |
type Location struct { | |
// Our example struct, you can use "-" to ignore a field fk_asset_id,lat,lon,spd,sig,hbk,tis | |
Id uint32 `csv:"fk_asset_id"` | |
Lat float64 `csv:"lat"` | |
Lon float64 `csv:"lon"` | |
Spd uint16 `csv:"spd"` | |
Sig uint16 `csv:"sig"` | |
Hbk uint16 `csv:"hbk"` | |
Tis uint32 `csv:"tis"` | |
} | |
type asset_inside_radius struct { | |
Id uint32 | |
Tis []uint32 | |
} | |
type Route_collection struct { | |
Lat float64 | |
Lon float64 | |
Air []asset_inside_radius | |
} | |
// haversin(θ) function | |
func hsin(theta float64) float64 { | |
return math.Pow(math.Sin(theta / 2), 2) | |
} | |
// Distance function returns the distance (in meters) between two points of | |
// a given longitude and latitude relatively accurately (using a spherical | |
// approximation of the Earth) through the Haversin Distance Formula for | |
// great arc distance on a sphere with accuracy for small distances | |
// | |
// point coordinates are supplied in degrees and converted into rad. in the func | |
// | |
// distance returned is METERS!!!!!! | |
// http://en.wikipedia.org/wiki/Haversine_formula | |
func Distance(lat1, lon1, lat2, lon2 float64) float64 { | |
// convert to radians | |
// must cast radius as float to multiply later | |
var la1, lo1, la2, lo2, r float64 | |
la1 = lat1 * 0.01745329251 | |
lo1 = lon1 * 0.01745329251 | |
la2 = lat2 * 0.01745329251 | |
lo2 = lon2 * 0.01745329251 | |
r = 6378137 // Earth radius in METERS | |
// calculate | |
h := hsin(la2 - la1) + math.Cos(la1) * math.Cos(la2) * hsin(lo2 - lo1) | |
return 2 * r * math.Asin(math.Sqrt(h)) | |
} | |
var ri = 0 | |
var ni = 0 | |
func parse_locations(i int, Location_in []*Location) { | |
var skip_lock = false | |
internal_rc := ri | |
lock = false | |
temp_route_collector := new(Route_collection) | |
temp_route_collector.Lat = Location_in[i].Lat | |
temp_route_collector.Lon = Location_in[i].Lon | |
route_collector = append(route_collector, temp_route_collector) | |
count_good := 0 | |
for _, second_Location := range Location_in { | |
distance := Distance(Location_in[i].Lat, Location_in[i].Lon, second_Location.Lat, second_Location.Lon) | |
if ( distance < 5 && second_Location.Spd > 0) { | |
count_good++ | |
//log.Printf("Iteration: %d Tis: %d",second_Location.Id,second_Location.Tis) | |
is_not_unique := false | |
tis_iterator := 0 | |
if internal_rc < len(route_collector) { | |
for _, t_air := range route_collector[internal_rc].Air { | |
if (t_air.Id == second_Location.Id) { | |
is_not_unique = true | |
//t_air.Tis = append (t_air.Tis, second_Location.Tis) | |
route_collector[internal_rc].Air[tis_iterator].Tis = append(route_collector[internal_rc].Air[tis_iterator].Tis, second_Location.Tis) | |
//log.Printf("Appended TIS since new ID was found") | |
} | |
//log.Printf("Tis Iterator Count %d,",tis_iterator) | |
tis_iterator++ | |
} | |
if (is_not_unique == false) { | |
ta_air := asset_inside_radius{} | |
ta_air.Id = second_Location.Id | |
ta_air.Tis = append(ta_air.Tis, second_Location.Tis) | |
route_collector[internal_rc].Air = append(route_collector[internal_rc].Air, ta_air) | |
//log.Printf("Appended New Route") | |
} | |
skip_lock = false | |
} else { | |
fmt.Printf("\nIndex Out for %d", internal_rc) | |
skip_lock = true | |
} | |
} | |
} | |
//FIle Dumopp code here | |
//log.Printf("%d i:%d", count_good, i) | |
if skip_lock == false { | |
for lock == true { | |
fmt.Printf("\nWaiting to get unlocked from %d", internal_rc) | |
} | |
lock = true | |
ri++ | |
ni++ | |
} | |
} | |
var lock = false | |
func lock_ri() { | |
ri++ | |
ni++ | |
} | |
var route_collector = []*Route_collection{} | |
func main() { | |
//var mutex = &sync.Mutex{} | |
now := time.Now() | |
secs := now.Unix() | |
s := strconv.Itoa(int(secs)) | |
f, err := os.Create(s + ".raw") | |
check(err) | |
defer f.Close() | |
LocationsFile, err := os.OpenFile("psf.data", os.O_RDONLY | os.O_CREATE, os.ModePerm) | |
if err != nil { | |
panic(err) | |
} | |
defer LocationsFile.Close() | |
Loc := []*Location{} | |
if err := gocsv.UnmarshalFile(LocationsFile, &Loc); err != nil { | |
// Load Locations from file | |
panic(err) | |
} | |
fmt.Printf("Done Marshalling\n") | |
runtime.GOMAXPROCS(4) | |
var wg sync.WaitGroup | |
wg.Add(6) | |
total_no_locations := len(Loc) | |
fmt.Printf("Length of Location %d", total_no_locations) | |
//file_is_busy := false | |
//1st loop | |
go func() { | |
defer wg.Done() | |
//Loop A Iterate | |
for ni < total_no_locations { | |
//mutex.Lock() | |
parse_locations(ni, Loc) | |
//lock_ri() | |
//mutex.Unlock() | |
} | |
lock = false | |
fmt.Printf("Out0") | |
}() | |
go func() { | |
defer wg.Done() | |
//Loop A Iterate | |
for ni < total_no_locations { | |
//mutex.Lock() | |
parse_locations(ni, Loc) | |
//lock_ri() | |
//mutex.Unlock() | |
} | |
lock = false | |
fmt.Printf("Out1") | |
}() | |
go func() { | |
defer wg.Done() | |
//Loop A Iterate | |
for ni < total_no_locations { | |
//mutex.Lock() | |
parse_locations(ni, Loc) | |
//lock_ri() | |
//mutex.Unlock() | |
} | |
lock = false | |
fmt.Printf("Out2") | |
}() | |
go func() { | |
defer wg.Done() | |
//Loop A Iterate | |
for ni < total_no_locations { | |
//mutex.Lock() | |
parse_locations(ni, Loc) | |
//lock_ri() | |
//mutex.Unlock() | |
} | |
lock = false | |
fmt.Printf("Out3") | |
}() | |
go func() { | |
defer wg.Done() | |
//Loop A Iterate | |
for ni < total_no_locations { | |
//mutex.Lock() | |
parse_locations(ni, Loc) | |
//lock_ri() | |
//mutex.Unlock() | |
} | |
lock = false | |
fmt.Printf("Out4") | |
}() | |
go func() { | |
defer wg.Done() | |
//Loop A Iterate | |
for ni < total_no_locations { | |
fmt.Printf("\nLocation :%d", ni) | |
time.Sleep(10 * time.Second) | |
} | |
fmt.Printf("\nThat's all folks") | |
}() | |
wg.Wait() | |
fmt.Println("\nCompute Finished going to write into file") | |
//File Dump Code Final | |
b, err := json.Marshal(route_collector) | |
if err != nil { | |
fmt.Println(err) | |
return | |
} | |
str := fmt.Sprint("\n", string(b)) | |
f.WriteString(str) | |
f.Sync() | |
f.Close() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment