Example #1
0
def widen_line(linestring: sg.LineString, width: float) -> sg.Polygon:
    linestrings = [
        linestring,
        linestring.parallel_offset(width, "left"),
        linestring.parallel_offset(width, "right"),
    ]
    return sg.MultiLineString(linestrings).minimum_rotated_rectangle
Example #2
0
def _make_xyz(row, distance_main, distance_help, bottom_level, bottom_width, talud_l, talud_r, total_depth = 10):
    # Set up basic profile parameters: bottom width & total width based on talud
    if math.isnan(bottom_width):
        bottom_width = 2
        logging.info(f"Profielen maken: {row['CODE']} geen bodembreedte gevonden, bodembreedte op 2 gezet.")
    total_width = bottom_width + total_depth * talud_l + total_depth * talud_r
    if math.isnan(total_width):
        total_width = bottom_width + 2 * total_depth * 2
        logging.info(f"Profielen maken: {row['CODE']} geen taluds gevonden, talud op 2 gezet.")

    upper_level = bottom_level + total_depth

    # Profile will be created using a short sub-segment of the source-line-geometry.
    l = row['geometry'].length
    logging.info(f'Profielen maken: {row["CODE"]}, op afstand: {distance_main} van lengte: {l}, '
                 f'bodembreedte: {bottom_width}, '
                 f'bodemhoogte: {bottom_level}, totale diepte: {total_depth}')

    point1 = row['geometry'].interpolate(distance_main)
    point2 = row['geometry'].interpolate(distance_help)
    baseline = LineString([point1, point2])

    left_inner = baseline.parallel_offset(bottom_width/2, 'left')
    right_inner = baseline.parallel_offset(bottom_width/2, 'right')
    left_inner_point = shapely.ops.transform(lambda x, y: (x, y, bottom_level), Point(left_inner.coords[0]))
    right_inner_point = shapely.ops.transform(lambda x, y: (x, y, bottom_level), Point(right_inner.coords[-1]))

    left_outer = baseline.parallel_offset(total_width/2, 'left')
    right_outer = baseline.parallel_offset(total_width/2, 'right')
    left_outer_point = shapely.ops.transform(lambda x, y: (x, y, upper_level), Point(left_outer.coords[0]))
    right_outer_point = shapely.ops.transform(lambda x, y: (x, y, upper_level), Point(right_outer.coords[-1]))

    profile_line = LineString([left_outer_point, left_inner_point, right_inner_point, right_outer_point])
    return profile_line
def _make_dwp(row, up_or_down: str = 'upstream', profile_dist: float = 5):
    width = row['WS_BODEMBREEDTE_L'] + 2 * row['WS_TALUD_LINKS_L'] + 2 * row[
        'WS_TALUD_RECHTS_L']
    l = row['geometry'].length
    logging.info(
        f'DWP maken: {up_or_down}, {row["CODE"]}, lengte: {l}, breedte: {width}'
    )
    if l > (profile_dist * 2 + 1):
        dist1 = profile_dist
        dist2 = profile_dist - 1
    else:
        dist1 = l * 0.2
        dist2 = l * 0.4
    if up_or_down.lower().startswith('down'):
        dist1 = dist1 * -1
        dist2 = dist2 * -1
    if math.isnan(width):
        width = 6
        logging.info(
            f"Normgeparametriseerdprofiel maken: {row['CODE']} er kon geen breedte gemaakt worden, geometrie wordt 6 meter breed"
        )
    point1 = row['geometry'].interpolate(dist1)
    point2 = row['geometry'].interpolate(dist2)
    baseline = LineString([point1, point2])
    left = baseline.parallel_offset(width / 2, 'left')
    right = baseline.parallel_offset(width / 2, 'right')
    left_point = left.coords[0]
    right_point = right.coords[-1]
    profile_line = LineString([left_point, right_point])
    return profile_line
Example #4
0
    def create_edge(self, edges):
        """Create the SUMO edge XML node(s) matching with the Webots road."""
        if self.startJunctionID == self.endJunctionID:
            print(
                'Warning: cannot export edge "%s" because start and end junctions are identical.'
                % self.id)
            return

        if len(self.wayPoints) < 2:
            print(
                'Warning: cannot export edge "%s" because it has less than 2 way-points.'
                % self.id)
            return

        laneWidth = self.width / self.lanes

        # The original path should be slightly shifted if the case where the
        # forwardLanes and backwardLanes are not matching.
        originalCoords = [[-x - self.translation[0], z + self.translation[2]]
                          for [x, y, z] in self.wayPoints]
        originalLineString = LineString(originalCoords)
        if self.oneWay:
            originalLineString = originalLineString.parallel_offset(
                0.5 * laneWidth * self.forwardLanes, 'left')
        else:
            offset = (self.forwardLanes - self.backwardLanes) * laneWidth * 0.5
            if offset > 0.0:
                originalLineString = originalLineString.parallel_offset(
                    offset, 'left')
            elif offset < 0.0:
                originalLineString = originalLineString.parallel_offset(
                    offset, 'left')
                originalLineString = LineString(
                    list(originalLineString.coords[::-1]))

        if isinstance(originalLineString, MultiLineString):
            originalPath = originalCoords
        else:
            originalPath = list(originalLineString.coords)

        # Create the forward edge
        if self.forwardLanes > 0:
            edge = ET.SubElement(edges, 'edge')
            edge.attrib['id'] = self.id
            edge.attrib['from'] = self.startJunctionID
            edge.attrib['to'] = self.endJunctionID
            edge.attrib['numLanes'] = str(self.forwardLanes)
            edge.attrib['width'] = str(laneWidth)
            edge.attrib['shape'] = Road._pathToString(originalPath)
        # Create the backward edge
        if self.backwardLanes > 0:
            edge = ET.SubElement(edges, 'edge')
            edge.attrib['id'] = '-' + self.id
            edge.attrib['to'] = self.startJunctionID
            edge.attrib['from'] = self.endJunctionID
            edge.attrib['numLanes'] = str(self.backwardLanes)
            edge.attrib['width'] = str(laneWidth)
            edge.attrib['shape'] = Road._pathToString(originalPath[::-1])
def create_line_string(geom, is_forward):
    ls = LineString([(geom.lonlats[i], geom.lonlats[i + 1])
                     for i in range(0, len(geom.lonlats), 2)])
    offset = .000045
    if is_forward:
        ls = ls.parallel_offset(offset, 'right')
    else:
        ls = ls.parallel_offset(offset, 'left')
    return ls
