Skip to content

Commit

Permalink
[Go] strconv.FormatFloat for fmt.Sprintf
Browse files Browse the repository at this point in the history
  • Loading branch information
Alfex4936 committed Sep 19, 2024
1 parent be8363f commit ca121e7
Show file tree
Hide file tree
Showing 5 changed files with 263 additions and 183 deletions.
2 changes: 1 addition & 1 deletion backend/handler/marker_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func RegisterMarkerRoutes(api fiber.Router, handler *MarkerHandler, authMiddlewa
api.Get("/markers/weather", handler.HandleGetWeatherByWGS84)

// api.Get("/markers/save-offline-test", handler.HandleTestDynamic)
api.Get("/markers/save-offline", authMiddleware.Verify, limiter.New(limiter.Config{
api.Get("/markers/save-offline", limiter.New(limiter.Config{
KeyGenerator: func(c *fiber.Ctx) string {
return handler.MarkerFacadeService.ChatUtil.GetUserIP(c)
},
Expand Down
74 changes: 61 additions & 13 deletions backend/service/marker_location_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"database/sql"
"encoding/json"
"errors"
"fmt"
"math"
"net/http"
Expand All @@ -12,6 +13,7 @@ import (
"path"
"sort"
"strconv"
"strings"
"sync"
"time"

Expand Down Expand Up @@ -98,9 +100,30 @@ WHERE MBRContains(
Location)
AND ST_Distance_Sphere(Location, ST_GeomFromText(?, 4326)) <= ?
GROUP BY m.MarkerID
ORDER BY distance ASC`
ORDER BY distance ASC
LIMIT ? OFFSET ?`
)

type PooledMarkers struct {
Markers []dto.MarkerWithDistanceAndPhoto
pool *sync.Pool
}

// Method to release the markers back to the pool
func (pm *PooledMarkers) Release() {
// Clear the slice before putting it back
pm.Markers = pm.Markers[:0]
pm.pool.Put(pm)
}

var markerPool = sync.Pool{
New: func() interface{} {
return &PooledMarkers{
Markers: make([]dto.MarkerWithDistanceAndPhoto, 0, 100),
}
},
}

type MarkerLocationService struct {
DB *sqlx.DB
Config *config.AppConfig
Expand Down Expand Up @@ -146,7 +169,7 @@ func RegisterMarkerLocationLifecycle(lifecycle fx.Lifecycle, service *MarkerLoca
// meters_per_degree = 40075000 / 360 / 1000
// IsMarkerNearby checks if there's a marker within n meters of the given latitude and longitude
func (s *MarkerLocationService) IsMarkerNearby(lat, long float64, bufferDistanceMeters int) (bool, error) {
point := fmt.Sprintf("POINT(%f %f)", lat, long)
point := formatPoint(lat, long)

// Execute the query
var nearby bool
Expand All @@ -160,7 +183,7 @@ func (s *MarkerLocationService) IsMarkerNearby(lat, long float64, bufferDistance

// IsMarkerNearby checks if there's a marker within n meters of the given latitude and longitude
func (s *MarkerLocationService) IsMarkerInRestrictedArea(lat, long float64) (string, bool, error) {
point := fmt.Sprintf("POINT(%f %f)", lat, long)
point := formatPoint(lat, long)

var name string
err := s.DB.Get(&name, isInRestrictedAreaQuery, point, point)
Expand All @@ -177,7 +200,6 @@ func (s *MarkerLocationService) IsMarkerInRestrictedArea(lat, long float64) (str
return name, true, nil
}

// TODO cache
// FindClosestNMarkersWithinDistance
func (s *MarkerLocationService) FindClosestNMarkersWithinDistance(lat, long float64, distance, pageSize, offset int) ([]dto.MarkerWithDistanceAndPhoto, int, error) {
// Calculate bounding box
Expand All @@ -188,19 +210,32 @@ func (s *MarkerLocationService) FindClosestNMarkersWithinDistance(lat, long floa
minLon := long - radDist*180/(math.Pi*math.Cos(radLat))
maxLon := long + radDist*180/(math.Pi*math.Cos(radLat))

point := fmt.Sprintf("POINT(%f %f)", lat, long)

var allMarkers []dto.MarkerWithDistanceAndPhoto
err := s.FindCloseMarkersStmt.Select(&allMarkers, point, minLon, minLat, maxLon, minLat, maxLon, maxLat, minLon, maxLat, minLon, minLat, point, distance)
point := formatPoint(lat, long)

pooledMarkers := markerPool.Get().(*PooledMarkers)

err := s.FindCloseMarkersStmt.Select(
&pooledMarkers.Markers,
point,
minLon, minLat,
maxLon, minLat,
maxLon, maxLat,
minLon, maxLat,
minLon, minLat,
point,
distance,
pageSize, // LIMIT
offset, // OFFSET
)
if err != nil {
return nil, 0, fmt.Errorf("error checking for nearby markers: %w", err)
pooledMarkers.Release()
return nil, 0, errors.New("error fetching nearby markers")
}

// Implementing pagination in application logic
markers := paginateMarkers(allMarkers, pageSize, offset)
total := len(allMarkers)
// Attach the pool reference for later use
pooledMarkers.pool = &markerPool

return markers, total, nil
return pooledMarkers.Markers, len(pooledMarkers.Markers), nil
}

func (s *MarkerLocationService) FindRankedMarkersInCurrentArea(lat, long float64, distance, limit int) ([]dto.MarkerWithDistanceAndPhoto, error) {
Expand Down Expand Up @@ -502,3 +537,16 @@ func (s *MarkerLocationService) TestDynamic(latitude, longitude, zoomScale float
resultImagePath, _ := util.PlaceMarkersOnImageDynamic(baseImageFilePath, markers, mapWcon.X, mapWcon.Y, zoomScale)
fmt.Println(resultImagePath)
}

func formatPoint(lat, long float64) string {
// Format the latitude and longitude with 6 decimal places
latStr := strconv.FormatFloat(lat, 'f', 6, 64)
longStr := strconv.FormatFloat(long, 'f', 6, 64)
var sb strings.Builder
sb.WriteString("POINT(")
sb.WriteString(latStr)
sb.WriteString(" ")
sb.WriteString(longStr)
sb.WriteString(")")
return sb.String()
}
5 changes: 3 additions & 2 deletions backend/service/marker_management_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -471,11 +471,12 @@ func (s *MarkerManageService) CreateMarkerWithPhotos(markerDto *dto.MarkerReques
if err != nil {
return nil, err
}
point := formatPoint(markerDto.Latitude, markerDto.Longitude)

// Insert the marker into the database
res, err := tx.Exec(
insertMarkerQuery,
userID, fmt.Sprintf("POINT(%f %f)", markerDto.Latitude, markerDto.Longitude), markerDto.Description,
userID, point, markerDto.Description,
)

if err != nil {
Expand Down Expand Up @@ -785,7 +786,7 @@ func (s *MarkerManageService) CheckNearbyMarkersInDB() ([]dto.MarkerGroup, error
var markerGroups []dto.MarkerGroup

for _, marker := range markers {
point := fmt.Sprintf("POINT(%f %f)", marker.Latitude, marker.Longitude)
point := formatPoint(marker.Latitude, marker.Longitude)

var nearbyMarkers []dto.MarkerWithDistance
err := s.DB.Select(&nearbyMarkers, findCloseMarkersAdminQuery, point, point, 10)
Expand Down
4 changes: 3 additions & 1 deletion backend/service/report_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,9 @@ func (s *ReportService) CreateReport(report *dto.MarkerReportRequest, form *mult
defer tx.Rollback() // Ensure the transaction is rolled back in case of error

// Insert the main report record
res, err := tx.Exec(insertReportQuery, report.MarkerID, report.UserID, fmt.Sprintf("POINT(%f %f)", report.Latitude, report.Longitude), fmt.Sprintf("POINT(%f %f)", report.NewLatitude, report.NewLongitude), report.Description, report.DoesExist)
point := formatPoint(report.Latitude, report.Longitude)
newPoint := formatPoint(report.NewLatitude, report.NewLongitude)
res, err := tx.Exec(insertReportQuery, report.MarkerID, report.UserID, point, newPoint, report.Description, report.DoesExist)
if err != nil {
return fmt.Errorf("failed to insert report: %w", err)
}
Expand Down
Loading

0 comments on commit ca121e7

Please sign in to comment.