예제 #1
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)
예제 #2
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
예제 #3
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
예제 #4
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)