Example #1
0
def is_edition_needed(lst_coord_0, lst_coord_1, lst_coord_2):

    p0 = lst_coord_0[0]
    l1 = lst_coord_0[1]
    l2 = lst_coord_1[1]
    l3 = lst_coord_2[1]

    angle_1 = GenUtil.compute_angle(l1, p0, l2, type=GenUtil.DEGREE)
    angle_2 = GenUtil.compute_angle(l1, p0, l3, type=GenUtil.DEGREE)
    angle_3 = GenUtil.compute_angle(l2, p0, l3, type=GenUtil.DEGREE)

    if angle_1 >= 165. or angle_2 >= 165. or angle_3 >= 165.:
        edition_needed = False
    else:
        edition_needed = True

    return edition_needed
Example #2
0
    def _extract_linked_lines(self, coord):

        linked_lines = []
        b_box = GenUtil.build_bounding_box(self. search_tolerance, coord)
        potential_lines = self.s_container.get_features(b_box, remove_features=[self.line])
        for potential_line in potential_lines:
            if potential_line.distance(Point(coord)) <= GenUtil.ZERO:
                linked_lines.append(potential_line)

        return linked_lines
Example #3
0
def calculate_mid_point(lst_coord_0, lst_coord_1, lst_coord_2):

    lst_coord = [[[None], [None], [None]], [[None], [None], [None]], [[None], [None], [None]]]
    for i, coords in enumerate([lst_coord_0, lst_coord_1, lst_coord_2]):
        if len(coords) <= 2:
            lst_coord[i][0] = coords[0]
            mid_point = LineString((coords[0], coords[1])).interpolate(.5, normalized=True)
            lst_coord[i][1] = (mid_point.x, mid_point.y)
            lst_coord[i][2] = coords[1]
        else:
            for j in range(3):
                lst_coord[i][j] = coords[j]

    try_0 = (lst_coord[0], lst_coord[1])
    try_1 = (lst_coord[1], lst_coord[2])
    try_2 = (lst_coord[0], lst_coord[2])
    max_sum_angles = -1.
    max_mid_p01_p11 = None

    for (lst_coord_a, lst_coord_b) in (try_0, try_1, try_2 ):

        p0 = lst_coord_a[0]
        p01 = lst_coord_a[1]
        p02 = lst_coord_a[2]

        p11 = lst_coord_b[1]
        p12 = lst_coord_b[2]

        tmp_mid_p01_p11 = LineString((p01, p11)).interpolate(.5, normalized=True)
        mid_p01_p11 = (tmp_mid_p01_p11.x, tmp_mid_p01_p11.y)
        line_mid_p0 = LineString((mid_p01_p11, p0))
        length_y_junction = line_mid_p0.length

        angle_mid_p01_p02 = GenUtil.compute_angle(mid_p01_p11, p01, p02, type=GenUtil.DEGREE)
        angle_mid_p11_p12 = GenUtil.compute_angle(mid_p01_p11, p11, p12, type=GenUtil.DEGREE)

        if length_y_junction <= command.yjunction:
            sum_angles = angle_mid_p01_p02 + angle_mid_p11_p12
            if sum_angles > max_sum_angles:
                max_sum_angles = sum_angles
                max_mid_p01_p11 = mid_p01_p11

    return max_mid_p01_p11
Example #4
0
    def _calculate_adj_area(self, coords):
        """Calculates the adjusted area of a polygon

        Parameters
        ----------
        coords : list
            List of x,y coordinates defining a polygon

        Returns
        -------
        float
            Minimum adjusted area
        """

        pol = Polygon(coords)
        cmp_index = GenUtil.calculate_compactness_index(pol.area, pol.length)
        adj_area = GenUtil.calculate_adjusted_area(pol.area, cmp_index)

        return adj_area
