github.com/pavlo67/common@v0.5.3/common/geolib/tile_ranges.go (about) 1 package geolib 2 3 import ( 4 "fmt" 5 6 "github.com/pavlo67/common/common/mathlib/plane" 7 ) 8 9 type XYRange [2]int 10 11 type XYRanges struct { 12 Zoom int 13 XT, YT XYRange 14 } 15 16 func (xyRanges XYRanges) Key() string { 17 return fmt.Sprintf("z%d_x%d_x%d_y%d_y%d", xyRanges.Zoom, xyRanges.XT[0], xyRanges.XT[1], xyRanges.YT[0], xyRanges.YT[1]) 18 } 19 20 func (xyRanges XYRanges) Canon() XYRanges { 21 xMin, xMax, yMin, yMax := xyRanges.XT[0], xyRanges.XT[1], xyRanges.YT[0], xyRanges.YT[1] 22 if xMax < xMin { 23 xMin, xMax = xMax, xMin 24 } 25 if yMax < yMin { 26 yMin, yMax = yMax, yMin 27 } 28 29 return XYRanges{xyRanges.Zoom, XYRange{xMin, xMax}, XYRange{yMin, yMax}} 30 } 31 32 //func (xyRanges XYRanges) Area() Area { 33 // xyRanges = xyRanges.Canon() 34 // 35 // // TODO!!! use +1 in XYRanges max itself 36 // 37 // return Area{ 38 // Tile{X: xyRanges.XT[0], Y: xyRanges.YT[0], Zoom: xyRanges.Zoom}.LeftTop(), 39 // Tile{X: xyRanges.XT[1] + 1, Y: xyRanges.YT[1] + 1, Zoom: xyRanges.Zoom}.LeftTop(), 40 // } 41 //} 42 43 func (xyRanges XYRanges) LeftTop() Point { 44 45 xyRanges = xyRanges.Canon() 46 47 return Tile{X: xyRanges.XT[0], Y: xyRanges.YT[0], Zoom: xyRanges.Zoom}.LeftTop() 48 } 49 50 func XYRangesAround(geoPoint Point, zoom int, hsX, hsY float64) XYRanges { 51 52 tileMin, tileMax := geoPoint.MovedAt(plane.Point2{-hsX, hsY}).Tile(zoom), geoPoint.MovedAt(plane.Point2{hsX, -hsY}).Tile(zoom) 53 54 if tileMax.X < tileMin.X { 55 tileMin.X, tileMax.X = tileMax.X, tileMin.X 56 } 57 if tileMax.Y < tileMin.Y { 58 tileMin.Y, tileMax.Y = tileMax.Y, tileMin.Y 59 } 60 61 return XYRanges{Zoom: zoom, XT: XYRange{tileMin.X, tileMax.X}, YT: XYRange{tileMin.Y, tileMax.Y}} 62 63 } 64 65 func PointInRanges(geoPoint Point, xyRanges XYRanges, tileSide int) plane.Point2 { 66 67 tile := geoPoint.Tile(xyRanges.Zoom) 68 leftTop := tile.LeftTop() 69 rightBottom := Tile{tile.X + 1, tile.Y + 1, tile.Zoom}.LeftTop() 70 71 x := float64(tileSide) * (float64(tile.X-xyRanges.XT[0]) + float64(geoPoint.Lon-leftTop.Lon)/float64(rightBottom.Lon-leftTop.Lon)) 72 y := float64(tileSide) * (float64(tile.Y-xyRanges.YT[0]) + float64(geoPoint.Lat-leftTop.Lat)/float64(rightBottom.Lat-leftTop.Lat)) 73 74 return plane.Point2{x, y} 75 }