Skip to content

Commit

Permalink
Merge pull request #3 from im7mortal/catchup_with_python
Browse files Browse the repository at this point in the history
Catchup with python
  • Loading branch information
im7mortal authored Feb 10, 2024
2 parents 2e399b3 + 79c9bc7 commit fcdb211
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 32 deletions.
23 changes: 13 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
UTM
===

Bidirectional UTM-WGS84 converter for golang. It use logic from [UTM python version](https://pypi.python.org/pypi/utm) by Tobias Bieniek
Bidirectional UTM-WGS84 converter for golang. It use logic from [UTM python version](https://pypi.python.org/pypi/utm)
by Tobias Bieniek

Usage
-----
Expand All @@ -15,13 +16,13 @@ Usage
Convert a latitude, longitude into an UTM coordinate

```go
easting, northing, zoneNumber, zoneLetter, err := UTM.FromLatLon(40.71435, -74.00597, false)
easting, northing, zoneNumber, zoneLetter, err := UTM.FromLatLon(40.71435, -74.00597, false)
```

Convert an UTM coordinate into a latitude, longitude.

```go
latitude, longitude, err := UTM.ToLatLon(377486, 6296562, 30, "V")
latitude, longitude, err := UTM.ToLatLon(377486, 6296562, 30, "V")
```

Since the zone letter is not strictly needed for the conversion you may also
Expand All @@ -30,24 +31,26 @@ to either ``true`` or ``false``. In this case you should define fields clearly(!
You can't set ZoneLetter or northern both.

```go
latitude, longitude, err := UTM.ToLatLon(377486, 6296562, 30, "", false)
latitude, longitude, err := UTM.ToLatLon(377486, 6296562, 30, "", false)
```

The UTM coordinate system is explained on this [Wikipedia page](https://en.wikipedia.org/wiki/Universal_Transverse_Mercator_coordinate_system)
The UTM coordinate system is explained on
this [Wikipedia page](https://en.wikipedia.org/wiki/Universal_Transverse_Mercator_coordinate_system)

Speed
-----

Benchmark | Amount of iterations | Average speed
--------------------- | -------------------- | -------------
ToLatLon | 10000000 | 123 ns/op
ToLatLonWithNorthern | 10000000 | 121 ns/op
FromLatLon | 20000000 | 80.6 ns/op
Benchmark | Amount of iterations | Average speed
----------------------|----------------------|---------------
ToLatLon | 10000000 | 123 ns/op
ToLatLonWithNorthern | 10000000 | 121 ns/op
FromLatLon | 20000000 | 80.6 ns/op

> go test -bench=.
Full example
-----------

```go
package main

Expand Down
6 changes: 3 additions & 3 deletions example/example.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package main

import (
"github.com/im7mortal/UTM"
"fmt"
"github.com/im7mortal/UTM"
)

func main() {
Expand All @@ -13,7 +13,7 @@ func main() {
}
fmt.Println(
fmt.Sprintf(
"Easting: %d; Northing: %d; ZoneNumber: %d; ZoneLetter: %s;",
"Easting: %f; Northing: %f; ZoneNumber: %d; ZoneLetter: %s;",
easting,
northing,
zoneNumber,
Expand All @@ -26,7 +26,7 @@ func main() {
}
fmt.Println(
fmt.Sprintf(
"Easting: %d; Northing: %d; ZoneNumber: %d; ZoneLetter: %s;",
"Easting: %f; Northing: %f; ZoneNumber: %d; ZoneLetter: %s;",
easting,
northing,
zoneNumber,
Expand Down
26 changes: 13 additions & 13 deletions utm.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func rad(d float64) float64 { return d * x }
func deg(r float64) float64 { return r / x }

var zoneLetters = []zoneLetter{
{84, " "},
{84, "X"},
{72, "X"},
{64, "W"},
{56, "V"},
Expand All @@ -71,7 +71,7 @@ var zoneLetters = []zoneLetter{

// ToLatLon convert Universal Transverse Mercator coordinates to a latitude and longitude
// Since the zone letter is not strictly needed for the conversion you may also
// the ``northern`` parameter instead, which is a named parameter and can be set
// the northern parameter instead, which is a named parameter and can be set
// to either true or false. In this case you should define fields clearly
// You can't set ZoneLetter or northern both.
func ToLatLon(easting, northing float64, zoneNumber int, zoneLetter string, northern ...bool) (latitude, longitude float64, err error) {
Expand Down Expand Up @@ -143,7 +143,7 @@ func ToLatLon(easting, northing float64, zoneNumber int, zoneLetter string, nort
n := r / epSinSqrt
rad := (1 - e) / epSin

c := fe * pCos * pCos
c := eP2 * pCos * pCos
c2 := c * c

d := x / (n * k0)
Expand All @@ -153,8 +153,8 @@ func ToLatLon(easting, northing float64, zoneNumber int, zoneLetter string, nort
d5 := d4 * d
d6 := d5 * d

latitude = pRad - (pTan / rad) *
(d2/2 -
latitude = pRad - (pTan/rad)*
(d2/2-
d4/24*(5+3*pTan2+10*c-4*c2-9*eP2)) +
d6/720*(61+90*pTan2+298*c+45*pTan4-252*eP2-3*c2)

Expand Down Expand Up @@ -226,11 +226,11 @@ func FromLatLon(latitude, longitude float64, northern bool) (easting, northing f
m2*math.Sin(2*latRad) +
m3*math.Sin(4*latRad) -
m4*math.Sin(6*latRad))
easting = k0*n * (a +
a3/6*(1-latTan2+c) +
easting = k0*n*(a+
a3/6*(1-latTan2+c)+
a5/120*(5-18*latTan2+latTan4+72*c-58*eP2)) + 500000
northing = k0 * (m + n*latTan * (a2/2 +
a4/24*(5-latTan2+9*c+4*c*c) +
northing = k0 * (m + n*latTan*(a2/2+
a4/24*(5-latTan2+9*c+4*c*c)+
a6/720*(61-58*latTan2+latTan4+600*c-330*eP2)))

if latitude < 0 {
Expand All @@ -255,13 +255,13 @@ func latLonToZoneNumber(latitude float64, longitude float64) int {
}

if 72 <= latitude && latitude <= 84 && longitude >= 0 {
if longitude <= 9 {
if longitude < 9 {
return 31
} else if longitude <= 21 {
} else if longitude < 21 {
return 33
} else if longitude <= 33 {
} else if longitude < 33 {
return 35
} else if longitude <= 42 {
} else if longitude < 42 {
return 37
}
}
Expand Down
6 changes: 3 additions & 3 deletions utm_deprecated.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ func FromLatLonF(lat, lon float64) (easting, northing float64) {
return
}

//Coordinate contains coordinates in the Universal Transverse Mercator coordinate system
// Coordinate contains coordinates in the Universal Transverse Mercator coordinate system
//
// Deprecated: Use ToLatLon functions to convert LatLon instead.
type Coordinate struct {
Expand All @@ -33,7 +33,7 @@ func (point *LatLon) FromLatLon() (coord Coordinate, err error) {
return
}

//LatLon contains a latitude and longitude
// LatLon contains a latitude and longitude
//
// Deprecated: Use FromLatLon functions to convert LatLon instead.
type LatLon struct {
Expand All @@ -43,7 +43,7 @@ type LatLon struct {

// ToLatLon convert Universal Transverse Mercator coordinates to a latitude and longitude
// Since the zone letter is not strictly needed for the conversion you may also
// the ``northern`` parameter instead, which is a named parameter and can be set
// the northern parameter instead, which is a named parameter and can be set
// to either true or false. In this case you should define fields clearly
// You can't set ZoneLetter or northern both.
//
Expand Down
2 changes: 1 addition & 1 deletion utm_deprecated_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package UTM_test

import (
"testing"
"github.com/im7mortal/UTM"
"testing"
)

type testDataDeprecated struct {
Expand Down
10 changes: 8 additions & 2 deletions utm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ var knownValues = []testData{
testCoordinate{377486, 6296562, 30, "V"},
true,
},
// Latitude 84
{
testLatLon{84, -5.00601},
testCoordinate{476594, 9328501, 30, "X"},
true,
},
}

func TestToLatLon(t *testing.T) {
Expand Down Expand Up @@ -149,15 +155,15 @@ func TestFromLatLonBadInput(t *testing.T) {
latLon.Latitude = i / 100
_, _, _, _, err := UTM.FromLatLon(latLon.Latitude, latLon.Longitude, false)
if err != nil {
t.Errorf("not cover Latitude %d", i/100)
t.Errorf("not cover Latitude %f", i/100)
}
}
latLon.Latitude = 0
for i := -18000.0; i < 18001.0; i++ {
latLon.Longitude = i / 100
_, _, _, _, err := UTM.FromLatLon(latLon.Latitude, latLon.Longitude, false)
if err != nil {
t.Errorf("not cover Longitude %d", i/100)
t.Errorf("not cover Longitude %f", i/100)
}
}
}
Expand Down

0 comments on commit fcdb211

Please sign in to comment.