Exemple #1
0
class GeodSharedMemoryBugTestIssue64(unittest.TestCase):
    def setUp(self):
        self.g = Geod(ellps='clrk66')
        self.ga = self.g.a
        self.mercury = Geod(a=2439700) # Mercury 2000 ellipsoid
                                       # Mercury is much smaller than earth.

    def test_not_shared_memory(self):
        self.assertEqual(self.ga, self.g.a)
        # mecury must have a different major axis from earth
        self.assertNotEqual(self.g.a, self.mercury.a)
        self.assertNotEqual(self.g.b, self.mercury.b)
        self.assertNotEqual(self.g.sphere, self.mercury.sphere)
        self.assertNotEqual(self.g.f, self.mercury.f)
        self.assertNotEqual(self.g.es, self.mercury.es)

        # initstrings were not shared in issue #64
        self.assertNotEqual(self.g.initstring, self.mercury.initstring)

    def test_distances(self):
        # note calculated distance was not an issue with #64, but it still a shared memory test
        boston_lat = 42.+(15./60.); boston_lon = -71.-(7./60.)
        portland_lat = 45.+(31./60.); portland_lon = -123.-(41./60.)

        az12,az21,dist_g = self.g.inv(boston_lon,boston_lat,portland_lon,portland_lat)

        az12,az21,dist_mercury = self.mercury.inv(boston_lon,boston_lat,portland_lon,portland_lat)
        self.assertLess(dist_mercury, dist_g)
Exemple #2
0
class GeodSharedMemoryBugTestIssue64(unittest.TestCase):
    def setUp(self):
        self.g = Geod(ellps='clrk66')
        self.ga = self.g.a
        self.mercury = Geod(a=2439700) # Mercury 2000 ellipsoid
                                       # Mercury is much smaller than earth.

    def test_not_shared_memory(self):
        self.assertEqual(self.ga, self.g.a)
        # mecury must have a different major axis from earth
        self.assertNotEqual(self.g.a, self.mercury.a)
        self.assertNotEqual(self.g.b, self.mercury.b)
        self.assertNotEqual(self.g.sphere, self.mercury.sphere)
        self.assertNotEqual(self.g.f, self.mercury.f)
        self.assertNotEqual(self.g.es, self.mercury.es)

        # initstrings were not shared in issue #64
        self.assertNotEqual(self.g.initstring, self.mercury.initstring)

    def test_distances(self):
        # note calculated distance was not an issue with #64, but it still a shared memory test
        boston_lat = 42.+(15./60.); boston_lon = -71.-(7./60.)
        portland_lat = 45.+(31./60.); portland_lon = -123.-(41./60.)

        az12,az21,dist_g = self.g.inv(boston_lon,boston_lat,portland_lon,portland_lat)

        az12,az21,dist_mercury = self.mercury.inv(boston_lon,boston_lat,portland_lon,portland_lat)
        self.assertLess(dist_mercury, dist_g)
Exemple #3
0
    def __init__(self, wkt_polygon, **params):
        super().__init__(**params)

        # TODO: wkt.loads may cause QGIS crash!!!
        #if sys.platform == 'linux':
        #    from shapely import wkt,geometry
        from shapely import wkt,geometry

        print("Original WKT:", wkt_polygon)
        self.poly = wkt.loads(wkt_polygon)
        #print("Before Orient:", self.poly.wkt)
        self.poly = geometry.polygon.orient(self.poly, 1.0)
        # print("After Orient:", self.poly.wkt)

        rect = self.poly.minimum_rotated_rectangle
        rect_coords = list(rect.exterior.coords)

        # 获取最佳包围矩形的三个点
        p1 = rect_coords[0]
        p2 = rect_coords[1]
        p4 = rect_coords[3]

        # 分别计算第一个点到邻近两个点的距离
        geod = Geod(ellps="WGS84")

        # distance1 代表与第二个点的距离,CCW
        angle1, backAngle1, distance1 = geod.inv(p1[0], p1[1], p2[0], p2[1])
        # distance1 代表与第4个点的距离
        angle2, backAngle2, distance2 = geod.inv(p1[0], p1[1], p4[0], p4[1])

        #print(angle1, backAngle1, distance1)
        #print(angle2, backAngle2, distance2)

        angle1 = angle1 if angle1 > 0 else angle1 + 360
        angle2 = angle2 if angle2 > 0 else angle2 + 360

        #print(angle1, backAngle1, distance1)
        #print(angle2, backAngle2, distance2)

        # 确定使用哪个方向上的点为我所用
        self.point_first = p1
        self.point_final = p2 if distance1 > distance2 else p4
        distance_final = distance1 if distance1 < distance2 else distance2
        self.angle_final_added = 0

        directionLeft = True
        if p1[0] < p2[0]:
            if distance2 > distance1:
                directionLeft = False
            else:
                directionLeft = True
        else:
            if distance2 > distance1:
                directionLeft = False
            else:
                directionLeft = True

        expand_count = int(distance_final / self.sidewiseline)
        self.leftExpand = expand_count if directionLeft is True else 0
        self.rightExpand = expand_count if directionLeft is not True else 0
Exemple #4
0
def deviations(lat1, lon1, lat2, lon2):
    """Desvíos entre lat1-lat2 y lon1-lon2 en metros."""
    from pyproj import Geod
    g = Geod(ellps="GRS80")
    azi1, azi2, dLat = g.inv(lon1, lat1, lon1, lat2)
    dLat = -dLat if lat1 > lat2 else dLat
    azi1, azi2, dLon = g.inv(lon1, lat1, lon2, lat1)
    dLon = -dLon if lon1 > lon2 else dLon
    return dLat, dLon
def listener():
    rospy.init_node('bot_yaw', 'bot_gps', anonymous=True, disable_signals=True)
    rospy.Subscriber("imu", Imu, callback)
    rospy.Subscriber("fix", NavSatFix, callback2)
    pub = rospy.Publisher('/cmd_vel', Twist, queue_size=1)
    rate = rospy.Rate(10)  # 10hz
    twist = Twist()

    while 1:
        geodesic = Geod(ellps='WGS84')
        bearing, reverse_bearing, dist = geodesic.inv(lon1, lat1, lon2, lat2)
        bearing = bearing + 180
        angle_diff = yaw - bearing
        print("Yaw: ", yaw, "Bearing: ", bearing)
        print("Angle: ", angle_diff)

        if angle_diff > 1:
            if angle_diff < 180:
                twist.angular.z = 0.7
            elif angle_diff > 180:
                twist.angular.z = -0.7
            pub.publish(twist)

        elif angle_diff < -1:
            angle_diff = abs(angle_diff)
            if angle_diff < 180:
                twist.angular.z = -0.7
            elif angle_diff > 180:
                twist.angular.z = 0.7
            pub.publish(twist)
        if angle_diff < 1 and angle_diff > -1:
            break
    while 1:
        bearing, reverse_bearing, dist = geodesic.inv(lon1, lat1, lon2, lat2)
        if dist > 3:
            twist.linear.y = 0
            twist.linear.z = 0
            twist.angular.x = 0
            twist.angular.y = 0
            twist.angular.z = 0
            twist.linear.x = -0.8
            print("Distance: ", dist)
            pub.publish(twist)
            flag = 0

        elif dist < 3:
            twist.linear.y = 0
            twist.linear.z = 0
            twist.angular.x = 0
            twist.angular.y = 0
            twist.angular.z = 0
            twist.linear.x = 0
            pub.publish(twist)

    rospy.spin()
Exemple #6
0
def plot_contours(area, points, fig, ax, plot_legend=True, plot_points=True):

    geod = Geod(ellps='WGS84')

    xmin = area.bounds[0]
    xmax = area.bounds[2]
    ymin = area.bounds[1]
    ymax = area.bounds[3]

    X = np.linspace(xmin, xmax)
    Y = np.linspace(ymin, ymax)
    Z = np.zeros([len(Y), len(X)])

    mindb = 60
    maxdb = 180
    N = int((maxdb - mindb) / 10)
    v = np.linspace(mindb, maxdb, N + 1)

    # generate contour volues with Shepard's Method
    for x in range(0, len(X)):
        for y in range(0, len(Y)):

            # sum of distances from this point to all points
            totaldist = sum(
                [geod.inv(X[x], Y[y], p[0], p[1])[2]**-8 for p in points])

            Z[y, x] = min(
                maxdb,
                sum([
                    p[2] * (geod.inv(X[x], Y[y], p[0], p[1])[2]**-8) /
                    totaldist for p in points
                ]))

    #CS = ax.contour(X,Y,Z,N, linewidth=0.5, colors='k', alpha=0.3)
    CSF = ax.contourf(X,
                      Y,
                      Z,
                      N,
                      cmap=plt.cm.RdYlGn_r,
                      alpha=1,
                      vmin=v[0],
                      vmax=v[-1],
                      levels=v)
    #vmin = min([p[2] for p in points]), vmax=max([p[2] for p in points]))

    if plot_legend:
        cb = fig.colorbar(CSF, ticks=v)
        cb.set_label("dB Loss")

    if plot_points:
        for p in points:
            print(p)
            ax.plot(p[0], p[1], '.', color='k', ms=4)
