Пример #1
0
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)
}
Пример #2
0
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)
}
Пример #3
0
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)
}
Пример #4
0
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)
}