Beispiel #1
0
def one_linestring_per_intersection(lines, crs):
    """ Move line endpoints to intersections of line segments.

    Given a list of touching or possibly intersecting LineStrings, return a
    list LineStrings that have their endpoints at all crossings and
    intersecting points and ONLY there.

    Args:
        a list of LineStrings or a MultiLineString

    Returns:
        a list of LineStrings
    """
    lines_merged = linemerge(lines)

    # intersecting multiline with its bounding box somehow triggers a first intersection
    try:
        bounding_box = box(*lines_merged.bounds)
        lines_merged = lines_merged.intersection(bounding_box)
    except:
        #if the bounding_box fails, then revert to lines merge.
        print('bounding box method did not work, falling to a more simple method, no need to worry')

    # merge the result
    lines_merged = linemerge(lines_merged)

    lines = [line for line in lines_merged]
    df = gdf(geometry=lines, crs=crs)
    return df
Beispiel #2
0
def vectorize_skeleton(img,
                       stride,
                       tolerance,
                       preserve_topology=True,
                       remove_hair=0):
    # Extract the image's graph.
    i, j = np.nonzero(img)
    unscaled_xy = np.c_[j, i]
    xy = unscaled_xy * stride * (
        len(img) /
        (len(img) - 1))  # minor expansion to ensure exact fit to borders
    xy = xy.round(2)
    try:
        u, v = np.array(list(cKDTree(xy).query_pairs(1.5 * stride))).T
    except ValueError:
        return linemerge([])

    # Make sure that no triangles will form at T junctions.
    unscaled_xy_set = set(map(tuple, unscaled_xy))
    unscaled_xy_u = unscaled_xy[u]
    unscaled_xy_v = unscaled_xy[v]
    is_diagonal = np.sum((unscaled_xy_v - unscaled_xy_u)**2, axis=-1) == 2
    keep_mask = ~is_diagonal.copy()
    for k in np.flatnonzero(is_diagonal):
        a = unscaled_xy_u[k]
        b = unscaled_xy_v[k]
        c = (a[0], b[1])
        d = (b[0], a[1])
        if c in unscaled_xy_set or d in unscaled_xy_set:
            keep_mask[k] = False
        else:
            keep_mask[k] = True
    u = u[keep_mask]
    v = v[keep_mask]

    # Convert to Shapely shape.
    lines = np.array([xy[u], xy[v]]).swapaxes(0, 1)
    shape = linemerge(lines).simplify(tolerance,
                                      preserve_topology=preserve_topology)

    # Remove any short deadends created by skeletonization.
    if remove_hair:
        strings = list(as_MultiLineString(shape))
        arity = {}
        for strn in strings:
            for point in strn.coords:
                arity.setdefault(point, 0)
                arity[point] += 1

        good_strings = []
        for strn in strings:
            if (arity[strn.coords[0]] != 1 and arity[strn.coords[-1]] != 1) \
               or strn.length >= remove_hair:
                good_strings.append(strn)
        shape = MultiLineString(good_strings)

    # Make sure the submission is valid.
    shape = ensure_no_duplicates(shape)

    return shape
def _create_offset_box(line, thickness, side, bevel=0.0, symmetric=False):

    offsetline = line.parallel_offset(thickness, side=side)

    if symmetric:
        offsetline2 = line.parallel_offset(thickness, side=_oderside(side))
        line = offsetline2

    if bevel > 0.0:

        raise Exception('Beveling not yet implemented')

    if side == 'left':
        connect1 = shpl_geom.LineString(
            (line.coords[-1], offsetline.coords[-1]))
        connect2 = shpl_geom.LineString((line.coords[0], offsetline.coords[0]))
        return shpl_geom.Polygon(
            ops.linemerge((line, connect1, offsetline, connect2)))
    else:
        connect1 = shpl_geom.LineString(
            (line.coords[-1], offsetline.coords[0]))
        connect2 = shpl_geom.LineString(
            (line.coords[0], offsetline.coords[-1]))
        return shpl_geom.Polygon(
            ops.linemerge((offsetline, connect1, line, connect2)))
Beispiel #4
0
def difference(line1, line2, close_ends=False):
    """ Create polygons from two LineString objects.

    Parameters:
        line1 (LineString) : a line representing the initial condition.
        line2 (LineString) : a line representing the final condition.
        close_ends (bool) : option to close open line ends with vertical line segments.

    Returns:
        intersections (Point array) : the intersections between the LineString objects.
        polygons (Polygon array) : the polygons between the lines.
        signs (int array) : contains values of +1 or -1 to identify polygons as cut or fill.

    """
    if close_ends==True:
        line1, line2 = close(line1, line2)

    intersections = line1.intersection(line2)

    segs1 = cut_by_points([line1], intersections)
    segs2 = cut_by_points([line2], intersections)

    polygons = polygonize([segs1, segs2])

    signs = sign(linemerge(segs1), linemerge(segs2))

    # can't pass the polygonize generator to my class so convert the polygons into an array
    polygontxt = []
    areas = []
    for i, poly in enumerate(polygons):
        polygontxt.append(poly)
        areas.append(poly.area*signs[i])
    cutfill = pnd.Series(asarray(areas), name='area')

    return intersections, polygontxt, cutfill
Beispiel #5
0
 def _linemerge(self, lines_to_merge):
     """Performs a linemerge operation on a list of lines.
     """
     try:
         for line in linemerge(lines_to_merge).geoms:
             yield line
     except AttributeError as ae:
         yield linemerge(lines_to_merge)
Beispiel #6
0
    def _calculate_route(self, start, end):
        """
        This function is called within join_event_routes
        calculates shortest route from two specific locations
        start: OSM way ID
        end: OSM WAY ID
        Returns Linestring object of route
        """
        # make sure all osm ways ids are int values
        start = int(start)
        end = int(end)
        # Using OSM ids as source and target values calculate shortest route and convert to shapely geometric object
        # query = f"SELECT seq, edge, b.the_geom AS \"the_geom (truncated)\" FROM pgr_dijkstra('select gid as id, source_osm as source, target_osm as target, length as cost FROM ways as ways_outer, (select ST_Expand(ST_Extent(the_geom),0.1) as box from ways as box_table where box_table.source_osm = {start} OR box_table.target_osm = {end}) as box_final where ways_outer.the_geom && box_final.box', {start}, {end}, false) as a INNER JOIN ways as b ON a.edge = b.gid ORDER BY seq;"
        # query = f"SELECT UNNEST(pgr_flipedges(ARRAY(SELECT st_astext(b.the_geom) AS \"the_geom (truncated)\" FROM pgr_dijkstra('select gid as id, source_osm as source, target_osm as target, length as cost FROM ways as ways_outer, (select ST_Expand(ST_Extent(the_geom),0.1) as box from ways as box_table where box_table.source_osm = {start} OR box_table.target_osm = {end}) as box_final where ways_outer.the_geom && box_final.box', {start}, {end}, false) as a INNER JOIN ways as b ON a.edge = b.gid ORDER BY seq)));"

        ###### DELETE

        # query = f"SELECT ST_SetSRID(UNNEST(pgr_flipedges(ARRAY(SELECT st_astext(b.the_geom) FROM pgr_dijkstra('select gid as id, source_osm as source, target_osm as target, length as cost FROM ways as ways_outer, (select ST_Expand(ST_Extent(the_geom),0.1) as box from ways as box_table where box_table.source_osm = {start} OR box_table.target_osm = {end}) as box_final where ways_outer.the_geom && box_final.box', {start}, {end}, false) as a INNER JOIN ways as b ON a.edge = b.gid ORDER BY seq))),4326);"
        # Load_populations.database.cursor.execute(query)
        # route_list = [wkb.loads(row[0], hex=True) for row in Load_populations.database.cursor]
        # merged_routes = ops.linemerge([*route_list])
        # print(merged_routes)
        ###### DELETE

        query1 = f"SELECT ST_Transform(ST_SetSRID(UNNEST(pgr_flipedges(ARRAY(SELECT st_astext(b.the_geom) FROM pgr_dijkstra('select gid as id, source_osm as source, target_osm as target, length as cost FROM ways as ways_outer, (select ST_Expand(ST_Extent(the_geom),0.1) as box from ways as box_table where box_table.source_osm = {start} OR box_table.target_osm = {end}) as box_final where ways_outer.the_geom && box_final.box', {start}, {end}, false) as a INNER JOIN ways as b ON a.edge = b.gid ORDER BY seq))),4326), 32630);"
        query2 = f"SELECT ST_Transform(ST_SetSRID(UNNEST(pgr_flipedges(ARRAY(SELECT st_astext(b.the_geom) FROM pgr_dijkstra('select gid as id, source_osm as source, target_osm as target, length as cost FROM ways as ways_outer, (select ST_Expand(ST_Extent(the_geom),0.1) as box from ways as box_table where box_table.source_osm = {end} OR box_table.target_osm = {start}) as box_final where ways_outer.the_geom && box_final.box', {end}, {start}, false) as a INNER JOIN ways as b ON a.edge = b.gid ORDER BY seq))),4326), 32630);"

        print("query1", query1)
        print("query2", query2)
        # This try exept block ensures that database query does not respond an error code
        try:
            Load_populations.database.cursor.execute(query1)
            route_list = [
                wkb.loads(row[0], hex=True)
                for row in Load_populations.database.cursor
            ]
            # merge linestrings into one large shapely linestring object
            merged_routes = ops.linemerge([*route_list])
            return merged_routes
        except:
            try:
                # rollback database before executing alternative query
                Load_populations.database.connection.rollback()
                # sometimes the route is only available in one direction
                Load_populations.database.cursor.execute(query2)
                route_list = [
                    wkb.loads(row[0], hex=True)
                    for row in Load_populations.database.cursor
                ]
                # reverse list order
                route_list.reverse()
                # merge linestrings into one large shapely linestring object
                merged_routes = ops.linemerge([*route_list])
                return merged_routes
            except:
                # rollback database before executing alternative query
                Load_populations.database.connection.rollback()
                return None
