示例#1
0
func (this *Index) GetWayInBBox(bb geo.Bbox, tag string) ([]int64, error) {
	var ret []int64
	size := bb.Size()
	iter := this.db.NewIterator(util.BytesPrefix([]byte(tag+":")), nil)
	for iter.Next() {
		key := iter.Key()
		//log.Println(iter.Key())
		if key[0] != byte('_') {
			tmp := Bboxfrombytes(iter.Value())
			//TODO determine best ratio
			if bb.IntersectWith(tmp) && size < tmp.Size()*1000 && size*1000 > tmp.Size() {
				//log.Println(iter.Key())
				//				ret = append(ret, Int64frombytes(key))
				k, _ := strconv.ParseInt(strings.Split(string(key[:]), ":")[1], 10, 64)
				ret = append(ret, k)
			}
		}
	}
	iter.Release()
	err := iter.Error()
	log.Printf("%d Ways found in %v", len(ret), bb)
	return ret, err
}
示例#2
0
// Scan before processing need to be call frist after start.
func (this *Db) ParseWays() error {
	//Le dernier est un faux

	start := time.Now()

	//On pull les dernier et on sync in order to "close" database at the end.
	defer this.WayIndex.PullBatch(true)
	//	defer this.WayIndex.db.Close()

	var bb geo.Bbox
	var ways []*osmpbf.Way
	wanted := treeset.NewWith(CompareInt64)
	//wanted := make(map[int64]*osmpbf.Node)

	var cw, cow, cn, last int64
	cow = this.WayIndex.Size()
	last = this.WayIndex.Last()
	found := make(map[int64]*osmpbf.Node, 0)
	//TODO find nodes by block of wa in order to not redecode the start of a block
	for i := 0; i < len(this.Descriptor.Ways)-1; i++ {
		if this.Descriptor.WaysId[i+1] < last {
			//There always be i+1 since the for condition
			continue
		}
		//log.Printf("Parsing block : %d", i)
		objects, err := this.Decoder.DecodeBlocAt(this.Descriptor.Ways[i])
		if err != nil {
			return err
		}
		for _, v := range objects {
			switch v := v.(type) {
			case *osmpbf.Way:
				//TODO better take to long and my be more slow that the little advatage it gave by resuming
				//if has, _ := this.WayIndex.db.Has(Int64bytes(v.ID), nil); has
				if v.ID <= last {
					//log.Printf("Passing %d", v.ID)
					//cow++
					continue
				}

				cw++
				//log.Printf("Adding to search %d", v.ID)
				ways = ExtendWays(ways, v)
				//TODO check ways with no nodes maybe ?
				//TODO used an ordered list (invert)
				for _, nodeId := range v.NodeIDs {
					/*
						for i := 0; i < len(wanted); i++ {
							if nodeId <= wanted[i] {
								break
							}
						}
						//We don't insert if nodeId == wanted[i] (duplicate)
						if i == len(wanted) || nodeId < wanted[i] {
							wanted = append(wanted[:i], append([]int64{nodeId}, wanted[i:]...)...)
						}

						//wanted = append(wanted, nodeId)
						//wanted[nodeId] = nil
					*/
					wanted.Add(nodeId)
				}
				break
			}
		}
		if wanted.Size() > CacheSize || i == len(this.Descriptor.Ways)-2 {
			log.Printf("On parse les points pour %d ways soit %d nodes recherchés", len(ways), wanted.Size())
			//TODO reused allready found on previous round
			found, _ = this.GetNodes(wanted, found)
			//On reset wanted to save space (not obligated but in case it not clear by getNodes)
			wanted.Clear()

			for _, way := range ways {
				for id, nodeId := range way.NodeIDs {
					cn++
					node := found[nodeId]
					p := geo.Point{node.Lon, node.Lat}

					if id == 0 {
						bb = geo.Bbox{p, p}
					} else {
						//TODO
						//Will enlarge bb if needed
						bb.AddInnerPoint(p)
					}
				}
				// environ 15% de temps en plus
				tag := "other"
				if _, ok := way.Tags["natural"]; ok {
					tag = "natural"
				}
				this.WayIndex.Add(way.ID, tag, bb)
			}
			//TODO check For update of file
			//this.WayIndex.db.Sync()

			//For testing purpose
			//log.Printf("%v %v", ways[0].ID, ways[0])
			//a, e := this.WayIndex.Get(ways[0].ID)
			//log.Printf("%v %v", a, e)
			/* //TODO ajout par batch
			log.Println("Starting db insertion")
			this.WayIndex.AddBatch(ways, bb)
			log.Println("db insertion ended")
			*/
			ways = make([]*osmpbf.Way, 0)

			estimation := time.Since(start).Minutes() * (float64(this.Descriptor.TotalWay()-cow) / float64(cw))

			time_esti, _ := time.ParseDuration(fmt.Sprintf("%.4fm", estimation))
			log.Printf("%dk/%dk %.2f/100 TIME ELAPSED : %s ESTIMATION : %s\r", (cw+cow)/1000, this.Descriptor.TotalWay()/1000, float64((cw+cow)*100)/float64(this.Descriptor.TotalWay()), time.Since(start).String(), time_esti.String())
		}
	}

	found = make(map[int64]*osmpbf.Node, 0)
	wanted.Clear()
	return nil
}