def get_lines_from_file(filename, interp_coord='LINEAR'):
        """
        Returns a list of ConstraintLine from an input file
        TODO 1: Value is ignored in i2s file format
        """
        lines = []
        if filename is not None:
            if filename.endswith('.i2s'):
                with bk.Read(filename) as in_i2s:
                    in_i2s.read_header()
                    for i, line in enumerate(in_i2s.get_open_polylines()):
                        lines.append(
                            ConstraintLine(i, list(line.polyline().coords),
                                           interp_coord))

            elif filename.endswith('.shp'):
                if shp.get_shape_type(filename) not in (shapefile.POLYLINE,
                                                        shapefile.POLYLINEZ,
                                                        shapefile.POLYLINEM):
                    raise TatooineException(
                        "The type of file %s is not POLYLINEZ[M]" % filename)
                for i, line in enumerate(shp.get_open_polylines(filename)):
                    lines.append(
                        ConstraintLine(i, list(line.polyline().coords),
                                       interp_coord))

            else:
                raise NotImplementedError(
                    "Only shp and i2s formats are supported for constraint lines"
                )

        return lines
Esempio n. 2
0
    def run(self):
        if self.state == Node.SUCCESS:
            return
        try:
            with open(self.filename):
                pass
        except PermissionError:
            self.fail('Access denied.')
            return
        self.data = PolylineData()
        is_i2s = self.filename[-4:] == '.i2s'
        if is_i2s:
            with BlueKenue.Read(self.filename) as f:
                f.read_header()
                for poly in f.get_open_polylines():
                    self.data.add_line(poly)
            self.data.set_fields(['Value'])
        else:
            try:
                for poly in Shapefile.get_open_polylines(self.filename):
                    self.data.add_line(poly)
            except ShapefileException as e:
                self.fail(e)
                return
            self.data.set_fields(Shapefile.get_all_fields(self.filename))

        if self.data.is_empty():
            self.fail('the file does not contain any 2D open polyline.')
            return

        self.success('The file contains {} open line{}.'.format(
            len(self.data), 's' if len(self.data) > 1 else ''))
Esempio n. 3
0
def get_hydraulic_axis(infile_axis):
    """
    @brief: Extract a unique line from i2s input file
    @param infile_axis <str>: path to file
    @return <shapely.geometry.LineString>: polyline representing the hydraulic axis
    """
    if infile_axis.endswith('.i2s'):
        with bk.Read(infile_axis) as in_i2s:
            in_i2s.read_header()
            lines = list(in_i2s.get_open_polylines())
    elif infile_axis.endswith('.shp'):
        if shp.get_shape_type(infile_axis) not in (shapefile.POLYLINE,
                                                   shapefile.POLYLINEZ,
                                                   shapefile.POLYLINEM):
            raise TatooineException("The type of file %s is not POLYLINE[ZM]" %
                                    infile_axis)
        lines = list(shp.get_open_polylines(infile_axis))
    else:
        raise NotImplementedError(
            "Only shp and i2s formats are supported for hydraulic axis")
    nb_lines = len(lines)
    if nb_lines != 1:
        raise TatooineException(
            "The file '{}' contains {} polylines instead of a unique line to define "
            "the hydraulic axis".format(infile_axis, nb_lines))
    return lines[0].polyline()
Esempio n. 4
0
    def polygon_event(self):
        filename, _ = QFileDialog.getOpenFileName(
            self,
            'Open a .shp file',
            '',
            'Polygon file (*.shp)',
            options=QFileDialog.Options() | QFileDialog.DontUseNativeDialog)
        if not filename:
            return
        if not test_open(filename):
            return

        polygons = []
        try:
            for polygon in Shapefile.get_polygons(filename):
                polygons.append(polygon)
        except struct.error:
            QMessageBox.critical(self, 'Error', 'Inconsistent bytes.',
                                 QMessageBox.Ok)
            return
        if not polygons:
            QMessageBox.critical(self, 'Error',
                                 'The file does not contain any polygon.',
                                 QMessageBox.Ok)
            return
        items = [
            '%d - %s' % (index, name)
            for (index,
                 name) in Shapefile.get_numeric_attribute_names(filename)
        ]
        if not items:
            QMessageBox.critical(
                self, 'Error', 'The polygons do not have numeric attributes.',
                QMessageBox.Ok)
            return
        dlg = AttributeDialog(items)
        if dlg.exec_() != QDialog.Accepted:
            return
        attribute_index, attribute_name = dlg.attribute_box.currentText(
        ).split(' - ')
        attribute_index = int(attribute_index)

        short_name = os.path.join(os.path.basename(filename),
                                  os.path.split(filename)[1])
        row = self.polygon_table.rowCount()
        self.polygon_table.insertRow(row)
        self.polygon_table.setItem(row, 0,
                                   QTableWidgetItem('POLY%d' % (row + 1)))
        self.polygon_table.setItem(row, 1, QTableWidgetItem(attribute_name))
        self.polygon_table.setItem(row, 2, QTableWidgetItem(short_name))
        self.parent.editor_tab.pool.add_polygonal_mask(polygons,
                                                       attribute_index)
