Exemple #1
0
def fish_distance(point1,point2):
    """
    Returns the shortest distance around land (see the Land model) between the two points.  Returns the distance in miles and
    the geos linestring that represents the path.
    
    NOTE: I'm assuming that the native units of the points and line is meters.  This is true for the MLPA project but may
    not be true for other processes.
    """
    # This is the straight line between the two points
    line = geos.LineString(point1,point2)
    
    # See if the straight line crosses land
    if line_crosses_land(line): 
        # The straight line cut across land so we have to do it the hard way.
        G = PickledGraph.objects.all()[0].graph
        G = add_points_to_graph([point1,point2],G)
        # G.add_nodes_from([point1,point2])
        # G = add_ocean_edges_for_node(G,get_node_from_point(G,point1))
        # G = add_ocean_edges_for_node(G,get_node_from_point(G,point2))
        # Replace the straight line with the shortest path around land
        line = geos.LineString( nx.dijkstra_path(G,get_node_from_point(G,point1),get_node_from_point(G,point2)) )
        line.srid = settings.GEOMETRY_DB_SRID
    
    # Figure out the distance of the line (straight or otherwise) in miles
    distance = length_in_display_units(line)
    return distance, line
Exemple #2
0
def distance_row_list(from_pnt, to_list):
    """
    NOTE: This method assumes that the projection units are meters.
    """
    result = []
    for point in to_list:
        result.append(length_in_display_units(point.distance(from_pnt)))
    return result
Exemple #3
0
def distance_row_dict(from_dict, to_dict):
    """
    from_dict will be a dict with a point as the key and a label as the value.
    to_dict will be of the same format with multiple entries.
    will return a dictionary with points as keys and a dictionary as values.
    NOTE: This method assumes that the projection units are meters.
    """
    from_pnt = from_dict.keys()[0]
    for s_pnt in SpacingPoint.objects.all():
        to_dict.update({s_pnt.geometry:s_pnt.name})
    result = {}
    for point, pnt_label in to_dict.iteritems():
        result[point] = {
            'label': pnt_label,
            'distance': length_in_display_units(point.distance(from_pnt)),
            'sort': point.y
        }
    return result
Exemple #4
0
def distance_row_dict(from_dict, to_dict):
    """
    from_dict will be a dict with a point as the key and a label as the value.
    to_dict will be of the same format with multiple entries.
    will return a dictionary with points as keys and a dictionary as values.
    NOTE: This method assumes that the projection units are meters.
    """
    from_pnt = from_dict.keys()[0]
    for s_pnt in SpacingPoint.objects.all():
        to_dict.update({s_pnt.geometry:s_pnt.name})
    result = {}
    for point, pnt_label in to_dict.iteritems():
        result[point] = {
            'label': pnt_label,
            'distance': length_in_display_units(point.distance(from_pnt)),
            'sort': point.y
        }
    return result
Exemple #5
0
def add_ocean_edges_complete(graph, verbose=False):
    if verbose:
        cnt = 1
        import time
        t0 = time.time()
        print "Starting at %s to add edges for %i nodes." % (time.asctime(time.localtime(t0)), graph.number_of_nodes() )
        edge_possibilities = graph.number_of_nodes() * (graph.number_of_nodes() -1)
        print "We'll have to look at somewhere around %i edge possibilities." % ( edge_possibilities )
        print "Node: ",
    for node in graph.nodes_iter():
        if verbose:
            print str(cnt) + ' ',
            cnt += 1
        for n in graph.nodes_iter():
            if node <> n:
                line = geos.LineString(node,n)
                if not line_crosses_land(line):
                    graph.add_edge(node,n,{'weight': length_in_display_units(node.distance(n))})
    if verbose:
        print "It took %i minutes to load %i edges." % ((time.time() - t0)/60, graph.number_of_edges() )
    return graph
Exemple #6
0
def fish_distance_from_edges(geom1,geom2):
    """
    
    """
    # Straight line between geoms
    line = shortest_line(geom1,geom2)
    
    # See if the line crosses land
    if line_crosses_land(line):
        # Get shortest centroid to centroid fish_distance line
        c_distance, c_line = fish_distance(geom1.centroid,geom2.centroid)
        # Replace the first point in the fish path with the point on geom1
        # that lies closest to the second point on the path.
        #print c_line[1]
        c_line[0] = closest_point(geom1, geos.Point( c_line.coords[1], srid=geom1.srid ) ).coords
        # Do the same for the last point in the path
        c_line[c_line.num_points - 1] = closest_point(geom2, geos.Point( c_line.coords[c_line.num_points - 2], srid=geom2.srid ) ).coords
        line = c_line
    # Adjust the distance
    distance = length_in_display_units(line)
    return distance, line
Exemple #7
0
def distance_row_list(from_pnt, to_list, straight_line=False, with_geom=False):
    """
    NOTE: This method assumes that the projection units are meters.  This should be changed.  Check out
    lingcod.unit_converter.models.  It's pretty easy to introspect the geometry for the srid and figure
    out the native units from that.  I'd fix it but this is my last week here before taking a big trip
    on a small boat.
    """
    result = []
    for point in to_list:
        point_pair_dict = {}
        if straight_line:
            point_pair_dict.update( {'distance': length_in_display_units(point.distance(from_pnt)) } )
            if with_geom:
                line = geos.LineString(point,from_pnt)
        else:
            distance, line = fish_distance_from_edges(from_pnt,point)
            point_pair_dict.update( {'distance': distance} )
        if with_geom:
            point_pair_dict.update( {'geometry': line} )
        result.append(point_pair_dict)
    return result
Exemple #8
0
def add_ocean_edges_for_node(graph, node):
    for n in graph:
        line = geos.LineString(node,n)
        if not line_crosses_land(line):
            graph.add_edge(node,n,{'weight': length_in_display_units(node.distance(n))})
    return graph