Beispiel #1
0
    def structures(self, elev, stream=None, ndigits=0, resolution=None, contour=None):
        """Return a tuple with lines structres options of a hypotetical plant.

        ::

              river
               \ \
                \i\-------_______
                |\ \              \
                | \ \              \
                )  \ \              )  cond0
               /    \ \           /
              /      \ \         /
             ( cond1  \ \       /
              \        \ \      |
               \        \ \     |
                \        \ \    |
                 o--------\r\---o
               pstk1       \ \   pstk0
                            \ \

        Parameters
        ----------

        elev: raster
            Raster instance already opened with the elevation.
        intake_pnt: point
            It is the point of the intake.
        restitution_pnt: point
            It is the point of the restitution.

        Returns
        -------

        a list of tuple: [(HydroStruct(intake, conduct=cond0, penstock=pstk0),
                           HydroStruct(intake, conduct=cond1, penstock=pstk1))]
           Return a list of tuples, containing two HydroStruct the first with
           the shortest penstock and the second with the other option.
        """

        def get_struct(contur, respoint):
            """Return the lines of the conduct and the penstock.

            Parameters
            ----------

            contur: line segment
                It is a line segment of the contur line splited with splitline
                function, where the first point is the intake.
            respoint: point
                It is the point of the plant restitution.

            Returns
            -------

            tuple: (conduct, penstock)
               Return two lines, the first with the conduct and the second with
               the penstock. Note: both conduct and penstock lines are coherent
               with water flow direction.
            """
            dist = contur.distance(respoint)
            conduct = contur.segment(0, dist.sldist)
            penstock = Line([dist.point, respoint])
            return conduct, penstock

        def get_all_structs(contur, itk, res):
            l0, l1 = splitline(contur, itk.point, 3 * itk.point.distance(res.point))
            # get structs
            c0, p0 = get_struct(l0, res.point)
            c1, p1 = get_struct(l1, res.point)
            s0, s1 = "option0", "option1"
            # TODO: uncomment this to have left and right distinction...
            # but sofar is not working properly, therefore is commented.
            # if stream is not None:
            #    sitk = stream.find['by_point'].geo(itk.point, maxdist=100000)
            #    s0, s1 = (('right', 'left') if isinverted(sitk, elev, reg)
            #              else ('left', 'right'))
            return (HydroStruct(itk, c0, p0, s0), HydroStruct(itk, c1, p1, s1))

        result = []
        if contour is None:
            levels = sorted(
                set(
                    [
                        closest(itk.elevation, ndigits=ndigits, resolution=resolution)
                        for itk in self.intakes
                    ]
                )
            )

            # generate the contur line that pass to the point
            contour_tmp = "tmpvect%04d" % random.randint(1000, 9999)
            r.contour(
                input="%s@%s" % (elev.name, elev.mapset),
                output=contour_tmp,
                step=0,
                levels=levels,
                overwrite=True,
            )

            cnt = VectorTopo(contour_tmp)
            cnt.open()
        else:
            cnt = contour

        for itk in self.intakes:
            # find the closest contur line
            contur_res = cnt.find["by_point"].geo(
                self.restitution.point, maxdist=100000.0
            )

            # TODO: probably find the contur line for the intake and
            # the restitution it is not necessary, and we could also remove
            # the check bellow: contur_itk.id != contur_res.id
            contur_itk = cnt.find["by_point"].geo(itk.point, maxdist=100000.0)
            if contur_itk is None or contur_res is None:
                msg = (
                    "Not able to find the contur line closest to the "
                    "intake point %r, of the plant %r"
                    "from the contur line map: %s"
                )
                raise TypeError(msg % (itk, self, cnt.name))
            if contur_itk.id != contur_res.id:
                print("=" * 30)
                print(itk)
                msg = (
                    "Contur lines are different! %d != %d, in %s."
                    "Therefore %d will be used."
                )
                print(msg % (contur_itk.id, contur_res.id, cnt.name, contur_itk.id))

            # check contour
            contur = not_overlaped(contur_itk)
            contur = sort_by_west2east(contur)
            result.append(get_all_structs(contur, itk, self.restitution))

        # remove temporary vector map
        if contour is None:
            cnt.close()
            cnt.remove()
        return result
