Ejemplo n.º 1
0
def bspline_param(vectormap, depvar):
    """Get output bspline parameter estimates"""
    stfact = Module("v.surf.bspline",
                    flags="ec",
                    input=vectormap,
                    column=depvar,
                    memory=1024,
                    stdout_=PIPE).outputs.stdout
    stepdist = float(stfact.split(':')[-1].strip())
    stfact = Module("v.surf.bspline",
                    flags="c",
                    input=vectormap,
                    ew_step=stepdist,
                    ns_step=stepdist,
                    column=depvar,
                    memory=1024,
                    stdout_=PIPE).outputs.stdout
    stfact = stfact.replace(" ", "")
    stfact = stfact.split("\n")[1:-1]
    stfact = [z.split("|") for z in stfact]
    stfact = [[float(x) for x in y if x != ''] for y in stfact]
    minlambda = min(stfact, key=lambda x: abs(x[1]))[0]
    return (stepdist, minlambda)
Ejemplo n.º 2
0
def main(options, flags):

    # Check if running in GRASS
    gisbase = os.getenv("GISBASE")
    if not gisbase:
        gs.fatal(
            _("$GISBASE not defined. You must be in GRASS GIS to run \
        this program"))
        return 0

    # Input
    IP = options['input']
    OP = options['output']
    CSV = options['csv']
    QGIS = options['qgis']
    flags_n = flags['n']

    # Check if raster is integer
    iscell = gs.raster.raster_info(IP)["datatype"]
    if iscell != u'CELL':
        gs.error(_('Input should be an integer raster layer'))

    # Get map category values and their labels
    CATV = Module('r.category', map=IP, stdout_=PIPE).outputs.stdout
    RCAT = CATV.split('\n')
    RCAT = filter(None, RCAT)
    RID = [z.split('\t')[0] for z in RCAT]
    RIDI = map(int, RID)

    # Get full color table
    RCOL = gs.read_command("r.colors.out", map=IP).split('\n')
    RCOL = [x for x in RCOL if "nv" not in x and 'default' not in x]
    RCOL = filter(None, RCOL)
    CCAT = [z.split(' ')[0] for z in RCOL]
    idx = [i for i, item in enumerate(CCAT) if not re.search('\.', item)]
    CCAT = [CCAT[i] for i in idx]
    RCOL = [RCOL[i] for i in idx]
    CCAT = map(int, CCAT)

    # Set strings / list to be used in loop
    CR = ""
    RECO = ""
    CL = ""
    CV = []

    # recode to consecutive category values
    if flags_n:
        RIDN = range(1, len(RID) + 1)
        RLAB = [z.split('\t')[1] for z in RCAT]
        for j in xrange(len(RID)):
            RECO = '{0}{1}:{1}:{2}\n'.format(RECO, RID[j], RIDN[j])
            A = map(int, [i for i, x in enumerate(CCAT) if x == RIDI[j]])
            CV.append(RCOL[A[0]].split(' ')[1])
            CR = '{}{} {}\n'.format(CR, RIDN[j], CV[j])
            CL = '{}{}|{}\n'.format(CL, RIDN[j], RLAB[j])

        CR = '{}nv 255:255:255\ndefault 255:255:255\n'.format(CR)
        Module("r.recode",
               flags="a",
               input=IP,
               output=OP,
               rules="-",
               stdin_=RECO,
               quiet=True)
        Module("r.colors", map=OP, rules="-", stdin_=CR, quiet=True)
        Module("r.category",
               map=OP,
               rules="-",
               stdin_=CL,
               quiet=True,
               separator="pipe")
    else:
        # Check if new layer should be created
        if len(OP) > 0:
            k = '{},{}'.format(IP, OP)
            gs.run_command("g.copy", raster=k)
        else:
            OP = IP

        # Remove redundant categories
        Module('r.category', map=OP, rules="-", stdin_=CATV, quiet=True)

        # Write color rules and assign colors
        for j in xrange(len(RIDI)):
            A = map(int, [i for i, x in enumerate(CCAT) if x == RIDI[j]])
            CV.append(RCOL[A[0]].split(' ')[1])
            CR = CR + str(RIDI[j]) + " " + CV[j] + "\n"
        CR = '{}nv 255:255:255\ndefault 255:255:255\n'.format(CR)
        Module("r.colors", map=OP, rules="-", stdin_=CR, quiet=True)

    # If attribute table (csv format) should be written
    if len(CSV) > 0:
        if flags_n:
            RCAT1 = [w.replace('|', ',') for w in filter(None, CL.split('\n'))]
        else:
            RCAT1 = [w.replace('\t', ',') for w in RCAT]
        RCAT1.insert(0, "CATEGORY,CATEGORY LABEL")
        CV1 = list(CV)
        CV1.insert(0, "RGB")
        with open(CSV, "w") as text_file:
            for k in xrange(len(RCAT1)):
                text_file.write('{},{}\n'.format(RCAT1[k], CV1[k]))

    # If QGIS Color Map text files should be written
    if len(QGIS) > 0:
        RGB = [w.replace(':', ',') for w in CV]
        if flags_n:
            RCAT = filter(None, CL.split('\n'))
            RCAT = [w.replace('|', ',') for w in RCAT]
        else:
            RCAT = [w.replace('\t', ',') for w in RCAT]
        with open(QGIS, "w") as text_file:
            text_file.write('# QGIS color map for {}\n'.format(OP))
            text_file.write("INTERPOLATION:EXACT\n")
            for k in xrange(len(RCAT)):
                RC2 = RCAT[k].split(',')
                text_file.write('{},{},255,{}\n'.format(
                    RC2[0], RGB[k], RC2[1]))