Exemple #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)
Exemple #8
0
 def lonlat(lon, lat):
     from pyproj import Geod
     geo = Geod(ellps='WGS84')
     x = [np.min(lon), np.max(lon), np.min(lat), np.max(lat)]
     return {
         'lon_0': .5 * np.sum(x[:2]),
         'lat_0': .5 * np.sum(x[2:]),
         'width': geo.inv(x[0], x[3], x[1], x[3])[2],
         'height': geo.inv(x[0], x[2], x[0], x[3])[2],
         'lat_1': -10,
         'lat_2': -40
     }
Exemple #9
0
def lonlat_gradient(lon, lat, data):
    """
    Calculate the 2D gradient of data on a regular lonlat grid.

    Parameters
    ----------
    lon, lat : 1D array
        Coordinates of the regular grid (sizes N, M).
    data: 2D array
        Whose derivative is taken (size M, N).

    Returns
    -------
    d_dx, d_dy, grad_norm: 2D array
        Gradients along lon and lat axes, and gradient norm (data units / m).

    """
    # Call pyproj
    geod = Geod(ellps='WGS84')

    # Ensure the grid is regular
    dlons = np.unique(np.diff(lon))
    dlats = np.unique(np.diff(lat))
    if (dlons.size > 1) | (dlats.size > 1):
        msg = 'Grid not regular. dlons, dlats: '
        raise ValueError(msg, dlons, dlats)

    # Make regularly spaced vectors around grid points
    _lon_bin = ps.binc2edge(lon)
    _lat_bin = ps.binc2edge(lat)

    # x spacing for each y value
    _, _, _dx = geod.inv(_lon_bin[0] * np.ones(lat.size), _lat_bin[:-1],
                         _lon_bin[1] * np.ones(lat.size), _lat_bin[1:])

    # y spacing for each x value
    _, _, _dy = geod.inv(_lon_bin[:-1], _lat_bin[0] * np.ones(lon.size),
                         _lon_bin[1:], _lat_bin[1] * np.ones(lon.size))

    # Convert to m
    dy, dx = np.meshgrid(_dy, _dx)

    # Calculate gradient assuming dlon = dlat = 1
    diff_y, diff_x = np.gradient(data)

    # Divide each gradient grid point by the represented distance
    d_dx = diff_x / dx
    d_dy = diff_y / dy

    # Calculate the norm of the gradient
    norm = np.sqrt(d_dx**2 + d_dy**2)

    return d_dx, d_dy, norm
Exemple #10
0
def lat_lon_grid_deltas(longitude, latitude, **kwargs):
    r"""Calculate the delta between grid points that are in a latitude/longitude format.

    Calculate the signed delta distance between grid points when the grid spacing is defined by
    delta lat/lon rather than delta x/y

    Parameters
    ----------
    longitude : array_like
        array of longitudes defining the grid
    latitude : array_like
        array of latitudes defining the grid
    kwargs
        Other keyword arguments to pass to :class:`~pyproj.Geod`

    Returns
    -------
    dx, dy:
        at least two dimensional arrays of signed deltas between grid points in the x and y
        direction

    Notes
    -----
    Accepts 1D, 2D, or higher arrays for latitude and longitude
    Assumes [..., Y, X] for >=2 dimensional arrays

    """
    from pyproj import Geod

    # Inputs must be the same number of dimensions
    if latitude.ndim != longitude.ndim:
        raise ValueError(
            'Latitude and longitude must have the same number of dimensions.')

    # If we were given 1D arrays, make a mesh grid
    if latitude.ndim < 2:
        longitude, latitude = np.meshgrid(longitude, latitude)

    geod_args = {'ellps': 'sphere'}
    if kwargs:
        geod_args = kwargs

    g = Geod(**geod_args)

    forward_az, _, dy = g.inv(longitude[..., :-1, :], latitude[..., :-1, :],
                              longitude[..., 1:, :], latitude[..., 1:, :])
    dy[(forward_az < -90.) | (forward_az > 90.)] *= -1

    forward_az, _, dx = g.inv(longitude[..., :, :-1], latitude[..., :, :-1],
                              longitude[..., :, 1:], latitude[..., :, 1:])
    dx[(forward_az < 0.) | (forward_az > 180.)] *= -1

    return dx * units.meter, dy * units.meter
Exemple #11
0
def test_geod_cities():
    # specify the lat/lons of some cities.
    boston_lat = 42.0 + (15.0 / 60.0)
    boston_lon = -71.0 - (7.0 / 60.0)
    portland_lat = 45.0 + (31.0 / 60.0)
    portland_lon = -123.0 - (41.0 / 60.0)
    g1 = Geod(ellps="clrk66")
    g2 = Geod(ellps="WGS84")
    az12, az21, dist = g1.inv(boston_lon, boston_lat, portland_lon,
                              portland_lat)
    print("distance between boston and portland, clrk66:")
    print("%7.3f %6.3f %12.3f" % (az12, az21, dist))
    assert_almost_equal((az12, az21, dist), (-66.531, 75.654, 4164192.708),
                        decimal=3)
    print("distance between boston and portland, WGS84:")
    az12, az21, dist = g2.inv(boston_lon, boston_lat, portland_lon,
                              portland_lat)
    assert_almost_equal((az12, az21, dist), (-66.530, 75.654, 4164074.239),
                        decimal=3)
    print("%7.3f %6.3f %12.3f" % (az12, az21, dist))
    print("testing pickling of Geod instance")
    with temporary_directory() as tmpdir:
        with open(os.path.join(tmpdir, "geod1.pickle"), "wb") as gp1w:
            pickle.dump(g1, gp1w, -1)
        with open(os.path.join(tmpdir, "geod2.pickle"), "wb") as gp2w:
            pickle.dump(g2, gp2w, -1)
        with open(os.path.join(tmpdir, "geod1.pickle"), "rb") as gp1:
            g3 = pickle.load(gp1)
        with open(os.path.join(tmpdir, "geod2.pickle"), "rb") as gp2:
            g4 = pickle.load(gp2)
    az12, az21, dist = g3.inv(boston_lon, boston_lat, portland_lon,
                              portland_lat)
    assert_almost_equal((az12, az21, dist), (-66.531, 75.654, 4164192.708),
                        decimal=3)
    print("distance between boston and portland, clrk66 (from pickle):")
    print("%7.3f %6.3f %12.3f" % (az12, az21, dist))
    az12, az21, dist = g4.inv(boston_lon, boston_lat, portland_lon,
                              portland_lat)
    print("distance between boston and portland, WGS84 (from pickle):")
    print("%7.3f %6.3f %12.3f" % (az12, az21, dist))
    assert_almost_equal((az12, az21, dist), (-66.530, 75.654, 4164074.239),
                        decimal=3)
    g3 = Geod("+ellps=clrk66")  # proj4 style init string
    print("inverse transform")
    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)
    az12, az21, dist = g3.inv(lon1pt, lat1pt, lon2pt, lat2pt)
    print("%7.3f %6.3f %12.3f" % (az12, az21, dist))
    assert_almost_equal((az12, az21, dist), (-66.531, 75.654, 4164192.708),
                        decimal=3)
Exemple #12
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
    )
