From b8b869f981aa97bf03059c27147877e564bc092f Mon Sep 17 00:00:00 2001 From: Fred Boniface Date: Fri, 11 Aug 2023 21:38:14 +0100 Subject: [PATCH] Trying to get the canvas looking okay. It doesn't --- imaging/circles.go | 68 ++++++++++++++++++++++++--------------------- output.png | Bin 11285 -> 1495 bytes run/server.go | 4 +++ 3 files changed, 40 insertions(+), 32 deletions(-) diff --git a/imaging/circles.go b/imaging/circles.go index ca7ee29..debb548 100644 --- a/imaging/circles.go +++ b/imaging/circles.go @@ -1,43 +1,49 @@ package imaging import ( + "fmt" "image" + "math" "git.fjla.uk/fred.boniface/map-dots/data" "git.fjla.uk/fred.boniface/map-dots/log" "github.com/fogleman/gg" ) -func mapCirclesToCanvas(img *image.RGBA, circles []data.LocationData) { - log.Msg.Debug("Mapping circles to canvas") +func mapCirclesToCanvas(img *image.RGBA, locations []data.LocationData) { + log.Msg.Debug("Mapping locations to canvas") dc := gg.NewContextForRGBA(img) dc.SetRGB(1, 1, 1) // Set canvas background color (white in this case) - circleRadius := 10 // Replace with your desired fixed radius + circleRadius := 4 // Replace with your desired fixed radius bounds := img.Bounds() canvasWidth := bounds.Max.X - bounds.Min.X canvasHeight := bounds.Max.Y - bounds.Min.Y var minLat, maxLat, minLon, maxLon float64 - for _, circle := range circles { - if circle.Latitude < minLat { - minLat = circle.Latitude + for _, loc := range locations { + if loc.Latitude < minLat { + minLat = loc.Latitude } - if circle.Latitude > maxLat { - maxLat = circle.Latitude + if loc.Latitude > maxLat { + maxLat = loc.Latitude } - if circle.Longitude < minLon { - minLon = circle.Longitude + if loc.Longitude < minLon { + minLon = loc.Longitude } - if circle.Longitude > maxLon { - maxLon = circle.Longitude + if loc.Longitude > maxLon { + maxLon = loc.Longitude } } - for _, circle := range circles { - // Convert latitude and longitude to pixel position on the canvas - pixelX, pixelY := convertCoordinatesToPixels(circle.Latitude, circle.Longitude, minLat, maxLat, minLon, maxLon, canvasWidth, canvasHeight) + centerLat := (maxLat + minLat) / 2.0 + centerLon := (maxLon + minLon) / 2.0 + latRange := maxLat - minLat + lonRange := maxLon - minLon + + for _, loc := range locations { + pixelX, pixelY := convertCoordinatesToPixels(loc.Latitude, loc.Longitude, centerLat, centerLon, latRange, lonRange, canvasWidth, canvasHeight) // Draw the circle on the canvas using gg dc.DrawCircle(float64(pixelX), float64(pixelY), float64(circleRadius)) @@ -50,29 +56,27 @@ func mapCirclesToCanvas(img *image.RGBA, circles []data.LocationData) { // Optional: Save the canvas as an image file err := dc.SavePNG("output.png") if err != nil { - // Handle error + log.Msg.Error("Error saving file") + } else { + fmt.Println("Canvas saves to file") } } -func convertCoordinatesToPixels(latitude, longitude float64, minLat, maxLat, minLon, maxLon float64, canvasWidth, canvasHeight int) (int, int) { - // Calculate margins as a percentage of canvas dimensions - marginPercentage := 0.1 // 10% margin - marginWidth := int(float64(canvasWidth) * marginPercentage) - marginHeight := int(float64(canvasHeight) * marginPercentage) +func convertCoordinatesToPixels(latitude, longitude float64, centerLat, centerLon, latRange, lonRange float64, canvasWidth, canvasHeight int) (int, int) { + // Calculate normalized latitude and longitude distances from the center + latDist := (latitude - centerLat) / (latRange * 0.5) + lonDist := (longitude - centerLon) / (lonRange * 0.5) - // Adjust the bounding box with margins - minLat -= (maxLat - minLat) * marginPercentage - maxLat += (maxLat - minLat) * marginPercentage - minLon -= (maxLon - minLon) * marginPercentage - maxLon += (maxLon - minLon) * marginPercentage + // Calculate the maximum distance from the center as a proportion of canvas size + maxDistance := math.Max(math.Abs(latDist), math.Abs(lonDist)) - // Calculate the position within the adjusted bounding box - latPercentage := (latitude - minLat) / (maxLat - minLat) - lonPercentage := (longitude - minLon) / (maxLon - minLon) + // Adjust the normalized distances to match the canvas size with margins + adjustedLatDist := latDist / maxDistance * 0.45 + adjustedLonDist := lonDist / maxDistance * 0.45 - // Calculate the pixel positions on the canvas - pixelX := int(lonPercentage*float64(canvasWidth-marginWidth*2)) + marginWidth - pixelY := canvasHeight - (int(latPercentage*float64(canvasHeight-marginHeight*2)) + marginHeight) + // Calculate pixel positions + pixelX := int((adjustedLonDist + 0.5) * float64(canvasWidth)) + pixelY := int((0.5 - adjustedLatDist) * float64(canvasHeight)) return pixelX, pixelY } diff --git a/output.png b/output.png index 3197ff3d8b88d5ff779ad01ee49457eaefcaa2f8..6d9e8d7ed0f5d806476e9984b3eaefefa7ce2d80 100644 GIT binary patch literal 1495 zcmeAS@N?(olHy`uVBq!ia0y~yV4MKL985qF{<{ljGcd5u^K@|xshIQT#>U)32?7oe z8-fg_iZ=)?zF@?xE0ld;-Dh0~b}w~*aQn&e3cLC3hZE-|CiI$Q z+b&zHvi-L2+J>b*zh6rnFWlyturw#)^}`p;DI8)G6eApti8Yn(zkmMuX9FH@{zGh* z32RSP_q~%7{lOf4V?#r|6U0@^SYKa{p2{r7aDd;Avym8g66u{$WkkpPXi$v?6$u5! jXmUYLENnCIuhM?!)u&F#zq0G0>8+y4Uq8wvqf=d;lSzB%0zu^9l@se}9fdMvwQp2w%e5_JQM zl^%Xf9`D7a^YMQvwA7Xak7f1 zTF7E)UIe?RcEpq%sNqV6hK3w{GmftkN`T0Fu3ChilJv4+uBHOu=P0k@&388?bR|}k-ovU+2 zb*;$JYY<$2|7wqE?=9EC*5oHmM_GKFdP117s>`n#xgX%*=!m*xz&{V?jo+M_p;K?% zsN1fdnwpxQpP!hRu%DLw6j8r($Bq}t9TABdeo890Q*yxu8^sAj0N|5l;t4DoT^k>r zNKW2A;Voxo0T#U&$yr-U~;xRQ`s4>%O>b@`5u>a%I7$|>jl&wTBiHwCRzSY8|4MC`nmlJE;iM_}qJ zy-^_v(F@bvr18c$q7^jw^e~db!5UGRE1787N6z=Zbmx(3nnc;UYsZcqKd6v!xQ#o) z4n#=KZ*crjtXnE)J=BC@H#T-FU!x6b4lxvNCw;NC-TeLl+_oSi5?|-Tb86s5_}_7$5TcZBBHZ zl1pGpIxk+lI5xeP#;v@0QrlKsdvv} zzYXpo$vomVUy9bs`l|KvTCw9gh?o=qyQi-|4UeCP>tEYh6LWzPjH18Sru|dY31K@f z4!_{2YQ1E3gBdqdfHN#RBPT@rJeG#Xa zX;~^dGe6OS*1ok04C_*LOUYsk-`C4a>3h0pycGs#GNF9eH(vwLyUNYB+=vQ^#E}&v zH9_L4AI~3YD5|1TQ)pZd4-a?v{o&zZPJw=TgHxWY<5dz`HFa)0_8glLYHoT;wZMaq zp}eDO+0R%bt`D=X*ovi-5SmElX8kgm0Zk-KcjY9+DdlpxL)O%YSka?bG_l_OtEQ$# zlF7Vx@Oa@=uDF3nfm5V^d-n6awn;Fl3DFNY6^$@le(_f*6k1F}1BMo%Ns>;{mxuhM zyLDH+r?YETEv^TrTC(Lwg4h(B3YCLr4(6Jyp?S~+AOkDhI_Ql@e z;Uo29qUyE_7cQ7?_$=@3r#Ra!Tk1&ZP$)_c7yg7GD#jwYIYk~xNY_hu#*)LC9mfO( zvLdIgc6O`pY*h4_lvuzSDjW#MoB9Rrlb6Q7*TAj4O3C=jq(i2s@ER5bF7CdXs3!Dqk zRfweN?8I}~*^gF>rd%8ISNkKXtm`+q;vNhkFP#Xt$A(AZ)bax9s=_Z<{y{0>hF18r z%+W01_Me+4*&ZR}3}Qr%=Pl#!(jU$fm_+d_MzKkh{TOy%UteECM9QgCr!q1!@OXS) zUfzilCzj{fn>KBN`GLt}CoYF?N>^A!U!Q$C_`qLYPfhK?cNAly=#|f2`@b_V=5D5x zI-&J3Vm5mD2It{hGWm_Elh5*!vWYB7>8wG3H(k*POVelO5kn7h#|xM|y^3YvNmUd_ ze_v0}b_h~IW!9=1QMhwNsv>nyZ_!T-ixq2AGWoiNVu?MmLhed~cF61=E{+)-+PvW239`Gs5;Fe$6M=mx!JTs2|} z9wHES@%tX+f8jRR`aS3J<;!F0pwg{%Bv0_wJ3qd<)O!~K*p~v!=C2#peSoUz>FJ3^ z<0@GN20bIl6#TfV)5GYBt4zR~*iVN4atr^}uQ#CYh!wt-AvCTe!#BJzAai~K3ZmH2 z68!3${$>wv8vqrq2s^WvZJYp%YNJKt*=QO!E-LDSN&~4qmU~}HmXgNGhC%NIHg+rM zJ@ECOzCy-q*;>XB;SQy&7{!z@BQY`Y!7PX3ubh~nps{gtJ(`7j(joAbc!4QxB&`F5 zZ7DDPf$ZjI4!-iCte!TAFQhJ?)rLWu2_1K99dATCDTV&HIvd3)h|Ng#2rC}$wEqsd$tQ}Pkp!F^7?Jp&n z^+30#G{V~IX&6`-D_ja+U{B~;eDkW3aShA@ViwN6}y+&Uk0{7n}}m(!ulgF5}T8-Gqq+UivH^R&c;^hvsyvG z^otiS&YNy<%#%GHa3tX!O1C6Ac!Jpb@W>c1%jq_;?@K6;%Y+8>#7%{JCCmt^+O4id z>x4fCIjUhXgCU+mSvVP11`4z@PUHUTLG#o9jO^X6g~G8SD@MmwV#gQ+5YPSu0^rSZ z?)t*;iPnU{%kDiC*7x2!jJ zslpWCH)2~sdX*ztK2qtI#ZtJYkLBJxJ1v({Ob;(cT@;AP$v1AGcF zo%qRal1jrj=-E_n=o5^Ax&g&Ft^kTDqZWAm6SAMQKo`6%c4{Pj?q#dk0>h&}dFs^r zL7e`q!Gx%h(8hI^W~f6{uhiTRw~IyjS8MoUMOj%HgO|oD(nj*oQ~>H{+y&ra@g0`{ zMO~=Be0U$xs|8n!|rU^ zMdvCXSf_6Jfe^OY8_Aq0^$U>Swu&Q;g`Yfm5-P3m!f)REyk%*DLGvLFuCVulFqJ^U z)Q;AX!YAq52bUP)#(E8D&9*@At<^O{doADX=cnmWb#vz60%5BN4BJfOWn!4T0P$4; z!+HJ3x9}1l9j5yIKK2*me;OYnVLZ$IL1#H5-i&yI5is)2$hS2j7;#|4fe{Br9vF4N zs007+IULjBqg0 zz^D#JRW!PR(IkzMJ@ms3_JJnDrfJZK3S8MgMlIY8~4Wl F_-}85F$4er diff --git a/run/server.go b/run/server.go index 66fde6b..9b8f895 100644 --- a/run/server.go +++ b/run/server.go @@ -60,6 +60,10 @@ func handleTraccarRequest(w http.ResponseWriter, r *http.Request) { ) } else { log.Msg.Debug("Position data fetched") + for _, loc := range locations { + fmt.Printf("Latitude: %.7f, Longitude: %.7f, Speed: %d, Altitude: %.4f\n", + loc.Latitude, loc.Longitude, loc.Speed, loc.Altitude) + } } var _ = imaging.Generate(height, width, style, format, locations)