def gdlComp(self, lons_lats, km_pts=20):
        """
        Compute geodesic line

            lons_lats: input coordinates.
            (start longitude, start latitude, end longitude, end latitude)

            km_pts: compute one point each 20 km (default).

        """

        try:
            lon_1, lat_1, lon_2, lat_2 = lons_lats

            pygd = Geod(ellps='WGS84')

            res = pygd.inv(lon_1, lat_1, lon_2, lat_2)
            dist = res[2]

            pts  = int(math.ceil(dist) / (km_pts * 1000))

            coords = pygd.npts(lon_1, lat_1, lon_2, lat_2, pts)

            coords_se = [(lon_1, lat_1)] + coords
            coords_se.append((lon_2, lat_2))

            self.__logger.info("Geodesic line succesfully created!")
            self.__logger.info("Total points = {:,}".format(pts))
            self.__logger.info("{:,.4f} km".format(dist / 1000.))

            return coords_se

        except Exception as e:
            self.__logger.error("Error: {0}".format(e.message))
Exemplo n.º 2
0
    def caculate_line(self, startx, starty, endx, endy):
        geod = Geod(ellps="WGS84")
        forwardAngle, backwardAngle, distance = geod.inv(
            startx, starty, endx, endy)
        
        stationCount = math.floor(distance / self.courseline)

        wished_startx, wished_starty, tempAngle = geod.fwd(
            startx, starty, backwardAngle, self.courseline * self.courseExpand)


        print("wished start x,y:", wished_startx, wished_starty)

        wishedDistance = self.courseline * (stationCount + self.courseExpand * 2)
        wished_endx, wished_endy, tempAngle = geod.fwd(
            wished_startx, wished_starty, forwardAngle, wishedDistance)

        print("wished end x,y:", wished_endx, wished_endy)

        points = geod.npts(wished_startx, wished_starty, wished_endx,
                           wished_endy, stationCount + self.courseExpand * 2)



        results = []
        results.append((wished_startx, wished_starty))
        results.extend(points)
        results.append((wished_endx, wished_endy))

        self.courseAngle = forwardAngle

        print(results)

        return results, forwardAngle
Exemplo n.º 3
0
def calc_geod_pts(point1, point2, num_pts):
    """
    Calculates a number of points, num_pts, along a line defined by point1 & point2

    Parameters
    ----------
    point1 : tuple of floats
        First geographic coordinate pair
        Format: (lat, lon)
    point2 : tuple of floats
        Second geographic coordinate pair
        Format: (lat, lon)
    num_pts : int
        Number of coordinate pairs to calculate

    Returns
    -------
    Yields a tuple of floats
    Format: (lon, lat)
    """
    geod = Geod("+ellps=WGS84")
    points = geod.npts(lon1=point1[1],
                       lat1=point1[0],
                       lon2=point2[1],
                       lat2=point2[0],
                       npts=num_pts)

    for pt in points:
        yield pt
Exemplo n.º 4
0
 def build_great_circle(self, start_latlng, end_latlng, distance):
     num_points = int(distance / self.ARC_LENGTH_SPACING)
     geod = Geod(ellps='WGS84')
     start_lat, start_lon = start_latlng
     end_lat, end_lon = end_latlng
     lonlats = geod.npts(start_lon, start_lat, end_lon, end_lat, num_points)
     latlngs = util.swap_pairs(lonlats)
     return latlngs
Exemplo n.º 5
0
def greatcircle(
    lat1: float, lon1: float, lat2: float, lon2: float, *args, **kwargs
) -> List[Tuple[float, float]]:
    geod = Geod(ellps="WGS84")
    return [
        (lat, lon)
        for (lon, lat) in geod.npts(lon1, lat1, lon2, lat2, *args, **kwargs)
    ]
Exemplo n.º 6
0
def vertical_cross(in_field, lon, lat, line_points, npts=100):
    """
    Interpolate 2D or multiple dimensional grid data to vertical cross section.

    :param in_field: 2D or multiple dimensional grid data,
                     the rightest dimension [..., lat, lon].
    :param lon: grid data longitude.
    :param lat: grid data latitude.
    :param line_points: cross section line points,
                        should be [n_points, 2] array.
    :param npts: the point number of great circle line.
    :return: cross section [..., n_points], points
    """

    if np.ndim(in_field) < 2:
        raise ValueError("in_field must be at least 2 dimension")

    # reshape field to 3d array
    old_shape = in_field.shape
    if np.ndim(in_field) == 2:
        field = in_field.reshape(1, *old_shape)
    else:
        field = in_field.reshape(np.product(old_shape[0:-2]), *old_shape[-2:])

    # get great circle points
    points = None
    n_line_points = line_points.shape[0]
    geod = Geod("+ellps=WGS84")
    for i in range(n_line_points - 1):
        seg_points = geod.npts(lon1=line_points[i, 0],
                               lat1=line_points[i, 1],
                               lon2=line_points[i + 1, 0],
                               lat2=line_points[i + 1, 1],
                               npts=npts)
        if points is None:
            points = np.array(seg_points)
        else:
            points = np.vstack((points, np.array(seg_points)))

    # convert to pixel coordinates
    x = np.interp(points[:, 0], lon, np.arange(len(lon)))
    y = np.interp(points[:, 1], lat, np.arange(len(lat)))

    # loop every level
    zdata = []
    for i in range(field.shape[0]):
        zdata.append(
            ndimage.map_coordinates(np.transpose(field[i, :, :]),
                                    np.vstack((x, y))))

    # reshape zdata
    zdata = np.array(zdata)
    if np.ndim(in_field) > 2:
        zdata = zdata.reshape(np.append(old_shape[0:-2], points.shape[0]))

    # return vertical cross section
    return zdata, points
Exemplo n.º 7
0
def test_geod_inverse_transform():
    gg = Geod(ellps="clrk66")
    lat1pt = 42.0 + (15.0 / 60.0)
    lon1pt = -71.0 - (7.0 / 60.0)
    lat2pt = 45.0 + (31.0 / 60.0)
    lon2pt = -123.0 - (41.0 / 60.0)
    """
    distance between boston and portland, clrk66:
    -66.531 75.654  4164192.708
    distance between boston and portland, WGS84:
    -66.530 75.654  4164074.239
    testing pickling of Geod instance
    distance between boston and portland, clrk66 (from pickle):
    -66.531 75.654  4164192.708
    distance between boston and portland, WGS84 (from pickle):
    -66.530 75.654  4164074.239
    inverse transform
    from proj.4 invgeod:
    b'-66.531\t75.654\t4164192.708\n'

    """
    print("from pyproj.Geod.inv:")
    az12, az21, dist = gg.inv(lon1pt, lat1pt, lon2pt, lat2pt)
    assert_almost_equal((az12, az21, dist), (-66.531, 75.654, 4164192.708),
                        decimal=3)

    print("forward transform")
    print("from proj.4 geod:")
    endlon, endlat, backaz = gg.fwd(lon1pt, lat1pt, az12, dist)
    assert_almost_equal((endlon, endlat, backaz), (-123.683, 45.517, 75.654),
                        decimal=3)
    print("intermediate points:")
    print("from geod with +lat_1,+lon_1,+lat_2,+lon_2,+n_S:")
    npts = 4
    lonlats = gg.npts(lon1pt, lat1pt, lon2pt, lat2pt, npts)
    lonprev = lon1pt
    latprev = lat1pt
    print(dist / (npts + 1))
    print("%6.3f  %7.3f" % (lat1pt, lon1pt))
    result_dists = (
        (-66.53059478766238, 106.79071710136431, 832838.5416198927),
        (-73.20928289863558, 99.32289055927389, 832838.5416198935),
        (-80.67710944072617, 91.36325611787134, 832838.5416198947),
        (-88.63674388212858, 83.32809401477382, 832838.5416198922),
    )
    for (lon, lat), (res12, res21, resdist) in zip(lonlats, result_dists):
        az12, az21, dist = gg.inv(lonprev, latprev, lon, lat)
        assert_almost_equal((az12, az21, dist), (res12, res21, resdist))
        latprev = lat
        lonprev = lon
    az12, az21, dist = gg.inv(lonprev, latprev, lon2pt, lat2pt)
    assert_almost_equal((lat2pt, lon2pt, dist), (45.517, -123.683, 832838.542),
                        decimal=3)