Exemple #13
0
def calc_dx_dy(lon, lat, shape='WGS84', radius=6370997.):
    """
    This definition calculates the distance between grid points
    that are in a latitude/longitude format.

    Using pyproj GEOD; different Earth Shapes
        https://jswhit.github.io/pyproj/pyproj.Geod-class.html
    Common shapes: 'sphere', 'WGS84', 'GRS80'

    :param lon: 1D or 2D longitude array.
    :param lat: 1D or 2D latitude array.
    :param shape: earth shape.
    :param radius: earth radius.
    :return: dx, dy; 2D arrays of distances between grid points
        in the x and y direction in meters

    :Example:
    >>> lat = np.arange(90,-0.1,-0.5)
    >>> lon = np.arange(0,360.1,0.5)
    >>> dx, dy = calc_dx_dy(lon, lat)
    """

    # check longitude and latitude
    if lon.ndim == 1:
        longitude, latitude = np.meshgrid(lon, lat)
    else:
        longitude = lon
        latitude = lat

    if radius != 6370997.:
        gg = Geod(a=radius, b=radius)
    else:
        gg = Geod(ellps=shape)

    dx = np.empty(latitude.shape)
    dy = np.zeros(longitude.shape)

    for i in range(latitude.shape[1]):
        for j in range(latitude.shape[0] - 1):
            _, _, dx[j, i] = gg.inv(
                longitude[j, i], latitude[j, i], longitude[j + 1, i],
                latitude[j + 1, i])
    dx[j + 1, :] = dx[j, :]

    for i in range(latitude.shape[1] - 1):
        for j in range(latitude.shape[0]):
            _, _, dy[j, i] = gg.inv(
                longitude[j, i], latitude[j, i], longitude[j, i + 1],
                latitude[j, i + 1])
    dy[:, i + 1] = dy[:, i]

    return dx, dy
Exemple #14
0
def lat_lon_grid_deltas(longitude, latitude, **kwargs):
    r"""Calculate the delta between grid points that are in a latitude/longitude format.

    Calculate the signed delta distance between grid points when the grid spacing is defined by
    delta lat/lon rather than delta x/y

    Parameters
    ----------
    longitude : array_like
        array of longitudes defining the grid
    latitude : array_like
        array of latitudes defining the grid
    kwargs
        Other keyword arguments to pass to :class:`~pyproj.Geod`

    Returns
    -------
    dx, dy:
        at least two dimensional arrays of signed deltas between grid points in the x and y
        direction

    Notes
    -----
    Accepts 1D, 2D, or higher arrays for latitude and longitude
    Assumes [..., Y, X] for >=2 dimensional arrays

    """
    from pyproj import Geod

    # Inputs must be the same number of dimensions
    if latitude.ndim != longitude.ndim:
        raise ValueError('Latitude and longitude must have the same number of dimensions.')

    # If we were given 1D arrays, make a mesh grid
    if latitude.ndim < 2:
        longitude, latitude = np.meshgrid(longitude, latitude)

    geod_args = {'ellps': 'sphere'}
    if kwargs:
        geod_args = kwargs

    g = Geod(**geod_args)

    forward_az, _, dy = g.inv(longitude[..., :-1, :], latitude[..., :-1, :],
                              longitude[..., 1:, :], latitude[..., 1:, :])
    dy[(forward_az < -90.) | (forward_az > 90.)] *= -1

    forward_az, _, dx = g.inv(longitude[..., :, :-1], latitude[..., :, :-1],
                              longitude[..., :, 1:], latitude[..., :, 1:])
    dx[(forward_az < 0.) | (forward_az > 180.)] *= -1

    return dx * units.meter, dy * units.meter
Exemple #15
0
 def get_wgs84_area(self, pixel=False):
     if Geod is not None:
         g = Geod(ellps='WGS84')
         extent = self.get_raster_extent(4326)
         ul = extent[0]
         ur = extent[1]
         lr = extent[2]
         _, _, width = g.inv(ul[0], ul[1], ur[0], ur[1])
         _, _, height = g.inv(ur[0], ur[1], lr[0], lr[1])
         area = width * height
         if pixel:
             return area / (self.cols * self.rows)
         else:
             return area
Exemple #16
0
def build_bins(pts, spacing=6.25, width=50, runin=0,
               isequence0=1000, ellps='WGS84'):
    """
    Build bins along a line of points.
    """
    gd = Geod(ellps=ellps)
    div_pts = divide_line(pts, spacing=spacing,
                          runin=runin, ellps=ellps)
    bins = []
    ndiv = len(div_pts)
    ibin = isequence0
    align_to_last_bin = False
    for i in range(0, ndiv - 1):
        lon0, lat0, x0, i0 = div_pts[i]
        lon1, lat1, x1, i1 = div_pts[i + 1]
        faz, baz, dist = gd.inv(lon0, lat0, lon1, lat1)
        # bin corners
        _bin = _build_bin(lon0, lat0, lon1, lat1, width, gd)
        # bin center
        _center = _calculate_center(_bin)
        # put it all together
        bins.append([ibin, None, _center, _bin])
        # handle bends in the line
        if align_to_last_bin:
            # align bins
            bins[-1][3][0] = bins[-2][3][1]
            bins[-1][3][3] = bins[-2][3][2]
            # recalculate center and offset
            bins[-1][2] = _calculate_center(bins[-1][3])
            align_to_last_bin = False
        if i0 == i1:
            ibin -= 1
            i += 1
            _bin = bins[-1]
            del bins[-1]
            align_to_last_bin = True
        # distance on line and line azimuth
        if i == 0:
            bins[-1][1] = div_pts[0][2]
            bins[-1] += [None]
        else:
            az, _, dx = gd.inv(bins[-1][2][0], bins[-1][2][1],
                              bins[-2][2][0], bins[-2][2][1])
            bins[-1][1] = bins[-2][1] + dx
            bins[-1] += [az]
        # increment bin number
        ibin += 1
    # assume first azimuth is the same as 2nd azimuth
    bins[0][4] = [bins[1][4]]
    return bins
Exemple #17
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.
Exemple #18
0
def compute_route(graph, track_corr, edge_ids):
    '''
        This function compute the resulting route of the map matched track.
        Parameters:
        ____________
            graph: OSMNX road network
                Osmnx road network of the area of study
            track_corr: np.array
                array of projected coodinates of the floating car track points
            edge_ids: np.array
                Array of road segments corresponding to the floating car track points  
        Returns:
        ___________
            route: resulting route of the map matched track            
    '''
    # define the reference system
    geod = Geod(ellps='WGS84')
    # Compute the route coordinates
    route = []
    path_length = []
    unlinked = []

    # find the route to the last point of the projected point
    for i in range(len(track_corr) - 1):
        if edge_ids[i] != edge_ids[i + 1]:
            # add the point to the route
            route.append(track_corr[i])
            route.append([
                graph.graph[edge_ids[i][1]][0][0],
                graph.graph[edge_ids[i][1]][0][1]
            ])
            _, _, distance = geod.inv(track_corr[i][1], track_corr[i][0],
                                      graph.graph[edge_ids[i][1]][0][1],
                                      graph.graph[edge_ids[i][1]][0][0])
            path_length.append(distance)
            unlinked.append(0)

        else:
            route.append(track_corr[i])
            _, _, distance = geod.inv(track_corr[i][1], track_corr[i][0],
                                      track_corr[i + 1][1],
                                      track_corr[i + 1][0])
            path_length.append(distance)
            unlinked.append(0)
    # Let's not forget the last point
    # route.append(track_corr[-1])
    route = np.array(route)

    return route
Exemple #19
0
def get_abi_pixel_lengths(dataset):
    """
    Returns the length scales in x and y of each pixel in the input dataset
    """
    g = Geod(ellps='WGS84')
    lat, lon = get_abi_lat_lon(dataset)
    dy, dx = np.zeros(lat.shape, dtype=float), np.zeros(lat.shape, dtype=float)
    dy[:-1] = g.inv(lon[:-1], lat[:-1], lon[1:], lat[1:])[-1] / 1e3
    dx[:, :-1] = g.inv(lon[:, :-1], lat[:, :-1], lon[:, 1:], lat[:,
                                                                 1:])[-1] / 1e3
    dy[1:] += dy[:-1]
    dy[1:-1] /= 2
    dx[:, 1:] += dx[:, :-1]
    dx[:, 1:-1] /= 2
    return dx, dy
Exemple #20
0
def run_geod(lat0, lon0, lat1, lon1):
    #global UNITS, ELLIPSOID
    #lat0 = deg2dms (lat0)
    #lon0 = deg2dms (lon0)
    #lat1 = deg2dms (lat1)
    #lon1 = deg2dms (lon1)
    ELLIPSOID = 'WGS84'
    UNITS = 'm'
    flds = []

    config = "+ellps={0}".format(ELLIPSOID)

    g = Geod(config)

    az, baz, dist = g.inv(lon0, lat0, lon1, lat1)

    if dist:
        dist /= FACTS[UNITS]

    #command = "%s +ellps=%s -f \"%%.6f\" <<EOF -I +units=%s\n%s %s %s %s\nEOF" % (GEOD, ELLIPSOID, UNITS, lat0, lon0, lat1, lon1)
    #print command
    #try :
    #fh = os.popen (command)
    #while 1 :
    #line = fh.readline ()
    #if not line : break
    #flds = line.split ()
    ##print flds
    #except Exception, e :
    #sys.stderr.write ("Error: failed to execute:\n%s" % command)
    #flds = None

    #   Return list containing azimuth, back azimuth, distance
    return az, baz, dist
    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))
