title: Solving Practical Problems with Golang Latitude and Longitude in DMS Format
date: 2022-05-30 10:53:00
toc: false
index_img: https://puep.qpic.cn/coral/Q3auHgzwzM4fgQ41VTF2rGpUMPpyPrsMm6TJcdtuTd00Qp3a7jkPEg/0
category:
- Go
tags: - Calculation
- Format
Problem#
Write a program that can calculate the distance between each pair of landing points in the table "Landing Points on Mars" and answer the following questions:
- Which two landing points are closest to each other?
- Which two landing points are farthest from each other?
Then, define a new world based on the table "Measured Radii of Various Planets" and perform the following calculations:
- Calculate the distance between London, UK (latitude 51°31', longitude 0°08') and Paris, France (latitude 48°51', longitude 2°21').
- Calculate the distance between your city and the capital city.
- Calculate the distance between Mount Sharp on Mars (latitude 5°4'48", longitude 137°51') and Olympus Mons (latitude 18°39', longitude 226°12').
Landing Points on Mars#
Probe or Lander | Landing Point | Latitude | Longitude |
---|---|---|---|
Spirit | Columbia Memorial | South 14°34'6.2" | East 175°28'21.5" |
Opportunity | Challenger | South 1°56'46.3" | East 354°28'24.2" |
Curiosity | Bradbury Landing | South 4°35'22.2" | East 137°26'30.1" |
InSight | Elysium Planitia | North 4°30'0.0" | East 135°54'0" |
Measured Radii of Various Planets#
Planet | Radius/km | Planet | Radius/km |
---|---|---|---|
Mercury | 2439.7 | Jupiter | 69911 |
Venus | 6051.8 | Saturn | 58232 |
Earth | 6371.0 | Uranus | 25362 |
Mars | 3389.5 | Neptune | 24622 |
Code#
package main
import (
"fmt"
"math"
"strings"
)
type location struct {
lat, long float64
}
func newLocation(lat, long coordinate) location {
return location{
lat: lat.decimal(),
long: long.decimal(),
}
}
type coordinate struct {
d, m, s float64
h rune
}
func (c coordinate) decimal() float64 {
sign := 1.0
switch strings.ToLower(string(c.h)) {
case "s", "w":
sign = -1
}
return sign * (c.d + c.m/60 + c.s/3600)
}
type world struct {
radius float64
}
func (w world) distance(p1, p2 location) float64 {
s1, c1 := math.Sincos(rad(p1.lat))
s2, c2 := math.Sincos(rad(p2.lat))
clong := math.Cos(rad(p1.long - p2.long))
return w.radius * math.Acos(s1*s2+c1*c2*clong)
}
func rad(deg float64) float64 {
return deg * math.Pi / 180
}
var (
mars = world{radius: 3389.5}
earth = world{radius: 6371}
)
func main() {
// South 14°34'6.2", East 175°28'21.5"
spirit := newLocation(coordinate{d: 14, m: 34, s: 6.2, h: 'S'}, coordinate{d: 175, m: 28, s: 21.5, h: 'E'})
// South 1°56'46.3", East 354°28'24.2"
opportunity := newLocation(coordinate{d: 1, m: 56, s: 46.3, h: 'S'}, coordinate{d: 354, m: 28, s: 24.2, h: 'E'})
// South 4°35'22.2", East 137°26'30.1"
curiosity := newLocation(coordinate{d: 4, m: 35, s: 22.2, h: 'S'}, coordinate{d: 137, m: 26, s: 30.1, h: 'E'})
// North 4°30'0.0", East 135°54'0"
insight := newLocation(coordinate{d: 4, m: 30, s: 0.0, h: 'N'}, coordinate{d: 135, m: 54, s: 0, h: 'E'})
fmt.Printf("Spirit to Opportunity %.2f km\n", mars.distance(spirit, opportunity))
fmt.Printf("Spirit to Curiosity %.2f km\n", mars.distance(spirit, curiosity))
fmt.Printf("Spirit to Insight %.2f km\n", mars.distance(spirit, insight))
fmt.Printf("Opportunity to Curiosity %.2f km\n", mars.distance(opportunity, curiosity))
fmt.Printf("Opportunity to Insight %.2f km\n", mars.distance(opportunity, insight))
fmt.Printf("Curiosity to Insight %.2f km\n", mars.distance(curiosity, insight))
london := newLocation(coordinate{d: 51, m: 30, s: 0, h: 'N'}, coordinate{d: 0, m: 8, s: 0, h: 'W'})
paris := newLocation(coordinate{d: 48, m: 51, s: 0, h: 'N'}, coordinate{d: 2, m: 21, s: 0, h: 'E'})
fmt.Printf("London to Paris %.2f km\n", earth.distance(london, paris))
// Ref: https://map.jiqrxx.com/jingweidu/
chengdu := newLocation(coordinate{d: 30, m: 39, s: 3.24, h: 'N'}, coordinate{d: 104, m: 4, s: 35.16, h: 'E'})
home := newLocation(coordinate{d: 30, m: 32, s: 51.02, h: 'N'}, coordinate{d: 104, m: 6, s: 15.70, h: 'E'})
fmt.Printf("Chengdu to Home %.2f km\n", earth.distance(chengdu, home))
mountSharp := newLocation(coordinate{d: 5, m: 4, s: 48, h: 'S'}, coordinate{d: 137, m: 51, s: 0, h: 'E'})
olympusMons := newLocation(coordinate{d: 18, m: 39, s: 0, h: 'N'}, coordinate{d: 226, m: 12, s: 0, h: 'E'})
fmt.Printf("Mount Sharp to Olympus Mons %.2f km\n", mars.distance(mountSharp, olympusMons))
}
Results#
Spirit to Opportunity 9669.71 km
Spirit to Curiosity 2291.55 km
Spirit to Insight 2580.13 km
Opportunity to Curiosity 8425.63 km
Opportunity to Insight 8365.45 km
Curiosity to Insight 545.38 km
London to Paris 343.62 km
Chengdu to Home 11.80 km
Mount Sharp to Olympus Mons 5328.08 km
Summary#
- Go language achieves object-oriented features of traditional languages to a large extent through composition of structures and methods without introducing any new features.
- Go language does not provide any special language features for constructors; constructors are just regular functions.
- Go language uses functions with names in the format
newType
orNewType
to construct values of a specific type, and whether the first letter is capitalized depends on whether the function needs to be exported for use by other packages. - DMS format (degrees/minutes/seconds) represents positions, not time, where each 60 seconds (") is one minute, and each 60 minutes (') is one degree. For example, the position of Bradbury Landing is represented in DMS format as "South 4°35'22.2", East 137°26'30.1"".