{"id":444,"date":"2025-04-07T11:49:05","date_gmt":"2025-04-07T11:49:05","guid":{"rendered":"https:\/\/uat.esri.com\/en-us\/software-engineering\/blog\/?post_type=blog&#038;p=444"},"modified":"2025-04-16T17:20:25","modified_gmt":"2025-04-16T17:20:25","slug":"positions-of-gps-satellites-in-3d","status":"publish","type":"blog","link":"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/articles\/positions-of-gps-satellites-in-3d","title":{"rendered":"Positions of GPS Satellites in 3D"},"content":{"rendered":"\n<p class=\"undefined block-editor-paragraph\">Calculating the 3D positions of GPS satellites can be challenging due to the complex trigonometry involved in translating 2D coordinates plus angular directions to a 3D space. In this article, let&#8217;s explore how to calculate the positions and display satellite locations in 3D, real-time, and even in Augmented Reality!<\/p>\n\n\n\n<p class=\"undefined block-editor-paragraph\"><em>This is a revision of a <a href=\"https:\/\/community.esri.com\/t5\/arcgis-maps-sdks-native-blog\/positions-of-gps-satellites-in-3d\/ba-p\/1070293\">previous post<\/a> I wrote in the Esri Community &#8211; Native SDKs Blog in 2021. The main concepts remain the same, while some new features are added to the project, and the codebase is migrated to adopt the new 200.x ArcGIS Maps SDK for Swift.<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-concepts\"><strong>Concepts<\/strong><\/h2>\n\n\n\n<p class=\"undefined block-editor-paragraph\">Handheld GPS\/GNSS receivers are widely used devices that leverage signals from satellites to determine precise geographic locations. The receivers are used in various occasions such as navigation, outdoor recreation, surveying, and scientific research. And they can connect to computers and phones easily. They often use the NMEA protocol to communicate location data and other satellite-derived information in a standardized format. This protocol allows GPS receivers to be integrated with mapping software, expanding their usability beyond standalone navigation to include real-time data analysis and visualization.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"284\" height=\"610\" src=\"https:\/\/uat.esri.com\/en-us\/software-engineering\/blog\/wp-content\/uploads\/2025\/04\/SatelliteTrackingViewSmall-1.png\" alt=\"\" class=\"wp-image-526\" srcset=\"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/app\/uploads\/2025\/04\/SatelliteTrackingViewSmall-1.png 284w, https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/app\/uploads\/2025\/04\/SatelliteTrackingViewSmall-1-140x300.png 140w\" sizes=\"auto, (max-width: 284px) 100vw, 284px\" \/><figcaption class=\"wp-element-caption\">A typical representation of a satellite tracking view on a mobile device.<\/figcaption><\/figure><\/div>\n\n\n<p class=\"undefined block-editor-paragraph\">Many handheld GNSS\/GPS receivers support tracking satellite positions in 2D (schematically demonstrated in the diagram above). They typically use <code>$GPGSV<\/code> sentences from the NMEA (National Marine Electronics Association) specifications, which describe satellite positions through elevation and azimuth angles. These angles enable the calculation of approximate satellite positions in the sky by factoring in the receiver&#8217;s location coordinates, Earth\u2019s radius, GPS satellite orbit altitude, elevation angle, and azimuth angle. On certain devices, each satellite shows up as a signal bar; other devices use 2 concentric circles to depict the earth and the satellites&#8217; orbit, and the satellites are plotted on the graph. These graphics are OK in terms of giving people a general sense on where the satellites are currently located, but are neither intuitive, nor informative in 3D space. <\/p>\n\n\n\n<p class=\"undefined block-editor-paragraph\">To gain that 3D perspective, let&#8217;s look more at the elevation and azimuth angles provided in the <code>$GPGSV<\/code> sentences from the NMEA specs.<\/p>\n\n\n\n<p class=\"undefined block-editor-paragraph\">What are these angles? Imagine yourself standing in an open field (depicted by the gray plane in the image below), holding both a GPS receiver and a compass. <strong>Azimuth<\/strong> (the blue vector) tells us what direction to face at, and <strong>Elevation<\/strong> (the red vector) tells us how high up in the sky to look at. Turning around from the true north and raising the head, you can gaze at the approximate direction of the satellite in the sky with these 2 angles. These 2 values are simple to interpret for someone standing on the surface of the earth. However, things get a bit trickier when it comes to mapping software.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"685\" height=\"566\" src=\"https:\/\/uat.esri.com\/en-us\/software-engineering\/blog\/wp-content\/uploads\/2025\/04\/AzimuthElevationSmall.png\" alt=\"\" class=\"wp-image-531\" srcset=\"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/app\/uploads\/2025\/04\/AzimuthElevationSmall.png 685w, https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/app\/uploads\/2025\/04\/AzimuthElevationSmall-300x248.png 300w\" sizes=\"auto, (max-width: 685px) 100vw, 685px\" \/><figcaption class=\"wp-element-caption\">Concepts of Azimuth and Elevation angles in 3D space<\/figcaption><\/figure><\/div>\n\n\n<p class=\"undefined block-editor-paragraph\">How to represent azimuth and elevation on a map, or a 3D globe? There are a few known variables. The device location is represented as a pair of latitude-longitude (<em>lat-lon<\/em>) coordinates, which is a point on the earth&#8217;s surface. We also know where we should look at with these 2 angles. In a simplified way, the earth can be treated as a sphere (rather than an ellipsoid, which would complicate the math by quite a bit). Thus, we don&#8217;t need to take the variation of the radius of the earth into account, as it is always 6371 km.<\/p>\n\n\n\n<p class=\"undefined block-editor-paragraph\">The real problem is &#8211; how to convert our <em>lat-lon<\/em> coordinates on the surface of the globe into the 3D coordinate system of a sphere. Some trigonometry has to be done.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-methods\"><strong>Methods<\/strong><\/h2>\n\n\n\n<p class=\"undefined block-editor-paragraph\">For the technical discussion below, I&#8217;ll use Swift and related Apple APIs to demonstrate the idea.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-geometry-matrix-and-rotations\">Geometry, Matrix and Rotations<\/h3>\n\n\n\n<p class=\"undefined block-editor-paragraph\">The first thought was to convert all the <em>lat-lon<\/em> coordinates into 3D Cartesian coordinates of the sphere. However, it is quite complicated and error-prone to transform all the angles into <em>xyz<\/em>&#8216;s. The <em>lat-lon<\/em> coordinates aren&#8217;t too bad &#8211; just a few rectangular to polar conversions. The real pain is the azimuth and elevation angles &#8211; to represent them in Cartesian, much vector and polar math need to be done. In contrast, the problem can seemingly be expressed succinctly in a spherical coordinate system. Which led me towards thinking of vector operations and matrices. The resulting coordinates of the satellite are the summation of 2 vectors: the one from the center of the earth to the device location, and the other one from the device location to the satellite in the orbit, represented by azimuth and elevation angles.<\/p>\n\n\n\n<p class=\"undefined block-editor-paragraph\">Finding it hard to visualize the spatial relationships of these vectors in the spherical coordinates, I decided to sketch the whole system in 3D to make it clearer. Using the online geometry sketching tool <a href=\"https:\/\/www.geogebra.org\/calculator\">GeoGebra<\/a>, I was able to create a spatial representation of the satellite and the earth.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"2063\" height=\"1016\" src=\"https:\/\/uat.esri.com\/en-us\/software-engineering\/blog\/wp-content\/uploads\/2025\/01\/202501-elevation-angle-plane.png\" alt=\"\" class=\"wp-image-455\" srcset=\"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/app\/uploads\/2025\/01\/202501-elevation-angle-plane.png 2063w, https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/app\/uploads\/2025\/01\/202501-elevation-angle-plane-1536x756.png 1536w, https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/app\/uploads\/2025\/01\/202501-elevation-angle-plane-2048x1009.png 2048w, https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/app\/uploads\/2025\/01\/202501-elevation-angle-plane-826x407.png 826w, https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/app\/uploads\/2025\/01\/202501-elevation-angle-plane-1920x946.png 1920w\" sizes=\"auto, (max-width: 2063px) 100vw, 2063px\" \/><figcaption class=\"wp-element-caption\">Diagram to show what is an Elevation Angle<\/figcaption><\/figure><\/div>\n\n\n<p class=\"undefined block-editor-paragraph\">In order to calculate the coordinates, vanilla Cartesian transformations aren&#8217;t enough. Quaternions are introduced to express a position and orientation in space. SIMD library is used so that small vectors and matrices are easily expressed and quickly computed.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-quartenions\">Quartenions<\/h4>\n\n\n\n<p class=\"undefined block-editor-paragraph\">Quaternions are defined by a scalar (real) part, and three imaginary parts collectively called the vector part. They are often used in graphics programming as a compact representation of the spatial rotation of an object in three dimensions. One of the advantage is that they don&#8217;t suffer from singularity points (or gimbal locks), which are hard to avoid in Cartesian space when compounding rotations. Furthermore, they are quicker to compute than the representations by matrices. For instance, the <em>lat-lon<\/em> coordinates can be effectively represented by quaternions.<\/p>\n\n\n\n<p class=\"undefined block-editor-paragraph\">Consider a unit vector of the earth radius, with starting point at the center of the earth and terminal point at 0\u00b0 East on the equatorial plane. By rotating this vector along the y-axis by <em>latitude<\/em> degrees, and z-axis by <em>longitude<\/em> degrees, we will have the vector pointing at the <em>lat-lon<\/em> position on the surface of the globe.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-simd\">SIMD<\/h4>\n\n\n\n<p class=\"undefined block-editor-paragraph\">Swift has a handy <a href=\"https:\/\/developer.apple.com\/documentation\/accelerate\/simd\"><code>simd<\/code><\/a> library. <code>simd<\/code> provides integer and floating-point types and functions for small vector and matrix computations. The functions provide basic arithmetic operations, element-wise mathematical operations, and geometric and linear algebra operations. It supports up to 4\u00d74 elements in a matrix, which is a perfect fit for quaternions.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-the-quest-to-find-the-3rd-axis\">The Quest to Find \u201cThe 3rd Axis\u201d<\/h3>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><a href=\"https:\/\/uat.esri.com\/en-us\/software-engineering\/blog\/wp-content\/uploads\/2025\/01\/202501-animation.mp4\"><img loading=\"lazy\" decoding=\"async\" width=\"2400\" height=\"1602\" src=\"https:\/\/uat.esri.com\/en-us\/software-engineering\/blog\/wp-content\/uploads\/2025\/01\/202501-video-playback.png\" alt=\"Thumbnail for the animated video\" class=\"wp-image-458\" srcset=\"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/app\/uploads\/2025\/01\/202501-video-playback.png 2400w, https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/app\/uploads\/2025\/01\/202501-video-playback-1536x1025.png 1536w, https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/app\/uploads\/2025\/01\/202501-video-playback-2048x1367.png 2048w, https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/app\/uploads\/2025\/01\/202501-video-playback-697x465.png 697w, https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/app\/uploads\/2025\/01\/202501-video-playback-1618x1080.png 1618w\" sizes=\"auto, (max-width: 2400px) 100vw, 2400px\" \/><\/a><figcaption class=\"wp-element-caption\"><a href=\"https:\/\/uat.esri.com\/en-us\/software-engineering\/blog\/wp-content\/uploads\/2025\/01\/202501-animation.mp4\">Tap the image to see the animation<\/a><\/figcaption><\/figure><\/div>\n\n\n<figure class=\"wp-block-video\"><video src=\"https:\/\/uat.esri.com\/en-us\/software-engineering\/blog\/wp-content\/uploads\/2025\/01\/202501-animation.mp4\"><\/video><\/figure>\n\n\n\n<p class=\"undefined block-editor-paragraph\">Using quaternions, we are able to represent the <em>lat-lon<\/em> coordinates with 2 rotations using <em>y<\/em> and <em>z<\/em> axes as the first and second axes. To get the vector that points at the satellite from the <em>lat-lon<\/em> location, we need a third axis to incorporate azimuth and elevation angles. This is the trickiest math for this problem. To get there, we&#8217;ll need to rotate a <em>vector<\/em> according to the elevation angle. That <em>vector<\/em> itself needs to be rotated from another vector by the azimuth angle. To better denote it, I&#8217;m calling this vector <em>the 3rd axis<\/em>.<\/p>\n\n\n\n<p class=\"undefined block-editor-paragraph\">It is hard to describe it in words, so please use <a href=\"https:\/\/www.geogebra.org\/calculator\/gzpa7gqe\">the visualization on GeoGebra<\/a> to see it in action. Toggle the graphics on the left pane to see their spatial relationships.<\/p>\n\n\n\n<p class=\"undefined block-editor-paragraph\">With 3 axes, 4 quaternions and all the mysterious steps, how to ensure the result is correct? Luckily, with the visuals created on GeoGebra, I can get the azimuth and elevation values reversely from the result by specifying the other parameters, namely latitude, longitude, earth radius and orbit radius. So, if my calculation is correct, the resulting satellite coordinates should be the same as on GeoGebra.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-algorithm\">Algorithm<\/h3>\n\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-swift\" data-lang=\"Swift\"><code>\/\/\/ Calculates a satellite&#039;s position from its elevation and azimuth angles.\n\/\/\/ - Parameters:\n\/\/\/ - deviceLocation: The location of the device that receives satellite info.\n\/\/\/ - elevation: The elevation angle.\n\/\/\/ - azimuth: The azimuth angle.\n\/\/\/ - satelliteAltitude: The satellite&#039;s altitude above ground level.\n\/\/\/ - earthRadius: The earth&#039;s radius.\n\/\/\/ - Returns: A point representing the position of the satellite.\nfunc satellitePosition(\n    deviceLocation: Point,\n    elevation: Measurement&lt;UnitAngle&gt;,\n    azimuth: Measurement&lt;UnitAngle&gt;,\n    satelliteAltitude: Measurement&lt;UnitLength&gt; = .init(value: 20200, unit: .kilometers),\n    earthRadius: Measurement&lt;UnitLength&gt; = .init(value: 6371, unit: .kilometers)\n) -&gt; Point {\n \n    \/\/ Degree to radian conversions.\n    let longitude = Measurement&lt;UnitAngle&gt;(value: deviceLocation.x, unit: .degrees).converted(to: .radians).value\n    let latitude = Measurement&lt;UnitAngle&gt;(value: deviceLocation.y, unit: .degrees).converted(to: .radians).value\n    let elevation = elevation.converted(to: .radians).value\n    let azimuth = azimuth.converted(to: .radians).value\n\n    \/\/ 1. Basic trigonometry\n    let r1 = earthRadius.value\n    let r2 = r1 + satelliteAltitude.value\n    let elevationAngle = elevation + .pi \/ 2\n    let inscribedAngle = asin(r1 * sin(elevationAngle) \/ r2) \/\/ Law of Sines\n    let centralAngle = .pi - elevationAngle - inscribedAngle \/\/ Internal angles sum = pi\n\n    \/\/ 2. Magical quaternions\n    let latLonAxis = simd_normalize(\n        sphericalToCartesian(r: r1, theta: .pi \/ 2 - latitude, phi: longitude)\n    )\n \n    \/\/ Find the vector between device location and North point (z axis)\n    var thirdAxis = simd_normalize(\n        simd_double3(0, 0, 1 \/ latLonAxis.z) - latLonAxis\n    )\n \n    \/\/ Rotate to the azimuth angle\n    let quaternionAzimuth = simd_quatd(\n    angle: 1.5 * .pi - azimuth,\n        axis: latLonAxis\n    )\n    thirdAxis = quaternionAzimuth.act(thirdAxis)\n \n    \/\/ Rotate the lat-lon vector to elevation angle, with the rotated third axis\n    let quaternionElevation = simd_quatd(\n        angle: -centralAngle,\n        axis: thirdAxis\n    )\n    let resultVector = quaternionElevation.act(latLonAxis)\n\n    \/\/ 3. Make result\n    let result = cartesianToSpherical(vector: resultVector)\n    let resultLatitude = Measurement(\n        value: .pi \/ 2 - result.theta,\n        unit: UnitAngle.radians\n    ).converted(to: .degrees).value\n\n    let resultLongitude = Measurement(\n        value: result.phi,\n        unit: UnitAngle.radians\n    ).converted(to: .degrees).value\n\n    return Point(\n        x: resultLongitude,\n        y: resultLatitude,\n        z: satelliteAltitude.converted(to: .meters).value,\n        spatialReference: .wgs84\n    )\n}\n<\/code><\/pre><\/div>\n\n\n\n<p class=\"undefined block-editor-paragraph\">The method to get the satellite&#8217;s position can be split into 3 parts &#8211; basic trigonometry, quaternion rotation, and coordinate system conversion.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"736\" height=\"736\" src=\"https:\/\/uat.esri.com\/en-us\/software-engineering\/blog\/wp-content\/uploads\/2025\/01\/202501-elevation-angle-plane-annotated.png\" alt=\"Annotated angles in the elevation tangent plane\" class=\"wp-image-454\" srcset=\"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/app\/uploads\/2025\/01\/202501-elevation-angle-plane-annotated.png 736w, https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/app\/uploads\/2025\/01\/202501-elevation-angle-plane-annotated-150x150.png 150w, https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/app\/uploads\/2025\/01\/202501-elevation-angle-plane-annotated-465x465.png 465w\" sizes=\"auto, (max-width: 736px) 100vw, 736px\" \/><figcaption class=\"wp-element-caption\">Various angles for calculation, visualized<\/figcaption><\/figure><\/div>\n\n\n<p class=\"undefined block-editor-paragraph\">First, we need some basic trigonometry on the <em>elevation plane<\/em>, i.e. the plane where the elevation angle exists. Using Law of Sines, we can get the value of the <em>central angle<\/em>, assuming both the earth radius and the satellite orbital distance are constants.<\/p>\n\n\n\n<p class=\"undefined block-editor-paragraph\">Second, the rotations.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Rotate the <em>x<\/em> unit vector (0\u00b0 East) to get the <em>latLonAxis<\/em> vector, which starts at the center of the earth, and ends at our <em>lat-lon<\/em> point on the earth surface.<\/li>\n\n\n\n<li>In order to find the axis for the elevation angle rotation, we need to first create the <em>thirdAxis<\/em> &#8211; which is a vector that runs perpendicular to the rotated azimuth vector. The azimuth vector itself, is a line on a tangent plane of the earth (which the point of tangency is the <em>lat-lon<\/em> point) that, by definition, starts at the <em>lat-lon<\/em> position and ends at 0\u00b0 North, which intersects with the <em>z<\/em> axis.<\/li>\n\n\n\n<li>Ensure the sign of these angular values match the direction of rotation.<\/li>\n<\/ul>\n\n\n\n<p class=\"undefined block-editor-paragraph\">Third, convert the Cartesian coordinates back to the (geographic) spherical coordinates.<\/p>\n\n\n\n<p class=\"undefined block-editor-paragraph\">There are a few possible ways to test the algorithm&#8217;s correctness. The most accurate and straightforward way is to run the algorithm, and compare the result with the satellite coordinates from GeoGebra. One can also run some ad-hoc testing with the real data from a GPS receiver. For example, we should expect all the satellites-in-view to be above, rather than below the horizon; If a satellite has a very small elevation angle and the result does show it just above the horizon and vice versa, then it&#8217;s very likely that we&#8217;ve done it right!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-edge-case-0-latitude\">Edge Case: 0\u00b0 Latitude<\/h3>\n\n\n\n<p class=\"undefined block-editor-paragraph\">When the device&#8217;s <em>lat-lon<\/em> location is on the equatorial plane where the latitude equals to 0\u00b0 (say we are in <a href=\"https:\/\/www.google.com\/maps\/place\/Quito,+Ecuador\/\">Quito, Ecuador<\/a>), the tangent plane at that point is parallel to the <em>z<\/em> axis, which leads to the division by zero problem that introduces some ambiguity. Having searched online, I cannot fine a definitive answer on what is the azimuth angle for a location on the equator. Thanks to one of the comments from the old article, Anthony proposed a workaround to add a small deviation when latitude is zero, and I think it is valid workaround.<\/p>\n\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-swift\" data-lang=\"Swift\"><code>var thirdAxis: simd_double3\nif latLonAxis.z == 0 {\n   \/\/ To avoid division by zero error.\n   thirdAxis = simd_double3(0, 0, 1)\n} else {\n   thirdAxis = simd_normalize(simd_double3(0, 0, 1 \/ latLonAxis.z) - latLonAxis)\n}<\/code><\/pre><\/div>\n\n\n\n<p class=\"undefined block-editor-paragraph\">The other way is to handle the division by zero as a special case. As we approach the equator from the Northern Hemisphere, the limit of the third axis approximately equals the <em>z<\/em> unit vector. If the azimuth angle reported by the GPS receiver is as expected, the result should be correct. While it can also be totally wrong if the reported azimuth angle is a default fallback value for this edge case.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-results\"><strong>Results<\/strong><\/h2>\n\n\n\n<p class=\"undefined block-editor-paragraph\">The results are verified and displayed using the ArcGIS Maps SDK for Swift, which provides 3D and Augmented Realit (AR) visualization of the calculations. <a href=\"https:\/\/github.com\/yo1995\/Daily_Swift_Tasks\/tree\/master\/NMEASatelliteDemo\">The demo app<\/a> is tested with <em>Bad Elf GPS Pro+<\/em> GNSS surveyor. It includes a test NMEA data that features a 2-minute driving trip around Redlands, CA.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"2456\" height=\"1746\" src=\"https:\/\/uat.esri.com\/en-us\/software-engineering\/blog\/wp-content\/uploads\/2025\/01\/202501-app-screenshot.png\" alt=\"Satellite 3D demo app screenshot\" class=\"wp-image-452\" srcset=\"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/app\/uploads\/2025\/01\/202501-app-screenshot.png 2456w, https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/app\/uploads\/2025\/01\/202501-app-screenshot-1536x1092.png 1536w, https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/app\/uploads\/2025\/01\/202501-app-screenshot-2048x1456.png 2048w, https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/app\/uploads\/2025\/01\/202501-app-screenshot-654x465.png 654w, https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/app\/uploads\/2025\/01\/202501-app-screenshot-1519x1080.png 1519w\" sizes=\"auto, (max-width: 2456px) 100vw, 2456px\" \/><figcaption class=\"wp-element-caption\">Screenshots of the Satellite demo app in 3D (left) and real-time satellite locating by thumb using AR (right)!<\/figcaption><\/figure><\/div>\n\n\n<p class=\"undefined block-editor-paragraph\">When thinking about satellites, people often perceive them as not-relatable high-tech objects that is only accessible by top officials and scientists. In other words, only professionals have the technical know-how to operate them. And even for them, trying to visualize the satellites in 3D is laborious. One of the less explained topics is how to solve the mathematical problem, specifically trigonometry, of converting receiver data (receiver <em>lat-lon<\/em> coordinates, Earth radius, GPS satellite orbit altitude, elevation angle, and azimuth angle) into <em>lat-lon-z<\/em> coordinates to represent them in 3D mapping. Which is exactly what this article wants to achieve.<\/p>\n\n\n\n<p class=\"undefined block-editor-paragraph\">At first, transforming the azimuth-elevation representation of a satellite position into its <em>lat-lon<\/em> location seems to be an insignificant chore. After all, there are only 2 values to be transformed, how hard it can be? It turns out to be a quite interesting topic that involves many concepts for translating one spatial representation to another. The resulting algorithm is still quite concise, thanks to the use of quaternions.<\/p>\n\n\n\n<p class=\"undefined block-editor-paragraph\">People love to see the satellites in a perceivable graphical representation! With today&#8217;s advancement in 3D mapping technology, it&#8217;s never been easier to visualize those remote objects in space at our fingertips. When I first presented the results, people were astounded by the fact that these satellites are just there, orbiting above our heads and working tirelessly to connect everyone, everywhere.<\/p>\n\n\n\n<p class=\"undefined block-editor-paragraph\">Best of all, you can try the app I&#8217;ve shown in this article out for free with ease! Follow the link at the end to download the project to trace the stellar whispers of satellites as they dance across the deep space, weaving secrets of the cosmos just for you.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-summary\"><strong>Summary<\/strong><\/h2>\n\n\n\n<p class=\"undefined block-editor-paragraph\">In this article, we have explored the fascinating challenge of calculating and visualizing GPS satellite positions in 3D. We tackled unique technical hurdles, such as converting azimuth and elevation angles into 3D <em>lat-lon<\/em> coordinates, leveraging quaternions for rotations, and simplifying complex spatial math with Swift&#8217;s SIMD library. In the end, we created a SwiftUI-based app that uses ArcGIS Maps SDK for Swift to display satellite positions in an intuitive 3D scene. To dive deeper into the code and learn more, check out the <a href=\"https:\/\/github.com\/yo1995\/Daily_Swift_Tasks\/tree\/master\/NMEASatelliteDemoSwiftUI\">GitHub repository<\/a> and <a href=\"https:\/\/developers.arcgis.com\/swift\/api-reference\/documentation\/arcgis\/\">ArcGIS Maps SDK documentation<\/a>.<\/p>\n\n\n\n<p class=\"undefined block-editor-paragraph\">If you\u2019re interested in solving GIS-related technical problems like these, consider exploring opportunities at <a href=\"https:\/\/www.esri.com\/en-us\/about\/careers\/overview\">Esri Careers<\/a>. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-bonus-augmented-reality\">Bonus: Augmented Reality<\/h2>\n\n\n\n<p class=\"undefined block-editor-paragraph\">Since we have done all the calculations to pinpoint the location of the satellites flying in the sky, why not go one step further to show them in Augmented Reality? Point the camera on the device to the sky, and you can see the satellite positions rendered in real time with AR. It would make a great educational tool for people who want to get a better sense of GPS satellites.<\/p>\n\n\n\n<p class=\"undefined block-editor-paragraph\"><a href=\"https:\/\/github.com\/yo1995\/Daily_Swift_Tasks\/tree\/master\/NMEASatelliteDemoSwiftUI\">In the app<\/a>, I added leader lines between the device location and the satellites. People can see through their AR camera and use their finger to follow along the approximate direction of a satellite. While it might be less accurate due to the general limitation of AR nowadays, it is still a fun experience and would be helpful if you are trying to observe the satellites with a telescope ;-).<\/p>\n\n\n\n<p class=\"undefined block-editor-paragraph\"><\/p>\n","protected":false},"author":11,"featured_media":0,"parent":0,"menu_order":0,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[3],"tags":[39,37,40,34],"class_list":["post-444","blog","type-blog","status-publish","format-standard","hentry","category-software-development","tag-3d","tag-ios-development","tag-satellite-positioning","tag-swift"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v23.2 (Yoast SEO v25.0) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Positions of GPS Satellites in 3D - Esri Software Engineering Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/articles\/positions-of-gps-satellites-in-3d\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Positions of GPS Satellites in 3D\" \/>\n<meta property=\"og:description\" content=\"Calculating the 3D positions of GPS satellites can be challenging due to the complex trigonometry involved in translating 2D coordinates plus angular directions to a 3D space. In this article, let&#8217;s explore how to calculate the positions and display satellite locations in 3D, real-time, and even in Augmented Reality! This is a revision of a [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/articles\/positions-of-gps-satellites-in-3d\" \/>\n<meta property=\"og:site_name\" content=\"Esri Software Engineering Blog\" \/>\n<meta property=\"article:modified_time\" content=\"2025-04-16T17:20:25+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/uat.esri.com\/en-us\/software-engineering\/blog\/wp-content\/uploads\/2025\/04\/SatelliteTrackingViewSmall-1.png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"12 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/articles\/positions-of-gps-satellites-in-3d\",\"url\":\"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/articles\/positions-of-gps-satellites-in-3d\",\"name\":\"Positions of GPS Satellites in 3D - Esri Software Engineering Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/articles\/positions-of-gps-satellites-in-3d#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/articles\/positions-of-gps-satellites-in-3d#primaryimage\"},\"thumbnailUrl\":\"https:\/\/uat.esri.com\/en-us\/software-engineering\/blog\/wp-content\/uploads\/2025\/04\/SatelliteTrackingViewSmall-1.png\",\"datePublished\":\"2025-04-07T11:49:05+00:00\",\"dateModified\":\"2025-04-16T17:20:25+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/articles\/positions-of-gps-satellites-in-3d#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/articles\/positions-of-gps-satellites-in-3d\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/articles\/positions-of-gps-satellites-in-3d#primaryimage\",\"url\":\"https:\/\/uat.esri.com\/en-us\/software-engineering\/blog\/wp-content\/uploads\/2025\/04\/SatelliteTrackingViewSmall-1.png\",\"contentUrl\":\"https:\/\/uat.esri.com\/en-us\/software-engineering\/blog\/wp-content\/uploads\/2025\/04\/SatelliteTrackingViewSmall-1.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/articles\/positions-of-gps-satellites-in-3d#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Positions of GPS Satellites in 3D\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/#website\",\"url\":\"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/\",\"name\":\"Esri Software Engineering Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Positions of GPS Satellites in 3D - Esri Software Engineering Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/articles\/positions-of-gps-satellites-in-3d","og_locale":"en_US","og_type":"article","og_title":"Positions of GPS Satellites in 3D","og_description":"Calculating the 3D positions of GPS satellites can be challenging due to the complex trigonometry involved in translating 2D coordinates plus angular directions to a 3D space. In this article, let&#8217;s explore how to calculate the positions and display satellite locations in 3D, real-time, and even in Augmented Reality! This is a revision of a [&hellip;]","og_url":"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/articles\/positions-of-gps-satellites-in-3d","og_site_name":"Esri Software Engineering Blog","article_modified_time":"2025-04-16T17:20:25+00:00","og_image":[{"url":"https:\/\/uat.esri.com\/en-us\/software-engineering\/blog\/wp-content\/uploads\/2025\/04\/SatelliteTrackingViewSmall-1.png","type":"","width":"","height":""}],"twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"12 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/articles\/positions-of-gps-satellites-in-3d","url":"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/articles\/positions-of-gps-satellites-in-3d","name":"Positions of GPS Satellites in 3D - Esri Software Engineering Blog","isPartOf":{"@id":"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/articles\/positions-of-gps-satellites-in-3d#primaryimage"},"image":{"@id":"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/articles\/positions-of-gps-satellites-in-3d#primaryimage"},"thumbnailUrl":"https:\/\/uat.esri.com\/en-us\/software-engineering\/blog\/wp-content\/uploads\/2025\/04\/SatelliteTrackingViewSmall-1.png","datePublished":"2025-04-07T11:49:05+00:00","dateModified":"2025-04-16T17:20:25+00:00","breadcrumb":{"@id":"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/articles\/positions-of-gps-satellites-in-3d#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/articles\/positions-of-gps-satellites-in-3d"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/articles\/positions-of-gps-satellites-in-3d#primaryimage","url":"https:\/\/uat.esri.com\/en-us\/software-engineering\/blog\/wp-content\/uploads\/2025\/04\/SatelliteTrackingViewSmall-1.png","contentUrl":"https:\/\/uat.esri.com\/en-us\/software-engineering\/blog\/wp-content\/uploads\/2025\/04\/SatelliteTrackingViewSmall-1.png"},{"@type":"BreadcrumbList","@id":"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/articles\/positions-of-gps-satellites-in-3d#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.esri.com\/en-us\/software-engineering\/blog"},{"@type":"ListItem","position":2,"name":"Positions of GPS Satellites in 3D"}]},{"@type":"WebSite","@id":"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/#website","url":"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/","name":"Esri Software Engineering Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"}]}},"text_date":"April 7, 2025","author_name":"Ting Chen","author_page":"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/author\/ting-chen","custom_image":"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/app\/uploads\/2025\/04\/SatelliteBanner.png","primary_product":false,"tag_data":[{"term_id":39,"name":"3D","slug":"3d","term_group":0,"term_taxonomy_id":39,"taxonomy":"post_tag","description":"","parent":0,"count":2,"filter":"raw"},{"term_id":37,"name":"iOS Development","slug":"ios-development","term_group":0,"term_taxonomy_id":37,"taxonomy":"post_tag","description":"","parent":0,"count":2,"filter":"raw"},{"term_id":40,"name":"Satellite Positioning","slug":"satellite-positioning","term_group":0,"term_taxonomy_id":40,"taxonomy":"post_tag","description":"","parent":0,"count":1,"filter":"raw"},{"term_id":34,"name":"swift","slug":"swift","term_group":0,"term_taxonomy_id":34,"taxonomy":"post_tag","description":"","parent":0,"count":3,"filter":"raw"}],"category_data":[{"term_id":3,"name":"Software development","slug":"software-development","term_group":0,"term_taxonomy_id":3,"taxonomy":"category","description":"Articles focusing on how we apply coding practices, software design, development methodologies, and tools used while building our products, systems, etc.","parent":0,"count":8,"filter":"raw"}],"product_data":{"errors":{"invalid_taxonomy":["Invalid taxonomy."]},"error_data":[]},"primary_product_link":"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/","short_description":"Learn the algorithms involved to map the positions of GPS satellites in the sky in real-time.","image":"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/app\/uploads\/2025\/01\/202501-title-image.png","_links":{"self":[{"href":"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/wp-json\/wp\/v2\/article\/444","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/wp-json\/wp\/v2\/article"}],"about":[{"href":"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/wp-json\/wp\/v2\/types\/blog"}],"author":[{"embeddable":true,"href":"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/wp-json\/wp\/v2\/users\/11"}],"version-history":[{"count":0,"href":"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/wp-json\/wp\/v2\/article\/444\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/wp-json\/wp\/v2\/media?parent=444"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/wp-json\/wp\/v2\/categories?post=444"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.esri.com\/en-us\/software-engineering\/blog\/wp-json\/wp\/v2\/tags?post=444"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}