Exemple #22
0
def calcEdgeLengths(nxG):
    '''Calculate the lengths of edges based on lat/lon position'''
    G = Geod(ellps='WGS84')
    for edge in nx.edges(nxG):
        nxG[edge[0]][edge[1]]['length'] = G.inv(
            nxG.nodes[edge[0]]['pos'][1], nxG.nodes[edge[0]]['pos'][0],
            nxG.nodes[edge[1]]['pos'][1], nxG.nodes[edge[1]]['pos'][0])[2]
Exemple #23
0
def c1ompare_points_old(a, b, dx, proj='LongLat'):
    if isinstance(dx, float):
        dx = [dx, dx]
    tolerance = [0.6 * x for x in dx]
    if (proj == 'horizontal'):
        pa = project(a, projection_type='proj_cartesian')
        pb = project(b, projection_type='proj_cartesian')
        #print tolerance, pa, pb
        if ( not (abs(pa[1] - pb[1]) < tolerance[1]) ):
            return False
        elif (abs(pa[0] - pb[0]) < tolerance[0]):
            return True
        else:
            return False
    else:
        from pyproj import Geod
        wgs84_geod = Geod(ellps='WGS84')
        az12,az21,dist = wgs84_geod.inv(a[0],a[1],a[0],a[1])
        return dist < tolerance[0] * 1e5

        if ( not (abs(a[1] - b[1]) < tolerance[1]) ):
            #AddComment('lat differ')
            return False
        elif (abs(a[0] - b[0]) < tolerance[0]):
            #AddComment('long same')
            return True
        elif ((abs(abs(a[0]) - 180) < tolerance[0]) and (abs(abs(b[0]) - 180) < tolerance[0])):
            #AddComment('long +/-180')
            return True
        else:
            #AddComment('not same %g %g' % (abs(abs(a[0]) - 180), abs(abs(b[0]) - 180) ) )
            return False
Exemple #24
0
 def get_distance_to_hypo(self,fault):
     '''
     Get straight line distance from subfault center to hypocenter
     '''   
     
     from numpy import argmin,size,ones
     from pyproj import Geod
     
     #Projection object for distances
     p=Geod(ellps='WGS84')
     
     #Firs find the coordiantes of the hypocenter
     time_start=fault[:,7]
     i=argmin(time_start)
     if size(i)>1: #Hypocenter is ambiguos
         'ERROR: Too many possible hypocenters'
     else:
         hypo=fault[i,0:3]
         # get horizontal distances
         az,baz,dist_h=p.inv(ones(len(fault))*hypo[1],ones(len(fault))*hypo[0],fault[:,1],fault[:,0])
         dist_h=dist_h/1000.
         #vertical dsitances
         dist_v=abs(ones(len(fault))*hypo[2]-fault[:,2])
         #total distance
         distance=(dist_h**2+dist_v**2)**0.5
         
     return distance
Exemple #25
0
	def __init__(self, srs, bbox, width=None, height=None, format=None, resource_id=None):
		super(WmsQuery, self).__init__()
		self.query_type = 'WMS'
		self.srs = srs
		self.bbox = bbox
		self.width = width
		self.height = height
		self.format = format
		self.resource_id = resource_id
		if width is not None and height is not None:
			# calculate resolution... this should slow things down, yay... :-(
			p = Proj(init=srs.lower())
			if not p.is_latlong():
				min_lon, min_lat = p(bbox.min_x,bbox.min_y, inverse=True)
				max_lon, max_lat = p(bbox.max_x,bbox.max_y, inverse=True)
			else:
				min_lon, min_lat = bbox.min_x, bbox.min_y
				max_lon, max_lat = bbox.max_x, bbox.max_y
			g = Geod(ellps='clrk66') # Use Clarke 1966 ellipsoid. 
			_,_,diagonal = g.inv(min_lon, min_lat, max_lon, max_lat)
			# distance calculated geodesic
			dist_x = sqrt(diagonal**2 / (1 + float(height)/float(width)) )
			dist_y = dist_x * (float(height)/float(width))
			self.x_res = dist_x / float(width)
			self.y_res = dist_y / float(height)
		else:
			self.x_res = None
			self.y_res = None
Exemple #26
0
def compute_lagdistances(sta,stnum,lon,lat):
    '''
    Compute the lag distances between all stations in the given set
    Input:
        sta:            Array with strings of station names (n x 1)
        stnum:          Array with unique station numbers (n x 1)
        lon:            Array with station longitudes (n x 1)
        lat:            Array with station latitudes (n x 1)
    Output:
        lagdistance:   Upper triangular matrix with lag distances for all station pairs (n x n)
    '''
    
    from pyproj import Geod
    import numpy as np
    
    # Make projection:
    p = Geod(ellps='WGS84')
    
    # Make lag matrix:
    lagdistance_full = np.zeros((len(stnum),len(stnum)))
    
    ## Start to fill in lag matrix
    # Loop over all stations, make a matrix with the lon and lat of just that station, and compute the distance to all other stations (lon,lat):
    for stationi in range(len(stnum)):
        azimuthi,backazimuthi,distancei = p.inv(lon[stationi]*np.ones(len(stnum)),lat[stationi]*np.ones(len(stnum)), lon, lat)
        
        # Fill the matrix with these distances for this station:
        lagdistance_full[stationi,:] = distancei/1000
    
    # Turn it into an upper triangular matrix:
    lagdistance = np.triu(lagdistance_full)    
                
    # Return lag distance:
    return lagdistance
def calculate_distances(d):
    g = Geod(ellps='WGS84')
    far_left_lat = d['elevation_latlon_list'][0][0]
    far_left_lon = d['elevation_latlon_list'][1][0]
    for i, v in d['twod_vertices'].iteritems():
        pt_lat = v[0]
        pt_lon = v[1]
        az1, az2, dist = g.inv(far_left_lon, far_left_lat, pt_lon, pt_lat)
        km_dist = dist / 1000.0
        d['twod_vertices'][i] = [v[0], v[1], v[2], km_dist]

    d['gps_dist'] = []
    for pt_lat, pt_lon in zip(d['gps_lat'], d['gps_lon']):
        az1, az2, dist = g.inv(far_left_lon, far_left_lat, pt_lon, pt_lat)
        km_dist = dist / 1000.0
        d['gps_dist'].append(km_dist)
def distance_matrix(pts, lon='lon', lat='lat', ellps='WGS84'):
    """
    Calculate distance between all points

    Parameters
    ----------
    pts: pandas.DataFrame
        Table of points with at least the collumns given by ``lon`` and ``lat``
    lon, lat: str, optional
        Column names for the longitude and latitude fields. Defaults are
        'lon' and 'lat'.
    ellps: str, optional
        Name of the ellipsoid. See :class:`pyproj.Geod` for valid names.

    Returns
    -------
    distances: numpy.ndarray
        len(pts) x len(pts) array of distances between all points in ``pts``.
    """
    gd = Geod(ellps=ellps)
    npts = len(pts)
    G = np.zeros((npts, npts))
    for i in range(npts):
        for j in range(npts):
            _, _, G[i][j] = gd.inv(pts.ix[i][lon], pts.ix[i][lat],
                                   pts.ix[j][lon], pts.ix[j][lat])
    return G
Exemple #29
0
def compute_wg84_line_length(input_geom):
    """
    Compute the length of a wg84 line (LineString and MultiLineString)

    :param input_geom: input geometry
    :type input_geom: shapely.geometry.LineString or shapely.geometry.MultiLineString
    :return: the line length
    :rtype: float

    """
    total_length = 0

    if input_geom.geom_type == "MultiLineString":
        for geom_line in input_geom.geoms:
            total_length += compute_wg84_line_length(geom_line)

    elif input_geom.geom_type == "LineString":
        coordinates_pairs = list(zip(input_geom.coords, input_geom.coords[1:]))
        for pair in coordinates_pairs:

            if len(pair[0]) == 3 or len(pair[1]) == 3:
                coords = pair[0][:-1] + pair[1][:-1]  # avoid to catch the elevation coord
            else:
                coords = pair[0] + pair[1]

            wgs84_geod = Geod(ellps='WGS84')
            _, _, length_computed = wgs84_geod.inv(*coords)
            total_length += length_computed

    return total_length
def grcrcl1(lon_1, lat_1, lon_2, lat_2):

    g = Geod(ellps='WGS84')

    az, az_inv, dist = g.inv(lon_1, lat_1, lon_2, lat_2)

    return dist
