banner
biuaxia

biuaxia

"万物皆有裂痕,那是光进来的地方。"
github
bilibili
tg_channel

Solving Practical Problems with Golang Latitude and Longitude DMS

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 LanderLanding PointLatitudeLongitude
SpiritColumbia MemorialSouth 14°34'6.2"East 175°28'21.5"
OpportunityChallengerSouth 1°56'46.3"East 354°28'24.2"
CuriosityBradbury LandingSouth 4°35'22.2"East 137°26'30.1"
InSightElysium PlanitiaNorth 4°30'0.0"East 135°54'0"

Measured Radii of Various Planets#

PlanetRadius/kmPlanetRadius/km
Mercury2439.7Jupiter69911
Venus6051.8Saturn58232
Earth6371.0Uranus25362
Mars3389.5Neptune24622

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 or NewType 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"".
Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.