Beispiel #1
0
def split_line_by_nearest_points(gdf_line, gdf_points, tolerance, crs):
    """
    Split the union of lines with the union of points resulting

    :param GeoDataFrame gdf_line:  GeoDataFrame with multiple rows of connecting line segments
    :param GeoDataFrame gdf_points: geodataframe with multiple rows of single points

    :returns: ``gdf_segments`` (GeoDataFrame of segments)
    :rtype: GeoDataFrame

    https://github.com/ojdo/python-tools/blob/master/shapelytools.py#L144
    """

    # union all geometries
    line = gdf_line.geometry.unary_union
    line._crs = crs
    snap_points = gdf_points.geometry.unary_union
    snap_points._crs = crs

    # snap and split coords on line
    # returns GeometryCollection
    # snap_points = snap(coords, line, tolerance)
    # snap_points._crs = crs
    split_line = split(line, snap(snap_points, line, tolerance))
    split_line._crs = crs
    segments = [feature for feature in split_line if feature.length > 0.01]

    gdf_segments = gdf(geometry=segments, crs=crs)
    # gdf_segments.columns = ['index', 'geometry']

    return gdf_segments
Beispiel #2
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 #3
0
def compute_intersections(lines, crs):
    import itertools
    inters = []
    for line1, line2 in itertools.combinations(lines, 2):
        if line1.intersects(line2):
            inter = line1.intersection(line2)
            if "Point" == inter.type:
                inters.append(inter)
            elif "MultiPoint" == inter.type:
                inters.extend([pt for pt in inter])
            elif "MultiLineString" == inter.type:
                multiLine = [line for line in inter]
                first_coords = multiLine[0].coords[0]
                last_coords = multiLine[len(multiLine) - 1].coords[1]
                inters.append(Point(first_coords[0], first_coords[1]))
                inters.append(Point(last_coords[0], last_coords[1]))
            elif "GeometryCollection" == inter.type:
                for geom in inter:
                    if "Point" == geom.type:
                        inters.append(geom)
                    elif "MultiPoint" == geom.type:
                        inters.extend([pt for pt in geom])
                    elif "MultiLineString" == geom.type:
                        multiLine = [line for line in geom]
                        first_coords = multiLine[0].coords[0]
                        last_coords = multiLine[len(multiLine) - 1].coords[1]
                        inters.append(Point(first_coords[0], first_coords[1]))
                        inters.append(Point(last_coords[0], last_coords[1]))

    geometry = inters
    df = gdf(geometry=geometry, crs=crs)
    return df
Beispiel #4
0
def frm_to_lgaFrm(frm, key = 'LGA'):
    lgas = load.load_lgas()
    indices = frm.index.names
    frm = frm.copy()
    frm = frm.reset_index()
    frm['geometry'] = frm[key].apply(lambda x: lgas.loc[x]['geometry'])
    frm = frm.set_index(indices)
    frm = gdf(frm)
    return frm
Beispiel #5
0
def computer_end_points(lines, crs):
    all_points = []
    for line in lines:
        for i in [0, -1]:  # start and end point
            all_points.append(line.coords[i])

    unique_points = set(all_points)
    endpts = [Point(p) for p in unique_points]
    df = gdf(geometry=endpts, crs=crs)

    return df
Beispiel #6
0
def simplify_liness_accurracy(lines, decimals, crs):
    new_lines = []
    for line in lines:
        points_of_line = []
        for point in line.coords:
            x = round(point[0], decimals)
            y = round(point[1], decimals)
            points_of_line.append((x, y))
        new_lines.append(LineString(points_of_line))
    df = gdf(geometry=new_lines, crs=crs)
    return df
Beispiel #7
0
def simplify_points_accurracy(buiding_centroids, decimals, crs):
    new_points = []
    names = []
    for point, name in zip(buiding_centroids.geometry, buiding_centroids.Name):
        x = round(point.x, decimals)
        y = round(point.y, decimals)
        new_points.append(Point(x, y))
        names.append(name)
    df = gdf(geometry=new_points, crs=crs)
    df["Name"] = names
    return df
