def __init__(self, resource): super(FlowtableDriver, self).__init__(data_resource=resource) self.env = self.resource.parent.grassenvironment self.ensure_grass() self._grassdatalookup = GrassDataLookup(self.g, self.grass_lowlevel)
class FlowtableDriver(drivers.Driver): def __init__(self, resource): super(FlowtableDriver, self).__init__(data_resource=resource) self.env = self.resource.parent.grassenvironment self.ensure_grass() self._grassdatalookup = GrassDataLookup(self.g, self.grass_lowlevel) def ensure_grass(self): if 'GISRC' not in os.environ: os.environ['LD_LIBRARY_PATH'] = ':'.join([os.environ['LD_LIBRARY_PATH'], "/usr/lib/grass64/lib"]) os.putenv("LD_LIBRARY_PATH",':'.join([os.environ['LD_LIBRARY_PATH'], "/usr/lib/grass64/lib"])) os.environ['DYLD_LIBRARY_PATH'] = os.path.join(settings.GISBASE, 'lib') os.putenv("DYLD_LIBRARY_PATH", os.path.join(settings.GISBASE, "lib")) os.environ['GIS_LOCK'] = str(os.getpid()) os.putenv('GIS_LOCK',str(os.getpid())) os.environ['GISRC'] = self._initializeGrassrc() os.putenv('GISRC', os.environ['GISRC']) if 'LOCATION_NAME' not in os.environ: os.environ['LOCATION_NAME'] = self.env.location os.putenv('LOCATION_NAME', self.env.location) if not hasattr(self, '_gsetup'): self._gsetup = importlib.import_module('grass.script.setup') self.g = importlib.import_module("grass.script") self.grass_lowlevel = importlib.import_module('grass.lib.gis') self.grass_lowlevel.G_gisinit('') self._gsetup.init(settings.GISBASE, self.env.database, self.env.location, self.env.map_set) def _initializeGrassrc(self): grassRcFile = tempfile.NamedTemporaryFile(prefix='grassrc-', delete=False) grassRcContent = "GISDBASE: %s\nLOCATION_NAME: %s\nMAPSET: %s\n" % \ (self.env.database, self.env.location, self.env.map_set) grassRcFile.write(grassRcContent) return grassRcFile.name def get_data_fields(self, **kwargs): return self.g.raster.list_pairs('rast') @property def proj(self): if not hasattr(self, '_proj'): self._proj = osr.SpatialReference() self._proj.ImportFromProj4( self.g.raster.read_command('g.proj', flags='j') ) return self._proj @property def region(self): if not hasattr(self, '_region'): self._region = self.g.region() return self._region def get_real_srs(self, srs): r_srs = osr.SpatialReference() if isinstance(srs, basestring): if srs.lower().startswith('epsg'): srs = int(srs[5:]) r_srs.ImportFromEPSG(srs) else: r_srs.ImportFromProj4(srs) else: r_srs.ImportFromEPSG(srs) return r_srs def get_fqpatch(self, srs, wherex, wherey): r_srs = self.get_real_srs(srs) crx = osr.CoordinateTransformation(r_srs, self.proj) easting, northing, _ = crx.TransformPoint(wherex, wherey) print crx print easting, northing, srs ### everything below here is specific to rhessys and the hackathon ### _, _, _, patch = self.g.read_command("r.what", **{ "input" : 'patch_5m', "null" : "None", "east_north" : "{easting},{northing}".format(easting=easting, northing=northing) }).strip().split('|') _, _, _, hillslope = self.g.read_command("r.what", **{ "input" : 'hillslope', "null" : "None", "east_north" : "{easting},{northing}".format(easting=easting, northing=northing) }).strip().split('|') _, _, _, zone = self.g.read_command("r.what", **{ "input" : 'hillslope', "null" : "None", "east_north" : "{easting},{northing}".format(easting=easting, northing=northing) }).strip().split('|') patch = int(patch) hillslope = int(hillslope) zone = int(zone) return patch, hillslope, zone def get_data_for_point(self, wherex, wherey, srs, fuzziness=0, **kwargs): patch, hillslope, zone = self.get_fqpatch(srs, wherex, wherey) fqpatch_id = FQPatchID(patchID=patch, hillID=hillslope, zoneID=zone) r_srs = self.get_real_srs(srs) # setup redis if necessary if not flowtable.llen(self.env.flow_table.name): flow_table = flowtableio.readFlowtable(os.path.join(settings.MEDIA_ROOT, self.env.flow_table.name)) for fqpatchid, entry in flow_table.items(): key = cPickle.dumps(fqpatchid) value = flowtableio.dumpReceivers(entry) flowtable.rpush(self.env.flow_table.name, key) flowtable.hset(self.env.flow_table.name + ".hash", key, value) # total_gamma = flowtableio.getEntryForFlowtableKey(fqpatch_id, self.flow_table).totalGamma hkey = cPickle.dumps(fqpatch_id) flowtable_entry = flowtableio.loadReceivers(flowtable.hget(self.env.flow_table.name + ".hash", hkey)) total_gamma = flowtable_entry[0].totalGamma receivers = [fqpatch_id] + flowtable_entry[1:] coords = self._grassdatalookup.getCoordinatesForFQPatchIDs( receivers, 'patch_5m','hillslope','hillslope') xrc = osr.CoordinateTransformation(self.proj, r_srs) self.ensure_grass() rasters = self.g.list_strings('rast') def best_type(k): try: return int(k) except: try: return float(k) except: return k c = [] for i, (fqpatchid, pairs) in enumerate(coords.items()): for a in pairs: c.append({ "type" : "Feature", "geometry" : { "type" : "Point", "coordinates" : xrc.TransformPoint(a.easting, a.northing)[0:2] }, "properties" : { "patchId" : fqpatchid.patchID, 'zoneId' : fqpatchid.zoneID, "hillId" : fqpatchid.hillID, "gamma" : receivers[i].gamma if hasattr(receivers[i], 'gamma') else None, "total_gamma" : None if hasattr(receivers[i], 'gamma') else total_gamma } }) return { "type" : "FeatureCollection", "features" : c } def get_metadata(self, **kwargs): return [] def compute_fields(self, **kwargs): r = self.region s_srs = self.proj e4326 = osr.SpatialReference() e4326.ImportFromEPSG(4326) crx = osr.CoordinateTransformation(s_srs, e4326) x0, y0, x1, y1 = r['w'], r['s'], r['e'], r['n'] self.resource.spatial_metadata.native_srs = s_srs xx0, yy0, _ = crx.TransformPoint(r['w'], r['s']) xx1, yy1, _ = crx.TransformPoint(r['e'], r['n']) self.resource.spatial_metadata.native_bounding_box = Polygon.from_bbox((x0, y0, x1, y1)) self.resource.spatial_metadata.bounding_box = Polygon.from_bbox((xx0, yy0, xx1, yy1)) self.resource.spatial_metadata.three_d = False self.resource.spatial_metadata.save() def ready_data_resource(self, **kwargs): print "ready data resource" r = self.region s_srs = self.proj print s_srs print s_srs.ExportToProj4() e3857 = osr.SpatialReference() e3857.ImportFromEPSG(3857) crx = osr.CoordinateTransformation(s_srs, e3857) x0, y0, x1, y1 = r['w'], r['s'], r['e'], r['n'] self.resource.spatial_metadata.native_srs = s_srs.ExportToProj4() xx0, yy0, _ = crx.TransformPoint(x0, y0) xx1, yy1, _ = crx.TransformPoint(x1, y1) raster = kwargs['RASTER'] if 'RASTER' in kwargs else self.env.default_raster cached_basename = os.path.join(self.cache_path, raster) cached_tiff = cached_basename + '.tif' output = cached_basename + '.native.tif' output_prj = cached_basename+ '.native.prj' print cached_tiff if not os.path.exists(cached_tiff): print "generating tiff" # Remove GRASS mask if present self.g.run_command('r.mask', flags='r') # TODO: Dynamically set name of mask layer # Mask layer must be 0|1 raster with 0 representing areas to # exclude mask = 'basin_dr5' # TODO: Make export layer contain session ID, etc. to support multi # user export = 'export' if mask: # Use mask to properly set alpha channel of exported TIFF self.g.write_command('r.mapcalc', stdin="{export}=if({mask},{raster},{mask})".format(export=export, mask=mask, raster=raster) ) self.g.run_command('r.out.gdal', flags='f', type='UInt16', input=export, output=output) else: self.g.run_command('r.out.gdal', flags='f', type='UInt16', input=raster, output=output) with open(output_prj, 'w') as prj: prj.write(s_srs.ExportToWkt()) sh.gdalwarp("-s_srs", output_prj, "-t_srs", "EPSG:3857", output, cached_tiff, '-srcnodata', '0', '-dstalpha') if export: # Clean up temporary export raster self.g.run_command('g.remove', rast=export) return self.cache_path, ( self.resource.slug, e3857.ExportToProj4(), { "type" : "gdal", "file" : cached_tiff, } )