Exemple #31
0
    def getAzimuth(self, point):
        """
		Get azimuth (in degrees) between current point and provided point (point).
		"""
        g = Geod(ellps="sphere")
        forward_azimuth, back_azimuth, distance = g.inv(self.longitude, self.latitude, point.longitude, point.latitude)
        return forward_azimuth
def test_geod_inv_honours_input_types(lons1, lats1, lons2):
    # 622
    gg = Geod(ellps="clrk66")
    outx, outy, outz = gg.inv(lons1=lons1, lats1=lats1, lons2=lons2, lats2=0)
    assert isinstance(outx, type(lons1))
    assert isinstance(outy, type(lats1))
    assert isinstance(outz, type(lons2))
def find_closest_soundings(l1b_file, tgt_latitude, tgt_longitude, max_distance, log_output=sys.stdout):
    l1b_obj = acos_file.L1B(l1b_file)

    sounding_ids = l1b_obj.get_sounding_ids()

    # Average over band first since this is likely to be consistent for
    # different types of L1B files
    latitudes  = l1b_obj.get_sounding_info('sounding_latitude')
    longitudes = l1b_obj.get_sounding_info('sounding_longitude')

    # Average over any non sounding id sized dimensions
    while len(latitudes.shape) > 1:
        extra_dims = numpy.where(numpy.array(latitudes.shape) != sounding_ids.shape[0])
        latitudes  = numpy.average(latitudes, extra_dims[0][0])
        longitudes = numpy.average(longitudes, extra_dims[0][0])

    g = Geod(ellps='WGS84')

    # Find all distances in file
    distances = numpy.zeros(len(sounding_ids), dtype=float)
    for dist_idx, lat_lon_tuple in enumerate(zip(latitudes, longitudes)):
        curr_lat, curr_lon = lat_lon_tuple 
        az12, az21, dist = g.inv(tgt_longitude,tgt_latitude,curr_lon,curr_lat)
        
        # Convert to km
        distances[dist_idx] = dist/1000.

    closest = numpy.where(distances <= max_distance)
    if len(closest[0]) > 0:
        print >>log_output, "%s" % l1b_file
        for close_idx in closest[0]:
            print >>log_output, '%d %f' % (sounding_ids[close_idx], distances[close_idx])
        print >>log_output, ""
    else:
        print >>sys.stderr, "No soundings found in %s closer than %f km" % (l1b_file, max_distance)
def compute_rhyp(stlon,stlat,stelv,hypolon,hypolat,hypodepth):
    '''
    Compute the hypocentral distance for a given station lon, lat and event hypo
    Input:
        stlon:          Float with the station/site longitude
        stlat:          Float with the station/site latitude
        stelv:          Float with the station/site elevation (km)
        hypolon:        Float with the hypocentral longitude
        hypolat:        Float with the hypocentral latitude
        hypodepth:      Float with the hypocentral depth (km)
    Output:
        rhyp:           Float with the hypocentral distance, in km
    '''
    
    import numpy as np
    from pyproj import Geod
    
    
    ## Make the projection:
    p = Geod(ellps='WGS84')
    
    ## Apply the projection to get azimuth, backazimuth, distance (in meters): 
    az,backaz,horizontal_distance = p.inv(stlon,stlat,hypolon,hypolat)

    ## Put them into kilometers:
    horizontal_distance = horizontal_distance/1000.
    stelv = stelv/1000
    ## Hypo deptha lready in km, but it's positive down. ST elevation is positive
    ##    up, so make hypo negative down (so the subtraction works out):
    hypodepth = hypodepth * -1
    
    ## Get the distance between them:
    rhyp = np.sqrt(horizontal_distance**2 + (stelv - hypodepth)**2)
    
    return rhyp
Exemple #35
0
def lonlat2distances(lon, lat, meters_per_unit=1, **kwargs):
    """
    Get distance between points of a GPS track.

    Distances are returned in meters by default. This
    can be adjusted by setting the `meters_per_unit`
    parameter (e.g. 1000 for km).

    Parameters
    ----------
    lon, lat : 1D array
        Plate carree coordinates to process.
    meters_per_unit : float
        Number of meters in the desired output unit of distance.
    kwargs : keyword arguments
        Passed to `pyroj.Geod` .

    Returns
    -------
    distances : 1D array
        Separating the input coordinates.
    """
    kwargs = {'ellps': 'WGS84', **kwargs}
    _geod = Geod(**kwargs)

    distances = np.array([
        _geod.inv(lon1, lat1, lon2, lat2)
        for (lon1, lat1, lon2,
             lat2) in zip(lon[:-1], lat[:-1], lon[1:], lat[1:])
    ])[:, 2]

    distances /= meters_per_unit

    return distances
def compute_repi(stlon,stlat,hypolon,hypolat):
    '''
    Compute the hypocentral distance for a given station lon, lat and event hypo
    Input:
        stlon:          Float with the station/site longitude
        stlat:          Float with the station/site latitude
        hypolon:        Float with the hypocentral longitude
        hypolat:        Float with the hypocentral latitude
    Output:
        repi:           Float with the epicentral distance, in km
    '''
    
    from pyproj import Geod
    
    
    ## Make the projection:
    p = Geod(ellps='WGS84')
    
    ## Apply the projection to get azimuth, backazimuth, distance (in meters): 
    az,backaz,horizontal_distance = p.inv(stlon,stlat,hypolon,hypolat)

    ## Put them into kilometers:
    horizontal_distance = horizontal_distance/1000.
 
    ## Epicentral distance is horizontal distance:
    repi = horizontal_distance
    
    return repi
def grcrcl1(lon_1, lat_1, lon_2, lat_2):
    
    g = Geod(ellps='WGS84')
    
    az, az_inv, dist = g.inv(lon_1, lat_1, lon_2, lat_2)
    
    return dist
Exemple #38
0
def lonlat2distancefrom(lon, lat, lon_0, lat_0, meters_per_unit=1, **kwargs):
    """
    Get distance between GPS track and a fixed coordinate.

    Distances are returned in meters by default. This
    can be adjusted by setting the `meters_per_unit`
    parameter (e.g. 1000 for km).

    Parameters
    ----------
    lon, lat : 1D array
        Plate carree coordinates of GPS track.
    lon_0, lat_0 : 1D array
        Plate carree coordinates of fixed coordinate.
    meters_per_unit : float
        Number of meters in the desired output unit of distance.
    kwargs : keyword arguments
        Passed to `pyroj.Geod` .

    Returns
    -------
    distances : 1D array
        Separating the input coordinates.
    """
    kwargs = {'ellps': 'WGS84', **kwargs}
    _geod = Geod(**kwargs)

    distances = np.array([
        _geod.inv(lon_, lat_, lon_0, lat_0) for (lon_, lat_) in zip(lon, lat)
    ])[:, 2]

    distances /= meters_per_unit

    return distances
Exemple #39
0
def arrivals(hypocenter, station_lon, station_lat):
    '''
    Get P and S arrival times
    '''

    from obspy.taup import TauPyModel
    from pyproj import Geod
    from numpy import rad2deg

    #Station to hypo distance
    g = Geod(ellps='WGS84')
    az, baz, dist = g.inv(hypocenter[0], hypocenter[1], station_lon,
                          station_lat)
    #Convert distance from m to degrees and km
    dist_deg = rad2deg(dist / 6371e3)
    print dist / 1000
    #Calculate theoretical arrivals
    mod = TauPyModel(model='Nocal')
    arrivals = mod.get_travel_times(source_depth_in_km=hypocenter[2],
                                    distance_in_degree=dist_deg,
                                    phase_list=('P', 'p', 'S', 's'))
    print arrivals

    #Parse arrivals
    ptime = 1e6
    stime = 1e6
    for k in range(len(arrivals)):
        if arrivals[k].name == 'p' or arrivals[k].name == 'P':
            ptime = min(arrivals[k].time, ptime)
        if arrivals[k].name == 's' or arrivals[k].name == 'S':
            stime = min(arrivals[k].time, stime)
    print ptime

    return ptime, stime
Exemple #40
0
def lonlat2heading(lon, lat, **kwargs):
    """
    Get forward azimuth from GPS track.

    Parameters
    ----------
    lon, lat : 1D array
        Plate carree coordinates to process. Length m.
    kwargs : keyword arguments
        Passed to `pyroj.Geod` .

    Returns
    -------
    heading : 1D array
        Forward azimuth. Length m-1.
    """
    kwargs = {'ellps': 'WGS84', **kwargs}
    _geod = Geod(**kwargs)

    heading = np.array([
        _geod.inv(lon1, lat1, lon2, lat2)
        for (lon1, lat1, lon2,
             lat2) in zip(lon[:-1], lat[:-1], lon[1:], lat[1:])
    ])[:, 0]

    return heading