Esempio n. 5
0
def get_field_index(filename, field_id):
    if field_id is not None:
        names, _ = shp.get_attribute_names(filename)
        try:
            return names.index(field_id)
        except ValueError:
            raise TatooineException("The field `%s` does not exist" % field_id)
Esempio n. 6
0
 def run(self):
     if self.state == Node.SUCCESS:
         return
     try:
         with open(self.filename):
             pass
     except PermissionError:
         self.fail('Access denied.')
         return
     self.data = PointData()
     try:
         for point, attribute in Shapefile.get_points(self.filename):
             self.data.add_point(point)
             self.data.add_attribute(attribute)
     except ShapefileException as e:
         self.fail(e)
         return
     self.data.set_fields(Shapefile.get_all_fields(self.filename))
     if self.data.is_empty():
         self.fail('the file does not contain any point.')
         return
     self.success('The file contains {} point{}.'.format(
         len(self.data), 's' if len(self.data) > 1 else ''))
Esempio n. 7
0
    def get_zones_from_i3s_file(shp_name, threshold, operator_str):
        polylines = []

        attributes = shp.get_numeric_attribute_names(shp_name)
        if args.attr_to_shift_z is not None:
            try:
                index_attr = [attr for _, attr in attributes].index(args.attr_to_shift_z)
            except ValueError:
                logger.critical('Attribute "%s" is not found.' % args.attr_to_shift_z)
                sys.exit(1)

        for polyline in shp.get_open_polylines(shp_name):
            if not polyline.polyline().is_valid:
                sys.exit("ERROR: polyline is not valid (probably because it intersects itself)!")

            # Shift z (if requested)
            if args.attr_to_shift_z is not None:
                dz = polyline.attributes()[index_attr]
                print(dz)

                polyline = polyline.apply_transformations([Transformation(0.0, 1.0, 1.0, 0.0, 0.0, dz)])

            # Linear interpolation along the line for values below the threshold
            if threshold is not None:
                np_coord = np.array(polyline.coords())
                Xt = np.sqrt(np.power(np.ediff1d(np_coord[:, 0], to_begin=0.), 2) +
                             np.power(np.ediff1d(np_coord[:, 1], to_begin=0.), 2))
                Xt = Xt.cumsum()
                ref_rows = np_coord[:, 2] > args.threshold
                np_coord[:, 2] = np.interp(Xt, Xt[ref_rows], np_coord[ref_rows, 2])
                polyline = geo.LineString(np_coord)
            polylines.append(polyline)

        zones = []
        for prev_line, next_line in zip(polylines[:-1], polylines[1:]):
            zones.append(Zone(prev_line, next_line, operator_str))
        return zones