Beispiel #7
0
    def place(self, dc):
        ls = defaultdict(list)
        for c in self.pa:
            attr = c.attrib
            if c.tag == "wire" and attr["layer"] in ("20", "21"):
                (x1, y1, x2,
                 y2) = [float(attr[t]) for t in "x1 y1 x2 y2".split()]
                p0 = dc.copy().goxy(x1, y1)
                p1 = dc.copy().goxy(x2, y2)
                ls[attr["layer"]].append(sg.LineString([p0.xy, p1.xy]))
            elif c.tag == "hole":
                (x, y, drill) = [float(attr[t]) for t in "x y drill".split()]
                p = dc.copy().goxy(x, y)
                dc.board.hole(p.xy, drill)
            elif c.tag == "circle" and attr["layer"] == "51":
                (x, y, radius) = [float(attr[t]) for t in "x y radius".split()]
                p = dc.copy().goxy(x, y)
                dc.board.hole(p.xy, 2 * radius)
            elif c.tag == "smd":
                (x, y, dx, dy) = [float(attr[t]) for t in "x y dx dy".split()]
                p = dc.copy().goxy(x, y)
                p.rect(dx, dy)
                p.setname(attr["name"])
                self.pad(p)
            elif c.tag == "pad":
                (x, y, diameter, drill) = [
                    float(attr[t]) for t in "x y diameter drill".split()
                ]
                nm = attr["name"]

                dc.push()
                dc.goxy(x, y)
                dc.board.hole(dc.xy, drill)
                n = {
                    "circle": 60,
                    "octagon": 8,
                    "square": 4
                }[attr.get("shape", "circle")]
                p = dc.copy()
                p.n_agon(diameter / 2, n)

                p.setname(nm)
                p.part = self.id
                self.pads.append(p)
                p.contact()

                if self.use_pad_text and nm not in ("RESERVED", ):
                    self.board.annotate(dc.xy[0], dc.xy[1], nm)
                dc.pop()
        if ls["20"]:
            g = so.linemerge(ls["20"])
            brd.layers['GML'].add(g)
        if self.use_silk and ls["21"]:
            g = so.linemerge(ls["21"]).buffer(self.board.silk / 2)
            self.board.layers['GTO'].add(g)
Beispiel #8
0
def vectorize_skeleton(img, stride, tolerance, preserve_topology=True, remove_hair=0):
    # Extract the image's graph.
    i,j = np.nonzero(img)
    unscaled_xy = np.c_[j,i]
    xy = unscaled_xy * stride * (len(img) / (len(img) - 1)) # minor expansion to ensure exact fit to borders
    xy = xy.round(2)
    try:
        u,v = np.array(list(cKDTree(xy).query_pairs(1.5*stride))).T
    except ValueError:
        return linemerge([])

    # Make sure that no triangles will form at T junctions.
    unscaled_xy_set = set(map(tuple, unscaled_xy))
    unscaled_xy_u = unscaled_xy[u]
    unscaled_xy_v = unscaled_xy[v]
    is_diagonal = np.sum((unscaled_xy_v - unscaled_xy_u)**2, axis=-1) == 2
    keep_mask = ~is_diagonal.copy()
    for k in np.flatnonzero(is_diagonal):
        a = unscaled_xy_u[k]
        b = unscaled_xy_v[k]
        c = (a[0], b[1])
        d = (b[0], a[1])
        if c in unscaled_xy_set or d in unscaled_xy_set:
            keep_mask[k] = False
        else:
            keep_mask[k] = True
    u = u[keep_mask]
    v = v[keep_mask]

    # Convert to Shapely shape.
    lines = np.array([xy[u], xy[v]]).swapaxes(0,1)
    shape = linemerge(lines).simplify(tolerance, preserve_topology=preserve_topology)

    # Remove any short deadends created by skeletonization.
    if remove_hair:
        strings = list(as_MultiLineString(shape))
        arity = {}
        for strn in strings:
            for point in strn.coords:
                arity.setdefault(point, 0)
                arity[point] += 1

        good_strings = []
        for strn in strings:
            if (arity[strn.coords[0]] != 1 and arity[strn.coords[-1]] != 1) \
               or strn.length >= remove_hair:
                good_strings.append(strn)
        shape = MultiLineString(good_strings)

    # Make sure the submission is valid.
    shape = ensure_no_duplicates(shape)

    return shape
Beispiel #9
0
    def shared_segs(self, g1, g2):
        """
        This function returns the segments that are shared with two input geometries.
        The shapely function `shapely.ops.shared_paths()` is adopted and can catch
        both the shared paths with the same direction for both inputs as well as the
        shared paths with the opposite direction for one the two inputs.

        The returned object extents the `segments` property with detected segments.
        Where each seperate segment is a linestring between two points.

        Parameters
        ----------
        g1 : shapely.geometry.LineString
            first geometry
        g2 : shapely.geometry.LineString
            second geometry
        """

        # detect potential shared paths between two linestrings
        try:
            fw_bw = shared_paths(g1, g2)
        except ValueError:
            self.valerr = True
            fw_bw = False
            # fw_bw = shared_paths(snap(g1, g2, tolerance=6), g2)

        # continue if any shared path was detected
        if fw_bw and not fw_bw.is_empty:

            forward = fw_bw[0]
            backward = fw_bw[1]

            if backward.is_empty:
                # only contains forward objects
                shared_segments = forward
            elif forward.is_empty:
                # only contains backward objects
                shared_segments = backward
            else:
                # both backward and forward contains objects, so combine
                forward = self.validate_linemerge(linemerge(forward))
                backward = self.validate_linemerge(linemerge(backward))

                shared_segments = geometry.MultiLineString(forward + backward)

            # add shared paths to segments
            self.segments.extend([list(shared_segments)])

            # also add the first coordinates of both geoms as a vertice to segments
            p1_g1 = geometry.Point([g1.xy[0][0], g1.xy[1][0]])
            p1_g2 = geometry.Point([g2.xy[0][0], g2.xy[1][0]])
            ls_p1_g1g2 = geometry.LineString([p1_g1, p1_g2])
            self.segments.extend([[ls_p1_g1g2]])
def get_defined_route(data):
    route_segments = []
    for i in range(len(data)):
        if (data[i]['geometry'].geom_type == 'LineString' and data[i]['attributes']['isRoute'] == 'Yes'):
            route_segments.append(data[i]['geometry'])

    # combine them into a multi-linestring
    multi_line = geometry.MultiLineString(route_segments)
    route = ops.unary_union(ops.linemerge(multi_line))
    if route.geom_type =="MultiString":
        multi_line = geometry.MultiLineString(route)
        route1 = ops.unary_union(ops.linemerge(multi_line))
        return route1
    else:
        return route
Beispiel #11
0
def generate() -> MultiLineString:
    """
    A python module called by the `script` command must implement this function, which takes
    no arguments and return a MultiLineString object.
    :return: resulting MultiLineString
    """
    segs = []

    # horizontal segments
    for i in range(math.floor(N / 2)):
        for j in range(M):
            append_maybe([(i, j), (i + 1, j)], segs)

    # add half horizontal segments
    if N % 2 == 0:
        for j in range(M):
            append_maybe([((N / 2) - 1, j), (N / 2, j)], segs)

    # add vertical segments
    for i in range(math.ceil(N / 2)):
        for j in range(M - 1):
            append_maybe([(i, j), (i, j + 1)], segs)

    half_mls = MultiLineString(segs)
    other_mls = affinity.translate(
        affinity.scale(half_mls, -1, 1, origin=(0, 0)), N - 1, 0)

    return ops.linemerge(ops.unary_union([half_mls, other_mls]))
Beispiel #12
0
def get_talus_inside_face(f, ttree, merge=True, displace=True):
    face = shape(f['geometry'])
    tals_candidates = tals_candidates = ttree.query(face)
    tals = [
        line for line in tals_candidates if line.intersects(face)
        and not line.intersection(face).geom_type.endswith('Point')
    ]
    tals = [
        line if face.contains(line) else line.intersection(face)
        for line in tals
    ]
    no_multipart = []
    for t in tals:
        if t.geom_type == 'MultiLineString' or t.geom_type == "GeometryCollection":
            for tt in t:
                if tt.geom_type == 'LineString':  # and not face.exterior.contains(tt):
                    no_multipart.append(tt)
        else:
            no_multipart.append(t)
    if merge:
        tals_merged = linemerge(no_multipart)
        if tals_merged.geom_type == 'LineString':
            no_multipart = [tals_merged]
        else:
            no_multipart = [t for t in tals_merged]
    if displace:
        no_multipart = [
            displace_line_from_centroid_when_snapped_to_road(face, t)
            for t in no_multipart
        ]
    return no_multipart
Beispiel #13
0
    def create_skeleton_line(self, simplify = True, simplify_tolerance = ''):
        u"""
        Create a skeleton line of the polygon by using the circumcenters of the
        triangles created by the Conforming Delaunay Triangulation applied by
        Triangle
        Optionally simplify (by default) the skeleton by using an algorithm
        provided by Shapely.
        """
        self.circumcenters = list()
        for t in self.tw.triangles:
            self.circumcenters.append(self.calculate_circumcenter(t))

        # list of skeleton segments
        skel_segments = list()
        for key in sorted(self.tw.shared_edges.iterkeys()):
            if self.tw.shared_edges[key] != 2:
                continue
            # retrieve endpoints of the skeleton segment
            from_pt = self.circumcenters[key[0] - 1]
            to_pt = self.circumcenters[key[1] - 1]
            # creating skeleton segment
            skel_segment = LineString([(cc.x, cc.y) for cc in (from_pt, to_pt)])
            skel_segments.append(skel_segment)
        else:
            # merging all skeleton segments to a single (possibly multiline)
            # object
            skel_line = linemerge(skel_segments)

        # simplifying skeleton line
        if simplify:
            if not simplify_tolerance:
                simplify_tolerance = self.SIMPLIFY_TOLERANCE
            skel_line = skel_line.simplify(simplify_tolerance, False)
        
        return skel_line