Example #5
0
    def vertex_orientation(self):
        """This method calculates the orientation of the vertex

        List containing the orientation at each vertex of the line.
        -1: anti clockwise, +1 Clockwise; 0 Straight line
        For closed line the first and last vertice bear the same value
        For open line the first and last value are None

        Parameters
        ----------
        None

        Returns
        -------
        None
        """

        try:
            return self._vertex_orientation
        except AttributeError:
            self._vertex_orientation = []
            for i in range(
                    1,
                    len(self.coords) -
                    1):  # '1' and 'cnt-1' to 'forget' first and last vertice
                orient = GenUtil.orientation(self.coords[i - 1],
                                             self.coords[i],
                                             self.coords[i + 1])
                self._vertex_orientation.append(orient)
            if self.is_closed:
                # Case of a closed line or polygon; we do not copy the first and lat even if they are the same
                orient = GenUtil.orientation(self.coords[-2], self.coords[0],
                                             self.coords[1])
                self._vertex_orientation = [orient] + self._vertex_orientation
            else:
                # Case of an open line; the first and last are None
                orient = None
                self._vertex_orientation = [
                    orient
                ] + self._vertex_orientation + [orient]
            return self._vertex_orientation
Example #6
0
    def cmp_index(self):
        """Calculates the value of the compactness index

        Parameters
        ----------
        None

        Returns
        -------
        float
            Value of the compactness index
        """
        try:
            return self._cmp_index
        except AttributeError:
            self._cmp_index = GenUtil.calculate_compactness_index(
                self.area, self.perimeter)
            return self._cmp_index
Example #7
0
def join_lines(s_container, command, geo_content, tolerance):

    # Loop over each line in the list
    for line in s_container.get_features():
        # Loop over the first and last vertice of the line
        for ind in [FIRST, LAST]:
            line_topology = Topology(s_container, line)
            if ind == LAST:
                line_topology.reverse()
            lst_coord_line = list(line.coords)
            if len(line_topology.start_linked_lines) == 0:
                b_box = GenUtil.build_bounding_box(tolerance, lst_coord_line[0])
                potential_lines = s_container.get_features(b_box, remove_features=[line])
                target_line = None
                for potential_line in potential_lines:
                    for i in [FIRST, LAST]:
                        lst_coord_potential = list(potential_line.coords)
                        if Point(lst_coord_line[0]).distance(Point(lst_coord_potential[i])) <= tolerance:
                            target_line = potential_line
                            target_coord = lst_coord_potential[i]

                    if target_line:
                        # We have a line to join with
                        new_line = LineString((lst_coord_line[0], target_coord))
                        merged_line = linemerge([line, new_line, target_line])
                        if merged_line.geom_type == GenUtil.LINE_STRING:
                            lst_merged_line_coord = list(merged_line.coords)
                            line.coords = lst_merged_line_coord
                            try:
                                s_container.del_feature(target_line)
                            except Exception:
                                pass
                            geo_content.nbr_join += 1
                        else:
                            # Possible problem with the merged line go to next line
                            pass
                    else:
                        # No line to merged with
                        pass
            else:
                # Line is not open. Go to next line
                pass

    return
Example #8
0
    def adj_area(self):
        """Calculates the value of the compactness index of the polygon

        Parameters
        ----------
        None

        Returns
        -------
        float
            Value of the compactness index
        """

        try:
            return self._adj_area
        except AttributeError:
            self._adj_area = GenUtil.calculate_adjusted_area(
                self.area, self.cmp_index)
            return self._adj_area
Example #9
0
    def base(self):
        """Length of the base of the bend. Distance between the first and last coordinate

        Parameters
        ----------
        None

        Returns
        -------
        Float
            Length of the bend of the polygon
        """

        try:
            return self._base
        except AttributeError:
            self._base = GenUtil.distance(self.bend_coords[0],
                                          self.bend_coords[-1])
            if self._base <= GenUtil.ZERO:
                self._base = GenUtil.ZERO  # Avois a case of division by zero
            return self._base
Example #10
0
    def sb_is_closed(self):
        """This method tests if a line is closed (first/last coordinates are the same)

        Parameters
        ----------
        None

        Returns
        -------
        bool
            True: the line is closed or False the line is open
        """

        try:
            return self._sb_is_closed
        except AttributeError:
            # A closed line need at least 4 vertex to be valid
            if len(self.coords) >= 4 and GenUtil.distance(
                    self.coords[0], self.coords[-1]) <= GenUtil.ZERO:
                self._sb_is_closed = True
            else:
                self._sb_is_closed = False
            return self._sb_is_closed