Esempio n. 8
0
    def from_file(filename, label, field_id=None, project_straight_line=False):
        section_seq = CrossSectionSequence()

        if filename.endswith('.i3s'):
            with bk.Read(filename) as in_i3s:
                in_i3s.read_header()
                for i, line in enumerate(in_i3s.get_open_polylines()):
                    line_id = i if field_id is None else line.attributes()[
                        0]  # Use `Value` if field is not None
                    z_array = np.array([(coord[2], )
                                        for coord in line.polyline().coords],
                                       dtype=float_vars('Z'))
                    line = line.to_2d()
                    section = CrossSection(line_id,
                                           list(line.polyline().coords), label)
                    section.coord.values = z_array
                    section_seq.add_section(section)

        elif filename.endswith('.shp'):
            shp_type = shp.get_shape_type(filename)
            if shp_type in (shapefile.POLYLINEZ, shapefile.POLYLINEM):
                field_id_index = get_field_index(filename, field_id)
                for i, line in enumerate(shp.get_open_polylines(filename)):
                    line_id = i if field_id is None else line.attributes(
                    )[field_id_index]
                    z_array = np.array([(coord[2], )
                                        for coord in line.polyline().coords],
                                       dtype=float_vars(['Z']))
                    line = line.to_2d()
                    section = CrossSection(line_id,
                                           list(line.polyline().coords), label)
                    section.coord.values = z_array
                    section_seq.add_section(section)

            elif shp_type in (shapefile.POINT, shapefile.POINTZ):
                field_id_index = get_field_index(filename, field_id)
                field_indexes, field_names = [], []
                if shp_type == shapefile.POINTZ:
                    field_names.append('Z')
                for index, name in shp.get_numeric_attribute_names(filename):
                    if name.startswith('Z'):
                        field_indexes.append(index)
                        field_names.append(name)
                coords, z_layers = [], []
                last_point_id = None
                for i, (point, attributes) in enumerate(
                        shp.get_points(filename,
                                       with_z=shp_type == shapefile.POINTZ)):
                    point_id = attributes[
                        field_id_index]  # FIXME: should raise exception if field_id_index is None!
                    if i > 0 and point_id != last_point_id:
                        z_array = np.array(z_layers,
                                           dtype=float_vars(field_names))
                        section = CrossSection(last_point_id, coords, label)
                        section.coord.values = z_array
                        section_seq.add_section(section)
                        coords, z_layers = [], []
                    coords.append(point[:2])
                    if shp_type == shapefile.POINTZ:
                        z_layers.append((point[2], ) +
                                        tuple(attributes[index]
                                              for index in field_indexes))
                    else:
                        z_layers.append(
                            tuple(attributes[index]
                                  for index in field_indexes))
                    last_point_id = point_id
                z_array = np.array(z_layers, dtype=float_vars(field_names))
                section = CrossSection(last_point_id, coords, label)
                section.coord.values = z_array
                section_seq.add_section(section)

            else:
                raise TatooineException(
                    "The type of file %s is not POINT[Z] or POLYLINEZ[M]" %
                    filename)

        else:
            raise NotImplementedError(
                "Only shp and i3s formats are supported for cross-sections")

        if project_straight_line:
            for section in section_seq:
                section.project_straight_line()
        return section_seq
Esempio n. 9
0
    def export_sections(self, path):
        """
        Export generated profiles in a shp, i3s or georefC file
        /!\ Not relevant if constant_long_disc is False
        TODO: Use class MascaretGeoFile
        """
        values = self.interp_values_from_geom()
        if path.endswith('.georefC'):
            with open(path, 'w') as out_geo:
                for dist in np.unique(self.points['Xl']):
                    pos = self.points['Xl'] == dist
                    points = self.points[pos]

                    # Compute Xt  (FIXME: rather keep from previous calculations...)
                    Xt = np.sqrt(
                        np.power(np.ediff1d(points['X'], to_begin=0.), 2) +
                        np.power(np.ediff1d(points['Y'], to_begin=0.), 2))
                    Xt = Xt.cumsum()
                    points = append_fields(points, 'Xt', Xt, usemask=False)

                    for i, row in enumerate(points):
                        if i == 0:
                            positions_str = ' %f %f %f %f' % (
                                row['X'], row['Y'], points[-1]['X'],
                                points[-1]['Y'])
                            positions_str += ' AXE %f %f' % (
                                row['X'], row['Y']
                            )  # FIXME: not the axis position...
                            out_geo.write(
                                'Profil Bief_0 %s %f%s\n' %
                                ('P' + str(dist), dist, positions_str))

                        layers_str = ' ' + ' '.join([
                            COURLIS_FLOAT_FMT % x for x in values[:, pos][:, i]
                        ])

                        out_geo.write(
                            '%f%s B %f %f\n' %
                            (row['Xt'], layers_str, row['X'], row['Y']))
            return

        lines = []
        for dist in np.unique(self.points['Xl']):
            pos = self.points['Xl'] == dist
            line = geometry.Polyline([
                (x, y, z)
                for (x,
                     y), z in zip(self.points[pos][['X', 'Y']], values[0, :])
            ])
            line.add_attribute(dist)
            lines.append(line)

        if path.endswith('.i3s'):
            with bk.Write(path) as out_i3s:
                out_i3s.write_header()
                out_i3s.write_lines(lines, [l.attributes()[0] for l in lines])

        elif path.endswith('.shp'):
            shp.write_shp_lines(path, shapefile.POLYLINEZ, lines, 'Z')

        else:
            raise NotImplementedError(
                "Only the shp (POLYLINEZ), i3s and georefC formats are supported for "
                "the generated cross-sections file")
