github.com/janelia-flyem/dvid@v1.0.0/datatype/imagetile/push.go (about) 1 package imagetile 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/janelia-flyem/dvid/datastore" 8 "github.com/janelia-flyem/dvid/datatype/roi" 9 "github.com/janelia-flyem/dvid/dvid" 10 "github.com/janelia-flyem/dvid/storage" 11 ) 12 13 // PushData does an imagetile-specific push using optional ROI and tile filters. 14 func (d *Data) PushData(p *datastore.PushSession) error { 15 return datastore.PushData(d, p) 16 } 17 18 // --- dvid.Filterer implementation ----- 19 20 // NewFilter returns a Filter for use with a push of key-value pairs. 21 func (d *Data) NewFilter(fs storage.FilterSpec) (storage.Filter, error) { 22 filter := &Filter{Data: d, fs: fs} 23 24 // if there's no filter, just use base Data send. 25 roidata, roiV, roiFound, err := roi.DataByFilter(fs) 26 if err != nil { 27 return nil, fmt.Errorf("No filter found that was parsable (%s): %v\n", fs, err) 28 } 29 filter.roi = roidata 30 tilespec, tilespecFound := fs.GetFilterSpec("tile") 31 32 if (!roiFound || roidata == nil) && !tilespecFound { 33 dvid.Debugf("No ROI or tile filter found for imagetile push, so using generic data push.\n") 34 return nil, nil 35 } 36 if tilespecFound { 37 filter.planes = strings.Split(tilespec, ",") 38 } 39 40 // Get the spans once from datastore. 41 filter.spans, err = roidata.GetSpans(roiV) 42 if err != nil { 43 return nil, err 44 } 45 46 return filter, nil 47 } 48 49 // --- dvid.Filter implementation ---- 50 51 type Filter struct { 52 *Data 53 fs storage.FilterSpec 54 roi *roi.Data 55 spans dvid.Spans 56 planes []string 57 } 58 59 func (f *Filter) Check(tkv *storage.TKeyValue) (skip bool, err error) { 60 tileCoord, plane, scale, err := DecodeTKey(tkv.K) 61 if err != nil { 62 return true, fmt.Errorf("key (%v) cannot be decoded as tile: %v", tkv.K, err) 63 } 64 if len(f.planes) != 0 { 65 var allowed bool 66 for _, allowedPlane := range f.planes { 67 if allowedPlane == "xy" && plane.Equals(dvid.XY) { 68 allowed = true 69 break 70 } 71 if allowedPlane == "xz" && plane.Equals(dvid.XZ) { 72 allowed = true 73 break 74 } 75 if allowedPlane == "yz" && plane.Equals(dvid.YZ) { 76 allowed = true 77 break 78 } 79 } 80 if !allowed { 81 return true, nil 82 } 83 } 84 extents, err := f.computeVoxelBounds(tileCoord, plane, scale) 85 if err != nil { 86 return true, fmt.Errorf("Error computing voxel bounds of tile: %v\n", err) 87 } 88 if inside, err := roi.VoxelBoundsInside(extents, f.roi.BlockSize, f.spans); err != nil { 89 return true, fmt.Errorf("can't determine intersection of tile and roi: %v\n", err) 90 } else if !inside { 91 return true, nil 92 } 93 return false, nil 94 }