Example #11
0
def extend_line(s_container, command, geo_content, tolerance):

    # Loop over each line in the list
    for line in s_container.get_features():
        # Loop over the first and last vertice of the line
        for ind in [FIRST, LAST]:
            line_topology = Topology(s_container, line)
            if ind == LAST:
                line_topology.reverse()
            lst_coord_line = list(line.coords)
            if len(line_topology.start_linked_lines) == 0:
                b_box = GenUtil.build_bounding_box(tolerance, lst_coord_line[0])
                potential_lines = s_container.get_features(b_box, remove_features=[line])
                new_coord = None
                distance_min = tolerance + 1.
                for potential_line in potential_lines:
                    linear_ref = potential_line.project(Point(lst_coord_line[0]))
                    point_on_line = potential_line.interpolate(linear_ref)
                    distance = Point(lst_coord_line[0]).distance(point_on_line)
                    if distance <= tolerance:
                        if distance_min > distance:
                            distance_min = distance
                            new_coord = (point_on_line.x, point_on_line.y)

                    if new_coord:
                        # We have a line to join with
                        lst_new_coord_line = [new_coord] + lst_coord_line
                        line.coords = lst_new_coord_line
                        geo_content.nbr_extend += 1
                    else:
                        # No line to merged with
                        pass
            else:
                # Line is not open. Go to next line
                pass

    return
Example #12
0
                         in_nbr_points=0, in_nbr_line_strings=0, in_nbr_polygons=0, in_nbr_holes=0,
                         out_nbr_points=0, out_nbr_line_strings=0, out_nbr_polygons=0, out_nbr_holes=0,
                         nbr_del_polygons=0, nbr_del_holes=0)

# Read the command line arguments
command = manage_arguments()

if command.dlayer:
    # Extract the list of layers to read
    in_layer_names = [layer_name for layer_name in command.dlayer_dict.keys()]
else:
    # Read all the layers in the input file
    in_layer_names = None

# Read and load the layers of the input file
GenUtil.read_in_file(command.in_file, geo_content, in_layer_names)

# Set the diameter for each layer
tmp_dlayer_dict = {}
for layer_name in geo_content.layer_names:
    if command.diameter is not None:
        # The same diameter value is applied to all the layers
        tmp_dlayer_dict[layer_name] = command.diameter
    else:
        # There is a specific diameter for each layer
        tmp_dlayer_dict[layer_name] = command.dlayer_dict[layer_name]

# Reset the value of dlayer
command.dlayer_dict = tmp_dlayer_dict

# Only keep in the in features the ones where the diameter is not -1
Example #13
0
    in_nbr_line_strings: 0
    out_nbr_line_strings: 0
    bounds: List[object] = None


geo_content = GeoContent(crs=None, driver=None, schemas={}, in_features=[], out_features=[],
                         nbr_xjunction=0, nbr_yjunction=0, nbr_join=0, nbr_noise=0, nbr_extend=0,
                         in_nbr_line_strings=0, out_nbr_line_strings=0, bounds=[])



# Read the command line arguments
command = read_arguments()


GenUtil.read_in_file (command.in_file, geo_content, [command.input_layer])


# test for Ycrossing
a = LineStringSc(((5,5),(5,10)))
b = LineStringSc(((0,4),(3,4),(5,5)))
c = LineStringSc(((5,5),(7,4),(10,4)))
d = LineStringSc(((5,10),(7,11), (10,11)))
e = LineStringSc(((0,11),(3,11),(5,10)))
lst_y_junction = [a,b,c,d,e]