Esempio n. 10
0
def ADCP_comp(args):
    x_mes = []
    y_mes = []
    cord_mes = open(args.inADCP_GPS).read().splitlines()
    for x_l in cord_mes:
        y, x = x_l.split(',')
        if x == NODATA or y == NODATA:
            print("Warning: one point is missing")
        else:
            x_mes.append(x)
            y_mes.append(y)
    x_mes = [float(a) for a in x_mes]
    y_mes = [float(a) for a in y_mes]
    inProj = Proj("+init=EPSG:%i" % args.inEPSG)
    outProj = Proj("+init=EPSG:%i" % args.outEPSG)
    x_mes, y_mes = transform(inProj, outProj, x_mes, y_mes)

    SCHEMA = {'geometry': 'LineString', 'properties': {'nom': 'str'}}
    with fiona.open(args.outADCP_GPS,
                    'w',
                    'ESRI Shapefile',
                    SCHEMA,
                    crs=from_epsg(args.outEPSG)) as out_shp:
        Ltest = LineString([(x_2, y_2) for x_2, y_2 in zip(x_mes, y_mes)])
        elem = {}
        elem['geometry'] = mapping(Ltest)
        elem['properties'] = {'nom': 'ADCP line'}
        out_shp.write(elem)

    p_raw = RawProfileObj(args.inADCP)
    processing_settings = {'proj_method': 2}
    startingpoint = dict(start=Vector(0, 0))
    p0 = ProcessedProfileObj(p_raw, processing_settings, startingpoint)
    profile_averaged = averaging.get_averaged_profile(p0, cfg={'order': 15})
    header = 'X;Y;Uadcp;Vadcp;MagnitudeXY;Hadcp\n'
    writeAscii2D(profile_averaged,
                 '{x};{y};{vx};{vy};{vmag};{depth}',
                 args.outADCP,
                 header=header)

    if args.inTELEMAC:
        with open(args.outT2DCSV, 'w', newline='') as csvfile:
            csvwriter = csv.writer(csvfile, delimiter=';')
            HEADER = [
                'folder', 'time_id', 'time', 'point_x', 'point_y', 'distance',
                'value'
            ]
            csvwriter.writerow(HEADER)

            for slf_path in args.inTELEMAC:
                folder = os.path.basename(os.path.split(slf_path)[0])
                with Serafin.Read(slf_path, 'fr') as resin:
                    resin.read_header()
                    logger.info(resin.header.summary())
                    resin.get_time()
                    output_header = resin.header.copy()
                    if args.shift:
                        output_header.transform_mesh([
                            Transformation(0, 1, 1, args.shift[0],
                                           args.shift[1], 0)
                        ])
                    mesh = MeshInterpolator(output_header, True)
                    lines = []
                    for poly in Shapefile.get_lines(args.outADCP_GPS,
                                                    shape_type=3):
                        lines.append(poly)
                    nb_nonempty, indices_nonempty, line_interpolators, line_interpolators_internal = \
                        mesh.get_line_interpolators(lines)
                    res = mesh.interpolate_along_lines(
                        resin, 'M', list(range(len(resin.time))),
                        indices_nonempty, line_interpolators, '{:.6e}')
                    csvwriter.writerows([[folder] + x[2] for x in res])
Esempio n. 11
0
def slf_flux2d(args):
    if len(args.scalars) > 2:
        logger.critical('Only two scalars can be integrated!')
        sys.exit(2)

    # Read set of lines from input file
    polylines = []
    if args.in_sections.endswith('.i2s'):
        with BlueKenue.Read(args.in_sections) as f:
            f.read_header()
            for polyline in f.get_open_polylines():
                polylines.append(polyline)
    elif args.in_sections.endswith('.shp'):
        try:
            for polyline in Shapefile.get_open_polylines(args.in_sections):
                polylines.append(polyline)
        except ShapefileException as e:
            logger.critical(e)
            sys.exit(3)
    else:
        logger.critical('File "%s" is not a i2s or shp file.' %
                        args.in_sections)
        sys.exit(2)

    if not polylines:
        logger.critical('The file does not contain any open polyline.')
        sys.exit(1)
    logger.debug('The file contains {} open polyline{}.'.format(
        len(polylines), 's' if len(polylines) > 1 else ''))

    # Read Serafin file
    with Serafin.Read(args.in_slf, args.lang) as resin:
        resin.read_header()
        logger.info(resin.header.summary())
        resin.get_time()

        if not resin.header.is_2d:
            logger.critical('The file has to be a 2D Serafin!')
            sys.exit(3)

        # Determine flux computations properties
        var_IDs = args.vectors + args.scalars
        variables_missing = [
            var_ID for var_ID in var_IDs if var_ID not in resin.header.var_IDs
        ]
        if variables_missing:
            if len(variables_missing) > 1:
                logger.critical(
                    'Variables {} are not present in the Serafin file'.format(
                        variables_missing))
            else:
                logger.critical(
                    'Variable {} is not present in the Serafin file'.format(
                        variables_missing[0]))
            logger.critical(
                'Check also `--lang` argument for variable detection.')
            sys.exit(1)
        if var_IDs not in PossibleFluxComputation.common_fluxes():
            logger.warn(
                'Flux computations is not common. Check what you are doing (or the language).'
            )

        flux_type = PossibleFluxComputation.get_flux_type(var_IDs)

        section_names = ['Section %i' % (i + 1) for i in range(len(polylines))]
        calculator = FluxCalculator(flux_type, var_IDs, resin, section_names,
                                    polylines, args.ech)
        calculator.construct_triangles(tqdm)
        calculator.construct_intersections()
        result = []
        for time_index, time in enumerate(tqdm(resin.time, unit='frame')):
            i_result = [str(time)]
            values = []

            for var_ID in calculator.var_IDs:
                values.append(resin.read_var_in_frame(time_index, var_ID))

            for j in range(len(polylines)):
                intersections = calculator.intersections[j]
                flux = calculator.flux_in_frame(intersections, values)
                i_result.append(settings.FMT_FLOAT.format(flux))

            result.append(i_result)

        # Write CSV
        mode = 'w' if args.force else 'x'
        with open(args.out_csv, mode) as out_csv:
            calculator.write_csv(result, out_csv, args.sep)