Beispiel #14
0
def MedialAxis(axis):
    """
    Calculate corridor medial axis
    using boundary points from first iteration swath units
    """

    output = config.filename('ax_medialaxis', axis=axis)

    coordinates, groups = BoundaryPoints(axis)

    voronoi = Voronoi(coordinates, qhull_options='Qbb Qc')
    lines = list(medial_segments(voronoi, groups))
    medialaxis = linemerge(lines)

    crs = fiona.crs.from_epsg(2154)
    driver = 'ESRI Shapefile'
    schema = {'geometry': 'LineString', 'properties': [('AXIS', 'int')]}
    options = dict(driver=driver, crs=crs, schema=schema)

    with fiona.open(output, 'w', **options) as fst:
        # test only one geometry
        fst.write({
            'geometry': medialaxis.__geo_interface__,
            'properties': {
                'AXIS': axis
            }
        })
Beispiel #15
0
def multiline_realation_to_shape(rel, refs_index):
    lines = []

    if 'members' in rel:
        members = rel['members']
    else:
        members = refs_index[rel['ref']]['members']

    for member in members:
        if member['type'] == 'way':
            way_shape = way_to_shape(member, refs_index)
        elif member['type'] == 'relation':
            if member['ref'] in refs_index:
                refs_index[member['ref']]['used'] = rel['id']
            way_shape = element_to_shape(member, refs_index)
        else:
            warning('multiline member not handled', pformat(member))
            continue

        if way_shape is None:
            # throw exception
            warning('Failed to make way in relation', pformat(rel))
            continue

        if isinstance(way_shape['shape'], Polygon):
            # this should not happen on real data
            way_shape['shape'] = LineString(way_shape['shape'].exterior.coords)
        lines.append(way_shape['shape'])
    if len(lines) < 1:
        return None

    multiline = MultiLineString(lines)
    multiline = linemerge(multiline)
    return {'shape': multiline, 'properties': get_element_props(rel)}
Beispiel #16
0
  def __unionIntersecting(self, features, idx, disjointFeatures):

    if not features:
      return disjointFeatures

    else:
      index = features.iterkeys().next()
      f = features[index][0]
      f_prop = features[index][1]
      
      if self.__ifDisjoint(f, [features[i][0] for i in features.keys()]):
        idx.delete(index, features[index][0].bounds)
        disjointFeatures.append(features[index])
        del features[index]
        return self.__unionIntersecting(features, idx, disjointFeatures) 
      else:
        intersecting_bounds = list(idx.intersection(f.bounds, objects=True))
        
        for n in intersecting_bounds:
          if index != n.id and (f.disjoint(n.object[0]) is False):
            idx.delete(index, f.bounds)
            if f.geom_type[0:4] == 'Mult' or n.object[0].geom_type[0:4] == 'Mult':
              f = f.union(n.object[0])
            else:
              f = linemerge([f, n.object[0]])
            del features[index]
            del features[n.id]
            idx.delete(n.id, n.object[0].bounds)
            idx.insert(index, f.bounds, f)
            features[index] = [f, f_prop]

        return self.__unionIntersecting(features, idx, disjointFeatures)
    def _merge_polygons(self):
        merge = []
        lines_only = True
        for fig in self.figs:
            if fig.geom_type != 'LineString' and \
               fig.geom_type != 'MultiLineString':
               lines_only = False
            merge.append(fig)
            
        for fig in merge:
            self.figs.remove(fig)
            
        if lines_only and self.ignore_width:
            result = linemerge(merge)
        else:
            try:
                result = cascaded_union(merge)
            except Exception as e:
                print "ERROR:", e

        if result.geom_type == 'Polygon' or result.geom_type == 'LineString':
            self.figs.append( result )
        elif result.geom_type == 'MultiPolygon' or result.geom_type == 'MultiLineString':
            for f in result:
                self.figs.append(f)
Beispiel #18
0
    def _extract_collection(self, result):
        """
        Extracts all geometries with the same topological dimension as the input geometry from a collection.

        Args:
            result (shapely.geometry.base.BaseGeometry): The intersection result.

        Returns:
            shapely.geometry.base.BaseGeometry: The extracted geometries with matching topological dimension.
        """
        if isinstance(result, GeometryCollection):
            matching_geometries = list()
            for part in result:
                if self.geom_dim(part) == self.dim:
                    matching_geometries.append(part)
            if self.dim == 0:
                points = list()
                for geom in matching_geometries:
                    if isinstance(geom, Point):
                        points.append(geom)
                    elif isinstance(geom, MultiPoint):
                        points.extend(geom.geoms)
                return MultiPoint(points)
            elif self.dim == 1:
                return linemerge(matching_geometries)
            elif self.dim == 2:
                return cascaded_union(matching_geometries)
        else:
            return result
Beispiel #19
0
    def _construct_row(self, obj, conn):
        tags = TagStore(obj['tags'])

        outtags, difficulty = basic_tag_transform(obj['id'], tags, self.config)

        # we don't support hierarchy at the moment
        outtags['top'] = True

        # geometry
        geom = build_route_geometry(conn, obj['members'], self.ways, self.data)

        if geom is None:
            return None

        if geom.geom_type not in ('MultiLineString', 'LineString'):
            raise RuntimeError("Bad geometry %s for %d" %
                               (geom.geom_type, obj['id']))

        # if the route is unsorted but linear, sort it
        if geom.geom_type == 'MultiLineString':
            fixed_geom = linemerge(geom)
            if fixed_geom.geom_type == 'LineString':
                geom = fixed_geom

        outtags['geom'] = from_shape(geom, srid=self.c.geom.type.srid)
        outtags['symbol'] = write_symbol(self.shield_fab, tags, difficulty,
                                         self.config.symbol_datadir)
        outtags['id'] = obj['id']

        return outtags
Beispiel #20
0
    def dissolve_ways(self, src_path, dst_path, fields=None, exclude=False):
        self.ways = fiona.open(**zip_path(src_path))
        self.fields = self._define_filter_fields(fields, exclude)
        self.src_path = src_path

        way_groups = self._determine_way_groups()
        metadata = self.ways.meta.copy()
        meta_fields = metadata['schema']['properties']
        self._filter_tags(meta_fields)

        logger.info('combining dissolve group geometries...')
        with fiona.open(dst_path, 'w', **metadata) as dissolve_shp:
            for group in way_groups:
                geom_list = list()
                for way_id in group:
                    feat = self.ways[way_id]
                    geom = shape(feat['geometry'])
                    geom_list.append(geom)

                group_tags = self.ways[group[0]]['properties']
                dissolve_geom = linemerge(geom_list)
                dissolve_tags = self._filter_tags(group_tags)
                dissolve_shp.write(dict(
                    geometry=mapping(dissolve_geom),
                    properties=dissolve_tags
                ))

        self.ways.close()
        return dst_path
Beispiel #21
0
        def clip_transit_routes(self):
            """Clips transportation routes, converts them to single
                parts,explodes the results to account for routes
                with the same name. Contains logic to ensure only
                records with geospatial data are return.
            """
            clp_routes = self._intxn_polys.intersection(self._routes)

            single_lines = {}
            for i, transit in enumerate(clp_routes):
                if 'GeometryCollection' not in type(transit).__name__:
                    if type(
                            transit
                    ) is shapely.geometry.multilinestring.MultiLineString:
                        single_lines[clp_routes.index[i]] = ops.linemerge(
                            transit)
                    else:
                        single_lines[clp_routes.index[i]] = transit

            columns = ['transit', 'geometry']
            explode_lines = gpd.GeoDataFrame(single_lines.items(),
                                             columns=columns)
            try:
                return explode_lines.explode().droplevel(0).reset_index(
                    0, drop=True)
            except:
                return explode_lines
Beispiel #22
0
    def test_merge_loops(self):
        """ It seems that loops won't merge,
        we should avoid these where possible """
        line1 = LineString([(1, 1), (2, 1), (2, 2), (1, 2), (1, 1)])
        line2 = LineString([(1, 1), (1, 0), (0, 0), (0, 1), (1, 1)])
        result = linemerge([line1, line2])

        expected = LineString([
            (1, 1),
            (2, 1),
            (2, 2),
            (1, 2),
            (1, 1),
            (1, 0),
            (0, 0),
            (0, 1),
            (1, 1),
        ])

        shapelyReality = MultiLineString([
            LineString([(1, 1), (2, 1), (2, 2), (1, 2), (1, 1)]),
            LineString([(1, 1), (1, 0), (0, 0), (0, 1), (1, 1)])
        ])

        #self.assertEqual(result.geom_type, 'LineString')
        self.assertEqual(result.geom_type, 'MultiLineString')
        self.LinesEquivalent(result, shapelyReality)
Beispiel #23
0
    def from_osm(osm, relation, *args, **kwargs):
        """
        A way to build a route from OpenStreetMaps data

        Args:
            osm (dpd.OSM.osm): the osm that contains the route as a relation
            relation (int): the relation to build a route for
        Returns:
            dpd.driving.Route: a route table
        """

        ways = [
            osm.ways[member["ref"]].geo
            for member in osm.relations[relation]["members"]
            if member["type"] == "way" and member["role"] == ""
        ]
        way = linemerge(ways)
        stops = []
        for member in osm.relations[relation]["members"]:
            if member["type"] == "node":
                stops.append({
                    "geo":
                    str((
                        osm.nodes[member["ref"]].geo.xy[0][0],
                        osm.nodes[member["ref"]].geo.xy[1][0],
                    )),
                    "name":
                    osm.nodes[member["ref"]].osm["tags"]["name"],
                })
        return Route(way, stops, *args, **kwargs)
Beispiel #24
0
    def _create_gdf_strokes(self):

        # create empty list to fill
        my_list = []

        # loop through merged geometry
        for a in self.merged:

            # get all segment points and make line strings
            linelist = _tuple_to_list(list(self.merged[a]))
            list_lines_segments = []

            for b in linelist:
                list_lines_segments.append(LineString(b))

            # merge seperate segments
            geom_multi_line = ops.linemerge(
                MultiLineString(list_lines_segments))

            # get other values for gdf
            id_value = a
            n_segments = len(self.merged[a])

            # append list
            my_list.append([id_value, n_segments, geom_multi_line])

        edge_gdf = gpd.GeoDataFrame(
            my_list,
            columns=["stroke_group", "n_segments", "geometry"],
            crs=self.gdf_projection,
        )
        edge_gdf.set_index("stroke_group", inplace=True)

        return edge_gdf
