title: Solving Practical Problems with Golang Latitude and Longitude DMS
date: 2022-05-30 20:56:00
toc: false
index_img: https://puep.qpic.cn/coral/Q3auHgzwzM4fgQ41VTF2rOU6dDf5z5eHjtKaxyHSNLafiaq6Z9sVjzQ/0
category:
- Go
tags: - Automatic
- Creation
- Computation
- Strings
- Printing
Problem#
Please write a program that uses the gps
structure to represent the Global Positioning System (GPS). This structure should consist of two location
structures and one world
structure, where the former is used to represent the current and target locations, and the latter is used to represent the world where the locations are located.
Please implement a description
method for the location
type, which returns a string containing the name, latitude, and longitude. As for the implementation of the world
type, please refer to the article:
{post cid="32"}
which mentions the func (w world) distance(p1, p2 location) float64
method.
Please bind two methods to the gps
type. The first one is the distance
method, which is used to calculate the distance between the current and target locations. The second one is the message
method, which describes the distance to the destination in kilometers as a string.
Finally, please create a rover
structure and embed gps
in it. Then write a main
function to test all the functionalities. Please initialize a Global Positioning System for Mars in the test function, set its current location to the Bradbury Landing site (-4.5895, 137.4417)
, and set the target location to the Elysium Planitia (4.5, 135.9)
. Then create a curiosity
rover and use the message
method to print the corresponding information (this method will be forwarded to the same-named method of the gps
type).
gps.go#
package main
import (
"fmt"
"math"
)
type world struct {
radius float64
}
type location struct {
name string
lat, long float64
}
func (l location) description() string {
return fmt.Sprintf("%v (%.1f°, %.1f°)", l.name, l.lat, l.long)
}
type gps struct {
world world
current location
destination location
}
func (g gps) distance() float64 {
return g.world.distance(g.current, g.destination)
}
func (g gps) message() string {
return fmt.Sprintf("%.1f km to %v", g.distance(), g.destination.description())
}
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
}
type rover struct {
gps
}
func main() {
mars := world{3389.5}
bradbury := location{"Bradbury Landing", -4.5895, 137.4417}
elysium := location{"Elysium Planitia", 4.5, 135.9}
gps := gps{mars, bradbury, elysium}
curiosity := rover{gps}
fmt.Println(curiosity.message())
}
Summary#
- Composition is a technique for breaking down large structures into smaller ones and combining them together.
- Embedding allows the outer structure to access the fields of the inner structure.
- When a type is embedded in a structure, its methods are automatically implemented for forwarding.
- If multiple embedded types have methods with the same name and these methods are called by the program, Go will prompt for naming conflicts.