Example #6
0
def draw_tick(segment, x, y, length=0.25):
    line = LineString(segment)
    left = line.parallel_offset(length, 'left')
    right0 = line.parallel_offset(length, 'right')
    right = LineString([right0.boundary.geoms[1], right0.boundary.geoms[0]
                        ])  # flip because 'right' orientation
    point = Point(x, y)
    a = left.interpolate(line.project(point))
    b = right.interpolate(line.project(point))
    line = LineString([a, b])
    return line
Example #7
0
def perpendicular(point_a, baseline):
    b = point_a
    a = baseline[1]
    cd_length = 800

    ab = LineString([a, b])
    left = ab.parallel_offset(cd_length / 2, 'left')
    right = ab.parallel_offset(cd_length / 2, 'right')
    c = left.boundary[1]
    d = right.boundary[0]  # note the different orientation for right offset
    cd = LineString([c, d])
    return cd
Example #8
0
def get_linestring_side(ls: LineString, p: Point) -> str:
    """ Return which side of the LineString is the given point, order by the sequence of the coordinates.

    Args:
        ls: reference LineString
        p: point to check

    Returns:
        Either "left" or "right"
    """
    right = ls.parallel_offset(0.1, side="right")
    left = ls.parallel_offset(0.1, side="left")
    return "left" if left.distance(p) < right.distance(p) else "right"
Example #9
0
class Threshold:
    def __init__(self, name, points, color):
        self.name = name
        self.line = LineString(points)
        self.parallel_in = self.line.parallel_offset(30, side='left')
        self.parallel_out = self.line.parallel_offset(30, side='right')

        length = self.line.length
        self.midpoint = self.line.interpolate(length / 2)
        self.mid_in = self.parallel_in.interpolate(length / 2)
        self.mid_out = self.parallel_out.interpolate(length / 2)

        self.p_in = int(self.mid_in.x), int(self.mid_in.y)
        self.p_out = int(self.mid_out.x), int(self.mid_out.y)

        t_array = np.array(self.line)
        self.t_vec = t_array[1] - t_array[0]

        self.color = color
        self.counter = {"in": 0, "out": 0}

    def check(self, line):
        if self.line.intersects(line):
            p_array = np.array(line)
            p_vec = p_array[1] - p_array[0]
            direction = np.inner(self.t_vec, p_vec)
            if direction > 0:
                self.counter["in"] += 1
                return True
            elif direction < 0:
                self.counter["out"] += 1
                return True

    def draw(self, image):
        print(self.counter)
        line = np.array(self.line, np.uint32)
        cv2.line(image, tuple(line[0]), tuple(line[1]), self.color, 2)

        cv2.circle(image, tuple(self.p_in), 18, self.color, -9)

        in_count = self.counter["in"]
        cv2.putText(image, "{}:{}".format(self.name, str(in_count)),
                    (int(self.p_in[0]) - 17, int(self.p_in[1]) + 5),
                    cv2.FONT_HERSHEY_PLAIN, 1, (0, 0, 0), 1)

        out_count = self.counter["out"]
        cv2.circle(image, tuple(self.p_out), 18, self.color, -9)

        cv2.putText(image, "{}:{}".format(self.name, str(out_count)),
                    (int(self.p_out[0]) - 17, int(self.p_out[1]) + 5),
                    cv2.FONT_HERSHEY_PLAIN, 1, (0, 0, 0), 1)
def draw_ticks(segment, xList, yList, length=0.25):
    xdata = list(segment.get_xdata())
    ydata = list(segment.get_ydata())
    line = LineString([(xdata[0], ydata[0]), (xdata[1], ydata[1])])
    left = line.parallel_offset(length, 'left')
    right0 = line.parallel_offset(length, 'right')
    right = LineString([right0.boundary.geoms[1], right0.boundary.geoms[0]]) # flip because 'right' orientation
    ticks = []
    for i,x in enumerate(xList):
        p = Point(xList[i],yList[i])
        a = left.interpolate(line.project(p))
        b = right.interpolate(line.project(p))
        ticks.append(LineString([a, p, b]).coords)           # keep p point to sort from distance later
    return ticks
Example #11
0
 def getContour(self, poly, side, offset):
     line = LineString(PolygonPath(poly).vertices)
     contour = [line.parallel_offset(offset, side, join_style=2)]
     for part in contour:  #get offset paths
         x, y = part.xy
         self.offsetX.append(x)
         self.offsetY.append(y)
Example #12
0
    def generate_path(self):
        """Generate parallel coverage path lines"""
        starting_breakdown = self.rP.bounds[0:2]  # poly.bounds = bounding box
        line = LineString([
            starting_breakdown,
            (starting_breakdown[0],
             starting_breakdown[1] + self.rP.bounds[3] - self.rP.bounds[1])
        ])
        try:
            bounded_line = self.rP.intersection(line)
        except TopologicalError as e:
            error("Problem looking for intersection.", exc_info=1)
            return

        lines = [bounded_line]
        #         iterations = int(ceil((self.rP.bounds[2] - self.rP.bounds[0]) / ft)) + 1
        iterations = int((self.rP.bounds[2] - self.rP.bounds[0]) / self.ft) + 2
        for x in range(1, iterations):
            bounded_line = line.parallel_offset(x * self.ft, 'right')
            if self.rP.intersects(bounded_line):
                try:
                    bounded_line = self.rP.intersection(bounded_line)
                except TopologicalError as e:
                    error("Problem looking for intersection.", exc_info=1)
                    continue
                lines.append(bounded_line)
        return lines
Example #13
0
    def find_cut_distance(current_string: LineString, pair, frequency: int,
                          offset_distance: float, side: str):
        neighbor_string = LineString(
            [[pair.node_from.utm.north, pair.node_from.utm.east],
             [pair.node_to.utm.north, pair.node_to.utm.east]])
        offsetted_neighbor_string = neighbor_string.parallel_offset(
            frequency * offset_distance, side='left', resolution=10)

        # Project neighbor string onto current string.
        if side == 'back':
            projected_point = Point(
                nearest_points(
                    current_string,
                    Point(list(offsetted_neighbor_string.coords)[-1]))[0])
        else:
            projected_point = Point(
                nearest_points(
                    current_string,
                    Point(list(offsetted_neighbor_string.coords)[0]))[0])

        # Create a line from the side of the current string to the projected points.
        if side == 'back':
            line = LineString(
                [Point(list(current_string.coords)[0]), projected_point])
        else:
            line = LineString(
                [Point(list(current_string.coords)[-1]), projected_point])

        return line.length