Beispiel #25
0
 def reindex_trimmed(trimmed=trimmedlarge, other=smallermerged):
     targetpoint = Point(list(trimmed.coords)[0])
     finallist = list(other)
     distlist = []
     indexlist = []
     index = 0
     check_for_intersects(trimmed, smallermerged)
     for linestring in finallist:
         endpoints = [
             list(linestring.coords)[0],
             list(linestring.coords)[-1]
         ]
         for point in endpoints:
             indexlist.append(index)
             dist = targetpoint.distance(Point(point))
             distlist.append(dist)
         index += 1
     targetindex = np.where(distlist == np.min(distlist))[0][0]
     if targetindex % 2 == 0:
         modifier = 0
     else:
         modifier = 1
     lineindex = indexlist[targetindex]
     targetlinecoords = finallist[lineindex].coords[:]
     targetlinecoords[(modifier * -1)] = targetpoint.coords[0]
     finallist[lineindex] = LineString(targetlinecoords)
     combinedlist = MultiLineString([trimmed, finallist[lineindex]])
     combined = ops.linemerge(combinedlist)
     del finallist[lineindex]
     finallist.insert(lineindex - 1, combined)
     final = MultiLineString(finallist)
     return (final)
Beispiel #26
0
def side_based_procedure(terrain, image):
    line = terrain.center_line.coords
    con = terrain.poly.boundary.coords
    mer = linemerge([con, line])
    uni = unary_union(mer)
    left_side, right_side = polygonize(uni)
    draw = ImageDraw.Draw(image)
    # draw.polygon(convert_to_map(v[0].boundary.coords), fill="#ff0000")
    # draw.polygon(convert_to_map(v[1].boundary.coords), fill="#00ff00")

    center_l = helpers.points_located_on_center_line(
        terrain.center_line, max(1, 1 / TIME_CONSUMPTION))

    left_points = helpers.uniformly_distribute_points(8 / TIME_CONSUMPTION,
                                                      terrain.poly)
    left_points += random_points_in_polygon(int(3 * TIME_CONSUMPTION),
                                            left_side)
    right_points = helpers.uniformly_distribute_points(8 / TIME_CONSUMPTION,
                                                       terrain.poly)
    right_points += random_points_in_polygon(int(3 * TIME_CONSUMPTION),
                                             right_side)

    image = put_rotated_sprites_onto_image(image, False, left_points,
                                           "mountains_side", left_side,
                                           center_l)
    image = put_rotated_sprites_onto_image(image, True, right_points,
                                           "mountains_side", right_side,
                                           center_l)

    if center_l:
        image = put_rotated_sprites_onto_image(image, False, center_l,
                                               "mountains", terrain.poly,
                                               center_l)
    return image
Beispiel #27
0
def extract_contour(topdown_seg_mask, canvas_size, thickness=5):
    topdown_seg_mask[topdown_seg_mask != 0] = 255
    ret, thresh = cv2.threshold(topdown_seg_mask, 127, 255, 0)
    contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

    mask = np.zeros_like(topdown_seg_mask)
    patch = box(1, 1, canvas_size[1] - 2, canvas_size[0] - 2)
    idx = 0
    for cnt in contours:
        cnt = cnt.reshape((-1, 2))
        cnt = np.append(cnt, cnt[0].reshape(-1, 2), axis=0)
        line = LineString(cnt)
        line = line.intersection(patch)
        if isinstance(line, MultiLineString):
            line = ops.linemerge(line)

        if isinstance(line, MultiLineString):
            for l in line:
                idx += 1
                cv2.polylines(mask, [np.asarray(list(l.coords), np.int32).reshape((-1, 2))], False, color=idx, thickness=thickness)
        elif isinstance(line, LineString):
            idx += 1
            cv2.polylines(mask, [np.asarray(list(line.coords), np.int32).reshape((-1, 2))], False, color=idx, thickness=thickness)

    return mask, idx
Beispiel #28
0
def merge_linestrings(first, second):

    new_coordinates = []

    first_geometry = first['geometry']
    second_geometry = second['geometry']

    f_lines = []
    if first_geometry['type'] == 'MultiLineString':
        first = geometry.MultiLineString(first_geometry['coordinates'])
        for f in first:
            f_lines.append(f)
    else:
        f_lines.append(geometry.LineString(first_geometry['coordinates']))

    if second_geometry['type'] == 'MultiLineString':
        second = geometry.MultiLineString(second_geometry['coordinates'])
        for s in second:
            f_lines.append(s)
    else:
        f_lines.append(geometry.LineString(second_geometry['coordinates']))

    merged_multiline = geometry.MultiLineString(f_lines)
    linestring = ops.linemerge(merged_multiline)
    return linestring
Beispiel #29
0
 def __plot_edges(self, to_plot: List, edges: List, vertices: List,
                  label: str):
     lines = []
     for edge_idx in to_plot:
         edge = edges[edge_idx]
         start_vertex = vertices[edge.start]
         end_vertex = vertices[edge.end]
         # Note it could be that the edge is supposed to be parabola (edge.is_linear
         # will be false), but in our case we always have boxes with 90 degree
         # corners. If it's a parabola then the focus is one of these corners, and by
         # drawing a line instead of a parabola we at worse cut through this point,
         # which is fine.
         lines.append(
             geometry.LineString([[start_vertex.X, start_vertex.Y],
                                  [end_vertex.X, end_vertex.Y]]))
     merged_line = ops.linemerge(geometry.MultiLineString(lines))
     kwargs = {
         "label": label,
         "alpha": 0.5,
         "color": self.__colour_mapping[label]
     }
     # Merged line is either a MultiLineString which means we need to draw multiple
     # lines, or it is a LineString which means we only need to draw one.
     if isinstance(merged_line, geometry.MultiLineString):
         for line in merged_line:
             xs, ys = self.__simplify_outlines(line)
             self.__ax.plot(xs, ys, **kwargs)
             kwargs.pop(
                 "label",
                 None)  # Only pass label once for single legend entry
     else:
         xs, ys = self.__simplify_outlines(merged_line)
         self.__ax.plot(xs, ys, **kwargs)
Beispiel #30
0
def build_lines(links, line_columns='all', group_id='trip_id', sum_columns=[], mean_columns=[], force_linestring=True):

    if line_columns is 'all':
        # all the columns that are shared by all the links of the group are listed
        variability = links.groupby(group_id).agg(lambda s: s.nunique()).max()
        line_columns = list(variability.loc[variability == 1].index)

    lines = links.groupby(group_id)[line_columns].first()

    if len(sum_columns):
        lines[sum_columns] = links.groupby(group_id)[sum_columns].sum()
    if len(mean_columns):
        lines[mean_columns] = links.groupby(group_id)[mean_columns].mean()

    links = links.loc[~links['geometry'].apply(lambda g: g.is_empty)]
    lines['geometry'] = links.groupby(group_id)['geometry'].agg(
        lambda s: ops.linemerge(list(s))) # force the series to a list
    lines = lines.dropna(subset =['geometry'])

    if force_linestring:
        lines['geometry'] = links.groupby(group_id)['geometry'].agg(
            lambda s: line_list_to_polyline(list(s))) # force the series to a list

    lines = lines.dropna(subset =['geometry'])
    lines = lines.loc[~lines['geometry'].apply(lambda g: g.is_empty)]
    
    return lines.reset_index()
def merge_layers(geom1, geom2):
    """Find the overlapping portions of two transit trips."""
    g2l = geom2['line'].buffer(bTol)  # snap(geom2['line'], geom1['line'], TOL)
    intersect_geom = geom1['line'].intersection(g2l)
    if intersect_geom.type == 'LineString':
        if intersect_geom.length > TOL:
            intersect = [intersect_geom]
        else:
            intersect = []
    elif intersect_geom.type == 'Point':
        intersect = []
    else:
        intersect = [g for g in intersect_geom
                     if g.type != 'Point' and g.length > TOL]
        if intersect:
            intersect = linemerge(intersect)
            if intersect.type == 'LineString':
                intersect = [intersect]
            else:
                intersect = list(intersect)
            intersect = [g for g in intersect if g.length > TOL]
    if not intersect:
        return [], [geom1, geom2]
    else:
        count = geom1['count'] + geom2['count']
        intersect = [dict(line=g, count=count) for g in intersect]
        sg1 = {'count': geom2['count'], 'line': geom1['line'].buffer(bTol)}
        sg2 = {'count': geom2['count'], 'line': g2l}
        g1 = diff_layers(geom1, sg2)
        g2 = diff_layers(geom2, sg1)
        return [intersect, g1 + g2]
Beispiel #32
0
def polygon_intersections(gdf):
    """Computes the intersections between all polygons in a GeoDataFrame.

    Parameters
    ----------
    gdf : Geopandas.GeoDataFrame

    Returns
    -------
    a Geodataframe containing the intersections
    """

    out_cols = ['id_1', 'id_2', 'geometry']
    out = gpd.GeoDataFrame(columns=out_cols)

    for i, major in gdf.iterrows():

        # Exterior only
        major_poly = major.geometry.exterior

        # Remove the major from the list
        gdf = gdf.loc[gdf.index != i]

        # Keep catchments which intersect
        gdfs = gdf.loc[gdf.intersects(major_poly)]

        for j, neighbor in gdfs.iterrows():

            # No need to check if we already found the intersect
            if j in out.id_1 or j in out.id_2:
                continue

            # Exterior only
            neighbor_poly = neighbor.geometry.exterior

            # Ok, the actual intersection
            mult_intersect = major_poly.intersection(neighbor_poly)

            # All what follows is to catch all possibilities
            # Should no happen in our simple geometries but ya never know
            if isinstance(mult_intersect, shpg.Point):
                continue
            if isinstance(mult_intersect, shpg.linestring.LineString):
                mult_intersect = [mult_intersect]
            if len(mult_intersect) == 0:
                continue
            mult_intersect = [m for m in mult_intersect if
                              not isinstance(m, shpg.Point)]
            if len(mult_intersect) == 0:
                continue
            mult_intersect = linemerge(mult_intersect)
            if isinstance(mult_intersect, shpg.linestring.LineString):
                mult_intersect = [mult_intersect]
            for line in mult_intersect:
                assert isinstance(line, shpg.linestring.LineString)
                line = gpd.GeoDataFrame([[i, j, line]],
                                        columns=out_cols)
                out = out.append(line)

    return out
