Пример #1
0
// Set sets a value of a raster in the database.
func (d *distros) set(vals []jdh.KeyValue) error {
	id := ""
	for _, kv := range vals {
		if len(kv.Value) == 0 {
			continue
		}
		if kv.Key == jdh.KeyId {
			id = kv.Value[0]
			break
		}
	}
	if len(id) == 0 {
		return errors.New("raster without identification")
	}
	rd, ok := d.ids[id]
	if !ok {
		return nil
	}
	ras := rd.data
	for _, kv := range vals {
		switch kv.Key {
		case jdh.RasPixel:
			if len(kv.Value) == 0 {
				continue
			}
			v := strings.TrimSpace(kv.Value[0])
			if len(v) == 0 {
				continue
			}
			coor := strings.Split(v, ",")
			if len(coor) != 3 {
				return errors.New("invalid raster pixel reference: " + v)
			}
			x64, err := strconv.ParseInt(coor[0], 10, 0)
			if err != nil {
				return err
			}
			y64, err := strconv.ParseInt(coor[1], 10, 0)
			if err != nil {
				return err
			}
			p64, err := strconv.ParseInt(coor[2], 10, 0)
			if err != nil {
				return err
			}
			pt, px := image.Pt(int(x64), int(y64)), int(p64)
			if ras.Raster.At(pt) == px {
				continue
			}
			ras.Raster.Set(pt, px)
		case jdh.RDisSource:
			v := jdh.UnknownRaster
			if len(kv.Value) > 0 {
				v = jdh.GetRasterSource(strings.TrimSpace(kv.Value[0]))
			}
			if ras.Source == v {
				continue
			}
		case jdh.RDisTaxon:
			v := ""
			if len(kv.Value) > 0 {
				v = strings.TrimSpace(kv.Value[0])
			}
			if len(v) == 0 {
				continue
			}
			if ras.Taxon == v {
				continue
			}
			tax, ok := d.taxId[v]
			if !ok {
				if !d.db.t.isInDB(v) {
					continue
				}
				tax = &rasTaxon{
					id:   v,
					rsLs: list.New(),
				}
				tax.elem = d.taxLs.PushBack(tax)
				d.taxId[tax.id] = tax
			}
			oldtax := rd.taxon
			oldtax.rsLs.Remove(rd.elem)
			rd.elem = tax.rsLs.PushBack(rd)
			rd.taxon = tax
			rd.data.Taxon = tax.id
			if oldtax.rsLs.Len() == 0 {
				oldtax.rsLs = nil
				d.taxLs.Remove(oldtax.elem)
				oldtax.elem = nil
				delete(d.taxId, oldtax.id)
			}
		case jdh.KeyComment:
			v := ""
			if len(kv.Value) > 0 {
				v = strings.TrimSpace(kv.Value[0])
			}
			if ras.Comment == v {
				continue
			}
			ras.Comment = v
		case jdh.KeyExtern:
			ok := false
			for _, v := range kv.Value {
				v = strings.TrimSpace(v)
				if len(v) == 0 {
					continue
				}
				serv, ext, err := jdh.ParseExtern(v)
				if err != nil {
					return err
				}
				if len(ext) == 0 {
					if !d.delExtern(rd, serv) {
						continue
					}
					ok = true
					continue
				}
				if d.addExtern(rd, v) != nil {
					continue
				}
				ok = true
			}
			if !ok {
				continue
			}
		case jdh.KeyReference:
			v := ""
			if len(kv.Value) > 0 {
				v = strings.TrimSpace(kv.Value[0])
			}
			if ras.Reference == v {
				continue
			}
			ras.Reference = v
		default:
			continue
		}
		d.changed = true
	}
	return nil
}
Пример #2
0
// List returns a list of rasters.
func (d *distros) list(vals []jdh.KeyValue) (*list.List, error) {
	l := list.New()
	noVal := true
	// creates the list
	for _, kv := range vals {
		if len(kv.Value) == 0 {
			continue
		}
		if kv.Key == jdh.RDisTaxon {
			if len(kv.Value[0]) == 0 {
				return nil, errors.New("taxon without identification")
			}
			tax, ok := d.taxId[kv.Value[0]]
			if !ok {
				return l, nil
			}
			for e := tax.rsLs.Front(); e != nil; e = e.Next() {
				rd := e.Value.(*raster)
				l.PushBack(rd.data)
			}
			noVal = false
			break
		}
		if kv.Key == jdh.RDisTaxonParent {
			if len(kv.Value[0]) == 0 {
				return nil, errors.New("taxon without identification")
			}
			pId := kv.Value[0]
			if !d.db.t.isInDB(pId) {
				return l, nil
			}
			for m := d.taxLs.Front(); m != nil; m = m.Next() {
				tax := m.Value.(*rasTaxon)
				if tax.id != pId {
					if !d.db.t.isDesc(tax.id, pId) {
						continue
					}
				}
				for e := tax.rsLs.Front(); e != nil; e = e.Next() {
					rd := e.Value.(*raster)
					l.PushBack(rd.data)
				}
			}
			noVal = false
			break
		}
	}
	if noVal {
		return nil, errors.New("taxon without identification")
	}

	// filters the list
	for _, kv := range vals {
		if l.Len() == 0 {
			break
		}
		if len(kv.Value) == 0 {
			continue
		}
		switch kv.Key {
		case jdh.RDisCols:
			val, err := strconv.ParseUint(kv.Value[0], 10, 0)
			if (err != nil) || (val == 0) {
				break
			}
			v := uint(val)
			for e := l.Front(); e != nil; {
				nx := e.Next()
				ras := e.Value.(*jdh.Raster)
				if ras.Cols != v {
					l.Remove(e)
				}
				e = nx
			}
		case jdh.RDisSource:
			val := strings.ToLower(strings.TrimSpace(kv.Value[0]))
			v := jdh.GetRasterSource(val)
			if v.String() != val {
				break
			}
			for e := l.Front(); e != nil; {
				nx := e.Next()
				ras := e.Value.(*jdh.Raster)
				if ras.Source != v {
					l.Remove(e)
				}
				e = nx
			}
		}
	}
	return l, nil
}