@@ -32,7 +32,6 @@ import "C"
3232
3333import (
3434 "errors"
35- "fmt"
3635 "math"
3736 "strconv"
3837 "strings"
@@ -72,6 +71,15 @@ const (
7271 RadsToDegs = 180.0 / math .Pi
7372)
7473
74+ const (
75+ latLngFloatPrecision = 5
76+ // latLngStringSize is the size to pre-allocate the buffer for.
77+ // Given latLngFloatPrecision, a typical string is "(DD.DDDDD, -DDD.DDDDD)"
78+ // which is ~25-30 bytes. 32 is a safe and efficient capacity to start with
79+ // to avoid re-allocation.
80+ latLngStringSize = 32
81+ )
82+
7583// PolygonToCells containment modes
7684const (
7785 ContainmentCenter ContainmentMode = C .CONTAINMENT_CENTER // Cell center is contained in the shape
@@ -122,7 +130,6 @@ var (
122130)
123131
124132type (
125-
126133 // Cell is an Index that identifies a single hexagon cell at a resolution.
127134 Cell int64
128135
@@ -468,7 +475,7 @@ func PolygonToCells(polygon GeoPolygon, resolution int) ([]Cell, error) {
468475// and then any newly found hexagons are used to test again until no new
469476// hexagons are found.
470477func PolygonToCellsExperimental (polygon GeoPolygon , resolution int , mode ContainmentMode , maxNumCellsReturn ... int64 ) ([]Cell , error ) {
471- var maxNumCells int64 = math .MaxInt64
478+ maxNumCells := int64 ( math .MaxInt64 )
472479 if len (maxNumCellsReturn ) > 0 {
473480 maxNumCells = maxNumCellsReturn [0 ]
474481 }
@@ -519,30 +526,55 @@ func CellsToMultiPolygon(cells []Cell) ([]GeoPolygon, error) {
519526 return nil , err
520527 }
521528
522- ret := []GeoPolygon {}
529+ currPoly := cLinkedGeoPolygon
530+ var countPoly int
531+ for currPoly != nil {
532+ countPoly ++
533+ currPoly = currPoly .next
534+ }
535+
536+ ret := make ([]GeoPolygon , countPoly )
523537
524538 // traverse polygons for linked list of polygons
525- currPoly := cLinkedGeoPolygon
539+ currPoly = cLinkedGeoPolygon
540+ countPoly = 0
526541 for currPoly != nil {
527- loops := []GeoLoop {}
542+ currLoop := currPoly .first
543+ var countLoop int
544+ for currLoop != nil {
545+ countLoop ++
546+ currLoop = currLoop .next
547+ }
548+ loops := make ([]GeoLoop , countLoop )
528549
529550 // traverse loops for a polygon
530- currLoop := currPoly .first
551+ currLoop = currPoly .first
552+ countLoop = 0
531553 for currLoop != nil {
532- loop := []LatLng {}
554+ currPt := currLoop .first
555+ var countPt int
556+ for currPt != nil {
557+ countPt ++
558+ currPt = currPt .next
559+ }
560+ loop := make ([]LatLng , countPt )
533561
534562 // traverse points for a loop
535- currPt := currLoop .first
563+ currPt = currLoop .first
564+ countPt = 0
536565 for currPt != nil {
537- loop = append (loop , latLngFromC (currPt .vertex ))
566+ loop [countPt ] = latLngFromC (currPt .vertex )
567+ countPt ++
538568 currPt = currPt .next
539569 }
540570
541- loops = append (loops , loop )
571+ loops [countLoop ] = loop
572+ countLoop ++
542573 currLoop = currLoop .next
543574 }
544575
545- ret = append (ret , GeoPolygon {GeoLoop : loops [0 ], Holes : loops [1 :]})
576+ ret [countPoly ] = GeoPolygon {GeoLoop : loops [0 ], Holes : loops [1 :]}
577+ countPoly ++
546578 currPoly = currPoly .next
547579 }
548580
@@ -669,7 +701,7 @@ func EdgeLengthM(e DirectedEdge) (float64, error) {
669701func NumCells (resolution int ) int {
670702 // NOTE: this is a mathematical operation, no need to call into H3 library.
671703 // See h3api.h for formula derivation.
672- return 2 + 120 * intPow (7 , ( resolution ) ) //nolint:mnd // math formula
704+ return 2 + 120 * intPow (7 , resolution ) //nolint:mnd // math formula
673705}
674706
675707// Res0Cells returns all the cells at resolution 0.
@@ -1059,11 +1091,10 @@ func maxGridDiskSize(k int) int {
10591091}
10601092
10611093func latLngFromC (cg C.LatLng ) LatLng {
1062- g := LatLng {}
1063- g .Lat = RadsToDegs * float64 (cg .lat )
1064- g .Lng = RadsToDegs * float64 (cg .lng )
1065-
1066- return g
1094+ return LatLng {
1095+ Lat : RadsToDegs * float64 (cg .lat ),
1096+ Lng : RadsToDegs * float64 (cg .lng ),
1097+ }
10671098}
10681099
10691100func cellBndryFromC (cb * C.CellBoundary ) CellBoundary {
@@ -1229,7 +1260,13 @@ func intsFromC(chs []C.int) []int {
12291260}
12301261
12311262func (g LatLng ) String () string {
1232- return fmt .Sprintf ("(%.5f, %.5f)" , g .Lat , g .Lng )
1263+ buf := make ([]byte , 0 , latLngStringSize )
1264+ buf = append (buf , '(' )
1265+ buf = strconv .AppendFloat (buf , g .Lat , 'f' , latLngFloatPrecision , 64 ) //nolint:mnd // float bit size
1266+ buf = append (buf , ',' , ' ' )
1267+ buf = strconv .AppendFloat (buf , g .Lng , 'f' , latLngFloatPrecision , 64 ) //nolint:mnd // float bit size
1268+ buf = append (buf , ')' )
1269+ return string (buf )
12331270}
12341271
12351272func (g LatLng ) toCPtr () * C.LatLng {
0 commit comments