Beispiel #33
0
def snap_points(points, lines, crs):
    tolerance = 0.5
    length = lines.shape[0]
    for i in range(length):
        for point in points.geometry:
            line = lines.loc[i, "geometry"]
            line._crs = crs
            point._crs = crs
            point_inline_projection = line.interpolate(line.project(point))
            point_inline_projection._crs = crs
            distance_to_line = point.distance(point_inline_projection)
            if (point.x, point.y) in line.coords:
                x = "nothing"
            else:
                if  distance_to_line < tolerance:
                    buff = point.buffer(0.1)
                    ### Split the line on the buffer
                    geometry = split(line, buff)
                    geometry._crs = crs
                    line_1_points = [tuple(xy) for xy in geometry[0].coords[:-1]]
                    line_1_points.append((point.x, point.y))
                    line_2_points = []
                    line_2_points.append((point.x, point.y))
                    line_2_points.extend([x for x in geometry[-1].coords[1:]])
                    ### Stitch together the first segment, the interpolated point, and the last segment
                    new_line = linemerge((LineString(line_1_points), LineString(line_2_points)))
                    lines.loc[i, "geometry"] = new_line

    G = points["geometry"].apply(lambda geom: geom.wkb)
    points = points.loc[G.drop_duplicates().index]

    G = lines["geometry"].apply(lambda geom: geom.wkb)
    lines = lines.loc[G.drop_duplicates().index]

    return points, lines
Beispiel #34
0
    def pfr_lines(self, inp, core):

        c = QuadContourGenerator.from_rectilinear(core.psi_data.R[0], core.psi_data.Z[:, 0], core.psi_data.psi_norm)
        contours = c.contour(0.999)

        if len(contours) == 1:
            # then we're definitely dealing with a surface inside the seperatrix
            raise ValueError("Did not find PFR flux surface. Stopping.")
        else:
            # we need to find the surface that is contained within the private flux region
            for j, contour in enumerate(contours):
                # if the contour is entirely below the x-point and contour extends to both the left and the
                # right of the x-point horizontally, then the contour is almost certainly the desired PFR contour
                if np.amax(contour[:, 1]) < core.pts.xpt[1] and \
                        np.amin(contour[:, 0]) < core.pts.xpt[0] < np.amax(contour[:, 0]):
                    # then it's a probably a pfr flux surface, might need to add additional checks later

                    # make sure the line goes from inboard to outboard
                    if contour[-1, 0] < contour[0, 0]:
                        contour = np.flipud(contour)

                    # find cut points
                    cut_pt_ib = LineString(contour).intersection(inp.wall_line)[0]
                    cut_pt_ob = LineString(contour).intersection(inp.wall_line)[1]

                    dist1 = LineString(contour).project(cut_pt_ib, normalized=True)
                    cutline_temp = cut(LineString(contour), dist1)[1]

                    # reverse line point order so we can reliably find the second intersection point
                    cutline_temp_rev = LineString(np.flipud(np.asarray(cutline_temp.coords)))

                    dist2 = cutline_temp_rev.project(cut_pt_ob, normalized=True)
                    cutline_final_rev = cut(cutline_temp_rev, dist2)[1]

                    # reverse again for final pfr flux line
                    pfr_flux_line = LineString(np.flipud(np.asarray(cutline_final_rev.coords)))

                    # add pfr_line intersection points on inboard side
                    # for some reason, union freaks out when I try to do inboard and outboard
                    # at the same time.
                    union = inp.wall_line.union(cut(LineString(contour), 0.5)[0])
                    result = [geom for geom in polygonize(union)][0]
                    inp.wall_line = LineString(result.exterior.coords)

                    # add pfr line intersection points on outboard side
                    union = inp.wall_line.union(cut(LineString(contour), 0.5)[1])
                    result = [geom for geom in polygonize(union)][0]
                    inp.wall_line = LineString(result.exterior.coords)

                    # cut out pfr section of wall line
                    wall_pts = np.asarray(inp.wall_line.xy).T

                    wall_start_pos = np.where((wall_pts == cut_pt_ob).all(axis=1))[0][0]
                    wall_line_rolled = LineString(np.roll(wall_pts, -wall_start_pos, axis=0))
                    wall_line_cut_pfr = cut(wall_line_rolled,
                                            wall_line_rolled.project(cut_pt_ib, normalized=True))[0]

                    # create LineString with pfr line and section of wall line
                    self.pfr_line = linemerge((pfr_flux_line, wall_line_cut_pfr))
                    break
Beispiel #35
0
def isNonAeroDynamic(index, cordpt, globaldata, wallpoints):
    main_pointx,main_pointy = getPoint(index, globaldata)
    cordptx = float(cordpt.split(",")[0])
    cordpty = float(cordpt.split(",")[1])
    line = shapely.geometry.LineString([[main_pointx, main_pointy], [cordptx, cordpty]])
    responselist = []
    for item in wallpoints:
        polygonpts = []
        for item2 in item:
            polygonpts.append([float(item2.split(",")[0]), float(item2.split(",")[1])])
        polygontocheck = shapely.geometry.Polygon(polygonpts)
        merged = linemerge([polygontocheck.boundary, line])
        borders = unary_union(merged)
        polygons = polygonize(borders)
        i = 0
        for p in polygons:
            i = i + 1
        if i == 1:
            responselist.append(False)
        else:
            responselist.append(True)
    if True in responselist:
        return True
    else:
        return False
Beispiel #36
0
def multiline_realation_to_shape(rel, refs_index):
    lines = []
    for member in rel['members']:
        if member['type'] != 'way':
            print('multiline member not handled', member)
            continue

        way_shape = way_to_shape(member, refs_index)
        if way_shape is None:
            # throw exception
            print('Failed to make way in relation', rel)
            continue

        if isinstance(way_shape['shape'], Polygon):
            # this should not happen on real data
            way_shape['shape'] = LineString(way.exterior.coords)
        lines.append(way_shape['shape'])
    if len(lines) < 1:
        return None

    multiline = MultiLineString(lines)
    multiline = linemerge(multiline)
    return {
        'shape': multiline,
        'properties': get_element_props(rel)
    }
    def transform_tags(self, osmid, tags):
        outtags = { 'intnames'  : {},
                    'top'          : None}
        for k in conf.TAGS_DIFFICULTY_MAP.keys():
            outtags[k] = None
        for k in conf.TAGS_PISTETYPE_MAP.keys():
            outtags[k] = None

        difficulty = 0

        if tags.has_key('piste:name'):
            outtags['name'] = tags['piste:name']
        elif tags.has_key('name'):
            outtags['name'] = tags['name']
        elif tags.has_key('piste:ref'):
            outtags['name'] = '[%s]' % tags['piste:ref']
        elif tags.has_key('ref'):
            outtags['name'] = '[%s]' % tags['ref']
        else:
            outtags['name'] = '(%s)' % osmid

        # default treatment of tags
        for (k,v) in tags.iteritems():
            if k == 'piste:difficulty':
                if v in conf.TAGS_DIFFICULTY_MAP.keys():
                    outtags[v] = True
                    difficulty = conf.TAGS_DIFFICULTY_MAP[v]
            if k == 'piste:type':
                if v in conf.TAGS_PISTETYPE_MAP.keys():
                    outtags[v] = True
            if k.startswith('name:'):
                outtags['intnames'][k[5:]] = v
                    

        outtags['symbol'] = symbols.get_symbol(difficulty, None, tags, symboltypes)

        cur = self.thread.cursor

        if 'name' not in outtags:
            outtags['name'] = '(%s)' % osmid

        if outtags['top'] is None:
            if 'network' in tags:
                top = self.db.select_one("EXECUTE get_route_top(%s, %s)",
                              (osmid, tags['network']), cur=cur)
                outtags['top'] = True if (top == 0) else False
            else:
                outtags['top'] = True

        # finally: compute the geometry
        routelines = self.db.select_column("EXECUTE get_route_geometry(%s)", 
                                           (osmid,), cur=cur)
        if routelines:
            outtags['geom'] = sops.linemerge(routelines)
            outtags['geom']._crs = int(conf.DB_SRID)
            
        # Clear elevation profile cache
        clearcache.clearElevationProfileCache(osmid)

        return outtags
Beispiel #38
0
    def load_lines_relevant(self, major_tile):
        print('Setting up %s...' % major_tile)

        relevant_pd = self.tl_relationshps[self.tl_relationshps['name'] ==
                                           major_tile]
        relevant_list = []
        try:
            relevant_list = relevant_pd['Relevant'].to_list()[0]
        except IndexError:
            print('No tiles for %s...' % major_tile)
            exit()
        if 'list' not in str(type(relevant_list)) or len(relevant_list) == 0:
            print('No tiles for %s...' % major_tile)
        else:
            line_list = []
            for i, item in enumerate(relevant_list):
                path_to_minor = os.path.join(self.ctr_folder, "%s.shp" % item)
                linestring_list, test_dic = self.load_tile(path_to_minor)

                for elev in test_dic.keys():
                    new_linestring_list = self.examine_head_tail(
                        elev, test_dic)
                    line_list = line_list + new_linestring_list
            merge_lines = linemerge(line_list)
            self.write_output_file(merge_lines, major_tile)
