コード例 #1
0
def square_grid(bbox, cell_size, units):
    fc = FeatureCollection([])
    x_fraction = cell_size / distance(Point((bbox[0], bbox[1])),
                                      Point((bbox[2], bbox[1])), units)
    cell_width = x_fraction * (bbox[2] - bbox[0])
    y_fraction = cell_size / distance(Point((bbox[0], bbox[1])),
                                      Point((bbox[0], bbox[3])), units)
    cell_height = y_fraction * (bbox[3] - bbox[1])

    current_x = bbox[0]
    while current_x <= bbox[2]:
        current_y = bbox[1]
        while current_y <= bbox[3]:
            cell_poly = Polygon(([
                [current_x, current_y],
                [current_x, current_y + cell_height],
                [current_x + cell_width, current_y + cell_height],
                [current_x + cell_width, current_y],
                [current_x, current_y]
            ],))
            fc["features"].append(cell_poly)

            current_y += cell_height

        current_x += cell_width

    return fc
コード例 #2
0
def square(bbox):
    horizontal_distance = distance(bbox.slice(0, 2), [bbox[2], bbox[1]],
                                   'miles')
    vertical_distance = distance(bbox.slice(0, 2), [bbox[0], bbox[3]], 'miles')
    if horizontal_distance >= vertical_distance:
        vertical_midpoint = (bbox[1] + bbox[3]) / 2
        return [
            bbox[0], vertical_midpoint - ((bbox[2] - bbox[0]) / 2), bbox[2],
            vertical_midpoint + ((bbox[2] - bbox[0]) / 2)
        ]
    else:
        horizontal_midpoint = (bbox[0] + bbox[2]) / 2
        return [
            horizontal_midpoint - ((bbox[3] - bbox[1]) / 2), bbox[1],
            horizontal_midpoint + ((bbox[3] - bbox[1]) / 2), bbox[3]
        ]
コード例 #3
0
def idw(control_points, value_field, b, cell_width, units):
    # check if field containing data exists..
    filtered = filter(
        lambda feature:
        (feature["properties"] and value_field in feature["properties"]),
        control_points["features"])
    if len(filtered) != 0:
        # create a sample square grid
        # compared to a point grid helps visualizing the output
        sampling_grid = square_grid(bbox(control_points), cell_width, units)
        for i in range(len(sampling_grid["features"])):
            zw = 0
            sw = 0
            # calculate the distance from each control point to cell's centroid
            for j in range(len(control_points["features"])):
                d = distance(centroid(sampling_grid["features"][j]),
                             control_points["features"][j], units)
                if d == 0:
                    zw = control_points["features"][j]["properties"][
                        value_field]
                w = 1.0 / pow(d, b)
                sw += w
                zw += w * control_points["features"][j]["properties"][
                    value_field]
            # write IDW value for each grid cell
            sampling_grid["features"][i]["properties"]["z"] = zw / sw
        return sampling_grid
    else:
        print('Specified Data Field is Missing')
コード例 #4
0
def point_grid(bbox, cellSize, units):
    fc = FeatureCollection([])
    x_fraction = cellSize / distance(Point(
        (bbox[0], bbox[1])), Point((bbox[2], bbox[1])), units)
    cell_width = x_fraction * (bbox[2] - bbox[0])
    y_fraction = cellSize / distance(Point(
        (bbox[0], bbox[1])), Point((bbox[0], bbox[3])), units)
    cell_height = y_fraction * (bbox[3] - bbox[1])

    current_x = bbox[0]
    while current_x <= bbox[2]:
        current_y = bbox[1]
        while current_y <= bbox[3]:
            fc["features"].append(Point((current_x, current_y)))

            current_y += cell_height
        current_x += cell_width

    return fc
コード例 #5
0
def inner_function(pt, coords, units):
    closest_pt = Point((float("inf"), float("inf")), {
        "dist": float("inf")
    })
    for i in range(len(coords)):
        start = Point(coords[i])
        stop = Point(coords[i + 1])
        # start
        start.properties.dist = distance(pt, start, units)
        # stop
        stop.properties.dist = distance(pt, stop, units)
        # perpendicular
        height_distance = max(start.properties.dist, stop.properties.dist)
        direction = bearing(start, stop)
        perpendicular_pt1 = destination(pt, height_distance, direction + 90, units)
        perpendicular_pt2 = destination(pt, height_distance, direction - 90, units)
        intersect = line_intersects(
            perpendicular_pt1.geometry.coordinates[0],
            perpendicular_pt1.geometry.coordinates[1],
            perpendicular_pt2.geometry.coordinates[0],
            perpendicular_pt2.geometry.coordinates[1],
            start.geometry.coordinates[0],
            start.geometry.coordinates[1],
            stop.geometry.coordinates[0],
            stop.geometry.coordinates[1]
        )

        if intersect:
            intersect_pt = Point(intersect)
            intersect_pt.properties.dist = distance(pt, intersect_pt, units)

        if start.properties.dist < closest_pt.properties.dist:
            closest_pt = start
            closest_pt.properties.index = i
        if stop.properties.dist < closest_pt.properties.dist:
            closest_pt = stop
            closest_pt.properties.index = i
        if intersect_pt and intersect_pt.properties.dist < closest_pt.properties.dist:
            closest_pt = intersect_pt
            closest_pt.properties.index = i

    return closest_pt
