func TestPlaces(t *testing.T) { mdb, err := mongo.Connect("mongodb://localhost/watch") if err != nil { log.Println("Error connecting to MongoDB:", err) return } defer mdb.Close() db, err := InitDB(mdb) if err != nil { t.Fatal(err) } var ( deviceID = "test0123456789" groupID = users.SampleGroupID ) places := []Place{ Place{Polygon: &geo.Polygon{{ {37.5667, 55.7152}, {37.5688, 55.7167}, {37.5703, 55.7169}, {37.5706, 55.7168}, {37.5726, 55.7159}, {37.5728, 55.7158}, {37.5731, 55.7159}, {37.5751, 55.7152}, {37.5758, 55.7148}, {37.5755, 55.7144}, {37.5749, 55.7141}, {37.5717, 55.7131}, {37.5709, 55.7128}, {37.5694, 55.7125}, {37.5661, 55.7145}, {37.5660, 55.7147}, {37.5667, 55.7152}}}, Name: "Работа"}, Place{Circle: &geo.Circle{geo.Point{37.589248, 55.765944}, 200.0}, Name: "Дом"}, Place{Polygon: &geo.Polygon{{ {37.6256, 55.7522}, {37.6304, 55.7523}, {37.6310, 55.7527}, {37.6322, 55.7526}, {37.6320, 55.7521}, {37.6326, 55.7517}, {37.6321, 55.7499}, {37.6305, 55.7499}, {37.6305, 55.7502}, {37.6264, 55.7504}, {37.6264, 55.7500}, {37.6254, 55.7500}, {37.6253, 55.7520}, {37.6256, 55.7522}}}, Name: "Знаменский монастырь"}, } for _, place := range places { place.GroupID = groupID id, err := db.Save(place) if err != nil { t.Fatal(err) } fmt.Println("id:", id.Hex()) } places, err = db.GetAll(groupID) if err != nil { t.Fatal(err) } fmt.Println("Places:", len(places)) // pretty.Println(places) track := tracks.TrackData{ DeviceID: deviceID, GroupID: groupID, Time: time.Now(), Location: geo.NewPoint(37.57351, 55.715084), } placeIDs, err := db.Track(track) if err != nil { t.Fatal(err) } fmt.Printf("In %d places\n%v\n", len(placeIDs), placeIDs) }
func TestGeo(t *testing.T) { mdb, err := Connect("mongodb://localhost/test") if err != nil { log.Println("Error connecting to MongoDB:", err) return } defer mdb.Close() // storeData описывает формат данных для хранения. type storeData struct { Point geo.Point // координаты Time time.Time // временная метка } coll := mdb.GetCollection("geo") defer mdb.FreeCollection(coll) coll.Database.DropDatabase() if err = coll.EnsureIndexKey("$2dsphere:point"); err != nil { return } p1 := geo.NewPoint(55.715084, 37.57351) p2 := geo.NewPoint(55.765944, 37.589248) _ = p1 _ = p2 err = coll.Insert(&storeData{ Point: *p1, Time: time.Now(), }) if err != nil { t.Fatal(err) } var data storeData err = coll.Find(bson.M{ "point": bson.M{ "$nearSphere": *p2, "$maxDistance": MaxDistance, }}).One(&data) if err != nil { t.Fatal(err) } fmt.Println(data) }
package ublox import ( "fmt" "testing" "github.com/mdigger/geotrack/geo" ) var ( token = "I6KKO4RU_U2DclBM9GVyrA" pointWork = geo.NewPoint(37.57351, 55.715084) // работа pointHome = geo.NewPoint(37.589248, 55.765944) // дом ) func TestClient(t *testing.T) { ubox := NewClient(token) data, err := ubox.GetOnline(pointWork, DefaultProfile) if err != nil { t.Fatal(err) } fmt.Println(data) }
func main() { log.SetOutput(os.Stdout) log.SetFlags(log.Ltime) mongourl := flag.String("mongo", "mongodb://localhost/watch", "mongoDB connection URL") radiofilter := flag.String("radio", "gsm", "filter for radio (comma separated)") countryfilter := flag.String("country", "250", "filter for country (comma separated)") minSamples := flag.Int64("minsample", 0, "filter for min samples count") flag.Usage = func() { fmt.Fprint(os.Stderr, "Import LBS database data\n") fmt.Fprintf(os.Stderr, "%s [-params] datafile.csv\n", os.Args[0]) flag.PrintDefaults() } flag.Parse() if flag.NArg() != 1 { flag.Usage() return } filename := flag.Arg(0) // устанавливаем соединение с сервером MongoDB log.Printf("Connecting to MongoDB %q...", *mongourl) mdb, err := mongo.Connect(*mongourl) if err != nil { log.Printf("Error connecting to MongoDB: %v", err) return } defer mdb.Close() db, err := lbs.InitDB(mdb) if err != nil { log.Printf("Error initializing indexes: %v", err) return } coll := db.GetCollection(lbs.CollectionName) defer db.FreeCollection(coll) bulk := coll.Bulk() bulk.Unordered() // разбираем фильтры и формируем соответствующие справочники var ( filterRadio = make(map[string]bool) filterCountry = make(map[uint16]bool) ) for _, radio := range strings.Split(*radiofilter, ",") { filterRadio[strings.ToLower(strings.TrimSpace(radio))] = true } for _, country := range strings.Split(*countryfilter, ",") { mcc, err := strconv.ParseUint(country, 10, 16) if err != nil { continue } filterCountry[uint16(mcc)] = true } if len(filterRadio) > 0 || len(filterCountry) > 0 { log.Printf("Filters country - %q, radio - %q", strings.Join(strings.Split(*countryfilter, ","), ", "), strings.Join(strings.Split(*radiofilter, ","), ", ")) } log.Printf("Reading data from CSV %q...", filename) file, err := os.Open(filename) if err != nil { log.Printf("Error opening CSV file: %v", err) return } defer file.Close() var counter, lines uint64 // счетчики r := csv.NewReader(file) for { record, err := r.Read() if err == io.EOF { break } if err != nil { log.Printf("Error parsing CSV file: %v", err) return } lines++ if lines == 1 { r.FieldsPerRecord = len(record) // устанавливаем количество полей continue // пропускаем первую строку с заголовком в CSV-файле } fmt.Fprintf(os.Stderr, "\r* find %8d | skipped %8d records ", counter, lines-1-counter) radio := strings.ToLower(record[0]) if len(filterRadio) > 0 && !filterRadio[radio] { continue // игнорируем записи с неподдерживаемым типом радио } samples, err := strconv.ParseInt(record[9], 10, 32) if err != nil { log.Printf("[%d] bad Samples: %s", lines, record[9]) continue } if samples < *minSamples { continue // не импортируем данные с маленьким количеством подтверждений } mcc, err := strconv.ParseUint(record[1], 10, 16) if err != nil { log.Printf("[%d] bad MCC: %s", lines, record[1]) continue } if len(filterCountry) > 0 && !filterCountry[uint16(mcc)] { continue // игнорируем записи с неподдерживаемым типом радио } mnc, err := strconv.ParseUint(record[2], 10, 16) if err != nil { log.Printf("[%d] bad MNC: %s", lines, record[2]) continue } area, err := strconv.ParseUint(record[3], 10, 16) if err != nil { log.Printf("[%d] bad Area: %s", lines, record[3]) continue } cell, err := strconv.ParseUint(record[4], 10, 32) if err != nil { log.Printf("[%d] bad Cell: %s", lines, record[4]) continue } lon, err := strconv.ParseFloat(record[6], 64) if err != nil { log.Printf("[%d] bad longitude:", lines, record[6]) continue } lat, err := strconv.ParseFloat(record[7], 64) if err != nil { log.Printf("[%d] bad latitude:", lines, record[7]) continue } distance, err := strconv.ParseFloat(record[8], 64) if err != nil { log.Printf("[%d] bad range:", lines, record[8]) continue } key := lbs.Key{ RadioType: radio, MobileCountryCode: uint16(mcc), MobileNetworkCode: uint16(mnc), LocationAreaCode: uint16(area), CellId: uint32(cell), } data := lbs.Data{ Location: geo.NewPoint(lon, lat), Accuracy: distance, } // created, err := strconv.ParseInt(record[11], 10, 64) // if err != nil { // log.Printf("[%d] bad Created: %s", lines, record[11]) // continue // } // updated, err := strconv.ParseInt(record[12], 10, 64) // if err != nil { // log.Printf("[%d] bad Updated: %s", lines, record[12]) // continue // } bulk.Upsert(key, bson.M{"$set": data}) counter++ } fmt.Fprintln(os.Stderr, "") if counter == 0 { log.Println("No record for import. Exit...") return } // если это не обновление, то подчищаем старые (не обновленные) данные if !strings.Contains(filename, "diff") { log.Println("Deleting old data...") deleteResult, err := coll.RemoveAll(nil) if err != nil { log.Printf("MongoDB deleting old data error: %v", err) return } if deleteResult.Removed > 0 { log.Printf("Deleted %d records", deleteResult.Removed) } } log.Printf("Bulk importing to MongoDB [%d records]...", counter) bulkResult, err := bulk.Run() if err != nil { log.Printf("MongoDB bulk insert error: %v", err) return } if bulkResult.Modified > 0 { log.Printf("Modified %d records", bulkResult.Modified) } total, err := coll.Count() if err != nil { log.Printf("MongoDB total counting error: %v", err) return } log.Printf("Total unique records in DB: %d", total) }