Example #14
0
 def offset(self, distance):
     self.points.append(self.points[0])
     line = LineString(self.getSequence())
     offset = line.parallel_offset(distance, 'right', join_style=1)
     # return list(offset.coords)
     self.setSequence(list(offset.coords))
     return self
Example #15
0
    def _cont_to_polys(self, cont_lats, cont_lons):
        polys = []

        start_idx = 0
        splits = []
        while True:
            try:
                split_idx = cont_lats[start_idx:].index(99.99)
                splits.append(start_idx + split_idx)
                start_idx += split_idx + 1
            except ValueError:
                break

        splits = [ -1 ] + splits + [ len(cont_lats) + 1 ]
        poly_lats = [ cont_lats[splits[i] + 1:splits[i + 1]] for i in xrange(len(splits) - 1) ]
        poly_lons = [ cont_lons[splits[i] + 1:splits[i + 1]] for i in xrange(len(splits) - 1) ]

        # Intersect with the US boundary shape file.
        for plat, plon in zip(poly_lats, poly_lons):
            cont = LineString(zip(plon, plat))

            if plat[0] != plat[-1] or plon[0] != plon[-1]:
                # If the line is not a closed contour, then it intersects with the edge of the US. Extend
                #   the ends a little bit to make sure it's outside the edge.
                dln = np.diff(plon)
                dlt = np.diff(plat)

                pre = [ (plon[0] - 0.5 * dln[0], plat[0] - 0.5 * dlt[0]) ]
                post = [ (plon[-1] + 0.5 * dln[-1], plat[-1] + 0.5 * dlt[-1]) ]

                cont.coords = pre + list(cont.coords) + post 

            # polygonize() will split the country into two parts: one inside the outlook and one outside.
            #   Construct test_ln that is to the right of (inside) the contour and keep only the polygon
            #   that contains the line
            test_ln = cont.parallel_offset(0.05, 'right')

            for poly in polygonize(self._conus.boundary.union(cont)):
                if (poly.crosses(test_ln) or poly.contains(test_ln)) and self._conus.contains(poly.buffer(-0.01)):
                    polys.append(poly)

        # Sort the polygons by area so we intersect the big ones with the big ones first.
        polys.sort(key=lambda p: p.area, reverse=True)

        # If any polygons intersect, replace them with their intersection.
        intsct_polys = []
        while len(polys) > 0:
            intsct_poly = polys.pop(0)
            pops = []
            for idx, poly in enumerate(polys):
                if intsct_poly.intersects(poly):
                    intsct_poly = intsct_poly.intersection(poly)
                    pops.append(idx)

            for pop_idx in pops[::-1]:
                polys.pop(pop_idx)

            intsct_polys.append(intsct_poly)
        return intsct_polys
Example #16
0
def generate_intersections(poly, width):
    """
    Get coverage lines inside a cell. Lines will be centered throught cell with padding of width/2.

    :param poly: Polygon data
    :param width: Width of distance between vertical lines
    :return: Intersected lines
    """
    initial_line = LineString([(poly.bounds[0] + width / 2.0, poly.bounds[1] - 1),
                               (poly.bounds[0] + width / 2.0, poly.bounds[3] + 1)])
    line = initial_line.parallel_offset(0, 'right')
    lines = []

    if poly.bounds[2] - poly.bounds[0] >= width / 2:
        iterations = int(math.ceil((poly.bounds[2] - poly.bounds[0] - width / 2.0) / width))
        for x in range(0, iterations):
            if poly.intersects(line):
                try:
                    bounded_line = deepcopy(line)
                    intersection_line = poly.intersection(line)

                    if intersection_line.bounds[1] != bounded_line.bounds[1]:
                        if intersection_line.bounds[1] > bounded_line.bounds[1]:
                            bounds = list(bounded_line.bounds)
                            bounds[1] = intersection_line.bounds[1] + width / 2.0
                        else:
                            bounds = list(bounded_line.bounds)
                            bounds[1] = intersection_line.bounds[1] - width / 2.0
                        bounded_line = LineString([tuple(bounds[:2]), tuple(bounds[2:])])

                    if intersection_line.bounds[3] != bounded_line.bounds[3]:
                        if intersection_line.bounds[3] > bounded_line.bounds[3]:
                            bounds = list(bounded_line.bounds)
                            bounds[3] = intersection_line.bounds[3] + width / 2.0
                        else:
                            bounds = list(bounded_line.bounds)
                            bounds[3] = intersection_line.bounds[3] - width / 2.0
                        bounded_line = LineString([tuple(bounds[:2]), tuple(bounds[2:])])

                except TopologicalError:
                    error("Problem looking for intersection.", exc_info=1)
                    continue
                lines.append(bounded_line)

            line = initial_line.parallel_offset(width * (x + 1), 'right')
    return lines
Example #17
0
def applyOffset( xN, yN, d):
    line = LineString(  tuple(zip(xN , yN)) ) #create a linestring with a list of turple
    offLine= line.parallel_offset(d , side='right' , resolution=16, join_style=2, mitre_limit=5)
    if "Multi" in str(type(offLine)) :
        offLineXY = offLine[0].xy #extract the coordinate
    else:
        offLineXY = offLine.xy #extract the coordinate
    # there is a bug in the Offset function. With side = right, sequence is revered and have to be reversed afterward    
    return np.array(list(reversed(offLineXY[0])))  , np.array(list(reversed(offLineXY[1])))
Example #18
0
 def getContour(self, poly, side, offset):
     list = [[], []]
     line = LineString(PolygonPath(poly).vertices)
     contour = [line.parallel_offset(offset, side, join_style=2)]
     for part in contour:  #get offset paths
         x, y = part.xy
         list[0].append(x)
         list[1].append(y)
     return list
