Ecliptic coordinates of an Observer in PyEphem - coordinates

I would like to have the ecliptic coordinates of a point on Earth. I can set up an observer using Pyephem:
station = ephem.Observer()
station.lon = '14:18:40.7'
station.lat = '48:19:14.0'
station.pressure = 0
station.epoch = ephem.J2000
station.elevation = 100.0
Then setup a date
station.date = ephem.date(datetime.utcnow())
But I don't know how to get this point coordinates in the Ecliptic system. If I try the Ecliptic function on the station Object it fails. Is there a way to do that in PyEphem?

If by “the ecliptic coordinates of a point on Earth” you mean “the ecliptic latitude and longitude which are overhead for a point on Earth,” then you might be able to generate a correct position by asking for the RA and declination of the point in the sky directly overhead for the location — where “directly overhead” is expressed astronomically as “at 90° altitude in the sky.” You would follow your code above with something like:
ra, dec = station.radec_of('0', '90')
ec = ephem.Ecliptic(ra, dec)
print 'Ecliptic latitude:', ec.lat
print 'Ecliptic longitude:', ec.lon
Try this technique out and see whether it returns a value anything like what you are expecting!

Related

Lunar Librations and Subsolar Point in Matlab

So I have been trying to write a program to generate the latitude and longitude of the lunar subsolar point in Matlab.
I have the ephemeris data from aero toolbox, but I can't seem to get values that make sense.
The method I'm currently trying (without success) is...
Generate a juliandate for a specific time
Find the position of the sun relative to the moon from the ephemeris data for the specified date
Find the (φ, θ, ψ) lunar attitude from the ephemeris data
Create a rotational matrix from the lunar attitude values
Transpose the matrix to get the inverse rotation (to convert the vector from the ICRF frame to the moon's coordinate system)
Apply that rotation to the direction of the sun vector
Convert to spherical coordinates (longitude, latitude)
mission_time = juliandate(2022, 1, 1);
sun_pos = planetEphemeris(mission_time, 'Moon', 'Sun');
moon_rot = moonLibration(mission_time);
rotm = eul2rotm(moon_rot);
rotm = transpose(rotm);
sun_vec = sun_pos / norm(sun_pos);
sun_vec = sun_vec * rotm;
[ss_long, ss_lat] = cart2sph(sun_vec(1), sun_vec(2), sun_vec(3))
fprintf("Subsolar Lat: %2.2f°\tSubsolar Long: %2.2f°\n", rad2deg(ss_long), rad2deg(ss_lat))
The subsolar latitude should be like ±1.57° but this calculation goes all over the place. What am I missing?

How to find the local horizon longitude of the highest point of the ecliptic

I would like to use pyephem or skyfield to find the degree of the local horizon (starting from South = 0°) at which is located the highest point of the ecliptic. Note that I am not trying to find the culmination of a planet. It could well be that, when looking South, there is no planet on the ecliptic by that time/latitude, but there will still be a highest point of the ecliptic. Can anyone help?
While it’s likely that someone will soon jump in with a closed-form solution that uses spherical trigonometry — in which case it’s likely that Skyfield or PyEphem will only be used to determine the Earth orientation — here’s a quick way to get an answer within about a degree:
Generate the ecliptic as 360 points one degree apart across the sky.
Compute the altitude and azimuth of each one.
Choose the highest.
The result agrees closely to what I see if I open Stellarium, turn on the ecliptic, and choose a field star right near the point where the ecliptic reaches the highest point in the sky.
import numpy as np
from skyfield import api, framelib
from skyfield.positionlib import Apparent
𝜏 = api.tau
ts = api.load.timescale()
eph = api.load('de421.bsp')
bluffton = api.Topos('40.74 N', '84.11 W')
t = ts.utc(2021, 2, 16, 22, 52)
angle = np.arange(360) / 360.0 * 𝜏
zero = angle * 0.0
f = framelib.ecliptic_frame
d = api.Distance([np.sin(angle), np.cos(angle), zero])
v = api.Velocity([zero, zero, zero])
p = Apparent.from_time_and_frame_vectors(t, f, d, v)
p.center = bluffton
alt, az, distance = p.altaz()
i = np.argmax(alt.degrees) # Which of the 360 points has highest altitude?
print('Altitude of highest point on ecliptic:', alt.degrees[i])
print('Azimuth of highest point on ecliptic:', az.degrees[i])
The result:
Altitude of highest point on ecliptic: 67.5477569215633
Azimuth of highest point on ecliptic: 163.42529398930515
This is probably a computationally expensive enough approach that it won’t interest you once you or someone else does the spherical trigonometry to find an equation for the azimuth; but at the very least this might provide numbers to check possible formulae against.

Confusion with using dec/ra to compute sub-lunar location

I have a need to compute the apparent azimuth and elevation angles as well as the sub-lunar lat/lon for a given date/time. The az/el angles I get generally agree with other sources (MoonCalc.org, Horizons, etc.) but there are not good comparison sources for the sub-lunar lat/lon. More importantly, I doubt the lat/lon I get using the dec/ra values because the ra barely changes over long time frames.
Here is the basic call I am making:
roc.date='2018/1/1 01:00:00'
moon=ephem.Moon(roc)
print('rocMoonTest: %s UTC-4, lat/lon = %0.4f [+N], %0.4f [+E]' %
(roc.date, math.degrees(roc.lat), math.degrees(roc.lon)))
print('Moon dec/ra = %s [+N], %s [+W]' % (moon.dec, moon.ra ))
print('Moon a_dec/a_ra = %s [+N], %s [+W]' % (moon.a_dec, moon.a_ra ))
print('Moon g_dec/g_ra = %s [+N], %s [+W]' % (moon.g_dec, moon.g_ra ))
print('Moon az/el = %0.4f, %0.4f' %
(math.degrees(moon.az), math.degrees(moon.alt)))
And then I iterate on that every 3 hours. Below is the output:
rocMoonTest: 2018/1/1 01:00:00 UTC-4, lat/lon = 43.0000 [+N], -78.0000 [+E]
Moon dec/ra = 18:53:07.1 [+N], 5:43:03.33 [+W]
Moon a_dec/a_ra = 19:22:21.3 [+N], 5:39:38.43 [+W]
Moon g_dec/g_ra = 19:22:44.7 [+N], 5:40:41.41 [+W]
Moon az/el = 105.3953, 43.0670
rocMoonTest: 2018/1/1 04:00:00 UTC-4, lat/lon = 43.0000 [+N], -78.0000 [+E]
Moon dec/ra = 19:07:55.4 [+N], 5:49:00.24 [+W]
Moon a_dec/a_ra = 19:32:24.2 [+N], 5:47:42.22 [+W]
Moon g_dec/g_ra = 19:32:35.1 [+N], 5:48:45.29 [+W]
Moon az/el = 169.5907, 65.8406
rocMoonTest: 2018/1/1 07:00:00 UTC-4, lat/lon = 43.0000 [+N], -78.0000 [+E]
Moon dec/ra = 19:13:15.7 [+N], 5:54:49.89 [+W]
Moon a_dec/a_ra = 19:41:07.2 [+N], 5:55:47.50 [+W]
Moon g_dec/g_ra = 19:41:05.5 [+N], 5:56:50.65 [+W]
Moon az/el = 246.5737, 49.4664
As expected and as verified by the az/el angles, the moon swings from East to West as the earth rotates and reaches a peak altitude somewhere during the period. However, none of the various dec/ra values change significantly. Over this 6 hour span, I would expect to see approximately a 6 hour change in the ra. Obviously, when I use any of these ra values to compute the longitude, I get the wrong answer. It appears the reference frame for dev/ra is not rotating with the earth. However, the docs indicate that I should expect it to.
Anyone care to explain where I went wrong in my understanding of the various right ascension variables and what the most direct way is to compute the sub-lunar lat/lon? Note, I would rather avoid using an approach that rotates the apparent az/el position into geodetic lat/lon.
The measurement “Right Ascension" is made not against the rotating surface of the Earth, but against the fixed stars of the sky — it is a kind of longitude but whose origin is the point on a star chart where the two great “equators of the sky,” the Earth’s equator and the “Solar System's equator”, the Ecliptic (which is not truly the Solar System equator because it's the plane of the Earth's orbit, rather than the weighted average of all planetary orbits), cross.
Since the point of their crossing itself moves as the ages pass, the system of Right Ascension is very slightly different every year, and very different across centuries and millenia. So Right Ascension and declination (celestial latitude) always have to be specified relative to some date, some exact moment like B1950 or J2000.
There is now a fixed coordinate system for RA and dec that doesn't move, the ICRS, which is oriented like J2000 but is defined using the positions of quasars which (we assume) won't move measurably within the lifetime of our species.
regarding this part of your question
what the most direct way is to compute the sub-lunar lat/lon?
Here is my code to calculate the sublunar point.
greenwich = ephem.Observer()
greenwich.lat = "0"
greenwich.lon = "0"
greenwich.date = datetime.utcnow()
#add Moon Sub Solar Point
moon = ephem.Moon(greenwich)
moon.compute(greenwich.date)
moon_lon = math.degrees(moon.ra - greenwich.sidereal_time() )
# map longitude value from -180 to +180
if moon_lon < -180.0 :
moon_lon = 360.0 + moon_lon
elif moon_lon > 180.0 :
moon_lon = moon_lon - 360.0
moon_lat = math.degrees(moon.dec)
print "moon Lon:",moon_lon, "Lat:",moon_lat
Hope that helps. I also use the same approach to calculate the sub-solar point. Works great for me.
EDIT: Yes... latitude of Greenwich is set to zero BECAUSE it doesn't matter at all for this calculation.
You might reinforce your thinking in the direction of this approach by taking a look at this other link:
Computing sub-solar point
Which gives basically the same solution, but for the sub_solar_point, also from Liam Kennedy (where he gave a non zero Lat for Greenwich), and also with an answer from Brandon Rhodes who wrapped the xephem library in python to give us pyephem, and until recently was actively maintaining it. Brandon is now focusing more on his next iteration, a pure python library called skyfield, which uses the latest available ephemeris with a more intuitive API.
https://pypi.org/project/skyfield/
https://rhodesmill.org/skyfield/installation.html
Although I can not contribute it now, might I suggest a comparison of the results of pyephem and skyfield, perhaps in a matplotlib figure or two, IOW, just how different/improved might be the results from skyfield?

iphone -- convert MKMapPoint distances to meters

Say I have a square which consists of four CLLocationCoordinate2D points, which are in lat, lon, and I want to find the area of the square in meters. I convert the CLLocationCoordinate2D points into MKMapPoints, and I find the area in X-Y space. However, the area I find is in the units of MKMapPoint, which don't directly translate to meters. How can I translate this area in MKMapPoint-space back into meters?
The MapKit function MKMetersBetweenMapPoints makes this easier.
For example, if you wanted to get the area of the currently displayed region:
MKMapPoint mpTopLeft = mapView.visibleMapRect.origin;
MKMapPoint mpTopRight = MKMapPointMake(
mapView.visibleMapRect.origin.x + mapView.visibleMapRect.size.width,
mapView.visibleMapRect.origin.y);
MKMapPoint mpBottomRight = MKMapPointMake(
mapView.visibleMapRect.origin.x + mapView.visibleMapRect.size.width,
mapView.visibleMapRect.origin.y + mapView.visibleMapRect.size.height);
CLLocationDistance hDist = MKMetersBetweenMapPoints(mpTopLeft, mpTopRight);
CLLocationDistance vDist = MKMetersBetweenMapPoints(mpTopRight, mpBottomRight);
double vmrArea = hDist * vDist;
The documentation states that the function takes "into account the curvature of the Earth."
You can use the Haversine formula to calculate it, assuming that the earth is a perfect sphere.
To understand how lat/lon vs meters works in the context of the earth, you may find it interesting to read about Nautical miles.
You can find some more resources and some sample code by googling objective-c Haversine formula.
Enjoy!

GPS coordinates in degrees to calculate distances

On the iPhone, I get the user's location in decimal degrees, for example: latitude 39.470920 and longitude = -0.373192; That's point A.
I need to create a line with another GPS coordinate, also in decimal degrees, point B. Then, calculate the distance (perpendicular) between the line from A to B and another point C.
The problem is I get confused with the values in degrees. I would like to have the result in meters. What's the conversion needed? How will the final formula to compute this look like?
Why don't you use CLLocations distanceFromLocation: method? It will tell you the precise distance between the receiver and another CLLocation.
CLLocation *locationA = [[CLLocation alloc] initWithLatitude:12.123456 longitude:12.123456];
CLLocation *locationB = [[CLLocation alloc] initWithLatitude:21.654321 longitude:21.654321];
CLLocationDistance distanceInMeters = [locationA distanceFromLocation:locationB];
// CLLocation is aka double
[locationA release];
[locationB release];
It's as easy as that.
(CLLocationDistance)distanceFromLocation:(const CLLocation *)location is the method to get the distance from on CLLocation to another.
Your problem is also of finding the shortest line between a line (A,B) and point C.
I guess if your 3 CLLocations are near ( less than a few kilometers apart), you can do the math "as if" the coordinates are points on a single plane, and use this in C++, or this or this and just use the CLLocations "as if" they were x and y coordinates on a plane.
If your coordinates are far away, or exact accuracy is important then the spherical shape of the earth matters, and you need to do things using great circle distance and other geometry on the face of a sphere.
Swift 3.0+
Only calculate distance between two coordinates:
let distance = source.distance(from: destination)
When you have array of locations:
To get distance from array of points use below reduce method.
Here locations is array of type CLLocation.
let calculatedDistance = locations.reduce((0, locations[0])) { ($0.0 + $0.1.distance(from: $1), $1)}.0
Here you will get distance in meters.