def check_intersections(self): """Display warning with intersections details""" logger.info("~> Checking that cross-sections do not intersect") intersections = get_intersections([section.geom for section in self]) if intersections: logger.warn("Following limits are found:") for (i, j) in intersections: logger.warn("- between '{}' and '{}'".format(self[i], self[j]))
def find_and_add_limit(self, constraint_line, dist_max=None): """ @param constraint_line <shapely.geometry.LineString>: 2D constraint line @param dist_max <float>: maximum search distance to rescue intersections for limits """ if self.geom.intersects(constraint_line.geom): intersection = self.geom.intersection(constraint_line.geom) if isinstance(intersection, MultiPoint): logger.warn( "Intersection between '{}' and '{}' contains multiple points, " "only the first is kept.".format(self, constraint_line)) intersection = intersection[0] if isinstance(intersection, Point): # Compute projections Xt_section = self.geom.project(intersection) Xt_line = constraint_line.geom.project(intersection) self.add_limit(constraint_line.id, Xt_section, Xt_line, intersection) else: raise TatooineException( "Intersection between '{}' and '{}' is empty or not supported: {}" .format(self, constraint_line, type(intersection))) else: if dist_max is not None: distance = self.geom.distance(constraint_line.geom) if distance < dist_max: for i, coord in enumerate(constraint_line.coord): # Try to find a point of the constraint line which is in the vicinity of the current section point = Point(coord) dist = self.geom.distance(point) if dist < dist_max: # A point is found and is considered Xt_line = constraint_line.geom.project(point) Xt_section = self.geom.project(point) intersection = self.geom.interpolate(Xt_section) self.add_limit(constraint_line.id, Xt_section, Xt_line, intersection) logger.debug( "Add a limit with the line {} after {} iterations (distance = {})" .format(constraint_line.id, i, dist)) break
def compute_dist_proj_axe(self, axe_geom, dist_max): """ @brief: Compute distance along hydraulic axis @param axe_geom <shapely.geometry.LineString>: hydraulic axis (/!\ Beware of its orientation) @param dist_max <float>: maximum search distance to rescue intersections for limits """ logger.info( "~> Compute distances along hydraulic axis to order cross-sections" ) to_keep_list = [] for section in self: section_geom = section.geom if section_geom.intersects(axe_geom): intersection = section_geom.intersection(axe_geom) if isinstance(intersection, Point): section.dist_proj_axe = axe_geom.project(intersection) else: raise TatooineException( "Intersection between '{}' and the hydraulic axis " "is not a unique point".format(section)) else: if dist_max is not None: for pos in (0, -1): dist = section_geom.distance( Point(axe_geom.coords[pos])) if dist < dist_max: section.dist_proj_axe = 0.0 if pos == 0 else axe_geom.length if section.dist_proj_axe == -1: logger.warn( "{} do not intersect the hydraulic axis (distance = {}m) and is ignored" .format(section, section.geom.distance(axe_geom))) to_keep_list.append(False) else: to_keep_list.append(True) self.section_list = [ p for p, to_keep in zip(self.section_list, to_keep_list) if to_keep ]
def __init__(self, array, vars2add, remove_duplicates=False): """ @param array: structured array. `X`, `Y` are compulsory but other variables (such as Z) and distances are optional @param var2add <[str]>: list including eventually `Xt` and/or `xt` top compute them if they are not already present @param remove_duplicates <bool>: remove consecutive duplicated points """ self.array = array self.coord_labels = list(self.array.dtype.fields.keys()) self.values = None if 'X' not in self.coord_labels and 'Y' not in self.coord_labels: raise TatooineException("Columns X and Y are compulsory.") if 'Xt' in vars2add: self.compute_Xt() if 'xt' in vars2add: self.compute_xt() if remove_duplicates: if not strictly_increasing(self.array['Xt']): logger.warn("Duplicated points are removed") # Suppression des doublons (points superposés dans la polyligne) points2keep = np.ediff1d(self.array['Xt'], to_begin=1.) != 0. self.array = self.array[points2keep]