Example #19
0
   def __init__(self, id, points_list, traffic_signs_idx, right_offset, left_offset, lanes_list):
      '''
      Class Area is defined by an ID, a list GPS points of the desired area, indices of the traffic signals, 
      right and left offsets and the number of lanes of each line connecting each two consecutive GPS points
      '''
      # Assining ID to the Area
      self.id = id
      # Converting GPS coordinates to UTM coordinates
      p = Proj(proj='utm', zone=34, ellps='WGS84', preserve_units=False)
      utm_points = [None]*len(points_list)
      for idx, point in enumerate(points_list):
         utm_points[idx] = p(point[0], point[1])

      # Creating lines from given points and their right and left offsets
      center_line = LineString(utm_points)
      right_line = center_line.parallel_offset(right_offset, 'right', join_style=2).coords[:]
      left_line = center_line.parallel_offset(left_offset, 'left', join_style=2).coords[:]

      # Generating area polygon
      self.polygon = Polygon(right_line + left_line)
      self.polygon_pixels = []
      
      # Obtaining bounding box of the generated polygon
      x, y = list(zip(*self.polygon.exterior.coords))
      self.bbox = [min(x), max(x), min(y), max(y)]
      
      # Dividing area into regions = number of given points -1
      self.regions = [None]*(len(utm_points)-1)
      start_line = [self.polygon.exterior.coords[len(utm_points)-1], self.polygon.exterior.coords[len(utm_points)]] 
      for i in range(len(self.regions)):          
         center_line = LineString([utm_points[i], utm_points[i+1]])
         right_line = center_line.parallel_offset(right_offset, 'right', join_style=2).coords[:]
         left_line = center_line.parallel_offset(left_offset, 'left', join_style=2).coords[:]
         normal_line = np.array([right_line[0], left_line[-1]])
         end_point = utm_points[i+1]
         traffic_sign = True if i+1 in traffic_signs_idx else False
         self.regions[i] = Region(self, i, start_line, normal_line, end_point, lanes_list[i], traffic_sign)
         start_line = normal_line
      self.regions.reverse()

      # Initializing maximum queue and maximum queue time and region of the area
      self.max_queue = []
      self.max_queue_time = 0.0
      self.max_queue_region = None
Example #20
0
    def draw_star(self, _=None):
        self.starsLayout.canvas.clear()

        Globals = self.Globals

        centerX, centerY = Globals.width / 2, Globals.height / 2
        width = Globals.width / Globals.GameSettings.intro_ship_star_width_divider
        height = Globals.height / Globals.GameSettings.intro_ship_star_height_divider

        cd_length = height

        for i in range(Globals.GameSettings.intro_ship_star_amount):


            x, y = random.randint(0, Globals.width), random.randint(0, Globals.height / 2) + Globals.height / 2

            line = LineString([(centerX, centerY), (x, y)])
            left = line.parallel_offset(cd_length / 2, 'left')
            right = line.parallel_offset(cd_length / 2, 'right')
            p1 = left.boundary[1]
            p2 = right.boundary[0]

            x1, y1 = p1.coords[0]
            x2, y2 = p2.coords[0]

            a = 0, y1
            b = x1, y1
            c = x2, y2

            angle = math.degrees(math.atan2(c[1] - b[1], c[0] - b[0]) - math.atan2(a[1] - b[1], a[0] - b[0]))
            angle = angle + 360 if angle < 0 else angle

            rect = LineString([(x, y), (x, y + height), (x + width, y + height), (x + width, y)])
            rect = affinity.rotate(rect, angle + 90, "center")
            rect = rect.coords


            with self.starsLayout.canvas:
                Color(1, 1, 1)

                Mesh(indices=(0, 1, 2, 3),
                     vertices=(rect[0][0], rect[0][1], 0, 0, rect[1][0], rect[1][1], 0, 1,
                               rect[2][0], rect[2][1], 1, 1, rect[3][0], rect[3][1], 1, 0),
                     mode="triangle_fan", texture=self.Globals.Textures.star)
Example #21
0
def create_path(a, b, contour, distancia, dir=0):
    conf_1 = -90
    conf_2 = -1
    conf_3 = "left"
    conf_4 = 0
    if dir == 1:
        conf_3 = "right"
    path = []
    contorno_points = []
    for c in contour:
        c = utils.to_utm(c)
        utm_pos = Point(c.x, c.y)
        contorno_points.append(utm_pos)
    a2 = utils.to_utm(a)
    a_utm = Point(a2.x, a2.y)
    b2 = utils.to_utm(b)
    b_utm = Point(b2.x, b2.y)
    ab_course = utils.bearing(a_utm, b_utm)
    a_utm = utils.offset(a2, ab_course - 90, distancia * 80)
    b_utm = utils.offset(b2, ab_course - 90, distancia * 80)
    a2, b2 = utils.extend(a_utm, b_utm)
    AB = LineString([a2, b2])
    contorno = Polygon(contorno_points)
    eroded = contorno.buffer(-distancia, resolution=16, join_style=1)
    line = AB.intersection(eroded)

    for x in range(1, 200):
        ab_1 = AB.parallel_offset(x * distancia, conf_3)
        line = ab_1.intersection(eroded)
        if (line.geom_type == "LineString"):
            if (len(line.coords) > 1):
                p1 = 1
                p2 = conf_2
                if x % 2 == 0:
                    p1 = 0
                    p2 = -conf_2
                centro = utils.offset(utils.toCoord(line.coords[p1]),
                                      ab_course + conf_1, distancia / 2)
                radius = distancia / 2
                start_angle, end_angle = 90 - ab_course - 90, 90 - ab_course + 90  # In degrees
                if x % 2 == 0:
                    start_angle, end_angle = 90 - ab_course + 90, 90 - ab_course - 90
                numsegments = 200
                theta = np.radians(
                    np.linspace(start_angle, end_angle, numsegments))
                x = centro.x + (radius * np.cos(theta)) * p2
                y = centro.y + (radius * np.sin(theta)) * p2
                arc = LineString(np.column_stack([x, y]))
                for c in arc.coords:
                    path.append(Point(c))
    final = LineString(path)
    path2 = []
    for x in range(0, int(final.length / 2)):
        p = final.interpolate(x * 2)
        path2.append(p)
    return path2
Example #22
0
def build_baseline_offset(baseline, offset=50):
    """
    build a simple polygon of width $offset around the
    provided baseline, 75% over the baseline and 25% below.
    """
    try:
        line = LineString(baseline)
        up_offset = line.parallel_offset(offset * 0.75, "right", join_style=2)
        bot_offset = line.parallel_offset(offset * 0.25, "left", join_style=2)
    except:
        #--- TODO: check if this baselines can be saved
        return False, None
    if (up_offset.type != "LineString" or up_offset.is_empty == True
            or bot_offset.type != "LineString" or bot_offset.is_empty == True):
        return False, None
    else:
        up_offset = np.array(up_offset.coords).astype(np.int)
        bot_offset = np.array(bot_offset.coords).astype(np.int)
        return True, np.vstack((up_offset, bot_offset))
Example #23
0
def parallel_offset_wrapper(line_string: LineString, distance, side):
    offseted = line_string.parallel_offset(distance, side)

    if side == "right":
        offseted = LineString(reversed(offseted.coords))

    z = line_string.coords[0][2]
    coords_3d = [(c[0], c[1], z) for c in offseted.coords]

    return LineString(coords_3d)