def erase_no_surrounding_areas(all_surroundings, zone, area_with_buffer):
    """
    Remove buildings inside zone and outside of buffer from Surroundings GeoDataFrame

    :param geopandas.GeoDataFrame all_surroundings: Surroundings GeoDataFrame
    :param geopandas.GeoDataFrame zone: Zone GeoDataFrame
    :param geopandas.GeoDataFrame area_with_buffer: Buffer area GeoDataFrame
    :return: GeoDataFrame with surrounding buildings
    """
    buffer_polygon = area_with_buffer.to_crs(zone.crs).geometry.values[0]
    zone_area = gdf(geometry=[zone.geometry.unary_union], crs=zone.crs)

    within_buffer = all_surroundings.geometry.intersects(buffer_polygon)
    surroundings = all_surroundings[within_buffer]
    rep_points = gdf(geometry=surroundings.geometry.representative_point(),
                     crs=all_surroundings.crs)
    not_in_zone = spatial_join(rep_points, zone_area,
                               how='left')['index_right'].isna()

    return surroundings[not_in_zone].copy()
def calc_surrounding_area(zone_gdf, buffer_m):
    """
    Adds buffer to zone to get surroundings area

    :param geopandas.GeoDataFrame zone_gdf: Zone GeoDataFrame
    :param float buffer_m: Buffer to add to zone building geometries
    :return: Surrounding area GeoDataFrame
    """
    surrounding_area = gdf(
        geometry=[zone_gdf.geometry.buffer(buffer_m).unary_union],
        crs=zone_gdf.crs)
    return surrounding_area
Beispiel #10
0
def create_terminals(buiding_centroids, crs, street_network):
    # get list of nearest points
    near_points = near_analysis(buiding_centroids, street_network, crs)
    # extend to the buiding centroids
    all_points = near_points.append(buiding_centroids)
    all_points.crs = crs
    # Aggregate these points with the GroupBy
    lines_to_buildings = all_points.groupby(['Name'])['geometry'].apply(lambda x: LineString(x.tolist()))
    lines_to_buildings = gdf(lines_to_buildings, geometry='geometry', crs=crs)

    lines_to_buildings = lines_to_buildings.append(street_network).reset_index(drop=True)
    lines_to_buildings.crs = crs
    return lines_to_buildings
Beispiel #11
0
def snappy_endings(lines, max_distance, crs):
    """Snap endpoints of lines together if they are at most max_length apart.

    Args:
        lines: a list of LineStrings or a MultiLineString
        max_distance: maximum distance two endpoints may be joined together
    """

    # initialize snapped lines with list of original lines
    # snapping points is a MultiPoint object of all vertices
    snapped_lines = [line for line in lines]
    snapping_points = vertices_from_lines(snapped_lines)

    # isolated endpoints are going to snap to the closest vertex
    isolated_endpoints = find_isolated_endpoints(snapped_lines)

    # only move isolated endpoints, one by one
    for endpoint in isolated_endpoints:
        # find all vertices within a radius of max_distance as possible
        target = nearest_neighbor_within(snapping_points, endpoint,
                                         max_distance)

        # do nothing if no target point to snap to is found
        if not target:
            continue

            # find the LineString to modify within snapped_lines and update it
        for i, snapped_line in enumerate(snapped_lines):
            if endpoint.touches(snapped_line):
                snapped_lines[i] = bend_towards(snapped_line,
                                                where=endpoint,
                                                to=target)
                break

        # also update the corresponding snapping_points
        for i, snapping_point in enumerate(snapping_points):
            if endpoint.equals(snapping_point):
                snapping_points[i] = target
                break

    # post-processing: remove any resulting lines of length 0
    snapped_lines = [s for s in snapped_lines if s.length > 0]

    df = gdf(geometry=snapped_lines, crs=crs)
    return df
Beispiel #12
0
def near_analysis(buiding_centroids, street_network, crs):
    near_point = []
    building_name = []
    for point, name in zip(buiding_centroids.geometry, buiding_centroids.Name):
        point._crs = crs
        distance = 10e10
        for line in street_network.geometry:
            line._crs = crs
            nearest_point_candidate = line.interpolate(line.project(point))
            distance_candidate = point.distance(nearest_point_candidate)
            if distance_candidate < distance:
                distance = distance_candidate
                nearest_point = nearest_point_candidate
        building_name.append(name)
        near_point.append(nearest_point)

    geometry = near_point
    df = gdf(geometry=geometry, crs=crs)
    df["Name"] = building_name
    return df