Beispiel #2
0
def write_structures(plants,
                     output,
                     elev,
                     stream=None,
                     ndigits=0,
                     resolution=None,
                     contour='',
                     overwrite=False):
    """Write a vector map with the plant structures"""
    def write_hydrostruct(out, hydro, plant):
        pot = plant.potential_power(intakes=[
            hydro.intake,
        ])
        (plant_id, itk_id, side, disch,
         gross_head) = (plant.id, hydro.intake.id, hydro.side,
                        float(hydro.intake.discharge),
                        float(hydro.intake.elevation -
                              plant.restitution.elevation))
        out.write(hydro.conduct,
                  (plant_id, itk_id, disch, 0., 0., 'conduct', side))
        out.write(hydro.penstock,
                  (plant_id, itk_id, disch, gross_head, pot, 'penstock', side))
        out.table.conn.commit()

    tab_cols = [
        (u'cat', 'INTEGER PRIMARY KEY'),
        (u'plant_id', 'VARCHAR(10)'),
        (u'intake_id', 'INTEGER'),
        (u'discharge', 'DOUBLE'),
        (u'gross_head', 'DOUBLE'),
        (u'power', 'DOUBLE'),
        (u'kind', 'VARCHAR(10)'),
        (u'side', 'VARCHAR(10)'),
    ]

    with VectorTopo(output, mode='w', overwrite=overwrite) as out:
        link = Link(layer=1, name=output, table=output, driver='sqlite')
        out.open('w')
        out.dblinks.add(link)
        out.table = out.dblinks[0].table()
        out.table.create(tab_cols)

        print('Number of plants: %d' % len(plants))

        # check if contour vector map is provide by the user
        if contour:
            cname, cmset = (contour.split('@') if '@' in contour else
                            (contour, ''))
            # check if the map already exist
            if bool(utils.get_mapset_vector(cname, cmset)) and overwrite:
                compute_contour = True
            remove = False
        else:
            # create a random name
            contour = 'tmp_struct_contour_%05d_%03d' % (os.getpid(),
                                                        random.randint(0, 999))
            compute_contour = True
            remove = True

        if compute_contour:
            # compute the levels of the contour lines map
            levels = []
            for p in plants.values():
                for itk in p.intakes:
                    levels.append(
                        closest(itk.elevation,
                                ndigits=ndigits,
                                resolution=resolution))
            levels = sorted(set(levels))
            # generate the contur line that pass to the point
            r.contour(input='%s@%s' % (elev.name, elev.mapset),
                      output=contour,
                      step=0,
                      levels=levels,
                      overwrite=True)

        # open the contur lines
        with VectorTopo(contour, mode='r') as cnt:
            for plant in plants.values():
                print(plant.id)
                for options in plant.structures(elev,
                                                stream=stream,
                                                ndigits=ndigits,
                                                resolution=resolution,
                                                contour=cnt):
                    for hydro in options:
                        print('writing: ', hydro.intake)
                        write_hydrostruct(out, hydro, plant)

        if remove:
            cnt.remove()
Beispiel #3
0
def write_structures(
    plants,
    output,
    elev,
    stream=None,
    ndigits=0,
    resolution=None,
    contour="",
    overwrite=False,
):
    """Write a vector map with the plant structures"""

    def write_hydrostruct(out, hydro, plant):
        pot = plant.potential_power(
            intakes=[
                hydro.intake,
            ]
        )
        (plant_id, itk_id, side, disch, gross_head) = (
            plant.id,
            hydro.intake.id,
            hydro.side,
            float(hydro.intake.discharge),
            float(hydro.intake.elevation - plant.restitution.elevation),
        )
        out.write(hydro.conduct, (plant_id, itk_id, disch, 0.0, 0.0, "conduct", side))
        out.write(
            hydro.penstock, (plant_id, itk_id, disch, gross_head, pot, "penstock", side)
        )
        out.table.conn.commit()

    tab_cols = [
        (u"cat", "INTEGER PRIMARY KEY"),
        (u"plant_id", "VARCHAR(10)"),
        (u"intake_id", "INTEGER"),
        (u"discharge", "DOUBLE"),
        (u"gross_head", "DOUBLE"),
        (u"power", "DOUBLE"),
        (u"kind", "VARCHAR(10)"),
        (u"side", "VARCHAR(10)"),
    ]

    with VectorTopo(output, mode="w", overwrite=overwrite) as out:
        link = Link(layer=1, name=output, table=output, driver="sqlite")
        out.open("w")
        out.dblinks.add(link)
        out.table = out.dblinks[0].table()
        out.table.create(tab_cols)

        print("Number of plants: %d" % len(plants))

        # check if contour vector map is provide by the user
        if contour:
            cname, cmset = contour.split("@") if "@" in contour else (contour, "")
            # check if the map already exist
            if bool(utils.get_mapset_vector(cname, cmset)) and overwrite:
                compute_contour = True
            remove = False
        else:
            # create a random name
            contour = "tmp_struct_contour_%05d_%03d" % (
                os.getpid(),
                random.randint(0, 999),
            )
            compute_contour = True
            remove = True

        if compute_contour:
            # compute the levels of the contour lines map
            levels = []
            for p in plants.values():
                for itk in p.intakes:
                    levels.append(
                        closest(itk.elevation, ndigits=ndigits, resolution=resolution)
                    )
            levels = sorted(set(levels))
            # generate the contur line that pass to the point
            r.contour(
                input="%s@%s" % (elev.name, elev.mapset),
                output=contour,
                step=0,
                levels=levels,
                overwrite=True,
            )

        # open the contur lines
        with VectorTopo(contour, mode="r") as cnt:
            for plant in plants.values():
                print(plant.id)
                for options in plant.structures(
                    elev,
                    stream=stream,
                    ndigits=ndigits,
                    resolution=resolution,
                    contour=cnt,
                ):
                    for hydro in options:
                        print("writing: ", hydro.intake)
                        write_hydrostruct(out, hydro, plant)

        if remove:
            cnt.remove()
file = '/appl/data/geo/mml/dem10m/2019/W3/W33/W3331.tif'
grassfile = 'W3331'
grasscontoursfile = 'W3331_contours'
contoursfile = "/scratch/project_2000599/grass/output/V4132.gpkg"

# Register external GeoTIFF in current mapset:
r.external(input=file, output=grassfile, flags="e", overwrite=True)

# Set GRASS region
g.region(raster=grassfile)

# Perform GRASS analysis, here calculate contours from DEM
r.contour(input=grassfile,
          output=grasscontoursfile,
          minlevel=200,
          maxlevel=800,
          step=10,
          overwrite=True)

#Write output to file
v.out_ogr(input=grasscontoursfile, output=contoursfile, overwrite=True)

# These can be left out, just debug info
# TODO: not working properly!
print("\n\n ***DEBUG INFO***")
print("GRASS version")
print(g.version())

print("GRASS env settings: gisdatabase, location, mapset")
print(g.gisenv())