# Test for X crossing
f = LineStringSc(((10,10), (10,15),(10,20)))
g = LineStringSc(((6,21),(8,21),(10,20)))
h = LineStringSc(((10,20),(12,21),(14,21)))
i = LineStringSc(((10,10), (8,9), (6,9)))
Example #14
0
    def create_replacement_line(lst_coords, bend, diameter):
        """Calculate the replacement line for a bend"""

        # Extract the sub line containing the bend with one extra vertice on each side
        sub_line = LineStringSb(lst_coords[bend.i - 1:bend.j + 1])
        bend_i = 1
        bend_j = len(bend.j) - 1

        # Translate to sub line so that the bend starts at 0,0
        xoff, yoff = lst_coords[bend.i][0], lst_coords[bend.i][1]
        line_translate = affinity.affine_transform(sub_line,
                                                   [1, 0, 0, 1, -xoff, -yoff])

        # Extract the angle between the base of the bend (bendi, bendj) and the x axis
        lst_coord = list(line_translate.coords)
        p0 = (lst_coord[bend_j][0], lst_coord[bend_j][1])
        p1 = (lst_coord[bend_i][0], lst_coord[bend_i][1])
        p2 = (abs(p0[0]) + 1., 0)
        angle = GenUtil.angle_vecor(p0, p1, p2)
        #        p0_x = line1_coord[bend_j][0]
        #        p0_y = line1_coord[bend_j][1]
        #        p1_x = abs(p0_x) + 1.  # In case x == 0
        #        p1_y = 0.

        #        dot = p0_x * p1_x + p0_y * p1_y
        #        len_a = (p0_x ** 2 + p0_y ** 2) ** .5
        #        len_b = (p1_x ** 2 + p1_y ** 2) ** .5

        angle = math.acos(dot / (len_a * len_b))
        angle = (angle * 180 / math.pi)

        if p0[1] >= 0.:
            angle = -angle  # Clockwise rotation


#        if p0_y >= 0.:
#            angle = -angle

# Rotate the bend so it's on the x axis
        a = math.cos(angle)
        b = -math.sin(angle)
        d = math.sin(angle)
        e = math.cos(angle)
        line_rotate = affinity.rotate(line_translate, angle, origin=(0, 0))
        lst_coords = list(line_rotate.coords)

        #        line_i = LineString(lst_coords[0:3])
        #        line_j = LineString(lst_coords[-2:])
        # Calculate the angle between the base of the bend of segment before and after the bend
        theta_i = lib_geobato.GenUtil.compute_angle(lst_coords[0],
                                                    lst_coords[1],
                                                    lst_coords[bend_j])
        theta_j = lib_geobato.GenUtil.compute_angle(lst_coords[bend_j],
                                                    lst_coords[-2],
                                                    lst_coords[-1])

        # Determine if the
        bend_line = LineString(lst_coord[bend_i:bend_j + 1])
        (minx, miny, maxx, maxy) = bend_line.bounds
        y_dynamic = (abs(miny) + abs(maxy)) * 10.
        x_middle = (lst_coords[bend_i][0] + lst_coords[bend_j][0]) / 2.
        line_y_positive = LineString(((x_middle, 0), (x_middle, y_dynamic)))
        line_y_negative = LineString(((x_middle, 0), (x_middle, -y_dynamic)))
        if line4.crosses(line_y_positive):
            bend_side = +1
        else:
            if line4.crosses(line_y_negative):
                bend_side = -1

        if lst_coords[0][1] >= 0.:
            start_line_side = 1
        else:
            start_line_side = -1

        if lst_coords[-1][1] >= 0.:
            end_line_side = 1
        else:
            end_line_side = -1

        if (start_line_side * end_line_side == -1):
            print("Nothing to do....")
            line5 = LineString(lst_coords[0:bend_i + 1] + lst_coords[bend_j:])
        else:
            # Both line are on the same side
            if start_line_side == 1 and end_line_side == 1:
                if bend_side == -1:
                    angle_bias = 2.
                    y_offset = -1
                else:
                    angle_bias = 3.
                    y_offset = 1
            if start_line_side == -1 and end_line_side == -1:
                if bend_side == 1:
                    angle_bias = 2.
                    y_offset = 1
                else:
                    angle_bias = 3.
                    y_offset = 1

            theta_i = (180. - theta_i) / angle_bias
            if theta_i >= 5.:
                hypothenus = x_middle / math.cos(theta_i * math.pi / 180.)
                y_height = math.sqrt(hypothenus**2 - x_middle**2)
                if bend_side == -1:
                    y_height *= y_offset
                new_coord = (x_middle, y_height)
                line5 = LineString(lst_coords[0:bend_i + 1] + [new_coord] +
                                   lst_coords[bend_j:])
            else:
                print("Nothing to do....")
                line5 = LineString(lst_coords[0:bend_i + 1] +
                                   lst_coords[bend_j:])