Esempio n. 12
0
def slf_max_over_files(args):
    if args.vars is None:
        with Serafin.Read(args.in_slfs[0], args.lang) as resin:
            resin.read_header()
            var_IDs = resin.header.var_IDs if args.vars is None else args.vars
    else:
        var_IDs = args.vars

    if args.operation == 'max':
        fun = np.maximum
    elif args.operation == 'min':
        fun = np.minimum
    else:
        raise NotImplementedError

    # Read polygons
    if args.in_polygons is not None:
        if not args.in_polygons.endswith('.shp'):
            logger.critical('File "%s" is not a shp file.' % args.in_polygons)
            sys.exit(3)
        polygons = []
        try:
            for polygon in Shapefile.get_polygons(args.in_polygons):
                polygons.append(polygon)
        except ShapefileException as e:
            logger.error(e)
            sys.exit(3)

        if not polygons:
            logger.error('The file does not contain any polygon.')
            sys.exit(1)
        logger.info('The file contains {} polygon{}.'.format(len(polygons), 's' if len(polygons) > 1 else ''))
    else:
        polygons = None

    output_header = None
    out_values = None  # min or max values
    mask_nodes = None
    for i, in_slf in enumerate(args.in_slfs):
        with Serafin.Read(in_slf, args.lang) as resin:
            resin.read_header()
            logger.info(resin.header.summary())
            if not resin.header.is_2d:
                logger.critical('The file has to be a 2D Serafin!')
                sys.exit(3)
            resin.get_time()

            for var_ID in var_IDs:
                if var_ID not in resin.header.var_IDs:
                    logger.critical('The variable %s is missing in %s' % (var_ID, in_slf))
                    sys.exit(3)

            if i == 0:
                output_header = resin.header.copy()
                output_header.empty_variables()
                for var_ID in var_IDs:
                    output_header.add_variable_from_ID(var_ID)
                out_values = np.empty((output_header.nb_var, output_header.nb_nodes),
                                      dtype=output_header.np_float_type)
                if polygons is not None:
                    mask_nodes = np.zeros(output_header.nb_nodes, dtype=bool)
                    for idx_node, (x, y) in enumerate(zip(output_header.x, output_header.y)):
                        point = Point(x, y)
                        for polygon in polygons:
                            if polygon.contains(point):
                                mask_nodes[idx_node] = True
                                break
                    logger.info('Number of nodes inside polygon(s): %i (over %i)'
                                % (mask_nodes.sum(), output_header.nb_nodes))
                else:
                    mask_nodes = np.ones(output_header.nb_nodes, dtype=bool)
            else:
                if not resin.header.same_2d_mesh(output_header):
                    logger.critical('The mesh of %s is different from the first one' % in_slf)
                    sys.exit(1)

            for time_index, time in enumerate(resin.time):
                for j, var_ID in enumerate(var_IDs):
                    values = resin.read_var_in_frame(time_index, var_ID)
                    if time_index == 0 and i == 0:
                        out_values[j, :] = values
                    else:
                        out_values[j, mask_nodes] = fun(out_values[j, mask_nodes], values[mask_nodes])

    with Serafin.Write(args.out_slf, args.lang, overwrite=args.force) as resout:
        resout.write_header(output_header)
        resout.write_entire_frame(output_header, 0.0, out_values)
