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" "go.uber.org/zap" ) 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 := 4 // Replace with your desired fixed radius bounds := img.Bounds() canvasWidth := bounds.Max.X - bounds.Min.X canvasHeight := bounds.Max.Y - bounds.Min.Y margin := 0.1 var minLat, maxLat, minLon, maxLon = math.MaxFloat64, -math.MaxFloat64, math.MaxFloat64, -math.MaxFloat64 for _, loc := range locations { if loc.Latitude < minLat { minLat = loc.Latitude } if loc.Latitude > maxLat { maxLat = loc.Latitude } if loc.Longitude < minLon { minLon = loc.Longitude } if loc.Longitude > maxLon { maxLon = loc.Longitude } } latRange := maxLat - minLat lonRange := maxLon - minLon minLat -= latRange * margin maxLat += latRange * margin minLon -= lonRange * margin maxLon += lonRange * margin minLatEqui := equirectangularProjection(minLat) maxLatEqui := equirectangularProjection(maxLat) latScale := float64(canvasHeight) / (maxLatEqui - minLatEqui) longScale := float64(canvasWidth) / (maxLon - minLon) for _, loc := range locations { x := int((loc.Longitude - minLon) * longScale) // Invert the Y-axis calculation y := canvasHeight - int((equirectangularProjection(loc.Latitude)-minLatEqui)*latScale) // Draw a dot (circle) at (x, y) dc.DrawCircle(float64(x), float64(y), 2) dc.SetRGBA(1, 1, 1, 0.3333333333) // Set dot color (black) dc.Fill() } // Optional: Save the canvas as an image file err := dc.SavePNG("output.png") if err != nil { log.Msg.Error("Error saving file") } else { fmt.Println("Canvas saves to file") } fmt.Println(minLat) fmt.Println(minLon) } 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) // Calculate the maximum distance from the center as a proportion of canvas size maxDistance := math.Max(math.Abs(latDist), math.Abs(lonDist)) // Adjust the normalized distances to match the canvas size with margins adjustedLatDist := latDist / maxDistance * 0.45 adjustedLonDist := lonDist / maxDistance * 0.45 // Calculate pixel positions pixelX := int((adjustedLonDist + 0.5) * float64(canvasWidth)) pixelY := int((0.5 - adjustedLatDist) * float64(canvasHeight)) return pixelX, pixelY } func equirectangularProjection(lat float64) float64 { log.Msg.Debug("Running equirectangular calculation", zap.Float64("lat", lat)) return lat * (math.Pi / 180) // Convert degrees to radians }