Beispiel #1
0
def calculate_green_spaces(division_dir, green_spaces_dir):

    division_path = find_shp_path(division_dir)

    if type(green_spaces_dir) != list:
        green_spaces_dir = [green_spaces_dir]
    green_spaces_paths = [find_shp_path(i) for i in green_spaces_dir]

    # create spatial index for green spaces
    green_spaces = []
    for green_spaces_path in green_spaces_paths:
        green_spaces.extend(list(iter_shp_as_shapely(green_spaces_path)))
    green_spaces_idx = create_spatial_index(green_spaces)

    divisions = list(iter_shp_as_shapely(division_path))
    total_divisions = len(divisions)

    green_relevance = {}
    for index, (id_division, division_shp) in enumerate(divisions):
        area = division_shp.area
        area_without_green = calc_area(division_shp, green_spaces,
                                       green_spaces_idx)
        area_green = area - area_without_green
        green_relevance[id_division] = area_green / area

        progress_msg = unicode(index) + " of " + unicode(total_divisions)
        print(progress_msg, end="\r" * len(progress_msg))

    return green_relevance
Beispiel #2
0
def intersect_data_with_shps(df, shp_path, lat_field="LAT", lon_field="LON"):
    """Asign an id from shp_path based on lat-lon intersection."""
    sf = shapefile.Reader(shp_path)
    id_field_name = sf.fields[1][0]

    # def wrapper(fn, shapes, shp_idx, shp_path):
    #     @wraps(fn)
    #     def inner(*args, **kwargs):
    #         kwargs["shapes"] = shapes
    #         kwargs["shp_idx"] = shp_idx
    #         kwargs["shp_path"] = shp_path
    #         fn(*args, **kwargs)
    #     return inner

    shapes = list(geo_utils.iter_shp_as_shapely(shp_path))

    # shp_idx = create_spatial_index(shapes)

    # func_get_id = wrapper(
    #     find_id_intersecting_shape, shapes, shp_idx, shp_path)
    # df[id_field_name] = map(func_get_id, df[lat_field], df[lon_field])

    def func(x):
        return find_id_intersecting_shape(x["LAT"], x["LON"], shapes, shp_path)

    df[id_field_name] = df.apply(func, axis=1)

    return df
Beispiel #3
0
def intersect_data_with_shps(df, shp_path, lat_field="LAT", lon_field="LON"):
    """Asign an id from shp_path based on lat-lon intersection."""
    sf = shapefile.Reader(shp_path)
    id_field_name = sf.fields[1][0]

    # def wrapper(fn, shapes, shp_idx, shp_path):
    #     @wraps(fn)
    #     def inner(*args, **kwargs):
    #         kwargs["shapes"] = shapes
    #         kwargs["shp_idx"] = shp_idx
    #         kwargs["shp_path"] = shp_path
    #         fn(*args, **kwargs)
    #     return inner

    shapes = list(geo_utils.iter_shp_as_shapely(shp_path))
    # shp_idx = create_spatial_index(shapes)

    # func_get_id = wrapper(
    #     find_id_intersecting_shape, shapes, shp_idx, shp_path)
    # df[id_field_name] = map(func_get_id, df[lat_field], df[lon_field])

    def func(x):
        return find_id_intersecting_shape(x["LAT"], x["LON"],
                                          shapes, shp_path)
    df[id_field_name] = df.apply(func, axis=1)

    return df
Beispiel #4
0
def create_context_polygon(context_shp_or_polygon):
    if not context_shp_or_polygon:
        return None
    elif (type(context_shp_or_polygon) != str and
          type(context_shp_or_polygon) != unicode):
        return context_shp_or_polygon
    else:
        return cascaded_union(
            [i[1].buffer(0) for i in
             iter_shp_as_shapely(context_shp_or_polygon)])
Beispiel #5
0
def create_context_polygon(context_shp_or_polygon):
    if not context_shp_or_polygon:
        return None
    elif (type(context_shp_or_polygon) != str
          and type(context_shp_or_polygon) != unicode):
        return context_shp_or_polygon
    else:
        return cascaded_union([
            i[1].buffer(0) for i in iter_shp_as_shapely(context_shp_or_polygon)
        ])