Beispiel #39
0
    def publish(self, file_name):
        self.region.UUID = str(CimWriter.uuid())
        self.cimobject_by_uuid_dict[self.region.UUID] = self.region

        self.add_location(self.centroid.x, self.centroid.y, is_center=True)

        total_line_length = 0
        for circuit in self.circuits:
            station1 = circuit.members[0]
            station2 = circuit.members[-1]

            if 'station' in station1.type:
                connectivity_node1 = self.substation_to_cim(station1, circuit.voltage)
            elif 'plant' in station1.type or 'generator' in station1.type:
                connectivity_node1 = self.generator_to_cim(station1, circuit.voltage)
            else:
                self.root.error('Invalid circuit! - Skip circuit')
                circuit.print_circuit()
                continue

            if 'station' in station2.type:
                connectivity_node2 = self.substation_to_cim(station2, circuit.voltage)
            elif 'plant' in station2.type or 'generator' in station2.type:
                connectivity_node2 = self.generator_to_cim(station2, circuit.voltage)
            else:
                self.root.error('Invalid circuit! - Skip circuit')
                circuit.print_circuit()
                continue

            lines_wsg84 = []
            line_length = 0
            for line_wsg84 in circuit.members[1:-1]:
                lines_wsg84.append(line_wsg84.geom)
                line_length += line_wsg84.length
            line_wsg84 = linemerge(lines_wsg84)
            total_line_length += line_length
            self.root.debug('Map line from (%lf,%lf) to (%lf,%lf) with length %s meters', station1.geom.centroid.y,
                            station1.geom.centroid.x, station2.geom.centroid.y, station2.geom.centroid.x,
                            str(line_length))
            self.line_to_cim(connectivity_node1, connectivity_node2, line_length, circuit.name, circuit.voltage,
                             line_wsg84.centroid.y, line_wsg84.centroid.x)

            # self.root.info('The inferred net\'s length is %s meters', str(total_line_length))

        self.attach_loads()

        cimwrite(self.cimobject_by_uuid_dict, file_name + '.xml', encoding='utf-8')
        cimwrite(self.cimobject_by_uuid_dict, file_name + '.rdf', encoding='utf-8')

        # pretty print cim file
        xml = parse(file_name + '.xml')
        pretty_xml_as_string = xml.toprettyxml(encoding='utf-8')
        matches = re.findall('#x[0-9a-f]{4}', pretty_xml_as_string)
        for match in matches:
            pretty_xml_as_string = pretty_xml_as_string.replace(match, unichr(int(match[2:len(match)], 16)))
        pretty_file = io.open(file_name + '_pretty.xml', 'w', encoding='utf8')
        pretty_file.write(unicode(pretty_xml_as_string))
        pretty_file.close()
def build_geometries(diff, srid):
    srid_txt = "EPSG:{}".format(srid)
    geom = {'line': [], 'point': [], 'polygon': []}
    for osm_id, node in diff['add']['node'].iteritems():
        x, y = projections.from4326(node["geom"], srid_txt)
        geom["point"].append({"geom": "SRID={};POINT({} {})".format(srid, x, y), "osm_id": osm_id, "tags": node["tags"]})
    for osm_id, way in diff['add']['way'].iteritems():
        line = projections.from4326(way["geom"], srid_txt)
        polygonize = check_tags_if_polygon(way["tags"])
        if polygonize:
            result, dangles, cuts, invalids = polygonize_full([line])
            #print result, dangles, cuts, invalids
            for poly in result:
                geom["polygon"].append({"geom": "SRID={};{}".format(srid, poly.wkt), "osm_id": osm_id, "way_area":poly.area, "tags": way["tags"]})
            for line in dangles:
                geom["line"].append({"geom": "SRID={};{}".format(srid, line.wkt), "osm_id": osm_id, "tags": way["tags"]})
            for line in cuts:
                geom["line"].append({"geom": "SRID={};{}".format(srid, line.wkt), "osm_id": osm_id, "tags": way["tags"]})
            for line in invalids:
                geom["line"].append({"geom": "SRID={};{}".format(srid, line.wkt), "osm_id": osm_id, "tags": way["tags"]})
        else:
            ll = ",".join([a[0] + a[1] for a in line])
            geom["line"].append({"geom": "SRID={};LINESTRING({})".format(srid, ll), "osm_id": osm_id, "tags": way["tags"]})
    for osm_id, relation in diff['add']['relation'].iteritems():
        lines = [projections.from4326(way, srid_txt) for way in relation["geom"]]
        polygonize = check_tags_if_polygon(relation["tags"])
        if polygonize:
            merged = linemerge(lines)
            polys = []
            lines = []
            for line in merged:
                if line.is_ring:
                    polys.append(line)
                else:
                    lines.append(line)
            if polys:
                # TODO: repair geometry
                poly = Polygon(polys[0], polys[1:])
                geom["polygon"].append({"geom": "SRID={};{}".format(srid, poly.wkt), "osm_id": -osm_id, "way_area":0, "tags": relation["tags"]})
            for line in lines:
                geom["line"].append({"geom": "SRID={};{}".format(srid, line.wkt), "osm_id": -osm_id, "tags": relation["tags"]})

            #result, dangles, cuts, invalids = polygonize_full(lines)
            ##print result, dangles, cuts, invalids
            #result = list(result)
            #sd = result[0]
            #for poly in result[1:]:
                #sd = sd.symmetric_difference(poly)
            #geom["polygon"].append({"geom": "SRID={};{}".format(srid, sd.wkt), "osm_id": -osm_id, "way_area":sd.area, "tags": relation["tags"]})
            #for line in dangles:
                #geom["line"].append({"geom": "SRID={};{}".format(srid, line.wkt), "osm_id": -osm_id, "tags": relation["tags"]})
            #for line in cuts:
                #geom["line"].append({"geom": "SRID={};{}".format(srid, line.wkt), "osm_id": -osm_id, "tags": relation["tags"]})

        else:
            ll = ",".join([a[0] + a[1] for a in line])
            geom["line"].append({"geom": "SRID={};LINESTRING({})".format(srid, ll), "osm_id": osm_id, "tags": relation["tags"]})
    return geom
Beispiel #41
0
def get_shapes_from_osm(relation_id):
    overpass = '******'+relation_id+');out body;>;out skel qt;>;out skel qt;'

    resp_overpass = requests.get(overpass)
    resutl = resp_overpass.json()['elements']

    relations = []
    ways = []
    nodes = []

    #stocker tous les nodes/ways dans une structure pour pouvoir les utiliser plus facilement plus tard
    for elem in resutl:
        if elem['type']=="relation" :
            relations.append(elem)
        if elem['type']=="way" :
            ways.append(elem)
        if elem['type']=="node" :
            nodes.append(elem)

    relation = relations[0]
    print ("traitement de la relation {}".format(relation['id']))

    ways_linestrings = []

    for member in relation['members']:
        if member['type'] == "way":
            current_way_details = [way for way in ways if way['id']==member['ref']]
            if len(current_way_details) != 1 :
                print ('>> KO (en cherchant le chemin {})'.format(member['ref']))
                continue
            nodes_in_current_way = []
            for current_node in current_way_details[0]['nodes'] :
                current_node_details = [node for node in nodes if node['id'] == current_node]
                if len(current_node_details) < 1 :
                    print ('>> KO (en cherchant les noeuds {})'.format(current_node))
                    continue
                nodes_in_current_way.append(current_node_details[0])

            #on construit une ligne avec les noeuds
            points_nodes = [(node['lon'], node['lat']) for node in nodes_in_current_way]
            way_linestring = LineString(points_nodes)
            ways_linestrings.append(way_linestring)

    #on fusionne tous les chemins en un
    final_linestring = linemerge(ways_linestrings)

    print(final_linestring)

    if final_linestring.geom_type == "LineString":
        print(list(final_linestring.coords))
    else :
        for a_line in final_linestring.geoms :
            print(list(a_line.coords))

    return "OK"
Beispiel #42
0
    def test_linemerge(self):

        lines = MultiLineString(
            [((0, 0), (1, 1)),
             ((2, 0), (2, 1), (1, 1))])
        result = linemerge(lines)
        self.assertIsInstance(result, LineString)
        self.assertFalse(result.is_ring)
        self.assertEqual(len(result.coords), 4)
        self.assertEqual(result.coords[0], (0.0, 0.0))
        self.assertEqual(result.coords[3], (2.0, 0.0))

        lines2 = MultiLineString(
            [((0, 0), (1, 1)),
             ((0, 0), (2, 0), (2, 1), (1, 1))])
        result = linemerge(lines2)
        self.assertTrue(result.is_ring)
        self.assertEqual(len(result.coords), 5)

        lines3 = [
            LineString(((0, 0), (1, 1))),
            LineString(((0, 0), (0, 1))),
        ]
        result = linemerge(lines3)
        self.assertFalse(result.is_ring)
        self.assertEqual(len(result.coords), 3)
        self.assertEqual(result.coords[0], (0.0, 1.0))
        self.assertEqual(result.coords[2], (1.0, 1.0))

        lines4 = [
            ((0, 0), (1, 1)),
            ((0, 0), (0, 1)),
        ]
        self.assertTrue(result.equals(linemerge(lines4)))

        lines5 = [
            ((0, 0), (1, 1)),
            ((1, 0), (0, 1)),
        ]
        result = linemerge(lines5)
        self.assertEqual(result.type, 'MultiLineString')
Beispiel #43
0
def clipped_polygon(azimuth,polygon,line1,line2):
    merged_line = linemerge([line1, line2])
    merged = linemerge([polygon.boundary, merged_line])
    borders = unary_union(merged)
    polygons = polygonize(borders)
    polygon_list = list(polygons)
    if len(polygon_list)>1:
        polygon1 = polygon_list[0]
        polygon2 = polygon_list[1]
        polygon1_area = polygon_area_calculator(polygon=polygon1)
        polygon2_area=polygon_area_calculator(polygon=polygon2)
        polygon_areas = (polygon1_area, polygon2_area)
        polygon_dict = {polygon1_area:polygon1, polygon2_area:polygon2}
        if azimuth >= 180:
            result = polygon_dict[max(polygon_areas)]
        elif azimuth == 0 or azimuth == 360:
            result = polygon_dict[max(polygon_areas)]
        else:
            result = polygon_dict[min(polygon_areas)]
        return result
    else:
        return polygon
def diff_layers(geom1, geom2):
    """Find the difference between two transit trips."""
    g1diff = geom1['line'].difference(geom2['line'])
    if g1diff.type == 'LineString' and g1diff > TOL:
        return [dict(line=g1diff, count=geom1['count'])]
    elif g1diff.type == 'MultiLineString':
        merge = linemerge(g1diff)
        if merge.type == 'LineString':
            merge = [merge]
        return [dict(line=g, count=geom1['count'])
                for g in merge if g.length > TOL]
    else:
        return []