Beispiel #13
0
def df_buffer_extent(inDf,
                     inEpsg,
                     meterTolerance,
                     geomCol="geometry",
                     mantainOriginalGeom=None):
    """
    For all geometries, calculate the boundary given by 
    the sum between the feature extent and the Tolerance variable
    """

    from shapely.geometry import Polygon
    from geopandas import GeoDataFrame as gdf
    from gasp.g.ext import featext_to_dfcols

    inDf = featext_to_dfcols(inDf, geomCol)

    inDf['minx'] = inDf.minx - meterTolerance
    inDf['miny'] = inDf.miny - meterTolerance
    inDf['maxx'] = inDf.maxx + meterTolerance
    inDf['maxy'] = inDf.maxy + meterTolerance

    # Produce new geometries
    geoms = [
        Polygon([[ext[0], ext[3]], [ext[1], ext[3]], [ext[1], ext[2]],
                 [ext[0], ext[2]], [ext[0], ext[3]]])
        for ext in zip(inDf.minx, inDf.maxx, inDf.miny, inDf.maxy)
    ]

    # Delete uncessary columns
    dropCols = ['minx', 'miny', 'maxx', 'maxy']
    if mantainOriginalGeom:
        inDf.rename(columns={geomCol: 'old_geom'}, inplace=True)
    else:
        dropCols.append(geomCol)

    inDf.drop(dropCols, axis=1, inplace=True)

    resDf = gdf(inDf, crs={'init': 'epsg:{}'.format(inEpsg)}, geometry=geoms)

    return resDf
Beispiel #14
0
aust_recovery_cv = narrow_recovery_df.set_index(narrow_recovery_df['Country/Region']).\
    loc['Australia',]

# charts
fig, (ax1, ax2, ax3) = plt.subplots(nrows=3, sharex=True, sharey=False)
aust_conf_cv.groupby('date')['confirmed'].sum().plot(ax=ax1, title="Confirmed")
aust_death_cv.groupby('date')['death'].sum().plot(ax=ax2, title="Deaths")
aust_recovery_cv.groupby('date')['recovery'].sum().plot(ax=ax3, title="Recovery")

#choose most recent date 
end_date = datetime.strftime(narrow_conf_df.date.max(),"%m/%d/%Y")
date_conf_df = narrow_conf_df.loc[narrow_conf_df['date']==end_date,]
#
# Datad=Frame as GeoDataFrame
points_list = [Point(x, y) for x, y in zip(date_conf_df.Long, date_conf_df.Lat)]
points = gdf(date_conf_df, geometry=points_list)
points.crs = {'init' :'epsg:4326'}
points = points.to_crs({'init': 'epsg:4283'})

# join points data to australia by location
m_layer = geopandas.sjoin(aust, points, how="inner", op='intersects')

#make the map
m_layer.plot(column='confirmed', cmap='Blues', linewidth=0.8, edgecolor='0.8',
             label="confirmed")
vmin = m_layer['confirmed'].min()
vmax = m_layer['confirmed'].max()
sm = plt.cm.ScalarMappable(cmap='Blues', norm=plt.Normalize(vmin=vmin, 
                                                            vmax=vmax))