Beispiel #6
0
def count_points(points_shp_path, polygons_shp_path):
    points_shp_path = pf.find_shp_path(points_shp_path)
    polygons_shp_path = pf.find_shp_path(polygons_shp_path)

    points = dict(iter_shp_as_shapely(points_shp_path))
    polygons = dict(iter_shp_as_shapely(polygons_shp_path))

    count = {id_polygon: 0 for id_polygon in polygons.iterkeys()}
    for id_polygon, polygon in polygons.iteritems():
        remove_points = []

        for id_point, point in points.iteritems():
            if polygon.contains(point):
                count[id_polygon] += 1
                remove_points.append(id_point)

        for remove_point in remove_points:
            del points[remove_point]

    return count
Beispiel #7
0
def count_points(points_shp_path, polygons_shp_path):
    points_shp_path = pf.find_shp_path(points_shp_path)
    polygons_shp_path = pf.find_shp_path(polygons_shp_path)

    points = dict(iter_shp_as_shapely(points_shp_path))
    polygons = dict(iter_shp_as_shapely(polygons_shp_path))

    count = {id_polygon: 0 for id_polygon in polygons.iterkeys()}
    for id_polygon, polygon in polygons.iteritems():
        remove_points = []

        for id_point, point in points.iteritems():
            if polygon.contains(point):
                count[id_polygon] += 1
                remove_points.append(id_point)

        for remove_point in remove_points:
            del points[remove_point]

    return count
Beispiel #8
0
def calculate_intersect_weights(division_dir,
                                buffer_dir,
                                weights_path,
                                empty_dirs=None,
                                force_buffer_sum=True):
    """Calculate perecentage of division_dir shapes intersecting buffer_dir.

    Find which shapes in the division shapefile intersect with each shape in
    buffer, and how much surface of the division shape is intersecting as well
    as how much of the buffer shape is being intersected by that division
    shape.

    If a list with "empty shapefiles" is provided, the surfaces from
    those shps that intersect with the buffer will not be taken into account
    for the calculation of weights. They will be subtracted both from divisions
    and buffers.

    Args:
        division_dir (str): Directory where shapefile with "inner shapes" is
            in this case the polygons used to divide the greater shape.
        buffer_dir (str): Directory where shapefile with "container shapes" is,
            in this case the buffers calculated over points or lines.
        empty_dirs (list): Paths to shapefiles with surfaces that shouldn't be
            taken into account in the calculation.

    Returns:
        dict: The perecentage of intersected surface is returned as calculated
            over total division area and total buffer area in a dictionary like
            this dict[id_buffer][id_division][division]

        >>> {
            "id_buffer1":
                {"id_division1": {"division": %_intersect_division_surface,
                                  "buffer": %_intersect_buffer_surface},
                 "id_division2": {"division": %_intersect_division_surface,
                                  "buffer": %_intersect_buffer_surface}
                },
            }
    """
    division_path = find_shp_path(division_dir)
    buffer_path = find_shp_path(buffer_dir)
    if empty_dirs:
        empty_paths = [find_shp_path(shp) for shp in empty_dirs]

    # create spatial index for divisions
    divisions = list(geo_utils.iter_shp_as_shapely(division_path))
    divisions_idx = create_spatial_index(divisions)

    # create spatial index for empty shapes
    if empty_dirs:
        empty_shps = []
        for empty_path in empty_paths:
            empty_shps.extend(list(geo_utils.iter_shp_as_shapely(empty_path)))

        empty_idx = create_spatial_index(empty_shps)

    weighted_intersections = {}
    for id_buffer, buffer_shp in geo_utils.iter_shp_as_shapely(buffer_path):
        buffer_shp = buffer_shp.buffer(0)
        weighted_intersections[id_buffer] = {}

        if empty_dirs:
            buffer_area = calc_area(buffer_shp, empty_shps, empty_idx)
        else:
            buffer_area = buffer_shp.area
        assert buffer_area > 0, "Buffer area can't be 0 " + unicode(id_buffer)

        intersect_generator = find_intersections(buffer_shp, divisions,
                                                 divisions_idx)

        for id_division, division_shp in intersect_generator:
            division_shp = division_shp.buffer(0)

            if empty_dirs:
                division_area = calc_area(division_shp, empty_shps, empty_idx)
            else:
                division_area = division_shp.area

            try:
                intersect = buffer_shp.intersection(division_shp)
                if empty_dirs:
                    intersect_area = calc_area(intersect, empty_shps,
                                               empty_idx)
                else:
                    intersect_area = intersect.area
            except Exception as inst:
                print("id_divison:", id_division,
                      "couldn't be intersected with id_buffer:", id_buffer)
                print(inst, "\n")

            weighted_intersections[id_buffer][id_division] = {
                "division": round(intersect_area / division_area, 30),
                "buffer": round(intersect_area / buffer_area, 30)
            }

        if force_buffer_sum:
            total_w = sum([
                i["buffer"]
                for i in weighted_intersections[id_buffer].itervalues()
            ])
            for id_division in weighted_intersections[id_buffer]:
                weighted_intersections[id_buffer][id_division][
                    "buffer"] /= total_w

    save_to_json(weighted_intersections, weights_path)
    return weighted_intersections