Exemple #41
0
def pyproj_distance(x1, y1, x2, y2, ellipsoid_name):
    """ Compute geodesic using pyproj package

    :param x1:
    :param y1:
    :param x2:
    :param y2:
    :param ellipsoid_name: name of ellipsoid
    :return: distance (in m)
    """
    geod = Geod(ellps=ellipsoid_name.upper())
    if np.size(x1) != np.size(x2):
        try:
            if np.size(x1) < np.size(x2):
                x1 = np.full(x2.shape, x1)
                y1 = np.full(x2.shape, y1)
            else:
                x2 = np.full(x1.shape, x2)
                y2 = np.full(x1.shape, y2)
        except ValueError:
            raise ValueError(
                "x1/y1 and x2/y2 must have the same size or one pair must be scalar"
            )

    return geod.inv(x1, y1, x2, y2)[2]
def distMatrix(inCoords, distanceMetric=False):
    """
    Compute distance matrix between points
    coords : nparray shape[nPoints,2], with first column X, and Y. Proj 4326(WGS84)
    Return matrix of distance matrix between points.
    """
    if distanceMetric:
        from pyproj import Geod
        geod = Geod(ellps='WGS84')

        distArray = np.zeros((len(inCoords), len(inCoords)))
        for n, p in enumerate(
                np.nditer(inCoords.T.copy(),
                          flags=['external_loop'],
                          order='F')):
            for i in range(len(inCoords)):
                x1, y1 = p
                x2, y2 = inCoords[i]
                angle1, angle2, dist = geod.inv(x1, y1, x2, y2)

                distArray[n, i] = dist

    else:
        from scipy.spatial import distance

        distArray = distance.cdist(inCoords, inCoords, 'euclidean')

    return distArray
Exemple #43
0
    def get_bounding_box(self):
        """Get the bounding box of this file."""
        from pyproj import Geod
        geod = Geod(ellps='WGS84')
        dataset_group = DATASET_KEYS[self.datasets[0]]
        idx = 0
        lons_ring = None
        lats_ring = None
        while True:
            path = 'Data_Products/{dataset_group}/{dataset_group}_Gran_{idx}/attr/'
            prefix = path.format(dataset_group=dataset_group, idx=idx)
            try:
                lats = self.file_content[prefix + 'G-Ring_Latitude']
                lons = self.file_content[prefix + 'G-Ring_Longitude']
                if lons_ring is None:
                    lons_ring = lons
                    lats_ring = lats
                else:
                    prev_lon = lons_ring[0]
                    prev_lat = lats_ring[0]
                    dists = list(geod.inv(lon, lat, prev_lon, prev_lat)[2] for lon, lat in zip(lons, lats))
                    first_idx = np.argmin(dists)
                    if first_idx == 2 and len(lons) == 8:
                        lons_ring = np.hstack((lons[:3], lons_ring[:-2], lons[4:]))
                        lats_ring = np.hstack((lats[:3], lats_ring[:-2], lats[4:]))
                    else:
                        raise NotImplementedError("Don't know how to handle G-Rings of length %d" % len(lons))

            except KeyError:
                break
            idx += 1

        return lons_ring, lats_ring
Exemple #44
0
 def midpoint_longest(north_lat, west_lon, south_lat, east_lon):
     g = Geod(ellps='WGS84')
     af, ab, dist = g.inv(west_lon, north_lat, east_lon, south_lat)
     rlon, rlat, az = g.fwd(west_lon, north_lat, af, dist/2)
     rlon += 180 if rlon < 0 else -180
     rlon = round(rlon, 6)
     rlat = round(rlat, 6)
     return rlat, rlon
Exemple #45
0
    def addLengthMeters(self, stream_network):
        """
        Adds length field in meters to network (The added field name will be 'LENGTH_M'). 
        
        .. note:: This may be needed for generating the kfac file depending on the units of your raster. See: :doc:`gis_tools`.       

        Parameters:
            stream_network(str): Path to stream network file.
        
        Here is an example of how to use this:
        
        .. code:: python
        
            import os
            from RAPIDpy.gis.taudem import TauDEM
            
            td = TauDEM()
                        
            output_directory = '/path/to/output/files'
            td.addLengthMeters(os.path.join(output_directory,"stream_reach_file.shp"))

        """
        network_shapefile = ogr.Open(stream_network, 1)
        network_layer = network_shapefile.GetLayer()
        network_layer_defn = network_layer.GetLayerDefn()
        
        #make sure projection EPSG:4326
        network_layer_proj = network_layer.GetSpatialRef()
        geographic_proj = osr.SpatialReference()
        geographic_proj.ImportFromEPSG(4326)
        proj_transform = None
        if network_layer_proj != geographic_proj:
            proj_transform = osr.CoordinateTransformation(network_layer_proj, geographic_proj)

        #check for field
        create_field=True
        for i in xrange(network_layer_defn.GetFieldCount()):
            field_name = network_layer_defn.GetFieldDefn(i).GetName()
            if field_name == 'LENGTH_M':
                create_field=False
                break
            
        if create_field:
            network_layer.CreateField(ogr.FieldDefn('LENGTH_M', ogr.OFTReal))

        geo_manager = Geod(ellps="WGS84")
        for network_feature in network_layer:
            feat_geom = network_feature.GetGeometryRef()
            #make sure coordinates are geographic
            if proj_transform:
                feat_geom.Transform(proj_transform)
                
            line = shapely_loads(feat_geom.ExportToWkb())
            lon_list, lat_list = line.xy
            az1, az2, dist = geo_manager.inv(lon_list[:-1], lat_list[:-1], lon_list[1:], lat_list[1:])
            network_feature.SetField('LENGTH_M', sum(dist))
            network_layer.SetFeature(network_feature)
Exemple #46
0
def test_geod_cities():
    # specify the lat/lons of some cities.
    boston_lat = 42.0 + (15.0 / 60.0)
    boston_lon = -71.0 - (7.0 / 60.0)
    portland_lat = 45.0 + (31.0 / 60.0)
    portland_lon = -123.0 - (41.0 / 60.0)
    g1 = Geod(ellps="clrk66")
    g2 = Geod(ellps="WGS84")
    az12, az21, dist = g1.inv(boston_lon, boston_lat, portland_lon, portland_lat)
    print("distance between boston and portland, clrk66:")
    print("%7.3f %6.3f %12.3f" % (az12, az21, dist))
    assert_almost_equal((az12, az21, dist), (-66.531, 75.654, 4164192.708), decimal=3)
    print("distance between boston and portland, WGS84:")
    az12, az21, dist = g2.inv(boston_lon, boston_lat, portland_lon, portland_lat)
    assert_almost_equal((az12, az21, dist), (-66.530, 75.654, 4164074.239), decimal=3)
    print("%7.3f %6.3f %12.3f" % (az12, az21, dist))
    print("testing pickling of Geod instance")
    with temporary_directory() as tmpdir:
        with open(os.path.join(tmpdir, "geod1.pickle"), "wb") as gp1w:
            pickle.dump(g1, gp1w, -1)
        with open(os.path.join(tmpdir, "geod2.pickle"), "wb") as gp2w:
            pickle.dump(g2, gp2w, -1)
        with open(os.path.join(tmpdir, "geod1.pickle"), "rb") as gp1:
            g3 = pickle.load(gp1)
        with open(os.path.join(tmpdir, "geod2.pickle"), "rb") as gp2:
            g4 = pickle.load(gp2)
    az12, az21, dist = g3.inv(boston_lon, boston_lat, portland_lon, portland_lat)
    assert_almost_equal((az12, az21, dist), (-66.531, 75.654, 4164192.708), decimal=3)
    print("distance between boston and portland, clrk66 (from pickle):")
    print("%7.3f %6.3f %12.3f" % (az12, az21, dist))
    az12, az21, dist = g4.inv(boston_lon, boston_lat, portland_lon, portland_lat)
    print("distance between boston and portland, WGS84 (from pickle):")
    print("%7.3f %6.3f %12.3f" % (az12, az21, dist))
    assert_almost_equal((az12, az21, dist), (-66.530, 75.654, 4164074.239), decimal=3)
    g3 = Geod("+ellps=clrk66")  # proj4 style init string
    print("inverse transform")
    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)
    az12, az21, dist = g3.inv(lon1pt, lat1pt, lon2pt, lat2pt)
    print("%7.3f %6.3f %12.3f" % (az12, az21, dist))
    assert_almost_equal((az12, az21, dist), (-66.531, 75.654, 4164192.708), decimal=3)
