gps_service.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package service
  2. import (
  3. "context"
  4. "time"
  5. "github.com/gofiber/fiber/v3"
  6. "github.com/gofiber/fiber/v3/middleware/requestid"
  7. "github.com/rotisserie/eris"
  8. "github.com/rs/zerolog/log"
  9. "github.com/spf13/viper"
  10. v1 "sikey.com.cn/benew/ext/api/v1"
  11. "sikey.com.cn/benew/ext/internal/model"
  12. )
  13. type GpsService struct {
  14. conf *viper.Viper
  15. mapLocationModel *model.MapLocationModel
  16. locationService *LocationService
  17. }
  18. func NewGpsService(conf *viper.Viper, mapLocationModel *model.MapLocationModel, locationService *LocationService) *GpsService {
  19. return &GpsService{
  20. conf: conf,
  21. mapLocationModel: mapLocationModel,
  22. locationService: locationService,
  23. }
  24. }
  25. func (s *GpsService) Request(ctx context.Context, request *v1.PostLocationRequest) (*v1.PostLocationResponse, error) {
  26. requestId := requestid.FromContext(ctx.Value("fiberCtx").(fiber.Ctx))
  27. l := log.With().Str("requestId", requestId).Logger()
  28. location := request.Lon + "," + request.Lat
  29. location = s.locationService.convertGpsPoint(ctx, location)
  30. // 距离算法判断是否丢弃点位
  31. // 跟上一次的点位作比较, 如果点位的移动速度超过了 trainSpeed 阈值, 我们需要丢弃这个点位
  32. isInvalidPosition, err := s.locationService.previousPositionDiff(ctx, request, location, request.PositionTime)
  33. if err != nil {
  34. return nil, eris.Wrapf(err, "error select by previous")
  35. }
  36. if isInvalidPosition {
  37. l.Warn().Str("now", location).Msgf("定位命中距离算法判断, 丢弃点位")
  38. return nil, v1.ErrAMAPLocationFailed
  39. }
  40. radius := radiusCorrect(request.Radius)
  41. positionTime := time.UnixMilli(request.PositionTime)
  42. // 数据写入数据库
  43. if err := s.mapLocationModel.Insert(ctx, &model.MapLocationModel{
  44. ExtID: request.ID,
  45. InfoCode: 10000,
  46. Info: "OK",
  47. Location: location,
  48. Radius: int32(radius),
  49. PointType: request.AccessType,
  50. PositionTime: positionTime,
  51. CreatedAt: time.Now(),
  52. }); err != nil {
  53. return nil, eris.Wrap(err, "insert location error")
  54. }
  55. return &v1.PostLocationResponse{
  56. Type: 0,
  57. PointType: request.AccessType,
  58. IMEI: request.IMEI,
  59. Location: location,
  60. Radius: int32(request.Radius),
  61. }, nil
  62. }