コード例 #6
0
def nearest(target_point, points):
    nearest_point = None
    min_dist = float("inf")
    for i in range(len(points["features"])):
        distance_to_point = distance(target_point, points["features"][i],
                                     'miles')
        if distance_to_point < min_dist:
            nearest_point = points["features"][i]
            min_dist = distance_to_point

    return nearest_point
コード例 #7
0
def length(coords, units):
    travelled = 0
    prev_coords = Point(coords[0])
    cur_coords = Point(coords[0])

    for i in range(len(coords)):
        cur_coords.geometry.coordinates = coords[i]
        travelled += distance(prev_coords, cur_coords, units)
        temp = prev_coords
        prev_coords = cur_coords
        cur_coords = temp

    return travelled
コード例 #8
0
def line_slice_along(line, start_dist, stop_dist, units):
    slice = []
    if line["type"] == 'Feature':
        coords = line.geometry.coordinates
    elif line["type"] == 'LineString':
        coords = line.coordinates
    else:
        raise ValueError('input must be a LineString Feature or Geometry')

    travelled = 0
    for i in range(len(coords)):
        if start_dist >= travelled and i == coords.length - 1:
            break
        elif travelled > start_dist and len(slice) == 0:
            overshot = start_dist - travelled
            if not overshot:
                return slice.append(coords[i])
            direction = bearing(coords[i], coords[i - 1]) - 180
            interpolated = destination(coords[i], overshot, direction, units)
            slice.append(interpolated.geometry.coordinates)

        if travelled >= stop_dist:
            overshot = stop_dist - travelled
            if not overshot:
                return slice.append(coords[i])
            direction = bearing(coords[i], coords[i - 1]) - 180
            interpolated = destination(coords[i], overshot, direction, units)
            slice.append(interpolated.geometry.coordinates)
            return LineString(tuple(slice))

        if travelled >= start_dist:
            slice.append(coords[i])

        travelled += distance(coords[i], coords[i + 1], units)

    return LineString(coords[coords.length - 1])
コード例 #9
0
def hex_grid(bbox, cell_size, units, triangles):
    x_fraction = cell_size / (distance(Point(
        (bbox[0], bbox[1])), Point((bbox[2], bbox[1])), units))
    cell_width = x_fraction * (bbox[2] - bbox[0])
    y_fraction = cell_size / (distance(Point(
        (bbox[0], bbox[1])), Point((bbox[0], bbox[3])), units))
    cell_height = y_fraction * (bbox[3] - bbox[1])
    radius = cell_width / 2

    hex_width = radius * 2
    hex_height = math.sqrt(3) / 2 * cell_height

    box_width = bbox[2] - bbox[0]
    box_height = bbox[3] - bbox[1]

    x_interval = 3 / 4 * hex_width
    y_interval = hex_height

    x_span = box_width / (hex_width - radius / 2)
    x_count = math.ceil(x_span)
    if round(x_span) == x_count:
        x_count += 1

    x_adjust = (
        (x_count * x_interval - radius / 2) - box_width) / 2 - radius / 2

    y_count = math.ceil(box_height / hex_height)

    y_adjust = (box_height - y_count * hex_height) / 2

    has_offset_y = y_count * hex_height - box_height > hex_height / 2
    if has_offset_y:
        y_adjust -= hex_height / 4

    fc = FeatureCollection([])
    for x in range(x_count):
        for y in range(y_count):

            is_odd = x % 2 == 1
            if y == 0 and is_odd:
                continue

            if y == 0 and has_offset_y:
                continue

            center_x = x * x_interval + bbox[0] - x_adjust
            center_y = y * y_interval + bbox[1] + y_adjust

            if is_odd:
                center_y -= hex_height / 2
            if triangles:
                fc["features"] += [
                    hex_triangles([center_x, center_y], cell_width / 2,
                                  cell_height / 2)
                ]
            else:
                fc["features"] += [
                    hexagon([center_x, center_y], cell_width / 2,
                            cell_height / 2)
                ]

    return fc
コード例 #10
0
def midpoint(point_from, point_to):
    dist = distance(point_from, point_to, 'miles')
    heading = bearing(point_from, point_to)

    return destination(point_from, dist / 2, heading, 'miles')