Exemplo n.º 8
0
def test_geod_inverse_transform():
    gg = Geod(ellps="clrk66")
    lat1pt = 42.0 + (15.0 / 60.0)
    lon1pt = -71.0 - (7.0 / 60.0)
    lat2pt = 45.0 + (31.0 / 60.0)
    lon2pt = -123.0 - (41.0 / 60.0)
    """
    distance between boston and portland, clrk66:
    -66.531 75.654  4164192.708
    distance between boston and portland, WGS84:
    -66.530 75.654  4164074.239
    testing pickling of Geod instance
    distance between boston and portland, clrk66 (from pickle):
    -66.531 75.654  4164192.708
    distance between boston and portland, WGS84 (from pickle):
    -66.530 75.654  4164074.239
    inverse transform
    from proj.4 invgeod:
    b'-66.531\t75.654\t4164192.708\n'

    """
    print("from pyproj.Geod.inv:")
    az12, az21, dist = gg.inv(lon1pt, lat1pt, lon2pt, lat2pt)
    assert_almost_equal((az12, az21, dist), (-66.531, 75.654, 4164192.708), decimal=3)

    print("forward transform")
    print("from proj.4 geod:")
    endlon, endlat, backaz = gg.fwd(lon1pt, lat1pt, az12, dist)
    assert_almost_equal((endlon, endlat, backaz), (-123.683, 45.517, 75.654), decimal=3)
    print("intermediate points:")
    print("from geod with +lat_1,+lon_1,+lat_2,+lon_2,+n_S:")
    npts = 4
    lonlats = gg.npts(lon1pt, lat1pt, lon2pt, lat2pt, npts)
    lonprev = lon1pt
    latprev = lat1pt
    print(dist / (npts + 1))
    print("%6.3f  %7.3f" % (lat1pt, lon1pt))
    result_dists = (
        (-66.53059478766238, 106.79071710136431, 832838.5416198927),
        (-73.20928289863558, 99.32289055927389, 832838.5416198935),
        (-80.67710944072617, 91.36325611787134, 832838.5416198947),
        (-88.63674388212858, 83.32809401477382, 832838.5416198922),
    )
    for (lon, lat), (res12, res21, resdist) in zip(lonlats, result_dists):
        az12, az21, dist = gg.inv(lonprev, latprev, lon, lat)
        assert_almost_equal((az12, az21, dist), (res12, res21, resdist))
        latprev = lat
        lonprev = lon
    az12, az21, dist = gg.inv(lonprev, latprev, lon2pt, lat2pt)
    assert_almost_equal(
        (lat2pt, lon2pt, dist), (45.517, -123.683, 832838.542), decimal=3
    )
Exemplo n.º 9
0
def get_line(start, end):
    x1 = start[Location.X.value]
    y1 = start[Location.Y.value]

    x2 = end[Location.X.value]
    y2 = end[Location.Y.value]

    geod = Geod("+ellps=WGS84")
    points = geod.npts(x1, y1,
                       x2, y2,
                       npts=100)

    return points
Exemplo n.º 10
0
class GeodeticPath:
    """Calculate the geodetic path between two points using pyproj Geod"""
    def __init__(self, lon0, lat0, lon1, lat1, ellps='WGS84', radians=False):
        """Initialize with the start and stop points."""

        self.geod = Geod(ellps=ellps)

        self.lon0 = lon0
        self.lat0 = lat0
        self.lon1 = lon1
        self.lat1 = lat1

        # Get the forward and backward azimuths and distance between the two points

        self.azimuth0, self.back_azimuth1, self.distance = self.geod.inv(
            lon0, lat0, lon1, lat1)

    def get_path_lonlats(self, separation):
        """Get the latitude and longitude of the path points, given a point separation in meters."""

        self.npts = int(self.distance / separation + 0.5)
        self.lonlats = np.array(
            self.geod.npts(self.lon0, self.lat0, self.lon1, self.lat1,
                           self.npts))
        self.lon = self.lonlats[:, 0]
        self.lat = self.lonlats[:, 1]

    def get_path(self, separation=None):
        """Get the path latitude, longitude, heading, and distance.
        If separation is None, assume get_path_lon_lats has already been called."""

        if separation != None:
            self.get_path_lonlats(separation)

        # Declare heading and distance arrays

        self.heading = np.zeros(len(self.lat), dtype=self.lat.dtype)
        self.along_track_distance = np.zeros(len(self.lat),
                                             dtype=self.lat.dtype)

        for i in range(len(self.lat) - 1):
            self.heading[i], back_azimuth, d = self.geod.inv(
                self.lon[i], self.lat[i], self.lon[i + 1], self.lat[i + 1])
            self.along_track_distance[i + 1] = self.along_track_distance[i] + d

        if back_azimuth < 0:
            self.heading[-1] = 180 + back_azimuth
        else:
            self.heading[-1] = back_azimuth - 180.
Exemplo n.º 11
0
    def midpoint_utm(self,p1,p2):
        """
        calculates midpoint between 2 points on earths surface

        input: p1,p2   location in the form (lon,lat)
        return: m      midpoint in the form (lon,lat)
        """

        g = Geod(ellps='WGS84')
        l = g.npts(p1[0],p1[0],p1[1],p1[1],1)
        
        m = l[0]
        # print 'm: ', m
        
        return m
Exemplo n.º 12
0
    def midpoint_utm(self, p1, p2):
        """
        calculates midpoint between 2 points on earths surface

        input: p1,p2   location in the form (lon,lat)
        return: m      midpoint in the form (lon,lat)
        """

        g = Geod(ellps='WGS84')
        l = g.npts(p1[0], p1[0], p1[1], p1[1], 1)

        m = l[0]
        # print 'm: ', m

        return m
Exemplo n.º 13
0
def geodesic(crs, start, end, steps):
    r"""Construct a geodesic path between two points.

    This function acts as a wrapper for the geodesic construction available in `pyproj`.

    Parameters
    ----------
    crs: `cartopy.crs`
        Cartopy Coordinate Reference System to use for the output
    start: (2, ) array_like
        A latitude-longitude pair designating the start point of the geodesic (units are
        degrees north and degrees east).
    end: (2, ) array_like
        A latitude-longitude pair designating the end point of the geodesic (units are degrees
        north and degrees east).
    steps: int, optional
        The number of points along the geodesic between the start and the end point
        (including the end points).

    Returns
    -------
    `numpy.ndarray`
        The list of x, y points in the given CRS of length `steps` along the geodesic.

    See Also
    --------
    cross_section

    """
    import cartopy.crs as ccrs
    from pyproj import Geod

    # Geod.npts only gives points *in between* the start and end, and we want to include
    # the endpoints.
    g = Geod(crs.proj4_init)
    geodesic = np.concatenate([
        np.array(start[::-1])[None],
        np.array(g.npts(start[1], start[0], end[1], end[0], steps - 2)),
        np.array(end[::-1])[None]
    ]).transpose()
    points = crs.transform_points(ccrs.Geodetic(), *geodesic)[:, :2]

    return points