Ejemplo n.º 3
0
def compute(pnt, dem, obs_heigh, maxdist, hcurv, downward, oradius, i, nprocs, obsabselev, memory):
    try:
        #the followig lines help to set a delay between a process and the others
        starting.acquire() # no other process can get it until it is released
        threading.Timer(0.1, starting.release).start() # release in a 0.1 seconds
        #using temporary regions (on the same mapset) for the different parallel computations
        gscript.use_temp_region()
        #extracting a point from the map of the locations
        Module("v.extract", input=pnt, output="zzpnt"+i, cats=i, flags="t", overwrite=True, quiet=True)
        #getting goordinates of the point location
        coords=Module("v.to.db", flags="p", map="zzpnt"+i, type="point", option="coor", separator="|", stdout_=PIPE)
        coords=coords.outputs.stdout.splitlines()[1:][0]
        x=float(coords.split("|")[1])
        y=float(coords.split("|")[2])
        z=float(coords.split("|")[3])
        coords=str(x)+","+str(y)
        #get elevation of the terrain at the point location
        querydem=Module("r.what", coordinates=coords.split(), map=dem, stdout_=PIPE)
        obselev=float(querydem.outputs.stdout.split("|")[3])
        #setting the working region around the point location
        Module("g.region", vector="zzpnt"+i)
        region = grasscore.region()
        E = region['e']
        W = region['w']
        N = region['n']
        S = region['s']
        #Module("g.region", flags="a", e=E+maxdist, w=W-maxdist, s=S-maxdist, n=N+maxdist) 
        Module("g.region", align=dem, e=E+maxdist, w=W-maxdist, s=S-maxdist, n=N+maxdist)
        #now we check if the size of the object for which we calculate solid angle in each pixel is equal to half the resolution or is set by the user
        if oradius == 0: 
            circle_radius=region['nsres']/2
        else:
            circle_radius=oradius
        #Executing viewshed analysis
        if obsabselev:
            relative_height = z - obselev
            #message1 = "* Considered elevation of dem/dsm is: %s *"
            #message2 = "* Relative height of observer above the dem/dsm is: %s *"
            #message3 = "* Absolute elevation of observer used in r.viewshed is: %s *"
            #gscript.message(message1 % (str(obselev)) )
            #gscript.message(message2 % (str(relative_height)))
            #gscript.message(message3 % (str(z)))
            if hcurv:
                Module("r.viewshed", input=dem, output="zzview"+i, coordinates=coords.split(), memory=memory, observer_elevation=relative_height, max_distance=maxdist,  flags="c", overwrite=True, quiet=True)
            else:
                Module("r.viewshed", input=dem, output="zzview"+i, coordinates=coords.split(), memory=memory, observer_elevation=relative_height, max_distance=maxdist, overwrite=True, quiet=True)                
            if downward:
                #Since UAV nor Satellite are not expected to see above their level (they are only looking to the ground) vertical angles above 90 are set to null. 
                Module("r.mapcalc", expression="zzview{I} = if(zzview{I}>90 && zzview{I}<180,null(),zzview{I})".format(I=i), overwrite=True, quiet=True)
        else:
            #message1 = "* Considered elevation of dem/dsm is: %s *"
            #message2 = "* Relative height of observer above the dem/dsm is: %s *"
            #message3 = "* Absolute elevation of observer used in r.viewshed is: %s *"
            #gscript.message(message1 % (str(obselev)) )
            #gscript.message(message2 % (str(obs_heigh)))
            #gscript.message(message3 % (str(obselev + obs_heigh)))            
            if hcurv:
                Module("r.viewshed", input=dem, output="zzview"+i, coordinates=coords.split(), memory=memory, observer_elevation=obs_heigh, max_distance=maxdist, flags="c", overwrite=True, quiet=True)
            else:
                Module("r.viewshed", input=dem, output="zzview"+i, coordinates=coords.split(), memory=memory, observer_elevation=obs_heigh, max_distance=maxdist, overwrite=True, quiet=True)
        #Since r.viewshed set the cell of the output visibility layer to 180 under the point, this cell is set to 0.01 
        Module("r.mapcalc",expression="zzview{I} = if(zzview{I}==180,0,zzview{I})".format(I=i), overwrite=True, quiet=True)
        #estimating the layer of the horizontal angle between point and each visible cell (angle of the horizontal line of sight)         
        Module("r.mapcalc", expression="{A} = \
            if( y()>{py} && x()>{px}, atan(({px}-x())/({py}-y())),  \
            if( y()<{py} && x()>{px}, 180+atan(({px}-x())/({py}-y())),  \
            if( y()<{py} && x()<{px}, 180+atan(({px}-x())/({py}-y())),  \
            if( y()>{py} && x()<{px}, 360+atan(({px}-x())/({py}-y())), \
            if( y()=={py} && x()>{px}, 90, \
            if( y()<{py} && x()=={px}, 180, \
            if( y()=={py} && x()<{px}, 270, \
            if( y()>{py} && x()=={px}, 0 \
            ) ) ) ) ) ) ) )".format(A='zzview_angle'+i,py=y, px=x), overwrite=True, quiet=True)
        #estimating the layer of the vertical angle between point and each visible cell  (angle of the vertical line of sight) ()
        Module("r.mapcalc", expression="zzview90_{I} = zzview{I} - 90".format(I=i), overwrite=True, quiet=True)
        #evaluate the vertical component of the versor oriented along the line of sight         
        Module("r.mapcalc", expression="zzc_view{I} = sin(zzview90_{I})".format(I=i), overwrite=True, quiet=True)
        #evaluate the northern component of the versor oriented along the line of sight  
        Module("r.mapcalc", expression="zzb_view{I} = cos(zzview90_{I})*cos(zzview_angle{I})".format(I=i), overwrite=True, quiet=True)
        #evaluate the eastern component of the versor oriented along the line of sight  
        Module("r.mapcalc", expression="zza_view{I} = cos(zzview90_{I})*sin(zzview_angle{I})".format(I=i), overwrite=True, quiet=True)    
        #estimate the three-dimensional distance between the point and each visible cell
        if obsabselev:
            Module("r.mapcalc", expression="{D} = pow(pow(abs(y()-{py}),2)+pow(abs(x()-{px}),2)+pow(abs({dtm}-{Z}),2),0.5)".format(D='zzdistance'+i, dtm=dem, Z=z, py=y, px=x), overwrite=True, quiet=True)
        else:
            Module("r.mapcalc", expression="{D} = pow(pow(abs(y()-{py}),2)+pow(abs(x()-{px}),2)+pow(abs({dtm}-({obs}+{obs_h})),2),0.5)".format(D='zzdistance'+i, dtm=dem, obs=obselev, obs_h=obs_heigh, py=y, px=x), overwrite=True, quiet=True)
        
        #estimating the layer of the angle between the versor of the terrain and the line of sight
        Module("r.mapcalc", expression="zzangle{I} = acos((zza_view{I}*zza_dem+zzb_view{I}*zzb_dem+zzc_view{I}*zzc_dem)/(sqrt(zza_view{I}*zza_view{I}+zzb_view{I}*zzb_view{I}+zzc_view{I}*zzc_view{I})*sqrt(zza_dem*zza_dem+zzb_dem*zzb_dem+zzc_dem*zzc_dem)))".format(I=i), overwrite=True, quiet=True)
        #in rare cases the angles may results, erroneusly, less than 90. Setting them to 90
        Module("r.mapcalc", expression="zzangle{I} = if(zzangle{I} > 90, zzangle{I}, 90)".format(I=i), overwrite=True, quiet=True) 
        #filtering 3d distance based on angle{I} map
        Module("r.mapcalc", expression="{D} = if(isnull(zzangle{I}),null(),{D})".format(D="zzdistance"+str(i),I=i), overwrite=True, quiet=True)
        #calculating H1 and H2 that are the distances from the observer to the more distant and less distant points of the inclinded circle representing the pixel
        Module("r.mapcalc", expression="zzH1_{I} = pow(pow({r},2)+pow({d},2)-(2*{r}*{d}*cos(270-zzangle{I})),0.5)".format(r=circle_radius,d="zzdistance"+str(i),I=i), overwrite=True, quiet=True) 
        Module("r.mapcalc", expression="zzH2_{I} = pow(pow({r},2)+pow({d},2)-(2*{r}*{d}*cos(zzangle{I}-90)),0.5)".format(r=circle_radius,d="zzdistance"+str(i),I=i), overwrite=True, quiet=True) 
        #calculating B1 and B2 that are the angles between the line passing through the observer and the center of the pixel and the distant and less distant points of the inclinded circle representing the pixel
        Module("r.mapcalc", expression="zzB1_{I} = acos( (pow({r},2)-pow(zzH1_{I},2)-pow({d},2)) / (-2*zzH1_{I}*{d}) ) ".format(r=circle_radius,d="zzdistance"+str(i),I=i), overwrite=True, quiet=True) 
        Module("r.mapcalc", expression="zzB2_{I} = acos( (pow({r},2)-pow(zzH2_{I},2)-pow({d},2)) / (-2*zzH2_{I}*{d}) ) ".format(r=circle_radius,d="zzdistance"+str(i),I=i), overwrite=True, quiet=True) 
        #calculating solid angle considering that the area of an asimetric ellipse is equal to the one of an ellipse having the minor axis equal to the sum of the tqo unequal half minor axes 
        Module("r.mapcalc", expression="zzsangle{I} = ({pi}*{r}*( {d}*tan(zzB1_{I}) + {d}*tan(zzB2_{I}) )/2 )  / (pow({r},2)+pow({d},2)) ".format(r=circle_radius,d="zzdistance"+str(i),I=i,pi=pi), overwrite=True, quiet=True) 
        #approximations for calculating solid angle can create too much larger values under or very close the position of the oserver. in such a case we assume that the solid angle is half of the visible sphere (2*pi)
        #The same occur when it is used an object_radius that is larger than the pixel size. In some cases this can produce negative values of zzB2 with the effect of creating negative values 
        Module("r.mapcalc", expression="zzsangle{I} = if(zzsangle{I}>2*{pi} || zzB2_{I}>=90,2*{pi},zzsangle{I})".format(I=i, pi=pi), overwrite=True, quiet=True)
        #removing temporary region    
        gscript.del_temp_region()
    except:
        #cleaning termporary layers
        #cleanup()
        #message = " ******** Something went wrong: please try to reduce the number of CPU (parameter 'procs') ******* "
        #gscript.message(message)
        #sys.exit()
        f = open("error_cat_"+i+".txt", "x")
        f.write("error in category: "+i)
        f.close()