コード例 #11
0
def triangle_grid(bbox, cell_size, units):
    fc = FeatureCollection([])
    x_fraction = cell_size / (distance([bbox[0], bbox[1]], [bbox[2], bbox[1]],
                                       units))
    cell_width = x_fraction * (bbox[2] - bbox[0])
    y_fraction = cell_size / (distance([bbox[0], bbox[1]], [bbox[0], bbox[3]],
                                       units))
    cell_height = y_fraction * (bbox[3] - bbox[1])

    xi = 0
    current_x = bbox[0]
    while current_x <= bbox[2]:
        yi = 0
        current_y = bbox[1]
        while current_y <= bbox[3]:
            if xi % 2 == 0 and yi % 2 == 0:
                fc["features"].append(
                    Polygon([[[current_x, current_y],
                              [current_x, current_y + cell_height],
                              [current_x + cell_width, current_y],
                              [current_x, current_y]]]),
                    Polygon(
                        [[[current_x, current_y + cell_height],
                          [current_x + cell_width, current_y + cell_height],
                          [current_x + cell_width, current_y],
                          [current_x, current_y + cell_height]]]))

            elif xi % 2 == 0 and yi % 2 == 1:
                fc["features"].append(
                    Polygon(
                        [[[current_x, current_y],
                          [current_x + cell_width, current_y + cell_height],
                          [current_x + cell_width, current_y],
                          [current_x, current_y]]]),
                    Polygon(
                        [[[current_x, current_y],
                          [current_x, current_y + cell_height],
                          [current_x + cell_width, current_y + cell_height],
                          [current_x, current_y]]]))

            elif yi % 2 == 0 and xi % 2 == 1:
                fc["feautres"].append(
                    Polygon(
                        [[[current_x, current_y],
                          [current_x, current_y + cell_height],
                          [current_x + cell_width, current_y + cell_height],
                          [current_x, current_y]]]),
                    Polygon(
                        [[[current_x, current_y],
                          [current_x + cell_width, current_y + cell_height],
                          [current_x + cell_width, current_y],
                          [current_x, current_y]]]))

            elif yi % 2 == 1 and xi % 2 == 1:
                fc["feautres"].append(
                    Polygon([[[current_x, current_y],
                              [current_x, current_y + cell_height],
                              [current_x + cell_width, current_y],
                              [current_x, current_y]]]),
                    Polygon(
                        [[[current_x, current_y + cell_height],
                          [current_x + cell_width, current_y + cell_height],
                          [current_x + cell_width, current_y],
                          [current_x, current_y + cell_height]]]))

            current_y += cell_height
            yi += 1

        xi += 1
        current_x += cell_width
    return fc
コード例 #12
0
def point_on_surface(feature_collection):
    # normalize
    if feature_collection.type != "FeatureCollection":
        if feature_collection.type != "Feature":
            feature_collection = Feature(feature_collection)
        feature_collection = FeatureCollection([feature_collection])

    # get centroid
    cent = centroid(feature_collection)

    # check to see if centroid is on surface
    on_surface = False
    i = 0
    while not on_surface and i < len(feature_collection["features"]):
        geom = feature_collection["features"][i]["geometry"]
        
        on_line = False
        if geom["type"] == "Point":
            if cent["geometry"]["coordinates"][0] == geom["coordinates"][0] and \
               cent["geometry"]["coordinates"][1] == geom["coordinates"][1]:
                on_surface = True
        elif geom["type"] == "MultiPoint":
            on_multi_point = False
            k = 0
            while not on_multi_point and k < len(geom["coordinates"]):
                if cent["geometry"]["coordinates"][0] == geom["coordinates"][k][0] and \
                   cent["geometry"]["coordinates"][1] == geom["coordinates"][k][1]:
                    on_surface = True
                    on_multi_point = True
                k += 1
        elif geom["type"] == "LineString":
            k = 0
            while not on_line and k < len(geom["coordinates"]) - 1:
                x = cent["geometry"]["coordinates"][0]
                y = cent["geometry"]["coordinates"][1]
                x1 = geom["coordinates"][k][0]
                y1 = geom["coordinates"][k][1]
                x2 = geom["coordinates"][k + 1][0]
                y2 = geom["coordinates"][k + 1][1]
                if point_on_segment(x, y, x1, y1, x2, y2):
                    on_line = True
                    on_surface = True
                k += 1
        elif geom["type"] == "MultiLineString":
            j = 0
            while j < len(geom["coordinates"]):
                on_line = False
                k = 0
                line = geom["coordinates"][j]
                while not on_line and k < len(line) - 1:
                    x = cent["geometry"]["coordinates"][0]
                    y = cent["geometry"]["coordinates"][1]
                    x1 = line[k][0]
                    y1 = line[k][1]
                    x2 = line[k + 1][0]
                    y2 = line[k + 1][1]
                    if point_on_segment(x, y, x1, y1, x2, y2):
                        on_line = True
                        on_surface = True
                    k += 1
                j += 1
        elif geom["type"] == "Polygon" or geom["type"] == "MultiPolygon":
            f = Feature(geom)
            if inside(cent, f):
                on_surface = True
        i += 1
    if on_surface:
        return cent
    else:
        vertices = FeatureCollection([])
        for i in range(len(feature_collection["features"])):
            vertices.features = \
                vertices["features"] + \
                explode(feature_collection["features"][i])["features"]
        closest_distance = float("inf")
        for i in range(len(vertices["feautres"])):
            dist = distance(cent, vertices["features"][i], "miles")
            if dist < closest_distance:
                closest_distance = dist
                closest_vertex = vertices.features[i]
        return closest_vertex