Esempio n. 13
0
def slf_volume(args):
    # Read set of lines from input file
    polygons = []
    if args.in_polygons.endswith('.i2s'):
        with BlueKenue.Read(args.in_polygons) as f:
            f.read_header()
            for poly in f.get_polygons():
                polygons.append(poly)
    elif args.in_polygons.endswith('.shp'):
        try:
            for polygon in Shapefile.get_polygons(args.in_polygons):
                polygons.append(polygon)
        except ShapefileException as e:
            logger.error(e)
            sys.exit(3)
    else:
        logger.error('File "%s" is not a i2s or shp file.' % args.in_polygons)
        sys.exit(2)

    if not polygons:
        logger.error('The file does not contain any polygon.')
        sys.exit(1)
    logger.debug('The file contains {} polygon{}.'.format(len(polygons), 's' if len(polygons) > 1 else ''))

    names = ['Polygon %d' % (i + 1) for i in range(len(polygons))]

    # Read Serafin file
    with Serafin.Read(args.in_slf, args.lang) as resin:
        resin.read_header()
        logger.info(resin.header.summary())
        resin.get_time()

        if not resin.header.is_2d:
            logger.error('The file has to be a 2D Serafin!')
            sys.exit(3)

        # Check variables consistency
        if args.upper_var not in resin.header.var_IDs:
            logger.error('Upper variable "%s" is not in Serafin file' % args.upper_var)
            sys.exit(1)
        upper_var = args.upper_var
        lower_var = args.lower_var
        if args.lower_var is not None:
            if args.lower_var == 'init':
                lower_var = VolumeCalculator.INIT_VALUE
            else:
                if lower_var not in resin.header.var_IDs:
                    logger.error('Lower variable "%s" is not in Serafin file' % lower_var)
                    sys.exit(1)

        if args.detailed:
            volume_type = VolumeCalculator.POSITIVE
        else:
            volume_type = VolumeCalculator.NET
        calculator = VolumeCalculator(volume_type, upper_var, lower_var, resin, names, polygons, args.ech)
        calculator.construct_triangles(tqdm)
        calculator.construct_weights(tqdm)

        result = []
        for time_index in tqdm(calculator.time_indices, unit='frame'):
            i_result = [str(resin.time[time_index])]
            values = calculator.read_values_in_frame(time_index)

            for j in range(len(calculator.polygons)):
                weight = calculator.weights[j]
                volume = calculator.volume_in_frame_in_polygon(weight, values, calculator.polygons[j])
                if calculator.volume_type == VolumeCalculator.POSITIVE:
                    for v in volume:
                        i_result.append(settings.FMT_FLOAT.format(v))
                else:
                    i_result.append(settings.FMT_FLOAT.format(volume))
            result.append(i_result)

        # Write CSV
        mode = 'w' if args.force else 'x'
        with open(args.out_csv, mode) as out_csv:
            calculator.write_csv(result, out_csv, args.sep)