Beispiel #45
0
    def intersection(self, geom):
        intersection_ids = list(self.index.intersection(geom.bounds))

        if not intersection_ids:
            raise EmtpyGeometryError('No intersection or empty geometry')

        intersections = []
        for i in intersection_ids:

            polygon = self.polygons[i]

            if polygon.contains(geom):
                return geom

            if polygon.intersects(geom):
                try:
                    new_geom_part = polygon.intersection(geom)
                    new_geom_part = filter_geometry_by_type(new_geom_part, geom.type)
                    if new_geom_part:
                        if isinstance(new_geom_part, list):
                            intersections.extend(new_geom_part)
                        else:
                            intersections.append(new_geom_part)
                except TopologicalError:
                        pass

        if not intersections:
            raise EmtpyGeometryError('No intersection or empty geometry')

        # intersections from multiple sub-polygons
        # try to merge them back to a single geometry
        try:
            if geom.type.endswith('Polygon'):
                union = cascaded_union(list(flatten_polygons(intersections)))
            elif geom.type.endswith('LineString'):
                linestrings = flatten_linestrings(intersections)
                linestrings = list(filter_invalid_linestrings(linestrings))
                if not linestrings:
                    raise EmtpyGeometryError()
                union = linemerge(linestrings)
                if union.type == 'MultiLineString':
                    union = list(union.geoms)
            elif geom.type == 'Point':
                union = intersections[0]
            else:
                log.warn('unexpexted geometry type %s', geom.type)
                raise EmtpyGeometryError()
        except ValueError, ex:
            # likely an 'No Shapely geometry can be created from null value' error
            log.warn('could not create union: %s', ex)
            raise EmtpyGeometryError()
Beispiel #46
0
	def merge_line(self):
		lines=[]
		for elmt in self.figs.elements:
			if elmt.active == 0:
				continue
			if elmt.element.geom_type=='LineString':
				lines.append(elmt.element)
				elmt.active = 0
			elif elmt.element.geom_type=='MultiLineString':
				lines.extend(elmt.element)
				elmt.active = 0
		if len(lines) > 0:
			self.figs.add(self.Figs(linemerge(lines)))
		else:
			print "no lines merged"
Beispiel #47
0
def merge_lines(lines):
    '''
    Returns tuple of merged lines.

    :param lines: iterable of :class:`shapely.geometry.LineString`

    :returns: tuple :class:`shapely.geometry.LineString`
    '''

    merged = linemerge(lines)
    if merged.geom_type == 'LineString':
        merged = (merged, )
    else: # MultiLineString
        merged = tuple(merged)
    return merged
Beispiel #48
0
 def get_slice(self, z_level):
     """Calculates the polygons in the slice for a plane."""
     unsorted_lines = []
     for triangle in self.ctriangles:
         if (triangle[2, 2] < z_level) or (triangle[0, 2] > z_level):
             pass
         elif (triangle[0, 2] < z_level) and (triangle[2, 2] > z_level):
             intersection = self.get_z_intersect(triangle, z_level)
             unsorted_lines.append(intersection)
         elif (triangle[0, 2] == z_level) and (triangle[2, 2] == z_level):
             print "WARNING: Triangle in z_level!"
         elif (triangle[0, 2] <= z_level) and (triangle[1, 2] > z_level):
             print 'TRIANGULO CON LADO EN Z'
         elif (triangle[1, 2] < z_level) and (triangle[2, 2] >= z_level):
             print 'TRIANGULO CON LADO EN Z'
     doubles = 0
     for n_line in range(len(unsorted_lines)):
         unsorted_lines[n_line] = np.round(unsorted_lines[n_line],5)
         if np.array_equal(unsorted_lines[n_line][0], unsorted_lines[n_line][1]):
             doubles = doubles +1
     if doubles > 0:
         print 'WARNING: Puntos dobles detectados'
     if not unsorted_lines == []:
         # Arrange the line segments so that each segment leads to the
         # nearest available segment. This is accomplished by using two
         # list of lines, and at each step moving the nearest available
         # line segment from the unsorted pile to the next slot in the
         # sorted pile.
         lines = []
         for line in unsorted_lines:
             lines.append(geometry.LineString(line))
         multiline = geometry.MultiLineString(lines)
         merged_line = ops.linemerge(multiline)
         polygons = []
         try:
             for merged in merged_line:
                 polygons.append(np.array(merged))
         except TypeError:
             # If there is only one contour
             polygons.append(np.array(merged_line))
         # for i, polygon in enumerate(polygons):
         #     roll_point = self.get_roll_point(polygon)
         #     if roll_point != 0:
         #         polygons[i] = polygon[roll_point:] + polygon[:roll_point]
         #     print 'Roll point: ' + str(roll_point)
         return [poly.filter_polyline(polygon, dist=0.05) for polygon in polygons]  # Polygons filter
     else:
         return None
Beispiel #49
0
    def isovalues(self, values):
        """return a list of multilinestring, one for each value in values"""
        idx = self.__meshDataProvider.triangles()
        vtx = self.__meshDataProvider.nodeCoord()
        lines = []
        for value in values:
            lines.append([])
            if self.__meshDataProvider.valueAtElement():
                val = self.__meshDataProvider.elementValues() - float(value)
            else:
                val = self.__meshDataProvider.nodeValues() - float(value)

            # we filter triangles in which the value is negative on at least
            # one node and positive on at leat one node
            filtered = idx[numpy.logical_or(
                val[idx[:, 0]]*val[idx[:, 1]] <= 0,
                val[idx[:, 0]]*val[idx[:, 2]] <= 0
                ).reshape((-1,))]
            # create line segments
            for tri in filtered:
                line = []
                # the edges are sorted to avoid interpolation error
                for edge in [sorted([tri[0], tri[1]]),
                             sorted([tri[1], tri[2]]),
                             sorted([tri[2], tri[0]])]:
                    if val[edge[0]]*val[edge[1]] <= 0:
                        if val[edge[1]] != val[edge[0]]:
                            alpha = -val[edge[0]]/(val[edge[1]] - val[edge[0]])
                            assert alpha >= 0 and alpha <= 1
                            line.append(tuple((1-alpha)*vtx[edge[0]] + alpha*vtx[edge[1]]))
                        else: # the edge is part of the isoline
                            print "meshlayer:isovalues: ", value, edge[0], edge[1], val[edge[0]], val[edge[1]], vtx[edge[0]], vtx[edge[1]]
                            line.append(tuple(vtx[edge[0]]))
                            line.append(tuple(vtx[edge[1]]))
                # avoiding loops
                l = list(set(line))
                if len(l) > 1:
                    lines[-1].append(l)
            if len(lines[-1]):
                m = linemerge([LineString(l) for l in lines[-1]])
                if isinstance(m, LineString):
                    lines[-1] = [list(m.coords)]
                else:
                    assert(isinstance(m, MultiLineString))
                    lines[-1] = [list(l.coords) for l in m]
        return lines
Beispiel #50
0
    def _geometric_process(self):

        if len(self._entries) != 1:
            merged_union = linemerge(unary_union(self._entries))
        else:
            merged_union = MultiLineString(self._entries)

        self._edges = [ Edge(tuple(g.coords)) for g in merged_union.geoms ]

        edges = map(lambda e: e._geom, self._edges)

        if self._bnode:
            xyset = set([edge.coords[i] for edge in edges for i in (0,-1)])
            self._nodes = map(lambda xy: Node(xy),xyset)

        if self._bface:
            self._faces = [Face(poly.exterior,poly.interiors) for poly in polygonize(edges)]
Beispiel #51
0
    def intersection(self, geom):
        intersection_ids = list(self.index.intersection(geom.bounds))

        if not intersection_ids:
            raise EmtpyGeometryError('No intersection or empty geometry')

        intersections = []
        for i in intersection_ids:

            polygon = self.polygons[i]

            if polygon.contains(geom):
                return geom

            if polygon.intersects(geom):
                try:
                    new_geom_part = polygon.intersection(geom)
                    new_geom_part = filter_geometry_by_type(new_geom_part, geom.type)
                    if new_geom_part:
                        if len(intersection_ids) == 1:
                            return new_geom_part

                        if isinstance(new_geom_part, list):
                            intersections.extend(new_geom_part)
                        else:
                            intersections.append(new_geom_part)
                except TopologicalError:
                        pass

        if not intersections:
            raise EmtpyGeometryError('No intersection or empty geometry')

        # intersections from multiple sub-polygons
        # try to merge them back to a single geometry
        if geom.type.endswith('Polygon'):
            union = cascaded_union(list(flatten_polygons(intersections)))
        elif geom.type.endswith('LineString'):
            union = linemerge(list(flatten_linestrings(intersections)))
            if union.type == 'MultiLineString':
                union = list(union.geoms)
        elif geom.type == 'Point':
            union = intersections[0]
        else:
            log.warn('unexpexted geometry type %s', geom.type)
            raise EmtpyGeometryError()
        return union
Beispiel #52
0
	def helper(self, geom, splitter, expected_chunks):
		s = split(geom, splitter)
		self.assertEqual(s.type, "GeometryCollection")
		self.assertEqual(len(s), expected_chunks)
		if expected_chunks > 1:
			# split --> expected collection that when merged is again equal to original geometry
			if s.geoms[0].type == 'LineString':
				self.assertTrue(linemerge(s).simplify(0.000001).equals(geom))
			elif s.geoms[0].type == 'Polygon':
				union = cascaded_union(s).simplify(0.000001)
				self.assertTrue(union.equals(geom))
				self.assertEqual(union.area, geom.area)
			else:
				raise ValueError
		elif expected_chunks == 1:
			# not split --> expected equal to line
			self.assertTrue(s[0].equals(geom))