Exemple #47
0
    def getHorizontalDistance(self, point):
        """
		Get horizontal distance (great circle distance, in km) between current point
		and provided point (point).
		"""
        g = Geod(ellps="sphere")
        forward_azimuth, back_azimuth, horizontal_distance = g.inv(
            self.longitude, self.latitude, point.longitude, point.latitude
        )
        return horizontal_distance * 1e-3  # 1e-3 is needed to convert from m to km
Exemple #48
0
 def _distance(self, start, to):
     '''
     Return distance.
     '''
     q = Geod(ellps='WGS84')
     fa, ba, d =\
         q.inv(start['lon'],
               start['lat'],
               to['lon'],
               to['lat'])
     return d
Exemple #49
0
class Measurer:
    def __init__(self, ellps="clrk66"):
        self.geod = Geod( ellps=ellps )

    def measure(self, shape):
        ret = 0
        for pt1, pt2 in cons( shape.coords ):
            try:
                azm1, azm2, dist = self.geod.inv( pt1[0], pt1[1], pt2[0], pt2[1] )
            except ValueError:
                continue
            ret += dist
        return ret
    def cell_height(self):
        cell_height = np.full(self.shape, np.nan)
        geod = Geod(ellps='WGS84')
        for i in range(self.shape[0]):
            _az12, _az21, cell_length = geod.inv(
                self.longitude[i, 0],
                self.latitude[i, 0] + .25,
                self.longitude[i, 0],
                self.latitude[i, 0] - .25,
            )
            cell_height[i, :] = cell_length

        return cell_height
Exemple #51
0
 def test_geod_nans(self):
     g = Geod(ellps='clrk66')
     (azi1, azi2, s12) = g.inv(43, 10, float('nan'), 20)
     self.assertTrue(azi1 != azi1)
     self.assertTrue(azi2 != azi2)
     self.assertTrue(s12 != s12)
     (azi1, azi2, s12) = g.inv(43, 10, 53, float('nan'))
     self.assertTrue(azi1 != azi1)
     self.assertTrue(azi2 != azi2)
     self.assertTrue(s12 != s12)
     # Illegal latitude is treated as NaN
     (azi1, azi2, s12) = g.inv(43, 10, 53, 91)
     self.assertTrue(azi1 != azi1)
     self.assertTrue(azi2 != azi2)
     self.assertTrue(s12 != s12)
     (lon2, lat2, azi2) = g.fwd(43, 10, float('nan'), 1e6)
     self.assertTrue(lon2 != lon2)
     self.assertTrue(lat2 != lat2)
     self.assertTrue(azi2 != azi2)
     (lon2, lat2, azi2) = g.fwd(43, 10, 20, float('nan'))
     self.assertTrue(lon2 != lon2)
     self.assertTrue(lat2 != lat2)
     self.assertTrue(azi2 != azi2)
     (lon2, lat2, azi2) = g.fwd(43, float('nan'), 20, 1e6)
     self.assertTrue(lon2 != lon2)
     self.assertTrue(lat2 != lat2)
     self.assertTrue(azi2 != azi2)
     # Illegal latitude is treated as NaN
     (lon2, lat2, azi2) = g.fwd(43, 91, 20, 1e6)
     self.assertTrue(lon2 != lon2)
     self.assertTrue(lat2 != lat2)
     self.assertTrue(azi2 != azi2)
     # Only lon2 is NaN
     (lon2, lat2, azi2) = g.fwd(float('nan'), 10, 20, 1e6)
     self.assertTrue(lon2 != lon2)
     self.assertTrue(lat2 == lat2)
     self.assertTrue(azi2 == azi2)
Exemple #52
0
    def size (self):
        from pyproj import Geod

        g = Geod(ellps='WGS84')
        lon_min = self.lonw
        lon_max = self.lone
        lat_min = self.lats
        lat_max = self.latn
        lon = (lon_min+lon_max)/2
        lat = (lat_min+lat_max)/2

        sn = g.inv (lon, lat_min, lon, lat_max, radians=False)[2]
        we = g.inv (lon_min, lat, lon_max, lat, radians=False)[2]

        return (sn, we) 
Exemple #53
0
 def zero_padding(self, outfname, component, evlo, evla, dt, minV=1.5, iter0=None, iterf=None, diter=None, verbose=True):
     # - Some initialisations. ------------------------------------------------------------------
     g = Geod(ellps='WGS84')
     dset    = h5py.File(outfname)
     dset.attrs.create(name = 'theta_max', data=self.attrs["theta_max"], dtype='f')
     dset.attrs.create(name = 'theta_min', data=self.attrs["theta_min"], dtype='f')
     dset.attrs.create(name = 'phi_min', data=self.attrs["phi_min"], dtype='f')
     dset.attrs.create(name = 'phi_max', data=self.attrs["phi_max"], dtype='f')
     lat_min = 90.0 - self.attrs["theta_max"]*180.0/np.pi
     lat_max = 90.0 - self.attrs["theta_min"]*180.0/np.pi
     lon_min = self.attrs["phi_min"]*180.0/np.pi
     lon_max = self.attrs["phi_max"]*180.0/np.pi
     dset.attrs.create(name = 'lat_min', data=lat_min, dtype='f')
     dset.attrs.create(name = 'lat_max', data=lat_max, dtype='f')
     dset.attrs.create(name = 'lon_min', data=lon_min, dtype='f')
     dset.attrs.create(name = 'lon_max', data=lon_max, dtype='f')
     dset.attrs.create(name = 'depth', data=self.attrs['depth'], dtype='f')
     dset.attrs.create(name = 'n_procs', data=self.attrs['n_procs'], dtype='f')
     dset.attrs.create(name = 'rotation_axis', data=self.attrs['rotation_axis'], dtype='f')
     dset.attrs.create(name = 'rotation_angle', data=self.attrs['rotation_angle'], dtype='f')
     group   = dset.create_group( name = component )
     in_group= self[component]
     # - Loop over processor boxes and check if depth falls within the volume. ------------------
     try: iterArr=np.arange(iter0 ,iterf+diter, diter, dtype=int)
     except: iterArr = in_group.keys()
     for iteration in iterArr:
         try: in_subgroup = in_group[str(iteration)]
         except KeyError: continue
         subgroup=group.create_group(name=str(iteration))
         if verbose: print 'Zero padding snapshot for iteration =',iteration
         time = float(iteration) * dt; mindist = time * minV
         for iproc in in_subgroup.keys():
             in_subdset  = in_subgroup[iproc]
             field       = in_subdset.value
             theta       = in_subdset.attrs['theta']
             phi         = in_subdset.attrs['phi']
             lat = 90.-theta/np.pi*180.; lon = phi/np.pi*180.
             lats, lons = np.meshgrid(lat, lon, indexing = 'ij')
             evlaArr = evla * np.ones(lats.shape); evloArr = evlo * np.ones(lats.shape)
             az, baz, distevent = g.inv(lons, lats, evloArr, evlaArr)
             distevent=distevent/1000.
             index_padding  = distevent < mindist
             field[index_padding] = 0
             subdset = subgroup.create_dataset(name=iproc, shape=field.shape, data=field)
             subdset.attrs.create(name = 'theta', data=theta, dtype='f')
             subdset.attrs.create(name = 'phi', data=phi, dtype='f')
     dset.close()
     return
Exemple #54
0
def divide_line(pts, spacing=6.25, runin=0.,
                ellps='WGS84', isegment0=0):
    """
    Divide a line into equally spaced segments.

    Parameters
    ----------
    pts : list of tuples 
        List of point coordinates in longitude and latitude that define the
        line.  Format is: ``[(lon_0, lat_0), (lon_1, lat_1), ...,
        (lon_n, lat_n)]``.
    spacing : float, optional
        Spacing between line segments in meters.
    runin : float, optional
        Length of a "run-in" segment prepended to the line.
    ellps : str, optional
        Name of the ellipse to use in geodetic calculations. Must be
        recognized by :class:`pyproj.Geod`.
    isegment0 : int, optional
        Sequence number of the first bin.

    Returns
    -------
    bins : list
        List of (lon, lat, offset, sequence) tuples.
    """
    gd = Geod(ellps=ellps)
    x = -runin
    _x = -runin
    ibin = isegment0
    bins = []
    for i in range(0, len(pts) - 1):
        _x0 = _x
        lon0, lat0 = pts[i]
        lon1, lat1 = pts[i + 1]
        faz, baz, dist = gd.inv(lon0, lat0, lon1, lat1)
        while _x <= dist:
            lon, lat, _ = gd.fwd(lon0, lat0, faz, _x)
            bins += [(lon, lat, x, ibin)]
            _x += spacing
            x += spacing
            ibin += 1
        _x -= dist
        x -= _x
        if _x > 0:
            x += _x
            bins += [(lon1, lat1, x, ibin - 1)]
    return bins