Esempio n. 14
0
def slf_bottom_friction(args):
    # Check argument consistency
    if args.in_strickler_zones is not None or args.in_strickler_attr is not None:
        if args.in_strickler_zones is None or args.in_strickler_attr is None:
            logger.critical(
                'Both arguments `--in_strickler_zones` and `--in_strickler_attr` have to be defined.'
            )
            sys.exit(2)

    # Read polygons to compute volume
    if not args.in_polygons.endswith('.shp'):
        logger.critical('File "%s" is not a shp file.' % args.in_polygons)
        sys.exit(3)
    polygons = []
    try:
        for polygon in Shapefile.get_polygons(args.in_polygons):
            polygons.append(polygon)
    except ShapefileException as e:
        logger.error(e)
        sys.exit(3)

    if not polygons:
        logger.error('The file does not contain any polygon.')
        sys.exit(1)
    logger.debug('The file contains {} polygon{}.'.format(
        len(polygons), 's' if len(polygons) > 1 else ''))

    names = ['Polygon %d' % (i + 1) for i in range(len(polygons))]

    varIDs = ['US', 'TAU']
    out_varIDs = ['W'] + varIDs
    pos_TAU = out_varIDs.index('TAU')
    with Serafin.Read(args.in_slf, args.lang) as resin:
        resin.read_header()
        if not resin.header.is_2d:
            logger.critical('The file has to be a 2D Serafin!')
            sys.exit(3)

        in_varIDs = resin.header.var_IDs

        # Compute Strickler values if necessary
        ori_values = {}
        if args.in_strickler_zones is not None:
            if not args.in_strickler_zones.endswith('.shp'):
                logger.critical('File "%s" is not a shp file.' %
                                args.in_strickler_zones)
                sys.exit(3)

            attributes = Shapefile.get_numeric_attribute_names(
                args.in_strickler_zones)
            try:
                index_attr = [attr for _, attr in attributes
                              ].index(args.in_strickler_attr)
            except ValueError:
                logger.critical('Attribute "%s" is not found.' %
                                args.in_strickler_attr)
                sys.exit(1)

            strickler_zones = []
            try:
                for zone in Shapefile.get_polygons(args.in_strickler_zones):
                    strickler_zones.append(zone)
            except ShapefileException as e:
                logger.error(e)
                sys.exit(3)

            if not strickler_zones:
                logger.error('The file does not contain any friction zone.')
                sys.exit(1)

            logger.debug('Recomputing friction coefficient values from zones')
            friction_coeff = np.full(
                resin.header.nb_nodes_2d,
                0.0)  # default value for nodes not included in any zone
            for i, (x, y) in enumerate(
                    zip(tqdm(resin.header.x), tqdm(resin.header.y))):
                point = Point(x, y)
                for zone in strickler_zones:
                    if zone.contains(point):
                        friction_coeff[i] = zone.attributes()[index_attr]
                        exit
            in_varIDs.append('W')
            ori_values['W'] = friction_coeff
        else:
            if 'W' not in resin.header.varIDs:
                logger.critical('The variable W is missing.')
                sys.exit(1)

        us_equation = None
        if args.friction_law:
            us_equation = get_US_equation(args.friction_law)

        resin.get_time()
        necessary_equations = get_necessary_equations(in_varIDs,
                                                      out_varIDs,
                                                      is_2d=True,
                                                      us_equation=us_equation)

        calculator = VolumeCalculator(VolumeCalculator.NET, 'TAU', None, resin,
                                      names, polygons, 1)
        calculator.construct_triangles(tqdm)
        calculator.construct_weights(tqdm)

        output_header = resin.header.copy()
        output_header.empty_variables()
        for var_ID in out_varIDs:
            output_header.add_variable_from_ID(var_ID)

        with Serafin.Write(args.out_slf, args.lang, args.force) as resout:
            resout.write_header(output_header)

            mode = 'w' if args.force else 'x'
            with open(args.out_csv, mode, newline='') as csvfile:
                csvwriter = csv.writer(csvfile, delimiter=args.sep)
                csvwriter.writerow(['time'] + names)

                for time_index, time in enumerate(tqdm(resin.time)):
                    values = do_calculations_in_frame(
                        necessary_equations,
                        resin,
                        time_index,
                        out_varIDs,
                        resin.header.np_float_type,
                        is_2d=True,
                        us_equation=STRICKLER_EQUATION,
                        ori_values=ori_values)
                    resout.write_entire_frame(output_header, time, values)

                    row = [time]
                    for j in range(len(calculator.polygons)):
                        weight = calculator.weights[j]
                        volume = calculator.volume_in_frame_in_polygon(
                            weight, values[pos_TAU], calculator.polygons[j])
                        row.append(volume)
                    csvwriter.writerow(row)
    def _handleOpenShapefile(self, filename):
        try:
            with open(filename, 'r'):
                pass
        except PermissionError:
            QMessageBox.critical(None, 'Error', 'Permission denied.',
                                 QMessageBox.Ok)
            self.parent.reset()
            return False
        try:
            shape_type = shp.get_shape_type(filename)
        except shapefile.ShapefileException:
            QMessageBox.critical(
                None, 'Error',
                'Failed to open shp file (is the .dbf file present?).',
                QMessageBox.Ok)
            self.parent.reset()
            return False

        if shape_type == 1:
            self.from_type = 'shp Point'
        elif shape_type == 11:
            self.from_type = 'shp PointZ'
        elif shape_type == 21:
            self.from_type = 'shp PointM'
        elif shape_type == 3:
            self.from_type = 'shp Polyline'
        elif shape_type == 13:
            self.from_type = 'shp PolylineZ'
        elif shape_type == 23:
            self.from_type = 'shp PolylineM'
        elif shape_type == 5:
            self.from_type = 'shp Polygon'
        elif shape_type == 15:
            self.from_type = 'shp PolygonZ'
        elif shape_type == 25:
            self.from_type = 'shp PolygonM'
        elif shape_type == 8:
            self.from_type = 'shp MultiPoint'
        elif shape_type == 18:
            self.from_type = 'shp MultiPointZ'
        elif shape_type == 28:
            self.from_type = 'shp MultiPointM'
        elif shape_type == 0:
            QMessageBox.critical(
                None, 'Error',
                'The shape type Null is currently not supported!',
                QMessageBox.Ok)
            self.parent.reset()
            return False
        else:
            QMessageBox.critical(
                None, 'Error',
                'The shape type MultiPatch is currently not supported!',
                QMessageBox.Ok)
            self.parent.reset()
            return False
        logging.debug('Input Shapefile format: %s (type = %d)' %
                      (self.from_type, shape_type))
        if shape_type in (1, 11, 21):
            self.converter = convert.ShpPointConverter(filename)
        elif shape_type in (3, 5, 13, 15, 23, 25):
            self.converter = convert.ShpLineConverter(filename)
        else:
            self.converter = convert.ShpMultiPointConverter(filename)
        return True