def plot_arrow(ax, ob, color=GRAY, scale_factor=1.0, offset=0.00, offset_side='right', index=None, center_text=True, fontsize=10, **kwargs):
    ls_ = scale(ob, xfact=scale_factor, yfact=scale_factor)
    ls_ = ls_.parallel_offset(offset, offset_side)
    if offset_side == 'right':
        ls_ = LineString(list(reversed(ls_.coords)))
    x, y = ls_.xy
    ax.arrow(x[0], y[0], x[1] - x[0], y[1]-y[0], color=color, zorder=1, **kwargs)

    if index is not None:
        # Get angle of this edge
        v0 = np.array([1, 0])
        v1 = np.array([x[1] - x[0], y[1] - y[0]])
        v0_ = v0 / np.linalg.norm(v0)
        v1_ = v1 / np.linalg.norm(v1)
        deg = get360Angle(v0_, v1_)
        deg_rot = deg
        # print("Index: {}; Degree: {}".format(index, deg))
        offset_ = offset * 2
        x_shift = 0
        y_shift = 0
        if deg > 0 and deg < 90:
            offset_ = offset * 4
        elif deg >= 90 and deg < 180:
            deg_rot = deg - 180
            offset_ = offset * 6
        elif deg == 180:
            deg_rot = deg - 180
            offset_ = offset * 6
        elif deg > 180 and deg < 270:
            deg_rot = deg - 180
        elif deg >= 270 and deg < 360:
            deg_rot =  deg - 360

        
        if deg == 180 or deg == 0:
            x_shift = -0.25
        elif deg == 90 or deg == 270:
            y_shift = -0.20
            x_shift = -0.05
        elif deg > 90 and deg < 315:
            x_shift = -.1
            y_shift = -.2
        elif deg > 42 and deg <= 45 or (deg == 315.0):
            x_shift = -0.2
            y_shift = -0.2
        # print(ls_.centroid)

        # print("Index; {}; DegRot: {}; x_shift: {}; y_shift: {}".format(index, deg_rot, x_shift, y_shift))
  
        # print("Offset: " , offset_)
        ls_ = ls_.parallel_offset(offset_, 'left')
        center = ls_.centroid
        # print(center, index)
        ax.text(center.x + x_shift, center.y + y_shift, str(index), rotation=deg_rot, fontsize=fontsize)
Example #25
0
def create_subrooms(areas_gdf, rooms_gdf):
    """In case of overlapping rooms, create subrooms.

    Args:
        areas_gdf (gpd.GeoDataFrame): Geodataframe.
        rooms_gdf (gpd.GeoDataFrame): Geodataframe.
    """
    areas_gdf = areas_gdf.copy()
    areas_gdf = areas_gdf.sort_values("floor_index")
    indices_occuring_multiple_times = (areas_gdf["polygon_index"].value_counts(
    )[areas_gdf["polygon_index"].value_counts() > 1].index.values)

    if len(indices_occuring_multiple_times) > 0:
        subset = areas_gdf.loc[areas_gdf["polygon_index"].isin(
            indices_occuring_multiple_times)].copy()
        for ind, grp in subset.groupby(["polygon_index"]):
            temp = rooms_gdf.loc[grp["floor_index"].values].copy().head(2)
            # Todo make it handle n number of locs using voronoi.
            temp.geometry = temp.centroid
            line_between = LineString(list(temp.geometry.values))

            if line_between.length == 0:
                continue

            p_1 = line_between.parallel_offset(200, "left").centroid
            p_2 = line_between.parallel_offset(200, "right").centroid
            orthogonal_line_between = LineString([p_1, p_2])

            res = (gpd.GeoDataFrame(geometry=[
                ops.split(grp.geometry.values[0], orthogonal_line_between)
            ]).explode().reset_index(drop=True))

            matching_gdf = (gpd.sjoin(res,
                                      temp).rename(columns={
                                          "index_right": "floor_index"
                                      }).sort_values("floor_index"))

            areas_gdf.loc[areas_gdf["floor_index"].isin(temp.index),
                          "geometry"] = matching_gdf.geometry.values
    areas_gdf["area_size"] = areas_gdf.geometry.area
    return areas_gdf
Example #26
0
def drawTrack(centerline, width = .75):
	# draws the track
	BLUE = '#0000FF'
	BLACK = '#000000'
	YELLOW = '#FFFF00'
	WHITE = '#000000'
	
	track = LineString(centerline)
	#track_bounds = track.bounds
	#ax_range = [int(track_bounds[0] - 1.0), int(track_bounds[2] + 1.0)]
	#ay_range = [int(track_bounds[1] - 1.0), int(track_bounds[3] + 1.0)]

	def plot_coords(ax, x, y, color='#999999', zorder=1):
	    ax.plot(x, y, 'o', color=color, zorder=zorder)

	def plot_line(ax, ob, color='#0000FF', linestyle='-'):
	    parts = hasattr(ob, 'geoms') and ob or [ob]
	    for part in parts:
	        x, y = part.xy
	        ax.plot(x, y, color=color, linewidth=3, solid_capstyle='round', zorder=1, linestyle=linestyle)

	### Plot the track
	# define the figure
	fig = pyplot.figure(1, figsize= [25,20], dpi=90)
	ax = fig.add_subplot(111)

	plot_line(ax, track, BLACK, '--')
	#x, y = list(track.coords)[0]
	#plot_coords(ax, x, y)
	offset_outer = track.parallel_offset(width, 'left', join_style=1)
	plot_line(ax, offset_outer, color=BLACK)
	offset_inner = track.parallel_offset(width, 'right', join_style=1)
	plot_line(ax, offset_inner, color=BLACK)


	ax.set_aspect('equal')
	ax.grid(True, which='both')
	pyplot.show()
	return 1
def exteriorRectangle(p0, p1, minWidth):
    segment = LineString([p0, p1])
    if segment.length > posDelta:
        exterior_offset = segment.parallel_offset(minWidth, 'left')
        exteriorRect = [p0, p1]
        toAdd = list(exterior_offset.coords)
        exteriorRect.extend(toAdd)
        if len(interiorRect) < 3:
            logger.error("Even worse, got to what should be a failure!")
            logger.error(str(segment.length))
            logger.error("ToAdd " + str(toAdd))
            logger.error("InteriorRect: " + str(exteriorRect))
        else:
            return Polygon(exteriorRect)