Beispiel #53
0
    def _topological_process(self):

        # initialisation des arcs (géométrie calculée, autres attributs à None)

        init_None = dict.fromkeys(('start_node','end_node','left_face','right_face'),None)
        if len(self._entries) != 1:
            merged_union = linemerge(unary_union(self._entries))
        else:
            merged_union = MultiLineString(self._entries)
        self._edges = [ Edge(tuple(g.coords),**init_None) for g in merged_union.geoms ]
        del merged_union


        # liste des géométries Shapely des Edge (arcs du graphe) et index spatial
        # (facilité d'écriture par la suite + fait une seule fois)

        edges   = map(lambda e: e._geom,self._edges)
        edge_si = geometry_spatial_index(edges)

        # construction des noeuds, mise à jour des noeuds départ et fin des arcs

        self._nodes, already_done = list(), dict()
        for edge in self._edges:
            for i,attname in ((0,'_start_node'),(-1,'_end_node')):
                xy = edge._geom.coords[i]
                inode = already_done.get(xy,None)
                if inode is None:
                    already_done[xy] = inode = len(self._nodes)
                    self._nodes.append(Node(xy))
                setattr(edge,attname,inode)
        del already_done

        # création des faces du graphe planaire

        self._faces = list()
        for polygon in polygonize(edges):
            new_face = Face(polygon.exterior,polygon.interiors,extring=None,intrings=list())
            self._faces.append(new_face)

        # liste des géométries Shapely des Face (faces du graphe et index spatial)
        # (facilité d'écriture par la suite + fait une seule fois)
        faces   = map(lambda pgf: pgf._geom,self._faces)
        face_si = geometry_spatial_index(faces)

        self._process_rings(edges,faces,edge_si,face_si)
Beispiel #54
0
	def add_holders(self, ring, holder_size, min_len):
		x = ring.xy[0]
		y = ring.xy[1]
			
		X1 = x[0]
		Y1 = y[0]

		lines = []

		for i in range(1,len(x)):
			X2 = x[i]
			Y2 = y[i]
			
			l = LineString( [(X1,Y1),(X2,Y2)] )
			
			if l.length >= min_len:
				lp1 = (l.length/2.0) - (holder_size/2.0)
				lp2 = (l.length/2.0) + (holder_size/2.0)
				
				hp1 = l.interpolate(lp1)
				hp2 = l.interpolate(lp2)
				
				l1 = cut_line(l, lp1)
				l2 = cut_line(l, lp2)
				
				lines.append(l1[0])
				lines.append(l2[1])
			else:
				lines.append(l)
			
			X1=X2
			Y1=Y2

		ml = linemerge(lines)
		
		lines = []
		
		if ml.geom_type == 'MultiLineString':
			for ls in ml:
				lines.append(ls)
		else:
			lines.append(ml)
		
		return lines
    def transform_tags(self, osmid, tags):
        outtags = { 'intnames' : {}, 
                    'level' : 35, 
                    'top' : None}

        # default treatment of tags
        for (k,v) in tags.iteritems():
            if k == 'name':
                outtags[k] = v
            elif k.startswith('name:'):
                outtags['intnames'][k[5:]] = v
            elif k == 'ref':
                if 'name' not in outtags:
                    outtags['name'] = '[%s]' % v
            elif k == 'network':
                outtags['level'] = conf.TAGS_NETWORK_MAP.get(v, 35)


        outtags['symbol'] = symbols.get_symbol(outtags['level'], None, tags, symboltypes)

        cur = self.thread.cursor

        if 'name' not in outtags:
            outtags['name'] = '(%s)' % osmid

        if outtags['top'] is None:
            if 'network' in tags:
                top = self.db.select_one("EXECUTE get_route_top(%s, %s)",
                              (osmid, tags['network']), cur=cur)
                outtags['top'] = True if (top == 0) else False
            else:
                outtags['top'] = True

        # finally: compute the geometry
        routelines = self.db.select_column("EXECUTE get_route_geometry(%s)", 
                               (osmid,), cur=cur)
        if routelines:
            outtags['geom'] = sops.linemerge(routelines)
            outtags['geom']._crs = int(conf.DB_SRID)

        # Clear elevation profile cache
        clearcache.clearElevationProfileCache(osmid)
            
        return outtags
Beispiel #56
0
def ensure_no_duplicates(shape):
    """
    This guarantees that the submission is valid even in the hypothetical
    scenario where line simplification might create quasi-duplicate edges.
    Otherwise, this function is a no-op.
    """
    strings = list(as_MultiLineString(shape))
    edges = []
    for strn in strings:
        for u,v in zip(strn.coords, strn.coords[1:]):
            edges.append((u,v))
    edges = np.array(edges)
    edges = edges.round(1)
    num_edges = len(edges)
    edges = { tuple(sorted(map(tuple, edge))) for edge in edges }
    if len(edges) < num_edges:
        print("INFORMATION: a duplicate edge had to be removed")
        edges = np.array(list(edges))
        return linemerge(edges)
    else:
        return shape
Beispiel #57
0
def join_features(features, props, buf=False):
    """ joins polygonal features
    """
    from feature import MultiPolygonFeature, MultiLineFeature
    from shapely.ops import linemerge

    if len(features) == 0:
        return features

    joined = []
    polygons = []
    lines = []

    for feat in features:
        if isinstance(feat, MultiPolygonFeature):
            polygons.append(feat.geom)
        elif isinstance(feat, MultiLineFeature):
            lines.append(feat.geom)
        else:
            joined.append(feat)  # cannot join this

    polygons = filter(lambda x: x is not None, polygons)
    if len(polygons) > 0:
        poly = polygons[0]
        if buf is not False:
            poly = poly.buffer(buf, 4)
        for poly2 in polygons[1:]:
            if buf is not False:
                poly2 = poly2.buffer(buf, 4)
            poly = poly.union(poly2)
        joined.append(MultiPolygonFeature(poly, props))

    if len(lines) > 0:
        rings = []
        for line in lines:
            geoms = hasattr(line, 'geoms') and line.geoms or [line]
            rings += geoms
        joined.append(MultiLineFeature(linemerge(rings), props))
    return joined
Beispiel #58
0
def get_scene_geometry(name):
    if not ':' in name:
        # Not a scene description
        return None
    
    geoms = []
    for obj in name.split('+'):
        oname = obj.strip()
        if oname.startswith(':'):
            geoms.append(world.current_scene[oname[1:]])
        else:
            scene, obj = oname.split(':', 2)
            oldscene = world.current_scene
            world.load_scene(scene)
            wkt = world.current_scene[obj]
            world.current_scene = oldscene
            geoms.append(wkt)

    if len(geoms) == 1:
        return geoms[0]
    else:
        return linemerge(geoms)
Beispiel #59
0
    def transform_tags(self, osmid, tags):
        outtags = {"intnames": {}, "level": 25, "top": None}

        # default treatment of tags
        for (k, v) in tags.iteritems():
            if k == "name":
                outtags[k] = v
            elif k.startswith("name:"):
                outtags["intnames"][k[5:]] = v
            elif k == "ref":
                if "name" not in outtags:
                    outtags["name"] = "[%s]" % v
            elif k == "network":
                outtags["level"] = conf.TAGS_NETWORK_MAP.get(v, 25)

        outtags["symbol"] = symbols.get_symbol(outtags["level"], None, tags, symboltypes)

        cur = self.thread.cursor

        if "name" not in outtags:
            outtags["name"] = "(%s)" % osmid

        if outtags["top"] is None:
            if "network" in tags:
                top = self.db.select_one("EXECUTE get_route_top(%s, %s)", (osmid, tags["network"]), cur=cur)
                outtags["top"] = True if (top == 0) else False
            else:
                outtags["top"] = True

        # finally: compute the geometry
        routelines = self.db.select_column("EXECUTE get_route_geometry(%s)", (osmid,), cur=cur)
        if routelines:
            outtags["geom"] = sops.linemerge(routelines)
            outtags["geom"]._crs = 900913

        return outtags
Beispiel #60
0
  def dissolve_lines(self, toDissolve, outFile, attributes, multiPart):

    with fiona.open(toDissolve, 'r') as input:
      schema = input.schema
      crs = input.crs

      features = {}
      for i, f in enumerate(input):
        features[i] = [shape(f['geometry']), f['properties']]
      
      if attributes:
      #TODO test this if block to make it dissolves features properly by attributes param

        for attr in schema['properties'].keys():
          if attr not in attributes:
            del schema['properties'][attr]

        attr_sets = {}
        for i in features.keys():
          prop_list = []
          for key in features[i][1].keys():
            if key in attributes:
              prop_list.append(features[i][1][key])
          
          attr_sets[tuple(prop_list)] = []
          features[i].append(tuple(prop_list))

        for i in features.keys():
          attr_sets[features[i][2]].append(features[i])
          del features[i][2]
        
        disjointFeatures = []
        for key in attr_sets.keys():
          for item in attr_sets[key]:
            idx = index.Index()
            for i in features.keys():
              idx.insert(i, features[i][0].bounds, features[i])
            disjointFeatures_partial = []
            disjointFeatures = disjointFeatures + self.__unionIntersecting(features, idx, disjointFeatures_partial)
         
        for feature in disjointFeatures:
           for attr in feature[1].keys():
             if attr not in attributes:
               del feature[1][attr]
    
        dissolveFeatures = disjointFeatures

      #no attributes specified, dissolve all features
      else:
        #if multiPart is True all features will be dissolve 
        if multiPart is True:
          features = linemerge([geom for geom, prop in features.values()])
          schema = {'geometry':features.geom_type, 'properties':{'fid':'int'}}
          dissolveFeatures = [(features, {'fid':1})] 
        #if multiPart is False dissolve all features that are not disjoint 
        elif multiPart is False:
          schema = {'geometry':'MultiLineString', 'properties':{'fid':'int'}}

          idx = index.Index()
          for i in features.keys():
            idx.insert(i, features[i][0].bounds, features[i])

          disjointFeatures = []
          self.__unionIntersecting(features, idx, disjointFeatures)

          dissolveFeatures = []          
          count = 0
          for geom, prop in disjointFeatures:
            dissolveFeatures.append((geom, {'fid':count}))
            count += 1

    with fiona.open(outFile, 'w', 'ESRI Shapefile', crs=crs, schema=schema) as output:
      for geom, prop in dissolveFeatures:
        output.write({'geometry': mapping(geom), 'properties':prop})