Exemplo n.º 14
0
def test_integrate(lat1, lon1, lat2, lon2):
    g = Geod(ellps='sphere')
    distance1 = g.inv(lon1, lat1, lon2, lat2)[2] / 1000.0
    points = g.npts(lon1, lat1, lon2, lat2, int(distance1) // 1)
    distance2 = 0
    distance3 = 0
    res = 0
    for i in range(len(points) - 1):
        lo1, la1, lo2, la2 = points[i] + points[i + 1]
        p1 = sphere2cartesian(90 - la1, 180 - lo1) * 6371
        p2 = sphere2cartesian(90 - la2, 180 - lo2) * 6371
        distance2 += np.linalg.norm(p1 - p2)
        az, baz, d = g.inv(lo1, la1, lo2, la2)
        distance3 += d
        res += abs(abs(az - baz) - 180)
    distance3 /= 1000.0
    res /= len(points)
    print(distance1, distance2, distance3)
    print(res)
Exemplo n.º 15
0
def ctr_generator(lons, lats, outfname, d = 10.):
    if lons.size != lats.size:
        raise ValueError('Size of longitude and latitude list must be the same')
    g           = Geod(ellps='WGS84')
    N           = lons.size
    lonlats     = []
    for i in range(N):
        lon1    = lons[i]
        lat1    = lats[i]
        if i < N-1:
            lon2    = lons[i+1]
            lat2    = lats[i+1]
        else:
            lon2    = lons[0]
            lat2    = lats[0]
        az, baz, dist   = g.inv(lon1, lat1, lon2, lat2)
        dist            = dist/1000.
        if d < dist:
            d               = dist/float(int(dist/d))
            Nd              = int(dist/d)
            lonlats         += [(lon1, lat1)]
            lonlats         += g.npts(lon1, lat1, lon2, lat2, npts=Nd-1)
        else:
            lonlats         += [(lon1, lat1)]
    with open(outfname, 'w') as fid:
        npts        = len(lonlats)
        fid.writelines('0. 0. \n')
        fid.writelines('%g \n' %npts)
        for lonlat in lonlats:
            if lonlat[0] < 0.:
                outlon  = lonlat[0]+360.
            else:
                outlon  = lonlat[0]
            outlat      = lonlat[1]
            fid.writelines('%g  %g\n' %(outlon, outlat))
        fid.writelines('%g \n' %npts)
        for i in range(npts):
            if i < npts-1:
                fid.writelines('%g  %g\n' %(i+1, i+2))
            else:
                fid.writelines('%g  %g\n' %(i+1, 1))
    def gdlComp(self, lons_lats, km_pts=20):
        """
        Compute geodesic line

            lons_lats: input coordinates.
            (start longitude, start latitude, end longitude, end latitude)

            km_pts: compute one point each 20 km (default).

        """

        try:
            lon_1, lat_1, lon_2, lat_2 = lons_lats

            pygd = Geod(ellps='WGS84')

            res = pygd.inv(lon_1, lat_1, lon_2, lat_2)
            dist = res[2]

            pts = int(math.ceil(dist) / (km_pts * 1000))

            coords = pygd.npts(lon_1, lat_1, lon_2, lat_2, pts)

            coords_se = [(lon_1, lat_1)] + coords
            coords_se.append((lon_2, lat_2))

            self.__distances.append({
                "id": len(self.__distances),
                "distance": dist,
                "coords": lons_lats
            })

            self.__logger.info("Geodesic line succesfully created!")
            self.__logger.info("Total points = {:,}".format(pts))
            self.__logger.info("{:,.4f} km".format(dist / 1000.))

            return coords_se

        except Exception as e:
            self.__logger.error("Error: {0}".format(e))
            raise ComputeGeodesicLineError(e)
Exemplo n.º 17
0
def get_gc_path(lon1,lat1,lon2,lat2,res):
	"""Calculate great circle paths for all station pairs
	Parameter:  lon1, lat1 -- longitude and latitude for the starting point
				lon2, lat2 -- longitude and latitude for the ending point
				res        -- resolution in km
	Return:     gc_path -- list containing longitudes and latitudes of points along the great circle
				dist    -- distance between the starting and ending points along the great circle
	"""
	g = Geod(ellps='WGS84')
	(az,baz,dist) = g.inv(lon1,lat1,lon2,lat2)
	dist /= 1000. # convert to km
	gc_path = g.npts(lon1,lat1,lon2,lat2,1+int(dist/res))
	gc_path.insert(0,(lon1,lat1))
	gc_path.append((lon2,lat2))
	gc_path_out = []
	for i in range(len(gc_path)):
		lon_out = gc_path[i][0]
		if lon_out < 0.:
			lon_out += 360.
		gc_path_out.append((lon_out, gc_path[i][1]))
	return gc_path_out,dist
Exemplo n.º 18
0
    def split_at_idl(self):
        """
        use when a line crosses the international dateline -> divides the line
        into two segments that meet at -180/180 degrees longitude
        """
        # discretize line along ellipsoid and find where it gets closest to idl
        g = Geod(ellps='sphere')
        lonlats = g.npts(self.plo[0], self.pla[0], self.plo[1], self.pla[1],
                         10000)
        modlons = numpy.array(lonlats)
        mdlo1 = abs(modlons[:, 0] - 180.)
        indlo1 = numpy.argmin(mdlo1)

        # create two lines/subsegments of original line that meet idl
        linplo1 = [-180., self.plo[0]]
        linpla1 = [lonlats[indlo1][1], self.pla[0]]
        linplo2 = [self.plo[1], 180]
        linpla2 = [self.pla[1], lonlats[indlo1][1]]
        line1 = Line([Point(lo, la) for lo, la in zip(linplo1, linpla1)])
        line2 = Line([Point(lo, la) for lo, la in zip(linplo2, linpla2)])

        return line1, line2, lonlats[indlo1][1]
Exemplo n.º 19
0
def parse_request():
    wktP1 = request.args.get('param1')
    wktP2 = request.args.get('param2')
    pointNum = request.args.get('param3')
    point1 = ogr.CreateGeometryFromWkt(wktP1)
    point2 = ogr.CreateGeometryFromWkt(wktP2)

    # print ("%d,%d" % (point1.GetX(), point1.GetY()))
    geoid = Geod(ellps="WGS84")
    extra_points = geoid.npts(point1.GetY(), point1.GetX(), point2.GetY(), point2.GetX(),  int(pointNum))
    list_of_lists = [list(elem) for elem in extra_points]
    # К extra_points надо добавить первую и последнюю точки, а то их там нет
    list_of_lists.insert(0, [point1.GetY(), point1.GetX()]);
    list_of_lists.append([point2.GetY(), point2.GetX()]);
    print (list_of_lists)

    for i in list_of_lists:
        f = i[0];
        i[0] = i[1];
        i[1] = f;
        print(i)

    return str(list_of_lists)
Exemplo n.º 20
0
def syn_ray(ray, model):
    """
    compute travel time along given ray
    :param ray: (lat1, lon1, lat2, lon2)
    :param model: function(lat, lon), return model
    :return: travel time, velocity
    """
    g = Geod(ellps='sphere')
    distance = g.inv(ray[1], ray[0], ray[3], ray[2])[2] / 1000.0
    points = g.npts(ray[1], ray[0], ray[3], ray[2], int(distance) // 1)
    time = 0
    for i in range(len(points) - 1):
        lo1, la1, lo2, la2 = points[i] + points[i + 1]
        az, baz, d = g.inv(lo1, la1, lo2, la2)
        d /= 1000.0
        if az < 0:
            az += 180
        phi = az * pi / 180
        m = model(la1, lo1)
        c = m[0]
        c += m[1] * cos(2*phi) + m[2] * sin(2*phi) +\
            m[3] * cos(4*phi) + m[4] * sin(4*phi)
        time += d / c
    return time, distance / time
Exemplo n.º 21
0
def greatcircle(lat1, lon1, lat2, lon2, *args, **kwargs):
    geod = Geod(ellps="WGS84")
    return geod.npts(lon1, lat1, lon2, lat2, *args, **kwargs)
Exemplo n.º 22
0
                )

                origLng, origLat = -transform(inProj, outProj, -180,
                                              0)[0], -transform(
                                                  inProj, outProj, 0, 90)[1]

                cc = 0
                for i in liens:
                    tmp = Image.new('RGBA', im.size, (0, 0, 0, 0))
                    cc += 1
                    g = Geod(ellps='WGS84')
                    startlong, startlat, endlong, endlat = -73.5673, 45.5017, i[
                        2], i[1]
                    (az12, az21, dist) = g.inv(startlong, startlat, endlong,
                                               endlat)
                    lonlats = g.npts(startlong, startlat, endlong, endlat,
                                     1 + int(dist / 50000))
                    lonlats.insert(0, (startlong, startlat))
                    lonlats.append((endlong, endlat))
                    c = 0
                    for ll in lonlats:
                        if c > 0:
                            x, y = transform(inProj, outProj, ll[0], ll[1])

                            x0C = int((x0 + origLng) * (w / (2 * origLng)))
                            y0C = int((y0 + origLat) * (h / (2 * origLat)))

                            xC = int((x + origLng) * (w / (2 * origLng)))
                            yC = int((y + origLat) * (h / (2 * origLat)))

                            if abs(x0C - xC) < 1633:
                                #				draw = ImageDraw.Draw(img, 'RGBA')
Exemplo n.º 23
0
az12,az21,dist = g.inv(lon1pt,lat1pt,lon2pt,lat2pt)
print "%7.3f %6.3f %12.3f" % (az12,az21,dist)
print 'forward transform'
print 'from proj.4 geod:'
print commands.getoutput('echo "42d15\'N 71d07\'W -66d31\'50.141 4164192.708" | geod +ellps=clrk66 -f "%.3f"')
endlon,endlat,backaz = g.fwd(lon1pt,lat1pt,az12,dist)
print 'from pyproj.Geod.fwd:'
print "%6.3f  %6.3f %13.3f" % (endlat,endlon,backaz)
print 'intermediate points:'
print 'from geod with +lat_1,+lon_1,+lat_2,+lon_2,+n_S:'
points = '+lon_1=%s +lat_1=%s +lon_2=%s +lat_2=%s' % (lon1pt,lat1pt,lon2pt,lat2pt,)
print points
print commands.getoutput('geod +ellps=clrk66 -f "%.3f" +n_S=5 '+points)
print 'from pyproj.Geod.npts:'
npts = 4
lonlats = g.npts(lon1pt,lat1pt,lon2pt,lat2pt,npts)
lonprev = lon1pt
latprev = lat1pt
print dist/(npts+1)
print '%6.3f  %7.3f' % (lat1pt, lon1pt)
for lon, lat in lonlats:
    az12,az21,dist = g.inv(lonprev,latprev,lon,lat)
    print '%6.3f  %7.3f %11.3f' % (lat, lon, dist)
    latprev = lat; lonprev = lon
az12,az21,dist = g.inv(lonprev,latprev,lon2pt,lat2pt)
print '%6.3f  %7.3f %11.3f' % (lat2pt, lon2pt, dist)

# specify the lat/lons of some cities.
boston_lat = 42.+(15./60.); boston_lon = -71.-(7./60.)
portland_lat = 45.+(31./60.); portland_lon = -123.-(41./60.)
newyork_lat = 40.+(47./60.); newyork_lon = -73.-(58./60.)
Exemplo n.º 24
0
def test_geod_inverse_transform():
    gg = Geod(ellps="clrk66")
    lat1pt = 42.0 + (15.0 / 60.0)
    lon1pt = -71.0 - (7.0 / 60.0)
    lat2pt = 45.0 + (31.0 / 60.0)
    lon2pt = -123.0 - (41.0 / 60.0)
    """
    distance between boston and portland, clrk66:
    -66.531 75.654  4164192.708
    distance between boston and portland, WGS84:
    -66.530 75.654  4164074.239
    testing pickling of Geod instance
    distance between boston and portland, clrk66 (from pickle):
    -66.531 75.654  4164192.708
    distance between boston and portland, WGS84 (from pickle):
    -66.530 75.654  4164074.239
    inverse transform
    from proj.4 invgeod:
    b'-66.531\t75.654\t4164192.708\n'

    """
    true_az12 = -66.5305947876623
    true_az21 = 75.65363415556968
    print("from pyproj.Geod.inv:")
    az12, az21, dist = gg.inv(lon1pt, lat1pt, lon2pt, lat2pt)
    assert_almost_equal((az12, az21, dist),
                        (true_az12, true_az21, 4164192.708),
                        decimal=3)

    print("forward transform")
    print("from proj.4 geod:")
    endlon, endlat, backaz = gg.fwd(lon1pt, lat1pt, az12, dist)
    assert_almost_equal((endlon, endlat, backaz), (lon2pt, lat2pt, true_az21),
                        decimal=3)

    inc_exc = ["excluding", "including"]
    res_az12_az21_dists_all = [
        (180.0, 0.0, 0.0),
        (-66.53059478766238, 106.79071710136431, 832838.5416198927),
        (-73.20928289863558, 99.32289055927389, 832838.5416198935),
        (-80.67710944072617, 91.36325611787134, 832838.5416198947),
        (-88.63674388212858, 83.32809401477382, 832838.5416198922),
        (-96.67190598522616, 75.65363415556973, 832838.5416198926),
    ]
    point_count = len(res_az12_az21_dists_all)
    for include_initial, include_terminus in itertools.product((False, True),
                                                               (False, True)):
        initial_idx = int(not include_initial)
        terminus_idx = int(not include_terminus)

        npts = point_count - initial_idx - terminus_idx
        print("intermediate points:")
        print("from geod with +lat_1,+lon_1,+lat_2,+lon_2,+n_S:")
        print(
            f"{lat1pt:6.3f} {lon1pt:7.3f} {lat2pt:6.3f} {lon2pt:7.3f} {npts}")

        lonlats = gg.npts(
            lon1pt,
            lat1pt,
            lon2pt,
            lat2pt,
            npts,
            initial_idx=initial_idx,
            terminus_idx=terminus_idx,
        )
        assert len(lonlats) == npts

        npts1 = npts + initial_idx + terminus_idx - 1
        del_s = dist / npts1
        print(
            f"Total distnace is {dist}, "
            f"Points count: {npts}, "
            f"{inc_exc[include_initial]} initial point, "
            f"{inc_exc[include_terminus]} terminus point. "
            f"The distance between successive points is {dist}/{npts1} = {del_s}"
        )

        from_idx = initial_idx
        to_idx = point_count - terminus_idx
        res_az12_az21_dists = res_az12_az21_dists_all[from_idx:to_idx]

        lonprev = lon1pt
        latprev = lat1pt
        for (lon, lat), (res12, res21, resdist) in zip(lonlats,
                                                       res_az12_az21_dists):
            o_az12, o_az21, o_dist = gg.inv(lonprev, latprev, lon, lat)
            if resdist == 0:
                assert_almost_equal(o_dist, 0)
            else:
                assert_almost_equal((o_az12, o_az21, o_dist),
                                    (res12, res21, resdist))
            latprev = lat
            lonprev = lon
        if not include_terminus:
            o_az12, o_az21, o_dist = gg.inv(lonprev, latprev, lon2pt, lat2pt)
            assert_almost_equal((lat2pt, lon2pt, o_dist),
                                (45.517, -123.683, 832838.542),
                                decimal=3)

        if include_initial and include_terminus:
            lons, lats, azis12, azis21, dists = np.hstack(
                (lonlats, res_az12_az21_dists)).transpose()

    del_s = dist / (point_count - 1)
    lons_a = np.empty(point_count)
    lats_a = np.empty(point_count)
    azis_a = np.empty(point_count)

    print("test inv_intermediate (by npts) with azi output")
    res = gg.inv_intermediate(
        out_lons=lons_a,
        out_lats=lats_a,
        out_azis=azis_a,
        lon1=lon1pt,
        lat1=lat1pt,
        lon2=lon2pt,
        lat2=lat2pt,
        npts=point_count,
        initial_idx=0,
        terminus_idx=0,
    )
    assert res.npts == point_count
    assert_almost_equal(res.del_s, del_s)
    assert_almost_equal(res.dist, dist)
    assert_almost_equal(res.lons, lons)
    assert_almost_equal(res.lats, lats)
    assert_almost_equal(res.azis[:-1], azis12[1:])
    assert res.lons is lons_a
    assert res.lats is lats_a
    assert res.azis is azis_a

    for flags in (GeodIntermediateFlag.AZIS_DISCARD,
                  GeodIntermediateFlag.AZIS_KEEP):
        print("test inv_intermediate (by npts) without azi output, no buffers")
        res = gg.inv_intermediate(
            lon1=lon1pt,
            lat1=lat1pt,
            lon2=lon2pt,
            lat2=lat2pt,
            npts=point_count,
            initial_idx=0,
            terminus_idx=0,
            flags=flags,
        )
        assert res.npts == point_count
        assert_almost_equal(res.del_s, del_s)
        assert_almost_equal(res.dist, dist)
        assert_almost_equal(res.lons, lons_a)
        assert_almost_equal(res.lats, lats_a)
        if flags == GeodIntermediateFlag.AZIS_DISCARD:
            assert res.azis is None
        else:
            assert_almost_equal(res.azis, azis_a)

        lons_b = np.empty(point_count)
        lats_b = np.empty(point_count)
        azis_b = np.empty(point_count)

        print("test inv_intermediate (by npts) without azi output")
        res = gg.inv_intermediate(
            out_lons=lons_b,
            out_lats=lats_b,
            out_azis=None,
            lon1=lon1pt,
            lat1=lat1pt,
            lon2=lon2pt,
            lat2=lat2pt,
            npts=point_count,
            initial_idx=0,
            terminus_idx=0,
            flags=flags,
        )
        assert res.npts == point_count
        assert_almost_equal(res.del_s, del_s)
        assert_almost_equal(res.dist, dist)
        assert_almost_equal(res.lons, lons_a)
        assert_almost_equal(res.lats, lats_a)
        assert res.lons is lons_b
        assert res.lats is lats_b
        if flags == GeodIntermediateFlag.AZIS_DISCARD:
            assert res.azis is None
        else:
            assert_almost_equal(res.azis, azis_a)

    print("test fwd_intermediate")
    res = gg.fwd_intermediate(
        out_lons=lons_b,
        out_lats=lats_b,
        out_azis=azis_b,
        lon1=lon1pt,
        lat1=lat1pt,
        azi1=true_az12,
        npts=point_count,
        del_s=del_s,
        initial_idx=0,
        terminus_idx=0,
    )
    assert res.npts == point_count
    assert_almost_equal(res.del_s, del_s)
    assert_almost_equal(res.dist, dist)
    assert_almost_equal(res.lons, lons_a)
    assert_almost_equal(res.lats, lats_a)
    assert_almost_equal(res.azis, azis_a)
    assert res.lons is lons_b
    assert res.lats is lats_b
    assert res.azis is azis_b

    print("test inv_intermediate (by del_s)")
    for del_s_fact, flags in (
        (1, GeodIntermediateFlag.NPTS_ROUND),
        ((point_count - 0.5) / point_count, GeodIntermediateFlag.NPTS_TRUNC),
        ((point_count + 0.5) / point_count, GeodIntermediateFlag.NPTS_CEIL),
    ):
        res = gg.inv_intermediate(
            out_lons=lons_b,
            out_lats=lats_b,
            out_azis=azis_b,
            lon1=lon1pt,
            lat1=lat1pt,
            lon2=lon2pt,
            lat2=lat2pt,
            del_s=del_s * del_s_fact,
            initial_idx=0,
            terminus_idx=0,
            flags=flags,
        )
        assert res.npts == point_count
        assert_almost_equal(res.del_s, del_s)
        assert_almost_equal(res.dist, dist)
        assert_almost_equal(res.lons, lons_a)
        assert_almost_equal(res.lats, lats_a)
        assert_almost_equal(res.azis, azis_a)
        assert res.lons is lons_b
        assert res.lats is lats_b
        assert res.azis is azis_b
Exemplo n.º 25
0
class TestRadians(unittest.TestCase):
    """Tests issue #84"""
    def setUp(self):
        self.g = Geod(ellps='clrk66')
        self.boston_d = (-71. - (7. / 60.), 42. + (15. / 60.))
        self.boston_r = (math.radians(self.boston_d[0]), math.radians(self.boston_d[1]))
        self.portland_d = (-123. - (41. / 60.), 45. + (31. / 60.))
        self.portland_r = (math.radians(self.portland_d[0]), math.radians(self.portland_d[1]))

    def test_inv_radians(self):

        # Get bearings and distance from Boston to Portland in degrees
        az12_d, az21_d, dist_d = self.g.inv(
            self.boston_d[0],
            self.boston_d[1],
            self.portland_d[0],
            self.portland_d[1],
            radians=False)

        # Get bearings and distance from Boston to Portland in radians
        az12_r, az21_r, dist_r = self.g.inv(
            self.boston_r[0],
            self.boston_r[1],
            self.portland_r[0],
            self.portland_r[1],
            radians=True)

        # Check they are equal
        self.assertAlmostEqual(az12_d, math.degrees(az12_r))
        self.assertAlmostEqual(az21_d, math.degrees(az21_r))
        self.assertAlmostEqual(dist_d, dist_r)

    def test_fwd_radians(self):
        # Get bearing and distance to Portland
        az12_d, az21_d, dist = self.g.inv(
            self.boston_d[0],
            self.boston_d[1],
            self.portland_d[0],
            self.portland_d[1],
            radians=False)

        # Calculate Portland's lon/lat from bearing and distance in degrees
        endlon_d, endlat_d, backaz_d = self.g.fwd(
            self.boston_d[0],
            self.boston_d[1],
            az12_d,
            dist,
            radians=False)

        # Calculate Portland's lon/lat from bearing and distance in radians
        endlon_r, endlat_r, backaz_r = self.g.fwd(
            self.boston_r[0],
            self.boston_r[1],
            math.radians(az12_d),
            dist,
            radians=True)

        # Check they are equal
        self.assertAlmostEqual(endlon_d, math.degrees(endlon_r))
        self.assertAlmostEqual(endlat_d, math.degrees(endlat_r))
        self.assertAlmostEqual(backaz_d, math.degrees(backaz_r))

        # Check to make sure we're back in Portland
        self.assertAlmostEqual(endlon_d, self.portland_d[0])
        self.assertAlmostEqual(endlat_d, self.portland_d[1])

    def test_npts_radians(self):
        # Calculate 10 points between Boston and Portland in degrees
        points_d = self.g.npts(
            lon1=self.boston_d[0],
            lat1=self.boston_d[1],
            lon2=self.portland_d[0],
            lat2=self.portland_d[1],
            npts=10,
            radians=False)

        # Calculate 10 points between Boston and Portland in radians
        points_r = self.g.npts(
            lon1=self.boston_r[0],
            lat1=self.boston_r[1],
            lon2=self.portland_r[0],
            lat2=self.portland_r[1],
            npts=10,
            radians=True)

        # Check they are equal
        for index, dpoint in enumerate(points_d):
            self.assertAlmostEqual(dpoint[0], math.degrees(points_r[index][0]))
            self.assertAlmostEqual(dpoint[1], math.degrees(points_r[index][1]))
Exemplo n.º 26
0
class GCMapper:
    def __init__(self, width=800,
            height=None, bgcol=DEFAULT_BG, proj='eqc',
            cols=DEFAULT_COLS, line_width=1, gc_resolution=100):
        '''
        Create an object for turning coordinate pairs into an image.

        Parameters
            height          the height of the resultant image
            width           the width of the resultant image
            bgcol           the background color of the image,
                            as an (r,g,b) triple
            proj            the projection name as a string (passed to
                            pyproj)
            cols            a function which takes one fractional
                            argument and returns a color (r,g,b) triple
            line_width      the width of lines drawn
            gc_resolution   the number of straight line segments
                            used to approximate each great-circle
                            curve

        Once the object is initialized, call set_data to add data.
        '''

        if height is None:
            height = width / 2

        self.height = height
        self.width = width
        self.bgcol = bgcol
        self.proj = proj
        self.line_width = line_width
        self.gc_resolution = gc_resolution
        self.cols = cols
        self.geo = Geod(a=1)

    def set_data(self, lon1, lat1, lon2, lat2, count=None):
        '''
        Set the coordinate pairs to be drawn. The pairs are given
        as equal-length lists of longitudes and latitudes of each
        point in the pair, giving four lists total. A fifth list,
        count, optionally gives the frequency at which each pair
        occurred in the source data.

        Parameters:
            lon1        the longitudes of the source points
            lat1        the latitudes of the source points
            lon2        the longitudes of the destination points
            lat2        the latitudes of the destination points
            count       the frequency of each pair

        Once the data is set, call draw() to render the image.
        '''
        self.data = np.array((lon1, lat1, lon2, lat2)).T
        self.data_size = self.data.shape[0]

        # calculate great-circle distances between each coordinate
        # pair. This will be used for determining which order to
        # draw the lines in.
        _, _, dist = self.geo.inv(np.array(lon1),
                                  np.array(lat1),
                                  np.array(lon2),
                                  np.array(lat2))

        # if a frequency count is given, take it into account when
        # creating weights. Weights determine the coloring and
        # drawing order of each line.
        if count is not None:
            self.weight = np.array(count) / dist
        else:
            self.weight = 1 / dist

        self.order = np.argsort(self.weight)

    def draw(self):
        '''
        Render the image. Assumes that set_data has already been called.

        Returns a Python Image Library (PIL) Image object.
        '''

        img = Image.new('RGB', (self.width, self.height), self.bgcol)
        canvas = Draw(img)

        # create the projection. Here we use an equidistant cylindrical projection,
        # but others may work with tweaking of the parameters.
        proj = Proj(proj=self.proj,
                a=self.width/(2*pi), # set the radius of the earth such that our
                                     # projections work
                x_0=self.width/2,    # center horizontally on the image
                y_0=self.height/2)   # center verticallly on the image

        # two branches below will use the same sequence of commands to
        # draw a great-circle on the map, so the common elements are wrapped
        # up into a locally defined function. Given a matrix of points and
        # a pen, draw the path through the points.
        def draw_(pts, pen):
            lons, lats = pts.T
            x, y = proj(lons, lats)
            y = self.height - y
            path = reduce(operator.add, zip(x, y))
            canvas.line(path, pen)

        # loop over every coordinate pair
        for i, (lon1, lat1, lon2, lat2) in enumerate(self.data[self.order]):
            # calculate the fraction of the paths already drawn, and use
            # it to create a pen of the appropriate color
            frac = i / float(self.data_size)
            pen = Pen(self.cols(frac), self.line_width)

            # find the intermediate coordinates along a line between the two 
            # coordinates
            pts = self.geo.npts(lon1, lat1, lon2, lat2, self.gc_resolution)
            pts = np.array(pts)

            # if the longitudinal distance between the two points (travelling
            # through the prime meridian) is more than 180 degrees, it's faster
            # to *not* travel through the prime meridian, so we have to special-
            # case the drawing of the lines.
            if abs(lon1 - lon2) >= HALF_ROTATION:
                # find the index of the path where the line wraps around the image
                (cut_point,), = np.where(np.abs(np.diff(pts[:,0])) > HALF_ROTATION)
                
                # draw the two resultant lines separately
                pts1 = pts[:cut_point+1,:]
                pts2 = pts[cut_point+1:,:]

                # plot one point after the break on each sides so that the
                # paths go to the edge of the screen
                x1, y1 = pts[cut_point+2, :]
                x2, y2 = pts[cut_point+1, :]

                if x1 > 0:
                    pts1 = np.vstack((pts1, [-HALF_ROTATION, y1]))
                    pts2 = np.vstack(([HALF_ROTATION, y2], pts2))
                else:
                    pts1 = np.vstack((pts1, [HALF_ROTATION, y1]))
                    pts2 = np.vstack(([-HALF_ROTATION, y2], pts2))

                draw_(pts1, pen)
                draw_(pts2, pen)
            else:
                # the path does not wrap the image, so we can simply draw
                # it as-is
                draw_(pts, pen)
            
        canvas.flush()

        return img
Exemplo n.º 27
0
length = 500  #km, size of the DEM
g = Geod(ellps='WGS84')  # Use Clarke WGS84 ellipsoid
total_pixels = (width * 1000 / pixels) * (length * 1000 / pixels)

endlon1, urcrnrlat, backaz = g.fwd(centerlon, centerlat, 0, width / 2)
urcrnrlon, endlat2, backaz = g.fwd(centerlon, centerlat, 90, width / 2)
endlon3, llcrnrlat, backaz = g.fwd(centerlon, centerlat, 180, width / 2)
llcrnrlon, endlat4, backaz = g.fwd(centerlon, centerlat, 270, width / 2)

pixel_id = list(range((width * 1000 / pixels)))
intermediate_pixels = width * 1000 / pixels - 2

lonlats = []
elevations = []
lonlats.append((llcrnrlon, llcrnrlat))
lonlats += g.npts(llcrnrlon, llcrnrlat, urcrnrlon, llcrnrlat,
                  intermediate_pixels)
lonlats.append((urcrnrlon, llcrnrlat))
el = srtm.get_data()
for i in range(len(lonlats)):
    elevation = el.get_elevation(lonlats[i][1], lonlats[i][0])
    elevations.append(elevation)
data = {'id': pixel_id, 'coordinates': lonlats, 'elevation': elevations}
df = pd.DataFrame(data, columns=['id', 'coordinates', 'elevation'])
pickle.dump(df, open("DEM.pickle", "wb"))
print(df.ix[1, 'elevation'])

#print (total_pixels)
print len((lonlats))
#print len(pixel_id)
#el = srtm.get_data()
#elevation = el.get_elevation(latitude,longitude)
Exemplo n.º 28
0
endlon, endlat, backaz = g.fwd(lon1pt, lat1pt, az12, dist)
print 'from pyproj.Geod.fwd:'
print "%6.3f  %6.3f %13.3f" % (endlat, endlon, backaz)
print 'intermediate points:'
print 'from geod with +lat_1,+lon_1,+lat_2,+lon_2,+n_S:'
points = '+lon_1=%s +lat_1=%s +lon_2=%s +lat_2=%s' % (
    lon1pt,
    lat1pt,
    lon2pt,
    lat2pt,
)
print points
print commands.getoutput('geod +ellps=clrk66 -f "%.3f" +n_S=5 ' + points)
print 'from pyproj.Geod.npts:'
npts = 4
lonlats = g.npts(lon1pt, lat1pt, lon2pt, lat2pt, npts)
lonprev = lon1pt
latprev = lat1pt
print dist / (npts + 1)
print '%6.3f  %7.3f' % (lat1pt, lon1pt)
for lon, lat in lonlats:
    az12, az21, dist = g.inv(lonprev, latprev, lon, lat)
    print '%6.3f  %7.3f %11.3f' % (lat, lon, dist)
    latprev = lat
    lonprev = lon
az12, az21, dist = g.inv(lonprev, latprev, lon2pt, lat2pt)
print '%6.3f  %7.3f %11.3f' % (lat2pt, lon2pt, dist)

# specify the lat/lons of some cities.
boston_lat = 42. + (15. / 60.)
boston_lon = -71. - (7. / 60.)
def interpolate(x1, y1, x2, y2, n):
    geoid = Geod(ellps="WGS84")
    return geoid.npts(x1, y1, x2, y2, n)
Exemplo n.º 30
0
class TestRadians(unittest.TestCase):
    """Tests issue #84"""
    def setUp(self):
        self.g = Geod(ellps='clrk66')
        self.boston_d = (-71. - (7. / 60.), 42. + (15. / 60.))
        self.boston_r = (math.radians(self.boston_d[0]), math.radians(self.boston_d[1]))
        self.portland_d = (-123. - (41. / 60.), 45. + (31. / 60.))
        self.portland_r = (math.radians(self.portland_d[0]), math.radians(self.portland_d[1]))

    def test_inv_radians(self):

        # Get bearings and distance from Boston to Portland in degrees
        az12_d, az21_d, dist_d = self.g.inv(
            self.boston_d[0],
            self.boston_d[1],
            self.portland_d[0],
            self.portland_d[1],
            radians=False)

        # Get bearings and distance from Boston to Portland in radians
        az12_r, az21_r, dist_r = self.g.inv(
            self.boston_r[0],
            self.boston_r[1],
            self.portland_r[0],
            self.portland_r[1],
            radians=True)

        # Check they are equal
        self.assertAlmostEqual(az12_d, math.degrees(az12_r))
        self.assertAlmostEqual(az21_d, math.degrees(az21_r))
        self.assertAlmostEqual(dist_d, dist_r)

    def test_fwd_radians(self):
        # Get bearing and distance to Portland
        az12_d, az21_d, dist = self.g.inv(
            self.boston_d[0],
            self.boston_d[1],
            self.portland_d[0],
            self.portland_d[1],
            radians=False)

        # Calculate Portland's lon/lat from bearing and distance in degrees
        endlon_d, endlat_d, backaz_d = self.g.fwd(
            self.boston_d[0],
            self.boston_d[1],
            az12_d,
            dist,
            radians=False)

        # Calculate Portland's lon/lat from bearing and distance in radians
        endlon_r, endlat_r, backaz_r = self.g.fwd(
            self.boston_r[0],
            self.boston_r[1],
            math.radians(az12_d),
            dist,
            radians=True)

        # Check they are equal
        self.assertAlmostEqual(endlon_d, math.degrees(endlon_r))
        self.assertAlmostEqual(endlat_d, math.degrees(endlat_r))
        self.assertAlmostEqual(backaz_d, math.degrees(backaz_r))

        # Check to make sure we're back in Portland
        self.assertAlmostEqual(endlon_d, self.portland_d[0])
        self.assertAlmostEqual(endlat_d, self.portland_d[1])

    def test_npts_radians(self):
        # Calculate 10 points between Boston and Portland in degrees
        points_d = self.g.npts(
            lon1=self.boston_d[0],
            lat1=self.boston_d[1],
            lon2=self.portland_d[0],
            lat2=self.portland_d[1],
            npts=10,
            radians=False)

        # Calculate 10 points between Boston and Portland in radians
        points_r = self.g.npts(
            lon1=self.boston_r[0],
            lat1=self.boston_r[1],
            lon2=self.portland_r[0],
            lat2=self.portland_r[1],
            npts=10,
            radians=True)

        # Check they are equal
        for index, dpoint in enumerate(points_d):
            self.assertAlmostEqual(dpoint[0], math.degrees(points_r[index][0]))
            self.assertAlmostEqual(dpoint[1], math.degrees(points_r[index][1]))
Exemplo n.º 31
0
 def interpolate_great_circle(start, stop, N=30):
     geoid = Geod(ellps="WGS84")
     middle = geoid.npts(*start[::-1], *stop[::-1], N)
     pts = [tuple(start)] + [pt[::-1] for pt in middle] + [tuple(stop)]
     return np.array(pts)
Exemplo n.º 32
0
def get_mesh(pfs, rfi, sd, idl):
    """
    From a set of profiles creates the mesh in the forward direction from the
    reference profile.

    :param pfs:
        List of :class:`openquake.hazardlib.geo.line.Line` instances
    :param rfi:
        Index of the reference profile
    :param sd:
        Sampling distance [km] for the edges
    :param idl:
        Boolean indicating the need to account for the IDL
    :returns:
        An updated list of the profiles i.e. a list of
        :class:`openquake.hazardlib.geo.line.Line` instances
    """
    g = Geod(ellps='WGS84')

    # Residual distance, last index
    rdist = [0 for _ in range(0, len(pfs[0]))]
    laidx = [0 for _ in range(0, len(pfs[0]))]

    # New profiles
    npr = list([copy.copy(pfs[rfi])])

    # Run for all the profiles 'after' the reference one
    for i in range(rfi, len(pfs) - 1):

        # Profiles
        pr = pfs[i + 1]
        pl = pfs[i]

        # Fixing IDL case
        if idl:
            for ii in range(0, len(pl)):
                ptmp = pl[ii][0]
                ptmp = ptmp + 360 if ptmp < 0 else ptmp
                pl[ii][0] = ptmp

        # Point in common on the two profiles
        cmm = np.logical_and(np.isfinite(pr[:, 2]), np.isfinite(pl[:, 2]))
        cmmi = np.nonzero(cmm)[0].astype(int)

        # Update last profile index
        mxx = 0
        for ll in laidx:
            if ll is not None:
                mxx = max(mxx, ll)

        # Loop over the points in the right profile
        for x in range(0, len(pr[:, 2])):

            # This edge is in common between the last and the current profiles
            if x in cmmi and laidx[x] is None:
                iii = []
                for li, lv in enumerate(laidx):
                    if lv is not None:
                        iii.append(li)
                iii = np.array(iii)
                minidx = np.argmin(abs(iii - x))
                laidx[x] = mxx
                rdist[x] = rdist[minidx]
            elif x not in cmmi:
                laidx[x] = None
                rdist[x] = 0

        # Loop over profiles
        for k in list(np.nonzero(cmm)[0]):

            # Compute distance and azimuth between the corresponding points
            # on the two profiles
            az12, _, hdist = g.inv(pl[k, 0], pl[k, 1], pr[k, 0], pr[k, 1])
            hdist /= 1e3
            vdist = pr[k, 2] - pl[k, 2]
            tdist = (vdist**2 + hdist**2)**.5
            ndists = int(np.floor((tdist + rdist[k]) / sd))

            ll = g.npts(pl[k, 0], pl[k, 1], pr[k, 0], pr[k, 1],
                        np.ceil(tdist) * 20)
            ll = np.array(ll)
            lll = np.ones_like(ll)
            lll[:, 0] = pl[k, 0]
            lll[:, 1] = pl[k, 1]

            _, _, hdsts = g.inv(lll[:, 0], lll[:, 1], ll[:, 0], ll[:, 1])
            hdsts /= 1e3
            deps = np.linspace(pl[k, 2], pr[k, 2], ll.shape[0], endpoint=True)
            tdsts = (hdsts**2 + (pl[k, 2] - deps)**2)**0.5
            assert len(deps) == ll.shape[0]

            # Compute distance between consecutive profiles
            dd = distance(pl[k, 0], pl[k, 1], pl[k, 2], pr[k, 0], pr[k, 1],
                          pr[k, 2])

            # Check distance
            if abs(dd - tdist) > 0.1 * tdist:
                print('dd:', dd)
                tmps = 'Error while building the mesh'
                tmps += '\nDistances: {:f} {:f}'
                raise ValueError(tmps.format(dd, tdist))

            # Adding new points along the edge with index k
            for j in range(ndists):

                # Add new profile
                if len(npr) - 1 < laidx[k] + 1:
                    npr = add_empty_profile(npr)

                # Compute the coordinates of intermediate points along the
                # current edge
                tmp = (j + 1) * sd - rdist[k]
                lo, la, _ = g.fwd(pl[k, 0], pl[k, 1], az12,
                                  tmp * hdist / tdist * 1e3)

                tidx = np.argmin(abs(tdsts - tmp))
                lo = ll[tidx, 0]
                la = ll[tidx, 1]

                # Fix longitudes
                if idl:
                    lo = lo + 360 if lo < 0 else lo

                # Computing depths
                de = pl[k, 2] + tmp * vdist / hdist
                de = deps[tidx]

                npr[laidx[k] + 1][k] = [lo, la, de]
                if (k > 0 and np.all(np.isfinite(npr[laidx[k] + 1][k]))
                        and np.all(np.isfinite(npr[laidx[k]][k]))):

                    p1 = npr[laidx[k]][k]
                    p2 = npr[laidx[k] + 1][k]
                    d = distance(p1[0], p1[1], p1[2], p2[0], p2[1], p2[2])

                    # Check
                    if abs(d - sd) > 0.1 * sd:
                        tmpf = 'd: {:f} diff: {:f} tol: {:f} sd:{:f}'
                        tmpf += '\nresidual: {:f}'
                        tmps = tmpf.format(d, d - sd, TOL * sd, sd, rdist[k])
                        raise ValueError(tmps)
                laidx[k] += 1

            rdist[k] = tdist - sd * ndists + rdist[k]
            assert rdist[k] < sd

    return npr
Exemplo n.º 33
0
def get_mesh(pfs, rfi, sd, idl):
    """
    :param pfs:
        List of :class:`openquake.hazardlib.geo.line.Line` instances
    :param rfi:
        Index of the reference profile
    :param sd:
        Sampling distance
    :param idl:
        Boolean indicating the need to account for IDL presence
    :returns:
        Profiles
    """
    g = Geod(ellps='WGS84')
    #
    # residual distance, last index
    rdist = [0 for _ in range(0, len(pfs[0]))]
    laidx = [0 for _ in range(0, len(pfs[0]))]
    #
    # new profiles
    npr = list([copy.deepcopy(pfs[rfi])])
    #
    # run for all the profiles 'after' the reference one
    for i in range(rfi, len(pfs) - 1):
        #
        # profiles
        pr = pfs[i + 1]
        pl = pfs[i]
        #
        # fixing IDL case
        if idl:
            for ii in range(0, len(pl)):
                ptmp = pl[ii][0]
                ptmp = ptmp + 360 if ptmp < 0 else ptmp
                pl[ii][0] = ptmp
        #
        # point in common on the two profiles
        cmm = np.logical_and(np.isfinite(pr[:, 2]), np.isfinite(pl[:, 2]))
        cmmi = np.nonzero(cmm)[0].astype(int)
        #
        # update last profile index
        mxx = 0
        for ll in laidx:
            if ll is not None:
                mxx = max(mxx, ll)
        #
        # loop over the points in the right profile
        for x in range(0, len(pr[:, 2])):
            #
            # this edge is in common between the last and the current profiles
            if x in cmmi and laidx[x] is None:
                iii = []
                for li, lv in enumerate(laidx):
                    if lv is not None:
                        iii.append(li)
                iii = np.array(iii)
                minidx = np.argmin(abs(iii - x))
                laidx[x] = mxx
                rdist[x] = rdist[minidx]
            elif x not in cmmi:
                laidx[x] = None
                rdist[x] = 0
        #
        # loop over profiles
        for k in list(np.nonzero(cmm)[0]):
            #
            # compute distance and azimuth between the corresponding points
            # on the two profiles
            az12, _, hdist = g.inv(pl[k, 0], pl[k, 1], pr[k, 0], pr[k, 1])
            hdist /= 1e3
            vdist = pr[k, 2] - pl[k, 2]
            tdist = (vdist**2 + hdist**2)**.5
            ndists = int(np.floor((tdist + rdist[k]) / sd))

            ll = g.npts(pl[k, 0], pl[k, 1], pr[k, 0], pr[k, 1],
                        np.ceil(tdist) * 20)
            ll = np.array(ll)
            lll = np.ones_like(ll)
            lll[:, 0] = pl[k, 0]
            lll[:, 1] = pl[k, 1]
            _, _, hdsts = g.inv(lll[:, 0], lll[:, 1], ll[:, 0], ll[:, 1])
            hdsts /= 1e3
            deps = np.linspace(pl[k, 2], pr[k, 2], ll.shape[0], endpoint=True)
            tdsts = (hdsts**2 + (pl[k, 2] - deps)**2)**0.5
            assert len(deps) == ll.shape[0]

            #
            # checking distance calculation
            dd = distance(pl[k, 0], pl[k, 1], pl[k, 2], pr[k, 0], pr[k, 1],
                          pr[k, 2])
            # >>> TOLERANCE
            if abs(dd - tdist) > 0.1 * tdist:
                print('dd:', dd)
                tmps = 'Error while building the mesh'
                tmps += '\nDistances: {:f} {:f}'
                raise ValueError(tmps.format(dd, tdist))
            #
            # adding new points along the edge with index k
            for j in range(ndists):
                #
                # add new profile
                if len(npr) - 1 < laidx[k] + 1:
                    npr = add_empy_profile(npr)
                #
                # compute the coordinates of intermediate points along the
                # current edge
                tmp = (j + 1) * sd - rdist[k]
                lo, la, _ = g.fwd(pl[k, 0], pl[k, 1], az12,
                                  tmp * hdist / tdist * 1e3)

                # ---------------------------------------------
                tidx = np.argmin(abs(tdsts - tmp))
                lo = ll[tidx, 0]
                la = ll[tidx, 1]

                #
                # fix longitudes
                if idl:
                    lo = lo + 360 if lo < 0 else lo
                #
                # computing depths
                de = pl[k, 2] + tmp * vdist / hdist
                # ---------------------------------------------
                de = deps[tidx]

                npr[laidx[k] + 1][k] = [lo, la, de]
                if (k > 0 and np.all(np.isfinite(npr[laidx[k] + 1][k]))
                        and np.all(np.isfinite(npr[laidx[k]][k]))):

                    p1 = npr[laidx[k]][k]
                    p2 = npr[laidx[k] + 1][k]
                    d = distance(p1[0], p1[1], p1[2], p2[0], p2[1], p2[2])

                    # >>> TOLERANCE
                    # if abs(d-sd) > TOL*sd:
                    if abs(d - sd) > 0.1 * sd:
                        tmpf = 'd: {:f} diff: {:f} tol: {:f} sd:{:f}'
                        tmpf += '\nresidual: {:f}'
                        tmps = tmpf.format(d, d - sd, TOL * sd, sd, rdist[k])
                        logging.warning(tmps)
                        #
                        # plotting
                        if False:
                            fig = plt.figure(figsize=(10, 8))
                            ax = fig.add_subplot(111, projection='3d')
                            for ipro, pro in enumerate(pfs):
                                tmp = [[p[0], p[1], p[2]] for p in pro]
                                tmp = np.array(tmp)
                                tmplon = tmp[:, 0]
                                if idl:
                                    tmplon = ([
                                        x + 360 if x < 0 else x for x in tmplon
                                    ])
                                tmplon0 = tmplon[0]
                                ax.plot(tmplon,
                                        tmp[:, 1],
                                        tmp[:, 2],
                                        'x--b',
                                        markersize=2)
                                ax.text(tmplon0, tmp[0, 1], tmp[0, 2],
                                        '{:d}'.format(ipro))
                            for pro in npr:
                                tmp = [[p[0], p[1], p[2]] for p in pro]
                                tmp = np.array(tmp)
                                tmplon = tmp[:, 0]
                                if idl:
                                    tmplon = ([
                                        x + 360 if x < 0 else x for x in tmplon
                                    ])
                                ax.plot(tmplon,
                                        tmp[:, 1],
                                        tmp[:, 2],
                                        'x--r',
                                        markersize=2)
                            if idl:
                                p1[0] = p1[0] + 360 if p1[0] < 0 else p1[0]
                                p2[0] = p2[0] + 360 if p2[0] < 0 else p2[0]
                            ax.plot([p1[0]], [p1[1]], [p1[2]], 'og')
                            ax.plot([p2[0]], [p2[1]], [p2[2]], 'og')
                            ax.invert_zaxis()
                            ax.view_init(50, 55)
                            plt.show()
                        # raise ValueError('')
                laidx[k] += 1
            rdist[k] = tdist - sd * ndists + rdist[k]
            assert rdist[k] < sd
    return npr
Exemplo n.º 34
0
def get_mesh(pfs, rfi, sd, idl):
    """
    From a set of profiles creates the mesh in the forward direction from the
    reference profile.

    :param pfs:
        List of :class:`openquake.hazardlib.geo.line.Line` instances
    :param rfi:
        Index of the reference profile
    :param sd:
        Sampling distance [km] for the edges
    :param idl:
        Boolean indicating the need to account for the IDL
    :returns:
        An updated list of the profiles i.e. a list of
        :class:`openquake.hazardlib.geo.line.Line` instances
    """
    g = Geod(ellps='WGS84')

    # Instantiate lists with the residual distance and the last profile index
    # with a finite value at a given depth
    rdist = [0 for _ in range(0, len(pfs[0]))]
    laidx = [0 for _ in range(0, len(pfs[0]))]
    angle = [0 for _ in range(0, len(pfs[0]))]

    # Creating a new list used to collect the new profiles which will describe
    # the mesh. We start with the initial profile i.e. the one identified by
    # the reference index rfi
    npr = list([copy.copy(pfs[rfi])])

    # Run for all the profiles 'after' the reference one
    for i in range(rfi, len(pfs) - 1):

        # Profiles: left and right
        pr = pfs[i + 1]
        pl = pfs[i]

        # Fixing IDL case
        if idl:
            for ii in range(0, len(pl)):
                ptmp = pl[ii][0]
                ptmp = ptmp + 360 if ptmp < 0 else ptmp
                pl[ii][0] = ptmp

        # Points in common on the two profiles i.e. points with finite
        # coordinates on both of them
        cmm = np.logical_and(np.isfinite(pr[:, 2]), np.isfinite(pl[:, 2]))
        cmmi = np.nonzero(cmm)[0].astype(int)

        # Find the index of the profiles previously analysed and with at least
        # a node in common with the current profile (i.e. with a continuity in
        # the mesh)
        mxx = 0
        for ll in laidx:
            if ll is not None:
                mxx = max(mxx, ll)

        # Loop over the points in the right profile
        for x in range(0, len(pr[:, 2])):

            # If true this edge connects the right and left profiles
            if x in cmmi and laidx[x] is None:
                iii = []
                for li, lv in enumerate(laidx):
                    if lv is not None:
                        iii.append(li)
                iii = np.array(iii)
                minidx = np.argmin(abs(iii - x))
                laidx[x] = mxx
                rdist[x] = rdist[minidx]
                angle[x] = angle[minidx]
            elif x not in cmmi:
                laidx[x] = None
                rdist[x] = 0
                angle[x] = None

        # Loop over the indexes of the edges in common for the two profiles
        # starting from the top and going down
        for k in list(np.nonzero(cmm)[0]):

            # Compute distance [km] and azimuth between the corresponding
            # points on the two consecutive profiles
            az12, _, hdist = g.inv(pl[k, 0], pl[k, 1], pr[k, 0], pr[k, 1])
            hdist /= 1e3
            # Vertical distance
            vdist = pr[k, 2] - pl[k, 2]
            # Total distance
            tdist = (vdist**2 + hdist**2)**.5

            # Update rdist
            new_rdist = rdist[k]
            if rdist[k] > 0 and abs(az12 - angle[k] > 2):
                new_rdist = update_rdist(rdist[k], az12, angle[k], sd)

            # Number of grid points
            # ndists = int(np.floor((tdist+rdist[k])/sd))
            ndists = int(np.floor((tdist + new_rdist) / sd))

            # Calculate points between the corresponding nodes on the
            # two profiles
            ll = g.npts(pl[k, 0], pl[k, 1], pr[k, 0], pr[k, 1],
                        np.ceil(tdist) * 20)
            ll = np.array(ll)
            lll = np.ones_like(ll)
            lll[:, 0] = pl[k, 0]
            lll[:, 1] = pl[k, 1]

            _, _, hdsts = g.inv(lll[:, 0], lll[:, 1], ll[:, 0], ll[:, 1])
            hdsts /= 1e3
            deps = np.linspace(pl[k, 2], pr[k, 2], ll.shape[0], endpoint=True)
            tdsts = (hdsts**2 + (pl[k, 2] - deps)**2)**0.5
            assert len(deps) == ll.shape[0]

            # Compute distance between nodels at depth 'k' on the two
            # consecutive profiles
            dd = distance(pl[k, 0], pl[k, 1], pl[k, 2], pr[k, 0], pr[k, 1],
                          pr[k, 2])

            # Check that the actual distance between these nodes is similar to
            # the one originally defined
            if abs(dd - tdist) > 0.1 * tdist:
                print('dd:', dd)
                tmps = 'Error while building the mesh'
                tmps += '\nDistances: {:f} {:f}'
                raise ValueError(tmps.format(dd, tdist))

            # Adding new points along the edge with index k
            for j in range(ndists):

                # Add new profile to 'npr' i.e. the list containing the new
                # set of profiles
                if len(npr) - 1 < laidx[k] + 1:
                    npr = add_empty_profile(npr)

                # Compute the coordinates of intermediate points along the
                # current edge. 'tmp' is the distance between the node on the
                # left edge and the j-th node on the edge. 'lo' and 'la' are
                # the coordinates of this new node
                # tmp = (j+1)*sd - rdist[k]
                tmp = (j + 1) * sd - new_rdist
                # lo, la, _ = g.fwd(pl[k, 0], pl[k, 1], az12,
                #                  tmp*hdist/tdist*1e3)

                # Find the index of the closest node in the vector sampled at
                # high frequency
                tidx = np.argmin(abs(tdsts - tmp))
                lo = ll[tidx, 0]
                la = ll[tidx, 1]

                # Fix longitudes in proximity of the IDL
                if idl:
                    lo = lo + 360 if lo < 0 else lo

                # Computing depths
                de = pl[k, 2] + tmp * vdist / hdist
                de = deps[tidx]

                # Updating the new profile
                npr[laidx[k] + 1][k] = [lo, la, de]
                if (k > 0 and np.all(np.isfinite(npr[laidx[k] + 1][k]))
                        and np.all(np.isfinite(npr[laidx[k]][k]))):

                    # Computing the distance between consecutive points on
                    # one edge
                    p1 = npr[laidx[k]][k]
                    p2 = npr[laidx[k] + 1][k]
                    d = distance(p1[0], p1[1], p1[2], p2[0], p2[1], p2[2])

                    # Check if the distance between consecutive points on one
                    # edge (with index k) is within a tolerance limit of the
                    # mesh distance defined by the user
                    if abs(d - sd) > TOL * sd:
                        tmpf = '\ndistance: {:f} difference: {:f} '
                        tmpf += '\ntolerance dist: {:f} sampling dist: {:f}'
                        tmpf += '\nresidual distance: {:f}'
                        tmps = tmpf.format(d, d - sd, TOL * sd, sd, new_rdist)
                        raise ValueError(tmps)
                laidx[k] += 1

            # Check that the residual distance along each edge is lower than
            # the sampling distance
            rdist[k] = tdist - sd * ndists + new_rdist
            angle[k] = az12
            assert rdist[k] < sd

    return npr
Exemplo n.º 35
0
# compute forward and back azimuths, plus distance
# between Boston and Portland.
az12, az21, dist = g.inv(boston_lon, boston_lat, portland_lon, portland_lat)
print("%7.3f %6.3f %12.3f" % (az12, az21, dist))
# compute latitude, longitude and back azimuth of Portland,
# given Boston lat/lon, forward azimuth and distance to Portland.
endlon, endlat, backaz = g.fwd(boston_lon, boston_lat, az12, dist)
print("%6.3f  %6.3f %13.3f" % (endlat, endlon, backaz))
# compute the azimuths, distances from New York to several
# cities (pass a list)
lons1 = 3 * [newyork_lon]
lats1 = 3 * [newyork_lat]
lons2 = [boston_lon, portland_lon, london_lon]
lats2 = [boston_lat, portland_lat, london_lat]
az12, az21, dist = g.inv(lons1, lats1, lons2, lats2)
for faz, baz, d in zip(az12, az21, dist):
    print("%7.3f %7.3f %9.3f" % (faz, baz, d))

###############################################################################
###############################################################################
g = Geod(ellps='clrk66')
###############################################################################
boston_lat = 42. + (15. / 60.)
boston_lon = -71. - (7. / 60.)
portland_lat = 45. + (31. / 60.)
portland_lon = -123. - (41. / 60.)
###############################################################################
lonlats = g.npts(boston_lon, boston_lat, portland_lon, portland_lat, 10)
for lon, lat in lonlats:
    print('%6.3f  %7.3f' % (lat, lon))
Exemplo n.º 36
0
    def get_bounding_box_lonlats(self, npts=100):
        """Returns array of lon/lats along the bounding Arcs

        :Parameters:
        npts: int
            Number of points to return along each line

        :Returns:
        (top, right, bottom, left) : 4 tuples containing lists 
                                    of len npts of lons/lats
        retval = (list(tplons),list(tplats)),
                 (list(rtlons),list(rtlats)),
                 (list(btlons),list(btlats)),
                 (list(ltlons),list(ltlats))
        
        eg for n=3
           ([tplon0,tplon1,tplon2],[tplat0,tplat1,tplat2]),
           ([rtlon0,rtlon1,rtlon2],[rtlat0,rtlat1,rtlat2]),
           ([btlon0,btlon1,btlon2],[btlat0,btlat1,btlat2]),
           ([ltlon0,ltlon1,ltlon2],[ltlat0,ltlat1,ltlat2]),
        """
        g = Geod(ellps='WGS84')

        # Top of bounding box
        # g.npts returns a list of tuples of lon/lat pairs
        #    [(lon0,lat0),(lon1,lat1),(lon2,lat2)]
        # zip reformats that into 2 tuples of lons and lats
        #    [(lon0,lon1,lon2),(lat0,lat1,lat2)]
        # list(tplons) returns list of lons
        #       [lon0,lon1,lon2]
        # list(tplats) returns list of lats
        #       [lat0,lat1,lat2]
        tplons, tplats = zip(*g.npts(self.corners[0].lon,
                                     self.corners[0].lat,
                                     self.corners[1].lon,
                                     self.corners[1].lat,
                                     npts,
                                     radians=True))
        # Right side of bounding box
        rtlons, rtlats = zip(*g.npts(self.corners[1].lon,
                                     self.corners[1].lat,
                                     self.corners[2].lon,
                                     self.corners[2].lat,
                                     npts,
                                     radians=True))
        # Bottom of bounding box
        btlons, btlats = zip(*g.npts(self.corners[2].lon,
                                     self.corners[2].lat,
                                     self.corners[3].lon,
                                     self.corners[3].lat,
                                     npts,
                                     radians=True))
        # Left side of bounding box
        ltlons, ltlats = zip(*g.npts(self.corners[3].lon,
                                     self.corners[3].lat,
                                     self.corners[0].lon,
                                     self.corners[0].lat,
                                     npts,
                                     radians=True))

        retval = [(list(tplons), list(tplats)), (list(rtlons), list(rtlats)),
                  (list(btlons), list(btlats)), (list(ltlons), list(ltlats))]
        return retval
Exemplo n.º 37
0
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
###############################################################################
from pyproj import Geod
g = Geod(ellps='krass')
###############################################################################
miniearth = Geod(a=2, b=1.97)
###############################################################################
###############################################################################
g.fwd(91, 29.6, 52.88778703659133, 3419167.0426993747)
###############################################################################
###############################################################################
g.inv(91, 29.6, 125.35, 43.88333)
###############################################################################
###############################################################################
g = Geod(ellps='krass')
lasa_lat = 29.6
lasa_lon = 91
cc_lat = 43.88333
cc_lon = 125.35
###############################################################################
lonlats = g.npts(lasa_lon, lasa_lat, cc_lon, cc_lat, 4)
for lon, lat in lonlats:
    print('%6.3f  %7.3f' % (lat, lon))