Example #28
0
    def _cont_to_polys(self, cont_lats, cont_lons, cont_val):
        """
        Take the lat/lon contours, split them into their different segments, and create polygons out of them. Contours
        that stretch from border to border will end up covering large sections of the country. That's okay; we'll take
        care of that later.
        """
        polys = {}

        start_idx = 0
        splits = []
        while True:
            try:
                split_idx = cont_lats[start_idx:].index(99.99)
                splits.append(start_idx + split_idx)
                start_idx += split_idx + 1
            except ValueError:
                break

        splits = [ -1 ] + splits + [ len(cont_lats) + 1 ]
        poly_lats = [ cont_lats[splits[i] + 1:splits[i + 1]] for i in xrange(len(splits) - 1) ]
        poly_lons = [ cont_lons[splits[i] + 1:splits[i + 1]] for i in xrange(len(splits) - 1) ]

        # Intersect with the US boundary shape file.
        for plat, plon in zip(poly_lats, poly_lons):
            cont = LineString(zip(plon, plat))

            if plat[0] != plat[-1] or plon[0] != plon[-1]:
                # If the line is not a closed contour, then it intersects with the edge of the US. Extend
                #   the ends a little bit to make sure it's outside the edge.
                dln = np.diff(plon)
                dlt = np.diff(plat)

                pre = [ (plon[0] - 0.03 * dln[0], plat[0] - 0.03 * dlt[0]) ]
                post = [ (plon[-1] + 0.03 * dln[-1], plat[-1] + 0.03 * dlt[-1]) ]

                cont.coords = pre + list(cont.coords) + post 

            # polygonize() will split the country into two parts: one inside the outlook and one outside.
            #   Construct test_ln that is to the right of (inside) the contour and keep only the polygon
            #   that contains the line
            test_ln = cont.parallel_offset(0.05, 'right')

            polys[cont] = []

            for poly in polygonize(self._conus.boundary.union(cont)):
                if (poly.crosses(test_ln) or poly.contains(test_ln)) and self._conus.contains(poly.buffer(-0.01)):
                    polys[cont].append(poly)

        return polys
Example #29
0
 def _calculate_parallel_coords(offset: float, line_width: float) \
         -> Optional[List[Tuple[float, float, float, float]]]:
     original_line = LineString(zip(new_x_vals, new_y_vals))
     try:
         offset_line = original_line.parallel_offset(offset)
         coords = offset_line.coords.xy
     except (NotImplementedError,
             Exception):  # FIXME Where is TopologyException
         _logger.exception(
             "Creating an offset line for lane markings failed")
         return None
     # NOTE The parallel LineString may have a different number of points than initially given
     num_coords = len(coords[0])
     z_vals = repeat(0.01, num_coords)
     marking_widths = repeat(line_width, num_coords)
     return list(
         zip(coords[0], coords[1], z_vals, marking_widths))
Example #30
0
def generate_intersections(poly, width):
    "Subdivide a filed into coverage lines."
    starting_breakdown = poly.bounds[0:2]
    line = LineString([
        starting_breakdown,
        (starting_breakdown[0],
         starting_breakdown[1] + poly.bounds[3] - poly.bounds[1])
    ])

    #     numCoords = len(line.coords) - 1
    #     for i in range(0,numCoords):
    #         point1 = line.coords[i]
    #         point2 = line.coords[i+1]
    #         print "Index " + str(i) + str(point1) + str(point2)
    #     print("----------line: %d",poly.bounds[3] - poly.bounds[1])
    #         ############
    #     ax, _ = make_axis()
    #     plot_line(line, ax)
    #     ax.axvline(x=0, color='black')
    #     ax.axhline(y=0, color='black')
    #     import pylab; pylab.show()
    # #######################

    try:
        bounded_line = poly.intersection(line)
    except TopologicalError as e:
        error("Problem looking for intersection.", exc_info=1)
        return

    lines = [bounded_line]

    iterations = int(math.ceil((poly.bounds[2] - poly.bounds[0]) / width)) + 1
    for x in range(1, iterations):
        bounded_line = line.parallel_offset(x * width, 'right')
        if poly.intersects(bounded_line):
            try:
                bounded_line = poly.intersection(bounded_line)
            except TopologicalError as e:
                error("Problem looking for intersection.", exc_info=1)
                continue
            lines.append(bounded_line)
            # print("lines append count %d",bounded_line.type)
            # print "+++++++++++++++++++++",bounded_line
    return lines
Example #31
0
    def offset_linestring(zone_latlon: LatLon, string: LineString,
                          offset_distance: float,
                          offset_multiplier: int) -> List[Node]:
        offsetted_string = string.parallel_offset(
            (offset_multiplier + 1) * offset_distance,
            side='left',
            resolution=10)

        nodes = []
        if isinstance(offsetted_string, LineString):
            for north, east in list(offsetted_string.coords):
                utm = UTM(north, east)
                nodes.append(Node(utm.convert_to_latlon(zone_latlon)))
        else:
            raise Exception(
                f"Error while offsetting linestring. The result geometry is not a LineString."
            )

        return nodes
Example #32
0
def sgm(x_t, y_t):
    sgm_length = 20000.0
    sgm_width = 30000.0
    zipxy = zip(x_t, y_t)
    line_t = LineString(zipxy)
    line_t_length = line_t.length
    sgm_nr = int(line_t_length / sgm_length)
    sgm_l = []
    sgm_l_left = []
    for sgm_i in range(0, sgm_nr, 1):
        t_startp = sgm_i * sgm_length
        t_endp = (sgm_i + 1) * sgm_length
        sgm_l_i_start = line_t.interpolate(t_startp)
        sgm_l_i_end = line_t.interpolate(t_endp)
        sgm_l_i = LineString([sgm_l_i_start, sgm_l_i_end])
        sgm_l_left_i = sgm_l_i.parallel_offset(sgm_width + 1000.0,
                                               'left',
                                               join_style=1)
        sgm_l.append(sgm_l_i)
        sgm_l_left.append(sgm_l_left_i)
    return sgm_nr, sgm_l, sgm_l_left