Ejemplo n.º 4
0
def main(options, flags):

    # Check if running in GRASS
    gisbase = os.getenv("GISBASE")
    if not gisbase:
        gs.fatal(
            _("$GISBASE not defined. You must be in GRASS GIS to run \
        this program"))
        return 0

    # Input
    input_raster = options["input"]
    output_raster = options["output"]
    output_csv = options["csv"]
    output_colorfile = options["qgis"]
    flag_recode = flags["n"]

    # Check if raster is integer
    iscell = gs.raster.raster_info(input_raster)["datatype"]
    if iscell != "CELL":
        gs.error(_("Input should be an integer raster layer"))

    # Get map category values and their labels
    rcategory_output = Module("r.category", map=input_raster,
                              stdout_=PIPE).outputs.stdout
    raster_cats = rcategory_output.split("\n")
    raster_cats = [_f for _f in raster_cats if _f]
    raster_id = [z.split("\t")[0] for z in raster_cats]
    raster_id_list = list(map(int, raster_id))

    # Get full color table
    raster_color = gs.read_command("r.colors.out",
                                   map=input_raster).split("\n")
    raster_color = [
        x for x in raster_color if "nv" not in x and "default" not in x
    ]
    raster_color = [_f for _f in raster_color if _f]
    raster_color_cat = [z.split(" ")[0] for z in raster_color]
    idx = [
        i for i, item in enumerate(raster_color_cat)
        if not re.search("\.", item)
    ]
    raster_color_cat = [raster_color_cat[i] for i in idx]
    raster_color = [raster_color[i] for i in idx]
    raster_color_cat = list(map(int, raster_color_cat))

    # Set strings / list to be used in loop
    color_rules = ""
    recode_rules = ""
    category_string = ""
    cv_string = []

    # recode to consecutive category values
    if flag_recode:
        raster_id_new = list(range(1, len(raster_id) + 1))
        raster_lab = [z.split("\t")[1] for z in raster_cats]
        for j in range(len(raster_id)):
            recode_rules = "{0}{1}:{1}:{2}\n".format(recode_rules,
                                                     raster_id[j],
                                                     raster_id_new[j])
            select_color = list(
                map(
                    int,
                    [
                        i for i, x in enumerate(raster_color_cat)
                        if x == raster_id_list[j]
                    ],
                ))
            if select_color:
                add_color = raster_color[select_color[0]].split(" ")[1]
                color_rules = "{}{} {}\n".format(color_rules, raster_id_new[j],
                                                 add_color)
                category_string = "{}{}|{}\n".format(category_string,
                                                     raster_id_new[j],
                                                     raster_lab[j])
                cv_string.append(add_color)

        color_rules = "{}nv 255:255:255\ndefault 255:255:255\n".format(
            color_rules)
        Module(
            "r.recode",
            flags="a",
            input=input_raster,
            output=output_raster,
            rules="-",
            stdin_=recode_rules,
            quiet=True,
        )
        Module("r.colors",
               map=output_raster,
               rules="-",
               stdin_=color_rules,
               quiet=True)
        Module(
            "r.category",
            map=output_raster,
            rules="-",
            stdin_=category_string,
            quiet=True,
            separator="pipe",
        )
    else:
        # Check if new layer should be created
        if len(output_raster) > 0:
            k = "{},{}".format(input_raster, output_raster)
            gs.run_command("g.copy", raster=k)
        else:
            output_raster = input_raster

        # Remove redundant categories
        Module(
            "r.category",
            map=output_raster,
            rules="-",
            stdin_=rcategory_output,
            quiet=True,
        )

        # Write color rules and assign colors
        for j in range(len(raster_id_list)):
            select_color = list(
                map(
                    int,
                    [
                        i for i, x in enumerate(raster_color_cat)
                        if x == raster_id_list[j]
                    ],
                ))
            if select_color:
                add_color = raster_color[select_color[0]].split(" ")[1]
                color_rules = (color_rules + str(raster_id_list[j]) + " " +
                               add_color + "\n")
                cv_string.append(add_color)
        color_rules = "{}nv 255:255:255\ndefault 255:255:255\n".format(
            color_rules)
        Module("r.colors",
               map=output_raster,
               rules="-",
               stdin_=color_rules,
               quiet=True)

    # If attribute table (csv format) should be written
    if len(output_csv) > 0:
        if flag_recode:
            raster_cat1 = [
                w.replace("|", ",'")
                for w in [_f for _f in category_string.split("\n") if _f]
            ]
        else:
            raster_cat1 = [w.replace("\t", ",'") for w in raster_cats]
        raster_cat1 = ["{}'".format(w) for w in raster_cat1]
        raster_cat1.insert(0, "CATEGORY,CATEGORY LABEL")
        cv_string1 = list(cv_string)
        cv_string1.insert(0, "RGB")
        with open(output_csv, "w") as text_file:
            for k in range(len(raster_cat1)):
                text_file.write("{},{}\n".format(raster_cat1[k],
                                                 cv_string1[k]))

    # If QGIS Color Map text files should be written
    if len(output_colorfile) > 0:
        rgb_string = [w.replace(":", ",") for w in cv_string]
        if flag_recode:
            raster_cats = [_f for _f in category_string.split("\n") if _f]
        else:
            raster_cats = [w.replace("\t", "|") for w in raster_cats]
        with open(output_colorfile, "w") as text_file:
            text_file.write("# QGIS color map for {}\n".format(output_raster))
            text_file.write("INTERPOLATION:EXACT\n")
            for k in range(len(raster_cats)):
                raster_cats2 = raster_cats[k].split("|")
                if raster_cats2[1]:
                    text_file.write("{},{},255,{}\n".format(
                        raster_cats2[0], rgb_string[k], raster_cats2[1]))
                else:
                    text_file.write("{},{},255,{}\n".format(
                        raster_cats2[0], rgb_string[k], "-"))