{
  "id": 241453,
  "title": "Ellipsoidal to Cartesian coordinates, and back again...",
  "url": "/competitions/google-smartphone-decimeter-challenge/discussion/241453",
  "author_name": "",
  "post_date": "2021-05-24T15:43:23.742947500Z",
  "votes": 36,
  "comment_count": 1,
  "views": 0,
  "content": "<p>At some point one may find it useful to convert from our WGS84 coordinates to earth-centered, earth-fixed, or ECEF, coordinates. To do so is fairly easy:</p>\n<blockquote>\n  <p>\\( x=(N+h) \\cos \\varphi\\,\\cos \\lambda \\)<br>\n  \\(y=(N+h)\\cos \\varphi\\,\\sin \\lambda \\)<br>\n  \\(z=\\left ((1-e^2)N+h \\right)\\sin \\varphi \\)</p>\n</blockquote>\n<p>where \\( \\varphi \\) is the latitude, \\( \\lambda \\) is the longitude and \\( h \\) is the height. (For more details see the <a href=\"https://gssc.esa.int/navipedia/index.php/Ellipsoidal_and_Cartesian_Coordinates_Conversion\" target=\"_blank\">ESA Navipedia page</a>). Here is some python sample code</p>\n<pre><code>def WGS84_to_ECEF(lat, lon, alt):\n    # convert to radians\n    rad_lat = lat * (np.pi / 180.0)\n    rad_lon = lon * (np.pi / 180.0)\n    a    = 6378137.0\n    # f is the flattening factor\n    finv = 298.257223563\n    f = 1 / finv   \n    # e is the eccentricity\n    e2 = 1 - (1 - f) * (1 - f)    \n    # N is the radius of curvature in the prime vertical\n    N = a / np.sqrt(1 - e2 * np.sin(rad_lat) * np.sin(rad_lat))\n    x = (N + alt) * np.cos(rad_lat) * np.cos(rad_lon)\n    y = (N + alt) * np.cos(rad_lat) * np.sin(rad_lon)\n    z = (N * (1 - e2) + alt)        * np.sin(rad_lat)\n    return x, y, z\n</code></pre>\n<p>One can apply the function to our dataframe,<code>df</code>, like so:</p>\n<pre><code>df['x'], df['y'], df['z'] = zip(*df.apply(lambda x: WGS84_to_ECEF(x.latDeg, x.lngDeg, x.heightAboveWgs84EllipsoidM), axis=1))\n</code></pre>\n<p>However, the conversion from ECEF back to WGS84 is not so easy as it requires an iterative procedure. In view of this it is perhaps best to make use of the <a href=\"https://github.com/pyproj4/pyproj\" target=\"_blank\">pyproj</a>  interface to PROJ cartographic projections and coordinate transformations library:</p>\n<pre><code>import pyproj\nfrom pyproj import Proj, transform\ntransformer = pyproj.Transformer.from_crs(\n    {\"proj\":'geocent', \"ellps\":'WGS84', \"datum\":'WGS84'},\n    {\"proj\":'latlong', \"ellps\":'WGS84', \"datum\":'WGS84'},)\n\ndef ECEF_to_WGS84(x,y,z):\n    lon, lat, alt = transformer.transform(x,y,z,radians=False)\n    return lon, lat, alt\n</code></pre>\n<p>All the best and good luck,<br>\ncarl</p>",
  "messages": [
    {
      "id": "1321296",
      "postDate": "05/24/2021 15:43:23",
      "content": "<p>At some point one may find it useful to convert from our WGS84 coordinates to earth-centered, earth-fixed, or ECEF, coordinates. To do so is fairly easy:</p>\n<blockquote>\n  <p>\\( x=(N+h) \\cos \\varphi\\,\\cos \\lambda \\)<br>\n  \\(y=(N+h)\\cos \\varphi\\,\\sin \\lambda \\)<br>\n  \\(z=\\left ((1-e^2)N+h \\right)\\sin \\varphi \\)</p>\n</blockquote>\n<p>where \\( \\varphi \\) is the latitude, \\( \\lambda \\) is the longitude and \\( h \\) is the height. (For more details see the <a href=\"https://gssc.esa.int/navipedia/index.php/Ellipsoidal_and_Cartesian_Coordinates_Conversion\" target=\"_blank\">ESA Navipedia page</a>). Here is some python sample code</p>\n<pre><code>def WGS84_to_ECEF(lat, lon, alt):\n    # convert to radians\n    rad_lat = lat * (np.pi / 180.0)\n    rad_lon = lon * (np.pi / 180.0)\n    a    = 6378137.0\n    # f is the flattening factor\n    finv = 298.257223563\n    f = 1 / finv   \n    # e is the eccentricity\n    e2 = 1 - (1 - f) * (1 - f)    \n    # N is the radius of curvature in the prime vertical\n    N = a / np.sqrt(1 - e2 * np.sin(rad_lat) * np.sin(rad_lat))\n    x = (N + alt) * np.cos(rad_lat) * np.cos(rad_lon)\n    y = (N + alt) * np.cos(rad_lat) * np.sin(rad_lon)\n    z = (N * (1 - e2) + alt)        * np.sin(rad_lat)\n    return x, y, z\n</code></pre>\n<p>One can apply the function to our dataframe,<code>df</code>, like so:</p>\n<pre><code>df['x'], df['y'], df['z'] = zip(*df.apply(lambda x: WGS84_to_ECEF(x.latDeg, x.lngDeg, x.heightAboveWgs84EllipsoidM), axis=1))\n</code></pre>\n<p>However, the conversion from ECEF back to WGS84 is not so easy as it requires an iterative procedure. In view of this it is perhaps best to make use of the <a href=\"https://github.com/pyproj4/pyproj\" target=\"_blank\">pyproj</a>  interface to PROJ cartographic projections and coordinate transformations library:</p>\n<pre><code>import pyproj\nfrom pyproj import Proj, transform\ntransformer = pyproj.Transformer.from_crs(\n    {\"proj\":'geocent', \"ellps\":'WGS84', \"datum\":'WGS84'},\n    {\"proj\":'latlong', \"ellps\":'WGS84', \"datum\":'WGS84'},)\n\ndef ECEF_to_WGS84(x,y,z):\n    lon, lat, alt = transformer.transform(x,y,z,radians=False)\n    return lon, lat, alt\n</code></pre>\n<p>All the best and good luck,<br>\ncarl</p>",
      "rawMarkdown": "At some point one may find it useful to convert from our WGS84 coordinates to earth-centered, earth-fixed, or ECEF, coordinates. To do so is fairly easy:\n\n> \\\\( x=(N+h) \\cos \\varphi\\,\\cos \\lambda \\\\)\n> \\\\(y=(N+h)\\cos \\varphi\\,\\sin \\lambda \\\\)\n> \\\\(z=\\left ((1-e^2)N+h \\right)\\sin \\varphi \\\\)\n\nwhere \\\\( \\varphi \\\\) is the latitude, \\\\( \\lambda \\\\) is the longitude and \\\\( h \\\\) is the height. (For more details see the [ESA Navipedia page](https://gssc.esa.int/navipedia/index.php/Ellipsoidal_and_Cartesian_Coordinates_Conversion)). Here is some python sample code\n\n\n```\ndef WGS84_to_ECEF(lat, lon, alt):\n    # convert to radians\n    rad_lat = lat * (np.pi / 180.0)\n    rad_lon = lon * (np.pi / 180.0)\n    a    = 6378137.0\n    # f is the flattening factor\n    finv = 298.257223563\n    f = 1 / finv   \n    # e is the eccentricity\n    e2 = 1 - (1 - f) * (1 - f)    \n    # N is the radius of curvature in the prime vertical\n    N = a / np.sqrt(1 - e2 * np.sin(rad_lat) * np.sin(rad_lat))\n    x = (N + alt) * np.cos(rad_lat) * np.cos(rad_lon)\n    y = (N + alt) * np.cos(rad_lat) * np.sin(rad_lon)\n    z = (N * (1 - e2) + alt)        * np.sin(rad_lat)\n    return x, y, z\n```\n\nOne can apply the function to our dataframe,`df`, like so:\n```\ndf['x'], df['y'], df['z'] = zip(*df.apply(lambda x: WGS84_to_ECEF(x.latDeg, x.lngDeg, x.heightAboveWgs84EllipsoidM), axis=1))\n```\n\nHowever, the conversion from ECEF back to WGS84 is not so easy as it requires an iterative procedure. In view of this it is perhaps best to make use of the [pyproj](https://github.com/pyproj4/pyproj)  interface to PROJ cartographic projections and coordinate transformations library:\n\n```\nimport pyproj\nfrom pyproj import Proj, transform\ntransformer = pyproj.Transformer.from_crs(\n    {\"proj\":'geocent', \"ellps\":'WGS84', \"datum\":'WGS84'},\n    {\"proj\":'latlong', \"ellps\":'WGS84', \"datum\":'WGS84'},)\n\ndef ECEF_to_WGS84(x,y,z):\n    lon, lat, alt = transformer.transform(x,y,z,radians=False)\n    return lon, lat, alt\n```\n\nAll the best and good luck,\ncarl",
      "votes": null
    },
    {
      "id": "1321710",
      "postDate": "05/24/2021 22:09:11",
      "content": "<p>This is great information. Thank you for sharing it. </p>",
      "rawMarkdown": "This is great information. Thank you for sharing it.",
      "votes": null
    }
  ],
  "comments": [
    {
      "id": 1321710,
      "author_name": "dehokanta",
      "author_url": "",
      "post_date": "05/24/2021 22:09:11",
      "content": "<p>This is great information. Thank you for sharing it. </p>",
      "votes": null,
      "replies": []
    }
  ],
  "raw_markdown_by_id": {
    "1321296": "At some point one may find it useful to convert from our WGS84 coordinates to earth-centered, earth-fixed, or ECEF, coordinates. To do so is fairly easy:\n\n> \\\\( x=(N+h) \\cos \\varphi\\,\\cos \\lambda \\\\)\n> \\\\(y=(N+h)\\cos \\varphi\\,\\sin \\lambda \\\\)\n> \\\\(z=\\left ((1-e^2)N+h \\right)\\sin \\varphi \\\\)\n\nwhere \\\\( \\varphi \\\\) is the latitude, \\\\( \\lambda \\\\) is the longitude and \\\\( h \\\\) is the height. (For more details see the [ESA Navipedia page](https://gssc.esa.int/navipedia/index.php/Ellipsoidal_and_Cartesian_Coordinates_Conversion)). Here is some python sample code\n\n\n```\ndef WGS84_to_ECEF(lat, lon, alt):\n    # convert to radians\n    rad_lat = lat * (np.pi / 180.0)\n    rad_lon = lon * (np.pi / 180.0)\n    a    = 6378137.0\n    # f is the flattening factor\n    finv = 298.257223563\n    f = 1 / finv   \n    # e is the eccentricity\n    e2 = 1 - (1 - f) * (1 - f)    \n    # N is the radius of curvature in the prime vertical\n    N = a / np.sqrt(1 - e2 * np.sin(rad_lat) * np.sin(rad_lat))\n    x = (N + alt) * np.cos(rad_lat) * np.cos(rad_lon)\n    y = (N + alt) * np.cos(rad_lat) * np.sin(rad_lon)\n    z = (N * (1 - e2) + alt)        * np.sin(rad_lat)\n    return x, y, z\n```\n\nOne can apply the function to our dataframe,`df`, like so:\n```\ndf['x'], df['y'], df['z'] = zip(*df.apply(lambda x: WGS84_to_ECEF(x.latDeg, x.lngDeg, x.heightAboveWgs84EllipsoidM), axis=1))\n```\n\nHowever, the conversion from ECEF back to WGS84 is not so easy as it requires an iterative procedure. In view of this it is perhaps best to make use of the [pyproj](https://github.com/pyproj4/pyproj)  interface to PROJ cartographic projections and coordinate transformations library:\n\n```\nimport pyproj\nfrom pyproj import Proj, transform\ntransformer = pyproj.Transformer.from_crs(\n    {\"proj\":'geocent', \"ellps\":'WGS84', \"datum\":'WGS84'},\n    {\"proj\":'latlong', \"ellps\":'WGS84', \"datum\":'WGS84'},)\n\ndef ECEF_to_WGS84(x,y,z):\n    lon, lat, alt = transformer.transform(x,y,z,radians=False)\n    return lon, lat, alt\n```\n\nAll the best and good luck,\ncarl",
    "1321710": "This is great information. Thank you for sharing it."
  },
  "source": "meta"
}