# Chlorepleth : 
def connect_building_to_grid(building_points, input_streets_shp):

    # Import data
    lines = gdf.from_file(input_streets_shp)

    # Create DF for points on line
    points_on_line = building_points[["Name", "geometry"]].copy()
    lines = lines[["geometry"]].copy()
    lines["FID"] = range(lines.shape[0])

    # points_on_line['Node Type'] = None

    for idx, point in points_on_line.iterrows():
        points_on_line.loc[idx, 'Building'] = point['Name']
        # points_on_line.loc[idx, 'Name'] = point['Name'] + ' Coupling Point'

    # Prepare DF for nearest point on line
    building_points['min_dist_to_lines'] = 0
    building_points['nearest_line'] = None

    for idx, point in building_points.iterrows():
        distances = lines.distance(point.geometry)
        nearest_line_idx = distances.idxmin()
        building_points.loc[idx, 'nearest_line'] = nearest_line_idx
        building_points.loc[idx, 'min_dist_to_lines'] = lines.distance(
            point.geometry).min()

        # find point on nearest line
        project_distances = lines.project(point.geometry)
        project_distance_nearest_line = lines.interpolate(
            project_distances[nearest_line_idx])
        points_on_line.loc[
            idx, 'geometry'] = project_distance_nearest_line[nearest_line_idx]

    # Determine Intersections of lines
    for idx, line in lines.iterrows():

        line.geometry = line.geometry.buffer(0.0001)
        line_intersections = lines.intersection(line.geometry)

        for index, intersection in line_intersections.iteritems():
            if intersection.geom_type == 'LineString' and index != idx:
                centroid_buffered = line_intersections[index].centroid.buffer(
                    0.1)  # middle of Linestrings
                if not points_on_line.intersects(centroid_buffered).any():
                    index_points_on_line = points_on_line.shape[
                        0]  # current number of rows in points_on_line
                    points_on_line.loc[
                        index_points_on_line,
                        'geometry'] = line_intersections[index].centroid
                    points_on_line.loc[index_points_on_line, 'Building'] = None
    # Name Points
    for idx, point in points_on_line.iterrows():
        points_on_line.loc[idx, 'Name'] = 'Node' + str(idx)
        points_on_line.loc[idx, 'Node_int'] = int(idx)

    # Split Linestrings at points_on_line
    tranches_list = []

    for idx, line in lines.iterrows():
        line_buffered = line.copy()
        line_buffered.geometry = line.geometry.buffer(0.0001)
        line_point_intersections = points_on_line.intersection(
            line_buffered.geometry)
        filtered_points = line_point_intersections[
            line_point_intersections.is_empty == False]

        start_point = Point(line.values[0].xy[0][0], line.values[0].xy[1][0])

        distance = filtered_points.distance(start_point)
        filtered_points = gdf(data=filtered_points)
        filtered_points['distance'] = distance
        filtered_points.sort_values(by='distance', inplace=True)

        # Create new Lines
        for idx1 in range(0, len(filtered_points) - 1):
            start = filtered_points.iloc[idx1][0]
            end = filtered_points.iloc[idx1 + 1][0]
            newline = LineString([start, end])
            tranches_list.append(newline)

    tranches = gdf(data=tranches_list, crs=points_on_line.crs)
    tranches.columns = ['geometry']
    tranches['Name'] = None
    tranches['Startnode'] = None
    tranches['Endnode'] = None
    tranches['Startnode_int'] = None
    tranches['Endnode_int'] = None
    tranches['Length'] = 0

    for idx, tranch in tranches.iterrows():
        # print (idx)
        # print (tranch)
        tranches.loc[idx, 'Name'] = 'tranch' + str(idx)
        tranches.loc[idx, 'Length'] = tranch.values[0].length
        # print (tranch.values[0].boundary)

        startnode = tranch.values[0].boundary[0]
        endnode = tranch.values[0].boundary[1]

        start_intersection = points_on_line.intersection(startnode.buffer(0.1))
        end_intersection = points_on_line.intersection(endnode.buffer(0.1))
        start_intersection_filtered = start_intersection[
            start_intersection.is_empty == False]
        end_intersection_filtered = end_intersection[end_intersection.is_empty
                                                     == False]

        startnode_index = start_intersection_filtered.index.values[0]
        endnode_index = end_intersection_filtered.index.values[0]

        tranches.loc[idx, 'Startnode'] = 'Node' + str(
            start_intersection_filtered.index.values[0])
        tranches.loc[idx, 'Endnode'] = 'Node' + str(endnode_index)
        tranches.loc[idx, 'Startnode_int'] = int(
            start_intersection_filtered.index.values[0])
        tranches.loc[idx, 'Endnode_int'] = int(endnode_index)

    # UTM to LAT, LON
    # building_nodes = building_nodes.to_crs("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs")
    # streets = streets.to_crs("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs")

    return points_on_line, tranches
Beispiel #16
0
    df_prcp['date'] = [datetime.datetime.strptime(d, "%Y-%m-%dT%H:%M:%S") for d in dates_prcp]
    df_prcp['prcp'] = [p for p in prcp]
    df_prcp['attributes'] = [p for p in attributes]
    df_prcp['station_id'] = [p for p in station]

    # Get lat/long of stations
    station_list = pd.read_csv(ghcnd_station_inventory)
    stations = df_prcp.merge(station_list, on='station_id', how='left')

    # Save precip data
    precip_path = data_path / 'precip' / 'station_data' / img
    precip_path_shp = precip_path / 'shp'
    try:
        precip_path_shp.mkdir(parents=True)
    except FileExistsError:
        pass
    stations.to_csv(precip_path / '{}'.format(img + '_precip.csv', index=False))

    # Sum daily measurements and save as shapefile
    stations = gdf(stations, geometry=geopandas.points_from_xy(stations.long, stations.lat))
    stations = stations.groupby(['station_id', 'name', 'elevation', 'lat', 'long']).sum().reset_index()
    stations = gdf(stations, geometry=geopandas.points_from_xy(stations.long, stations.lat))
    stations.crs = 'EPSG:4269'
    stations = stations.to_crs('EPSG:4326')
    stations.to_file(str(precip_path_shp / '{}'.format(img + '_precip.shp')))