Example #33
0
    def test_parallel_offset_linestring(self):
        line1 = LineString([(0, 0), (10, 0)])
        left = line1.parallel_offset(5, 'left')
        self.assertEqual(left, LineString([(0, 5), (10, 5)]))
        right = line1.parallel_offset(5, 'right')
        self.assertEqual(right, LineString([(10, -5), (0, -5)]))
        right = line1.parallel_offset(-5, 'left')
        self.assertEqual(right, LineString([(10, -5), (0, -5)]))
        left = line1.parallel_offset(-5, 'right')
        self.assertEqual(left, LineString([(0, 5), (10, 5)]))

        # by default, parallel_offset is right-handed
        self.assertEqual(line1.parallel_offset(5), right)

        line2 = LineString([(0, 0), (5, 0), (5, -5)])
        self.assertEqual(line2.parallel_offset(2, 'left', resolution=1),
                         LineString([(0, 2), (5, 2), (7, 0), (7, -5)]))
        self.assertEqual(
            line2.parallel_offset(2, 'left', join_style=2, resolution=1),
            LineString([(0, 2), (7, 2), (7, -5)]))
Example #34
0
    def test_parallel_offset_linestring(self):
        line1 = LineString([(0, 0), (10, 0)])
        left = line1.parallel_offset(5, 'left')
        self.assertEqual(left, LineString([(0, 5), (10, 5)]))
        right = line1.parallel_offset(5, 'right')
        self.assertEqual(right, LineString([(10, -5), (0, -5)]))
        right = line1.parallel_offset(-5, 'left')
        self.assertEqual(right, LineString([(10, -5), (0, -5)]))
        left = line1.parallel_offset(-5, 'right')
        self.assertEqual(left, LineString([(0, 5), (10, 5)]))

        # by default, parallel_offset is right-handed
        self.assertEqual(line1.parallel_offset(5), right)

        line2 = LineString([(0, 0), (5, 0), (5, -5)])
        self.assertEqual(line2.parallel_offset(2, 'left', resolution=1),
                         LineString([(0, 2), (5, 2), (7, 0), (7, -5)]))
        self.assertEqual(line2.parallel_offset(2, 'left', join_style=2,
                         resolution=1),
                         LineString([(0, 2), (7, 2), (7, -5)]))
def generate_intersections(poly, width):
    "Subdivide a filed into coverage lines."
    starting_breakdown = poly.bounds[0:2]
    line = LineString([starting_breakdown, (starting_breakdown[0],
                                            starting_breakdown[1] +
                                            poly.bounds[3] - poly.bounds[1])])
    try:
        bounded_line = poly.intersection(line)
    except TopologicalError as e:
        error("Problem looking for intersection.", exc_info=1)
        return
    lines = [bounded_line]
    iterations = int(math.ceil((poly.bounds[2] - poly.bounds[0]) / width)) + 1
    for x in range(1, iterations):
        bounded_line = line.parallel_offset(x * width, 'right')
        if poly.intersects(bounded_line):
            try:
                bounded_line = poly.intersection(bounded_line)
            except TopologicalError as e:
                error("Problem looking for intersection.", exc_info=1)
                continue
            lines.append(bounded_line)
    return lines
Example #36
0
    ax.set_aspect(1)

line = LineString([(0, 0), (1, 1), (0, 2), (2, 2), (3, 1), (1, 0)])
line_bounds = line.bounds
ax_range = [int(line_bounds[0] - 1.0), int(line_bounds[2] + 1.0)]
ay_range = [int(line_bounds[1] - 1.0), int(line_bounds[3] + 1.0)]

fig = pyplot.figure(1, figsize=(SIZE[0], 2 * SIZE[1]), dpi=90)

# 1
ax = fig.add_subplot(221)

plot_line(ax, line)
x, y = list(line.coords)[0]
plot_coords(ax, x, y)
offset = line.parallel_offset(0.5, 'left', join_style=1)
plot_line(ax, offset, color=BLUE)

ax.set_title('a) left, round')
set_limits(ax, ax_range, ay_range)

#2
ax = fig.add_subplot(222)

plot_line(ax, line)
x, y = list(line.coords)[0]
plot_coords(ax, x, y)

offset = line.parallel_offset(0.5, 'left', join_style=2)
plot_line(ax, offset, color=BLUE)
    def run(self):
        # show the dialog
        self.dlg.show()
        # Run the dialog event loop
        result = self.dlg.exec_()
        # See if OK was pressed
        if result == 1:
			layers = iface.legendInterface().layers()
			if len(layers) != 0:
				#Check that there is a selected layer
				layer = iface.mapCanvas().currentLayer()
				if layer.type() == 0:
					#check selected layer is a vector layer
					if layer.geometryType() == 1:
						#check to see if selected layer is a linestring geometry
						if len(layer.selectedFeatures()) != 0:
							#Dir = float(self.dlg.ui.radLeft.isChecked()
							layers = iface.legendInterface().layers()
							Lexists = "false"
							#check to see if the virtual layer already exists
							for layer in layers:
								if layer.name() == "Parallel_Offset":
									Lexists = "true"
									vl = layer
							#if it doesn't exist create it
							if Lexists == "false":
								vl = QgsVectorLayer("Linestring?field=offset:integer&field=direction:string(10)&field=method:string(10)","Parallel_Offset","memory")
								#vl = QgsVectorLayer("Linestring", "Parallel_Offset", "memory")
								pr = vl.dataProvider()
								vl.startEditing()
								#pr.addAttributes( [ QgsField("offset", Double), QgsField("direction",  String), QgsField("method", String) ] )
							else:
								pr = vl.dataProvider()
								vl.startEditing()
						
							#get the direction
							Dir = 'right'
							if self.dlg.ui.radLeft.isChecked():
								Dir = 'left'
							#get the method
							if self.dlg.ui.radRound.isChecked():
								js = 1
							if self.dlg.ui.radMitre.isChecked():
								js = 2
							if self.dlg.ui.radBevel.isChecked():
								js = 3
							#get the offset
							loffset = float(self.dlg.ui.txtDistance.text())
						
							#create the new feature from the selection
					
							for feature in layer.selectedFeatures():
								geom = feature.geometry()
								h = geom.asPolyline()
								line = LineString(h)
								nline = line.parallel_offset(loffset, Dir,resolution=16,join_style=js,mitre_limit=10.0)
								#turn nline back into a polyline and add it to the map as a new layer.
								fet = QgsFeature()
								fet.setGeometry(QgsGeometry.fromWkt(str(nline)))
								fet.setAttributes( [loffset,Dir ,js] )
								pr.addFeatures( [ fet ] )
								vl.commitChanges()
							QgsMapLayerRegistry.instance().addMapLayer(vl)
							mc=self.iface.mapCanvas()
							mc.refresh()