Beispiel #9
0
def calculate_intersect_weights(division_dir, buffer_dir, weights_path, empty_dirs=None, force_buffer_sum=True):
    """Calculate perecentage of division_dir shapes intersecting buffer_dir.

    Find which shapes in the division shapefile intersect with each shape in
    buffer, and how much surface of the division shape is intersecting as well
    as how much of the buffer shape is being intersected by that division
    shape.

    If a list with "empty shapefiles" is provided, the surfaces from
    those shps that intersect with the buffer will not be taken into account
    for the calculation of weights. They will be subtracted both from divisions
    and buffers.

    Args:
        division_dir (str): Directory where shapefile with "inner shapes" is
            in this case the polygons used to divide the greater shape.
        buffer_dir (str): Directory where shapefile with "container shapes" is,
            in this case the buffers calculated over points or lines.
        weights_path (str): Json path where calculated weights will be saved.
        empty_dirs (list): Paths to shapefiles with surfaces that shouldn't be
            taken into account in the calculation.
        force_buffer_sum (bool): Recalculate weights of a buffer so they always
            sum 1.0.

    Returns:
        dict: The perecentage of intersected surface is returned as calculated
            over total division area and total buffer area in a dictionary like
            this dict[id_buffer][id_division][division]

        >>> {
            "id_buffer1":
                {"id_division1": {"division": %_intersect_division_surface,
                                  "buffer": %_intersect_buffer_surface},
                 "id_division2": {"division": %_intersect_division_surface,
                                  "buffer": %_intersect_buffer_surface}
                },
            }
    """
    division_path = pf.find_shp_path(division_dir)
    buffer_path = pf.find_shp_path(buffer_dir)
    if empty_dirs:
        empty_paths = [pf.find_shp_path(shp) for shp in empty_dirs]

    # create spatial index for divisions
    divisions = list(geo_utils.iter_shp_as_shapely(division_path))
    divisions_idx = create_spatial_index(divisions)

    # create spatial index for empty shapes
    if empty_dirs:
        empty_shps = []
        for empty_path in empty_paths:
            empty_shps.extend(list(geo_utils.iter_shp_as_shapely(empty_path)))

        empty_idx = create_spatial_index(empty_shps)

    weighted_intersections = {}
    for id_buffer, buffer_shp in geo_utils.iter_shp_as_shapely(buffer_path):
        buffer_shp = buffer_shp.buffer(0)
        weighted_intersections[id_buffer] = {}

        if empty_dirs:
            buffer_area = calc_area(buffer_shp, empty_shps, empty_idx)
        else:
            buffer_area = buffer_shp.area
        assert buffer_area > 0, "Buffer area can't be 0 " + unicode(id_buffer)

        intersect_generator = find_intersections(buffer_shp, divisions, divisions_idx)

        for id_division, division_shp in intersect_generator:
            division_shp = division_shp.buffer(0)

            if empty_dirs:
                division_area = calc_area(division_shp, empty_shps, empty_idx)
            else:
                division_area = division_shp.area

            try:
                intersect = buffer_shp.intersection(division_shp)
                if empty_dirs:
                    intersect_area = calc_area(intersect, empty_shps, empty_idx)
                else:
                    intersect_area = intersect.area
            except Exception as inst:
                print("id_divison:", id_division, "couldn't be intersected with id_buffer:", id_buffer)
                print(inst, "\n")

            weighted_intersections[id_buffer][id_division] = {
                "division": round(intersect_area / division_area, 30),
                "buffer": round(intersect_area / buffer_area, 30),
            }

        if force_buffer_sum:
            total_w = sum([i["buffer"] for i in weighted_intersections[id_buffer].itervalues()])
            for id_division in weighted_intersections[id_buffer]:
                weighted_intersections[id_buffer][id_division]["buffer"] /= total_w

    save_to_json(weighted_intersections, weights_path)
    return weighted_intersections