Esempio n. 16
0
def slf_int2d(args):
    # Read set of points file
    fields, indices = Shapefile.get_attribute_names(args.in_points)
    points = []
    attributes = []
    for point, attribute in Shapefile.get_points(args.in_points, indices):
        points.append(point)
        attributes.append(attribute)

    if not points:
        logger.critical('The Shapefile does not contain any point.')
        sys.exit(1)

    # Read Serafin file
    with Serafin.Read(args.in_slf, args.lang) as resin:
        resin.read_header()
        logger.info(resin.header.summary())

        if not resin.header.is_2d:
            logger.critical('The file has to be a 2D Serafin!')
            sys.exit(3)

        resin.get_time()

        output_header = resin.header.copy()

        mesh = MeshInterpolator(output_header, True)
        is_inside, point_interpolators = mesh.get_point_interpolators(points)
        nb_inside = sum(map(int, is_inside))

        if nb_inside == 0:
            logger.critical('No point inside the mesh.')
            sys.exit(3)
        logger.debug(
            'The file contains {} point{}. {} point{} inside the mesh'.format(
                len(points), 's' if len(points) > 1 else '', nb_inside,
                's are' if nb_inside > 1 else ' is'))

        var_IDs = output_header.var_IDs if args.vars is None else args.vars

        mode = 'w' if args.force else 'x'
        with open(args.out_csv, mode, newline='') as csvfile:
            csvwriter = csv.writer(csvfile, delimiter=args.sep)

            header = ['time_id', 'time']
            if args.long:
                header = header + [
                    'point_id', 'point_x', 'point_y', 'variable', 'value'
                ]
            else:
                for pt_id, (x, y) in enumerate(points):
                    for var in var_IDs:
                        header.append(
                            'Point %d %s (%s|%s)' %
                            (pt_id + 1, var, settings.FMT_COORD.format(x),
                             settings.FMT_COORD.format(y)))
            csvwriter.writerow(header)

            for time_index, time in enumerate(tqdm(resin.time, unit='frame')):
                values = [time_index, time]

                for var_ID in var_IDs:
                    var = resin.read_var_in_frame(time_index, var_ID)
                    for pt_id, (point, point_interpolator) in enumerate(
                            zip(points, point_interpolators)):
                        if args.long:
                            values_long = values + [str(pt_id + 1)] + [
                                settings.FMT_COORD.format(x) for x in point
                            ]

                        if point_interpolator is None:
                            if args.long:
                                csvwriter.writerow(values_long +
                                                   [var_ID, settings.NAN_STR])
                            else:
                                values.append(settings.NAN_STR)
                        else:
                            (i, j, k), interpolator = point_interpolator
                            int_value = settings.FMT_FLOAT.format(
                                interpolator.dot(var[[i, j, k]]))
                            if args.long:
                                csvwriter.writerow(values_long +
                                                   [var_ID, int_value])
                            else:
                                values.append(int_value)

                if not args.long: csvwriter.writerow(values)
Esempio n. 17
0
import os.path
import shapefile

from pyteltools.geom import conversion, geometry, Shapefile

# Write polylines shapefile
lines = [
    geometry.Polyline([(0, 0, 0), (10, 20, 30)],
                      attributes=[0],
                      m_array=[[0], [100]])
]
Shapefile.write_shp_lines('from_scratch/polyline.shp', shapefile.POLYLINE,
                          lines, 'LineID')
Shapefile.write_shp_lines('from_scratch/polylinez.shp', shapefile.POLYLINEZ,
                          lines, 'LineID')
Shapefile.write_shp_lines('from_scratch/polylinem.shp', shapefile.POLYLINEM,
                          lines, 'LineID')

# Write polygons shapefile
lines = [
    geometry.Polyline([(0, 0, 0), (10, 20, 30), (10, 40, 30), (0, 0, 0)],
                      attributes=[0],
                      m_array=[[0], [100], [200], [300]])
]
Shapefile.write_shp_lines('from_scratch/polygon.shp', shapefile.POLYGON, lines,
                          'PolyID')
Shapefile.write_shp_lines('from_scratch/polygonz.shp', shapefile.POLYGONZ,
                          lines, 'PolyID')
Shapefile.write_shp_lines('from_scratch/polygonm.shp', shapefile.POLYGONM,
                          lines, 'PolyID')