Exemple #55
0
def okada_synthetics(strike,dip,rake,length,width,lon_source,lat_source,
                    depth_source,lon_obs,lat_obs,mu):
    '''
    Calculate neu synthetics for a subfault using Okada analytical solutions
    '''
    
    from okada_wrapper import dc3dwrapper
    from numpy import array,cos,sin,deg2rad,zeros
    from pyproj import Geod
    
    theta=strike-90
    theta=deg2rad(theta)
    
    #Rotaion matrices since okada_wrapper is only for east striking fault
    R=array([[cos(theta),-sin(theta)],[sin(theta),cos(theta)]])
    R2=array([[cos(-theta),-sin(-theta)],[sin(-theta),cos(-theta)]])
                       
    #position of point from lon/lat to x/y assuming subfault center is origin
    P=Geod(ellps='WGS84')
    az,baz,dist=P.inv(lon_source,lat_source,lon_obs,lat_obs)
    dist=dist/1000.
    x_obs=dist*sin(deg2rad(az))
    y_obs=dist*cos(deg2rad(az))
    
    #Calculate on rotated position
    xy=R.dot(array([x_obs, y_obs]))
    
    #Get Okada displacements
    lamb=mu
    alpha = (lamb + mu) / (lamb + 2 * mu)
    ss_in_m=1.0*cos(deg2rad(rake))
    ds_in_m=1.0*sin(deg2rad(rake))
    success, u, grad_u = dc3dwrapper(alpha, [xy[0], xy[1], 0.0],depth_source,dip,
                            [-length/2., length/2.], [-width/2., width/2],
                            [ss_in_m, ds_in_m, 0.0])
            
    #Rotate output
    urot=R2.dot(array([[u[0]], [u[1]]]))
    u[0]=urot[0]
    u[1]=urot[1]
    
    #output
    n=u[1]
    e=u[0]
    z=u[2]  
      
    return n,e,z
Exemple #56
0
 def midpoint_shortest(north_lat, west_lon, south_lat, east_lon):
     g = Geod(ellps='WGS84')
     af, ab, dist = g.inv(west_lon, north_lat, east_lon, south_lat)
     rlon, rlat, az = g.fwd(west_lon, north_lat, af, dist/2)
     # decimal places   degrees      distance
     #        0         1            111   km
     #        1         0.1          11.1  km
     #        2         0.01         1.11  km
     #        3         0.001        111   m
     #        4         0.0001       11.1  m
     #        5         0.00001      1.11  m
     #        6         0.000001     0.111 m
     #        7         0.0000001    1.11  cm
     #        8         0.00000001   1.11  mm
     rlon = round(rlon, 6)
     rlat = round(rlat, 6)
     return rlat, rlon
Exemple #57
0
	def getShortestDistance(self,point):
		"""
		Compute shortest distance (in km) between point and rupture.
		The shortest distance is defined as the minimum
		distance between the given point and the points
		constituting the rupture surface mesh.
		"""
		g = Geod(ellps="sphere")
		point_list = self.rupture_surface.ravel()
		lons_rup = numpy.array([point_list[i].longitude for i in range(len(point_list))])
		lats_rup = numpy.array([point_list[i].latitude for i in range(len(point_list))])
		lons_point = numpy.array([point.longitude for i in range(len(point_list))])
		lats_point = numpy.array([point.latitude for i in range(len(point_list))])
		fwd_azs,back_azs,hor_dists = g.inv(lons_point,lats_point,lons_rup,lats_rup)
		vert_dists = numpy.array([(point.depth - point_list[i].depth) * 1e3 for i in range(len(point_list))])
		dists = numpy.sqrt(hor_dists**2 + vert_dists**2)
		return min(dists) * 1e-3
Exemple #58
0
def __azdist(sacobj,  ellps):
    """
    Return forward/backazimuth and distance using
    pyproj (proj4 bindings)
    """
    from pyproj import Geod
    g = Geod(ellps=ellps)
    stla, stlo = sacobj.stla, sacobj.stlo
    evla, evlo = sacobj.evla, sacobj.evlo
    az,  baz,  dist = g.inv(evlo,  evla,  stlo,  stla)
    # convert units so that they show the same as SAC
    if az < 0:
        az += 360
    if baz < 0:
        baz += 360
    dist /= 1000
    return az,  baz,  dist
Exemple #59
0
def distances_from_cross_section(cross):
    """Calculate the distances in the x and y directions along a cross-section.

    Parameters
    ----------
    cross : `xarray.DataArray`
        The input DataArray of a cross-section from which to obtain geometeric distances in
        the x and y directions.

    Returns
    -------
    x, y : tuple of `xarray.DataArray`
        A tuple of the x and y distances as DataArrays

    """
    if (CFConventionHandler.check_axis(cross.metpy.x, 'lon')
            and CFConventionHandler.check_axis(cross.metpy.y, 'lat')):
        # Use pyproj to obtain x and y distances
        from pyproj import Geod

        g = Geod(cross.metpy.cartopy_crs.proj4_init)
        lon = cross.metpy.x
        lat = cross.metpy.y

        forward_az, _, distance = g.inv(lon[0].values * np.ones_like(lon),
                                        lat[0].values * np.ones_like(lat),
                                        lon.values,
                                        lat.values)
        x = distance * np.sin(np.deg2rad(forward_az))
        y = distance * np.cos(np.deg2rad(forward_az))

        # Build into DataArrays
        x = xr.DataArray(x, coords=lon.coords, dims=lon.dims, attrs={'units': 'meters'})
        y = xr.DataArray(y, coords=lat.coords, dims=lat.dims, attrs={'units': 'meters'})

    elif (CFConventionHandler.check_axis(cross.metpy.x, 'x')
            and CFConventionHandler.check_axis(cross.metpy.y, 'y')):

        # Simply return what we have
        x = cross.metpy.x
        y = cross.metpy.y

    else:
        raise AttributeError('Sufficient horizontal coordinates not defined.')

    return x, y
Exemple #60
0
def kml_trackers(request):
	trackers = Tracker.objects.filter(Q(view_users=request.user) | Q(creator=request.user))
	placemarks = ""
	g = Geod(ellps='clrk66')
	added_tracker_pks = []
	for tr in trackers:
		if tr.pk in added_tracker_pks:
			continue
		added_tracker_pks.append(tr.pk)
		pos_qs = Position.objects.filter(tracker=tr).order_by('-date')
		count = pos_qs.count()
		if not count:
			continue
		pos_qs = pos_qs.order_by('-date')
		pos = pos_qs[0]
		p = pos.point
		p_prev = None
		angle = 0.0
		stay = None
		if datetime.datetime.now() - pos.date > datetime.timedelta(seconds=settings.MIN_LINK_TIMEOUT):
			stay = True
		elif pos.speed != None:
			stay = pos.speed <= settings.STAY_AVG_SPEED
		if count > 1:
			pos_prev = pos_qs[1]
			p_prev = pos_prev.point
			angle, angle2, dist = g.inv(p_prev.x, p_prev.y, p.x, p.y)
			if stay == None:
				avg_speed = dist/float((pos.date-pos_prev.date).seconds)
				avg_speed = avg_speed*10/36.
				logger.debug("avg_speed: %s" % avg_speed)
				stay = avg_speed <= settings.STAY_AVG_SPEED
		if stay == None:
			stay = True
		if stay:
			image_url = settings.MEDIA_URL + 'images/icons/busstop.png'
			graphic = 'circle'
			angle = 0.0
		else:
			image_url = settings.MEDIA_URL + 'images/icons/bus.png'
			graphic = 'bus'

		marker_color = tr.marker_color if tr.marker_color else '00ff00'
		placemarks += """<Placemark><name>%s</name><description>%s</description><angle>%1.4f</angle><image>%s</image><graphic>%s</graphic><marker_color>#%s</marker_color><Point><coordinates>%1.6f,%1.6f</coordinates></Point></Placemark>""" % (tr.name, tr.description, angle, image_url, graphic, marker_color, p.x, p.y)
	kml = """<?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://earth.google.com/kml/2.2"><Document>%s</Document></kml>""" % placemarks
	return HttpResponse(kml)