Example #38
0
    def draw_text_on_line(
        self,
        coords,
        text,
        color=(0, 0, 0),
        font_size=10,
        font_family='Tahoma',
        font_style=cairo.FONT_SLANT_NORMAL,
        font_weight=cairo.FONT_WEIGHT_NORMAL,
        text_halo_width=1,
        text_halo_color=(1, 1, 1),
        text_halo_line_cap=cairo.LINE_CAP_ROUND,
        text_halo_line_join=cairo.LINE_JOIN_ROUND,
        text_halo_line_dash=None,
        text_transform=None,
    ):
        '''
        Draws text on a line. Tries to find a position with the least change
        in gradient and which is closest to the middle of the line.

        :param coords: iterable containing all coordinates as ``(lon, lat)``
        :param text: text to be drawn
        :param color: ``(r, g, b[, a])``
        :param font_size: font-size in unit (pixel/point)
        :param font_family: font name
        :param font_style: ``cairo.FONT_SLANT_NORMAL``,
            ``cairo.FONT_SLANT_ITALIC`` or ``cairo.FONT_SLANT_OBLIQUE``
        :param font_weight: ``cairo.FONT_WEIGHT_NORMAL`` or
            ``cairo.FONT_WEIGHT_BOLD``
        :param text_halo_width: border-width in unit (pixel/point)
        :param text_halo_color: ``(r, g, b[, a])``
        :param text_halo_line_cap: one of :const:`cairo.LINE_CAP_*`
        :param text_halo_line_join: one of :const:`cairo.LINE_JOIN_*`
        :param text_halo_line_dash: list/tuple used by
            :meth:`cairo.Context.set_dash`
        :param text_transform: one of ``'lowercase'``, ``'uppercase'`` or
            ``'capitalize'``
        '''

        text = text.strip()
        if not text:
            return
        coords = map(lambda c: self.transform_coords(*c), coords)

        self.context.select_font_face(font_family, font_style, font_weight)
        self.context.set_font_size(font_size)
        text = utils.text_transform(text, text_transform)
        width, height = self.context.text_extents(text)[2:4]
        font_ascent, font_descent = self.context.font_extents()[0:2]
        self.context.new_path()
        #: make sure line does not intersect other conflict objects
        line = LineString(coords)
        line = self.map_area.intersection(line)
        line = line.difference(self.map_area.exterior.buffer(height))
        line = line.difference(self.conflict_area)
        #: check whether line is empty or is split into several different parts
        if line.geom_type == 'GeometryCollection':
            return
        elif line.geom_type == 'MultiLineString':
            longest = None
            min_len = width * 1.2
            for seg in line.geoms:
                seg_len = seg.length
                if seg_len > min_len:
                    longest = seg
                    min_len = seg_len
            if longest is None:
                return
            line = longest
        coords = tuple(line.coords)
        seg = utils.linestring_text_optimal_segment(coords, width)
        # line has either to much change in gradients or is too short
        if seg is None:
            return
        #: crop optimal segment of linestring
        start, end = seg
        coords = coords[start:end+1]
        #: make sure text is rendered from left to right
        if coords[-1][0] < coords[0][0]:
            coords = tuple(reversed(coords))
        # translate linestring so text is rendered vertically in the middle
        line = LineString(tuple(coords))
        offset = font_ascent / 2. - font_descent
        line = line.parallel_offset(offset, 'left', resolution=3)
        # make sure text is rendered centered on line
        start_len = (line.length - width) / 2.
        char_coords = None
        chars = utils.generate_char_geoms(self.context, text)
        #: draw all character paths
        for char in utils.iter_chars_on_line(chars, line, start_len):
            for geom in char.geoms:
                char_coords = iter(geom.exterior.coords)
                self.context.move_to(*char_coords.next())
                for lon, lat in char_coords:
                    self.context.line_to(lon, lat)
                self.context.close_path()
        #: only add line to reserved area if text was drawn
        if char_coords is not None:
            covered = line.buffer(height)
            self.conflict_union(covered)
        #: draw border around characters
        self.context.set_line_cap(cairo.LINE_CAP_ROUND)
        self.context.set_source_rgba(*text_halo_color)
        self.context.set_line_width(2 * text_halo_width)
        self.context.set_line_cap(text_halo_line_cap)
        self.context.set_line_join(text_halo_line_join)
        self.context.set_dash(text_halo_line_dash or tuple())
        self.context.stroke_preserve()
        #: fill actual text
        self.context.set_source_rgba(*color)
        self.context.fill()
    ax.set_aspect(1)

line = LineString([(0, 0), (1, 1), (0, 2), (2, 2), (3, 1), (1, 0)])
line_bounds = line.bounds
ax_range = [int(line_bounds[0] - 1.0), int(line_bounds[2] + 1.0)]
ay_range = [int(line_bounds[1] - 1.0), int(line_bounds[3] + 1.0)]

fig = pyplot.figure(1, figsize=(SIZE[0], 2 * SIZE[1]), dpi=90)

# 1
ax = fig.add_subplot(221)

plot_line(ax, line)
x, y = list(line.coords)[0]
plot_coords(ax, x, y)
offset = line.parallel_offset(0.5, 'left', join_style=2, mitre_limit=0.1)
plot_line(ax, offset, color=BLUE)

ax.set_title('a) left, limit=0.1')
set_limits(ax, ax_range, ay_range)

#2
ax = fig.add_subplot(222)

plot_line(ax, line)
x, y = list(line.coords)[0]
plot_coords(ax, x, y)

offset = line.parallel_offset(0.5, 'left', join_style=2, mitre_limit=10.0)
plot_line(ax, offset, color=BLUE)
Example #40
0
    xPoints, yPoints = zip(*PolylineCodec().
                            decode(str(polylines[i][POLYLINE].values()[0])))
    abcisses += xPoints
    images += yPoints
resultPoints = list(imap(list, izip(abcisses, images)))
reducedList = []

#Reduce the number of points to optimize further computation.
for i in range (0, len(resultPoints), 100):
    reducedList.append(resultPoints[i])

#Convert the line into a LineString to use the parallel_offset function.
line = LineString(reducedList)

#Build the left Buffer.
leftBuffer = line.parallel_offset(BUFFER_OFFSET,'left')
xLeft, yLeft = leftBuffer.xy
xLeftPoints = xLeft.tolist()
yLeftPoints = yLeft.tolist()
bufferLeftPoints = list(imap(list, izip(xLeftPoints, yLeftPoints)))

#Build the right Buffer.
rightBuffer = line.parallel_offset(BUFFER_OFFSET,'right')
xRight, yRight = rightBuffer.xy
xRightPoints = xRight.tolist()
yRightPoints = yRight.tolist()
bufferRightPoints = list(imap(list, izip(xRightPoints, yRightPoints)))

#Create a map.
map = folium.Map()