def distance_segment_to_segment(f1, f2, t1, t2): """Distance between segments. If no intersection within range, simplified to distance from f2 to [t1,t2]. :param f1: From :param f2: :param t1: To :param t2: :return: (distance, proj on f, proj on t, rel pos on t) """ # TODO: Should be improved f1_gp = frame.GeoPoint(f1[0], f1[1], degrees=True) f2_gp = frame.GeoPoint(f2[0], f2[1], degrees=True) path_f = nv.GeoPath(f1_gp, f2_gp) t1_gp = frame.GeoPoint(t1[0], t1[1], degrees=True) t2_gp = frame.GeoPoint(t2[0], t2[1], degrees=True) path_t = nv.GeoPath(t1_gp, t2_gp) p_int = path_f.intersect(path_t) p_int_gp = p_int.to_geo_point() if path_f.on_path(p_int)[0] and path_t.on_path(p_int)[0]: # Intersection point is on segments, between both begins and ends loc = (p_int_gp.latitude_deg[0], p_int_gp.longitude_deg[0]) u_f = distance_gp(f1_gp, p_int_gp) / distance_gp(f1_gp, f2_gp) u_t = distance_gp(t1_gp, p_int_gp) / distance_gp(t1_gp, t2_gp) return 0, loc, loc, u_f, u_t # No intersection, use last point of map segment (the assumption is the observations are far apart) # TODO: decide which point to use (see distance_segment_to_segment) p_int, u_t = _project_nvector(t1_gp, t2_gp, f2_gp) u_f = 1 d, _, _ = f2_gp.distance_and_azimuth(p_int) return d, (f1, f2), (p_int_gp.latitude_deg[0], p_int_gp.longitude_deg[0]), u_f, u_t
def intersection_point(a1, a2, b1, b2): frame = nv.FrameE(a=EARTH_RADIUS, f=0) pointA1 = frame.GeoPoint(a1[0], a1[1], degrees=True) pointA2 = frame.GeoPoint(a2[0], a2[1], degrees=True) pointB1 = frame.GeoPoint(b1[0], b1[1], degrees=True) pointB2 = frame.GeoPoint(b2[0], b2[1], degrees=True) pathA = nv.GeoPath(pointA1, pointA2) pathB = nv.GeoPath(pointB1, pointB2) ipoint = pathA.intersect(pathB).to_geo_point() return float(ipoint.latitude_deg[0]), float(ipoint.longitude_deg[0])
def test_geo_path_on_path(lat_a, lat_b, method): wgs84 = FrameE(name='WGS84') point_a = wgs84.GeoPoint(latitude=lat_a, longitude=0, degrees=True) point_b = wgs84.GeoPoint(latitude=lat_b, longitude=0, degrees=True) point_c = wgs84.GeoPoint(latitude=0.5 * (lat_a + lat_b), longitude=0, degrees=True) path = nv.GeoPath(point_a, point_b) for point in [point_a, point_b, point_c]: assert path.on_path(point, method=method) point_a1 = wgs84.GeoPoint(latitude=lat_a, longitude=1e-6, degrees=True) point_b1 = wgs84.GeoPoint(latitude=lat_b, longitude=1e-6, degrees=True) for point in [point_a1, point_b1]: assert not path.on_path(point, method=method) tol = 1e-10 lat_e, lat_f = (lat_a - tol, lat_b + tol) if lat_a < lat_b else (lat_a + tol, lat_b - tol) point_e = wgs84.GeoPoint(latitude=lat_e, longitude=0, degrees=True) point_f = wgs84.GeoPoint(latitude=lat_f, longitude=0, degrees=True) for point in [point_e, point_f]: assert not path.on_path(point, method=method)
def calc_dist( alt1, lat1, lon1, alt2, lat2, lon2, ): import nvector as nv wgs84 = nv.FrameE(name='WGS84') pt1 = wgs84.GeoPoint(latitude=lat1, longitude=lon1, z=alt1, degrees=True) pt2 = wgs84.GeoPoint(latitude=lat2, longitude=lon2, z=alt2, degrees=True) # Great circle dist # dist_gc = np.sqrt(np.sum(pt1.delta_to(pt2).pvector ** 2)) / 1E3 # Straight-line dist dist_strt = np.sqrt( np.sum((pt1.to_ecef_vector().pvector - pt2.to_ecef_vector().pvector)** 2)) / 1E3 # midpoint between the two midpt = nv.GeoPath(pt1, pt2).interpolate(0.5).to_geo_point() midpt_ll = [midpt.latitude, midpt.longitude] # dist. from straight-line midpoint up to ground level hypot = np.sqrt( np.sum((pt1.to_ecef_vector().pvector - midpt.to_ecef_vector().pvector) **2)) / 1E3 midpt_depth = np.sqrt(hypot**2 - (dist_strt / 2)**2) return dist_strt, midpt_depth
def extrap_edge(edge_line, near_line, far_line): """Extrapolate points to edges of grid.""" for edge, near, far in np.nditer([edge_line, near_line, far_line], flags=['refs_ok'], op_flags=op_flags): path = nv.GeoPath(far[()], near[()]) edge[()] = path.interpolate(2.)
def distance_to_line(cls, p0, p1, p2, latlong=True): """ Compute nearest distance between point p0 and line defined by points (p1, p2). Args: p0, p1 p2 - (tuple[2](float)) Coordinates latlong - True for lat-long system Return: (float) distance in meters """ if latlong: idx_lat, idx_long = 0, 1 else: idx_lat, idx_long = 1, 0 # If p1 == p2, then just point distance p1a, p2a = np.asarray(p1), np.asarray(p2) if np.allclose(p1a, p2a): return cls.compute_coordinate_distance(p0, p1, latlong) # Build up sphere line and compute distance point1 = cls.__wgs84.GeoPoint(p1[idx_lat], p1[idx_long], degrees=True) point2 = cls.__wgs84.GeoPoint(p2[idx_lat], p2[idx_long], degrees=True) point0 = cls.__wgs84.GeoPoint(p0[idx_lat], p0[idx_long], degrees=True) path_line = nv.GeoPath(point1, point2) return path_line.cross_track_distance(point0).ravel()
def area(self): base = nvector.GeoPath(self.corner1, self.corner2) base_length = abs(base.track_distance(method='greatcircle').ravel()[0]) height = abs( base.cross_track_distance(self.corner3, method='greatcircle').ravel()[0]) area = 0.5 * height * base_length / 1000 / 1000 return area
def _project_nvector(s1, s2, p, delta=0.0): path = nv.GeoPath(s1, s2) p_intr = _cross_track_point(path, p) pin = p_intr.to_nvector().normal s1n = s1.to_nvector().normal s2n = s2.to_nvector().normal ti = np.linalg.norm(pin - s1n) / np.linalg.norm(s2n - s1n) ti = max(delta, min(1 - delta, ti)) return path.interpolate(ti).to_geo_point(), ti
def crosstrack_distance(a1, a2, b): frame = nv.FrameE(a=EARTH_RADIUS, f=0) pointA1 = frame.GeoPoint(a1[0], a1[1], degrees=True) pointA2 = frame.GeoPoint(a2[0], a2[1], degrees=True) pointB = frame.GeoPoint(b[0], b[1], degrees=True) pathA = nv.GeoPath(pointA1, pointA2) cr_distance = pathA.cross_track_distance(pointB, method='greatcircle').ravel() return cr_distance[0]
def closest_point_on_circle(a1, a2, b): frame = nv.FrameE(a=EARTH_RADIUS, f=0) pointA1 = frame.GeoPoint(a1[0], a1[1], degrees=True) pointA2 = frame.GeoPoint(a2[0], a2[1], degrees=True) pointB = frame.GeoPoint(b[0], b[1], degrees=True) pathA = nv.GeoPath(pointA1, pointA2) closest_point = pathA.closest_point_on_great_circle(pointB).to_geo_point() lat, lon = closest_point.latitude_deg.tolist( )[0], closest_point.longitude_deg.tolist()[0] return lat, lon
def getMidpoint(location1, location2): # see http://nvector.readthedocs.org/en/latest/src/overview.html?highlight=midpoint#description nv_location1 = tuple2nvVector(location1) nv_location2 = tuple2nvVector(location2) path = nv.GeoPath(nv_location1, nv_location2) #halfway = 0.5 nv_midpoint = path.interpolate(0.5).to_geo_point() mid_lat, mid_lon = nv_midpoint.latlon_deg[:2] midpoint = (mid_lat[0], mid_lon[0]) return nv_midpoint
def position_on_path(a1, a2, b): frame = nv.FrameE(a=EARTH_RADIUS, f=0) pointA1 = frame.GeoPoint(a1[0], a1[1], degrees=True) pointA2 = frame.GeoPoint(a2[0], a2[1], degrees=True) pointB = frame.GeoPoint(b[0], b[1], degrees=True) pathA = nv.GeoPath(pointA1, pointA2) if pathA.on_great_circle(pointB): if pathA.on_path(pointB): return PositionOnPath.OnPath else: return PositionOnPath.NotOnPathOnCircle else: return PositionOnPath.NotOnCircle
def load_line(self, pointA, pointB): self.path = nvector.GeoPath(pointA, pointB) # Ick. This looks horrible. p_AB_E = nvector.diff_positions(pointA, pointB) frame_N = nvector.FrameN(pointA) p_AB_N = p_AB_E.change_frame(frame_N) p_AB_N = p_AB_N.pvector.ravel() azimuth = numpy.arctan2(p_AB_N[1], p_AB_N[0]) self.course = numpy.rad2deg(azimuth) % 360 #print 'azimuth:', azimuth, self.course self.course_distance = self.path.positionB.distance_and_azimuth(self.path.positionA)[0] self.offset = 0.0
def get_distance_from_boundaries(animal_position, perimeter): north_west_corner = perimeter['north_west_corner'] north_east_corner = perimeter['north_east_corner'] south_west_corner = perimeter['south_west_corner'] south_east_corner = perimeter['south_east_corner'] earth_radius = 6371e3 frame = nv.FrameE(a=earth_radius, f=0) # Convert the positions to the format used by the nvector library animal_geo_point = frame.GeoPoint(animal_position['latitude'], animal_position['longitude'], degrees=True) north_west_geo_point = frame.GeoPoint(north_west_corner['latitude'], north_west_corner['longitude'], degrees=True) north_east_geo_point = frame.GeoPoint(north_east_corner['latitude'], north_east_corner['longitude'], degrees=True) south_west_geo_point = frame.GeoPoint(south_west_corner['latitude'], south_west_corner['longitude'], degrees=True) south_east_geo_point = frame.GeoPoint(south_east_corner['latitude'], south_east_corner['longitude'], degrees=True) # Get the four boundaries west_boundary = nv.GeoPath(north_west_geo_point, south_west_geo_point) east_boundary = nv.GeoPath(north_east_geo_point, south_east_geo_point) north_boundary = nv.GeoPath(north_west_geo_point, north_east_geo_point) south_boundary = nv.GeoPath(south_west_geo_point, south_east_geo_point) # Caclulate the absolute distance of the animal from each of the four boundaries dist_to_west_boundary = abs((west_boundary.cross_track_distance(animal_geo_point, method='greatcircle').ravel())[0]) dist_to_east_boundary = abs((east_boundary.cross_track_distance(animal_geo_point, method='greatcircle').ravel())[0]) dist_to_north_boundary = abs((north_boundary.cross_track_distance(animal_geo_point, method='greatcircle').ravel())[0]) dist_to_south_boundary = abs((south_boundary.cross_track_distance(animal_geo_point, method='greatcircle').ravel())[0]) # Put the distances in a dictonary and return distance_to_boundaries = {} distance_to_boundaries['west'] = dist_to_west_boundary distance_to_boundaries['east'] = dist_to_east_boundary distance_to_boundaries['north'] = dist_to_north_boundary distance_to_boundaries['south'] = dist_to_south_boundary return distance_to_boundaries
def arc(poi1, poi2): points = [] frame_E = nv.FrameE(a=e_radius * 1000, f=0) gp1 = frame_E.GeoPoint(latitude=poi1.latitude, longitude=poi1.longitude, degrees=True) gp2 = frame_E.GeoPoint(latitude=poi2.latitude, longitude=poi2.longitude, degrees=True) distance, _azia, _azib = gp1.distance_and_azimuth(gp2) distance = max(1, int(distance / 50000)) path = nv.GeoPath(gp1, gp2) for i in range(0, distance + 1): geo = path.interpolate((1.0 / distance) * i).to_geo_point() points += [poi(geo.latitude_deg, geo.longitude_deg, 10)] return points
def targetHit(pellet, shot_destination, target): #conversion nv_target = tuple2nvLocation(target, False) nv_pellet = tuple2nvLocation(pellet, False) nv_shot_destination = tuple2nvLocation(shot_destination, False) #is the shot far enough? if nv_pellet.distance_and_azimuth( nv_target) < nv_pellet.distance_and_azimuth(nv_shot_destination): #path from pellet to shoot destination path = nv.GeoPath(nv_pellet, nv_shot_destination) #target distance to path target_offset = path.cross_track_distance(nv_target).ravel() #check if shot within tolerance if abs(target_offset) < 10: return True return False
def way_points_interp(location_block): lat_lon1 = location_block[0] lat_lon2 = location_block[1] n = location_block[2] wgs84 = nv.FrameE(name='WGS84') lat1, lon1 = lat_lon1 lat2, lon2 = lat_lon2 n_EB_E_t0 = wgs84.GeoPoint(lat1, lon1, degrees=True).to_nvector() n_EB_E_t1 = wgs84.GeoPoint(lat2, lon2, degrees=True).to_nvector() path = nv.GeoPath(n_EB_E_t0, n_EB_E_t1) interpolate_coor = [[lat1, lon1]] piece_fraction = 1 / n for n in range(n - 1): g_EB_E_ti = path.interpolate(piece_fraction * (n + 1)).to_geo_point() interpolate_coor.append( [g_EB_E_ti.latitude_deg[0], g_EB_E_ti.longitude_deg[0]] ) return interpolate_coor
def interpolate_path(path, dd): """ TODO: interplate time as third term :param path: (lat, lon) :param dd: Distance difference (meter) :return: """ path_new = [path[0]] for p1, p2 in zip(path, path[1:]): dist = distance(p1, p2) if dist > dd: s1 = frame.GeoPoint(p1[0], p1[1], degrees=True) s2 = frame.GeoPoint(p2[0], p2[1], degrees=True) segment = nv.GeoPath(s1, s2) dt = int(math.floor(dist / dd)) for dti in range(1, dt): p_new = segment.interpolate(dti / dt).to_geo_point() path_new.append( (p_new.latitude_deg[0], p_new.longitude_deg[0])) path_new.append(p2) return path_new
def dist_to_ref(probe_point, link_start): """Get the perpendicular distance from a point to a line determined by two points. Courtesy of example 5 from: https://pypi.python.org/pypi/nvector Args: probe_point (tuple): the lat,lon coordinates of the probe point link_start (tuple): the lat,lon coordinates of the link start link_end (tuple): the lat,lon coordinates of the link end Returns: The perpendicular distance (float) """ #frame = nv.FrameE(a=6371e3, f=0) #pointA1 = frame.GeoPoint(link_start[0], link_start[1], degrees=True) #pointA2 = frame.GeoPoint(link_end[0], link_end[1], degrees=True) #pointB = FRAME.GeoPoint(probe_point[0], probe_point[1], degrees=True) path = nv.GeoPath(probe_point, link_start) s_AB2 = path.track_distance(method='greatcircle').ravel() #d_to_ref, _, _ = link_start.distance_and_azimuth(probe_point) return abs(s_AB2[0])
def dist_to_link(probe_point, link_start, link_end): """Get the perpendicular distance from a point to a line determined by two points. Courtesy of example 10 from: https://pypi.python.org/pypi/nvector Args: probe_point (tuple): the lat,lon coordinates of the probe point link_start (tuple): the lat,lon coordinates of the link start link_end (tuple): the lat,lon coordinates of the link end Returns: The perpendicular distance (float) """ #frame = nv.FrameE(a=6371e3, f=0) #pointA1 = frame.GeoPoint(link_start[0], link_start[1], degrees=True) #pointA2 = frame.GeoPoint(link_end[0], link_end[1], degrees=True) #pointB = FRAME.GeoPoint(probe_point[0], probe_point[1], degrees=True) pathA = nv.GeoPath(link_start, link_end) s_xt = pathA.cross_track_distance(probe_point, method='greatcircle').ravel() return abs(s_xt[0])
def nearest_point_on_line(cls, p0, p1, p2, lat_long=True): """ Compute nearest point on line defined by points (p1, p2) from point p0 Args: p0, p1, p2 - (tuple[2](float)) Coordinates. lat_long - (bool) Whether it's lat-long system Return: (tuple[2](float)) Lat-long coordinate of nearest point. """ if lat_long: idx_lat, idx_long = 0, 1 else: idx_lat, idx_long = 1, 0 point1 = cls.__wgs84.GeoPoint(p1[idx_lat], p1[idx_long], degrees=True) point2 = cls.__wgs84.GeoPoint(p2[idx_lat], p2[idx_long], degrees=True) point0 = cls.__wgs84.GeoPoint(p0[idx_lat], p0[idx_long], degrees=True) path_line = nv.GeoPath(point1, point2) result = path_line.closest_point_on_great_circle(point0).latlon_deg return (result[0][0], result[1][0])
def center_from_opposite_trap(self, opposite_trap_center): orthogonal_path = nvector.GeoPath(self.trap_center, opposite_trap_center) self.center = orthogonal_path.interpolate(-0.5).to_geo_point()
data = [] for j in range(len(wq)): # get water test point p1 = frame.GeoPoint(wq.iloc[j]['lat'], wq.iloc[j]['lng'], degrees=True) for i in range(len(cip)): # get main replacement path l1 = frame.GeoPoint(cip.iloc[i]['from_lat'], cip.iloc[i]['from_lng'], degrees=True) l2 = frame.GeoPoint(cip.iloc[i]['to_lat'], cip.iloc[i]['to_lng'], degrees=True) path = nv.GeoPath(l1, l2) # calculate distance d = path.cross_track_distance(p1, method='greatcircle').ravel() if np.abs(d[0]) <= MAX_DISTANCE: p2 = path.closest_point_on_great_circle(p1) # check if on path, append and break (only line per water test) if path.on_path(p2)[0]: data.append({ 'p1_lat': p1.latitude_deg, 'p1_lng': p1.longitude_deg, 'p2_lat': p2.latitude_deg[0],
def extrap_corner(horz_near, horz_far, vert_near, vert_far): """Extrapolate grid corners to the edges of the grid.""" horz_path = nv.GeoPath(horz_far, horz_near) vert_path = nv.GeoPath(vert_far, vert_near) return horz_path.intersection(vert_path).to_nvector()
def find_path(self): self.path = nvector.GeoPath(self.point_a, self.point_b) return self.path
def center_from_adjacent_trap(self, adjacent_trap_center): # Center of the divider orthogonal_path = nvector.GeoPath(self.trap_center, adjacent_trap_center) self.center = orthogonal_path.interpolate(0.5).to_geo_point()
def extrap_corner(horz_near, horz_far, vert_near, vert_far): horz_path = nv.GeoPath(horz_far, horz_near) vert_path = nv.GeoPath(vert_far, vert_near) return horz_path.intersection(vert_path).to_nvector()
zoom = 1 self.ax.set_xlim([-self.radius / zoom, self.radius / zoom]) self.ax.set_ylim([-self.radius / zoom, self.radius / zoom]) self.ax.set_zlim([-self.radius / zoom, self.radius / zoom]) def save_fig(self, filename): self.ax.set_aspect('equal') self.ax.axis('off') plt.savefig(filename, dpi=300) def show(self): plt.show() if __name__ == '__main__': import nvector a = nvector.GeoPoint(10, 10, degrees=True) b = nvector.GeoPoint(20, 20, degrees=True) path = nvector.GeoPath(a, b) xs = [] ys = [] zs = [] n_steps = 5 for step in range(n_steps + 1): pvector = path.interpolate(step / n_steps).to_ecef_vector().pvector xs.append(pvector[0][0]) ys.append(pvector[1][0]) zs.append(pvector[2][0]) plt = SpherePlot(radius=10)
def find_center(self): path = nvector.GeoPath(self.base1.center, self.base2.center) self.center = path.interpolate(0.5).to_geo_point()