package com.harbour.history.service.impl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.harbour.common.core.domain.AjaxResult;
import com.harbour.common.core.domain.PageQuery;
import com.harbour.common.core.page.TableDataInfo;
import com.harbour.common.utils.StringUtils;
import com.harbour.enums.ShowShipType;
import com.harbour.history.domain.HisShip;
import com.harbour.history.domain.HisShipMmsi;
import com.harbour.history.domain.HisShipSpeed;
import com.harbour.history.domain.ShipInfoBaseVo;
import com.harbour.history.domain.req.HisShipQuery;
import com.harbour.history.domain.req.PortraitQuery;
import com.harbour.history.domain.vo.ShipBasePortraitVo;
import com.harbour.history.domain.vo.ShipBehavPortraitVo;
import com.harbour.history.mapper.HisShipMapper;
import com.harbour.history.service.IHisShipService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* <p>
* 船舶历史信息 服务实现类
* </p>
*
* @author dingxintao
* @since 2022-02-18
*/
@Service
@Slf4j
public class HisShipServiceImpl extends ServiceImpl<HisShipMapper, HisShip> implements IHisShipService {
/**
* 船舶历史信息 分页查询
*
* @param query
* @param pageQuery
* @return com.harbour.common.core.page.TableDataInfo<com.harbour.history.domain.HisShip>
* @date 2022/3/28 21:45
**/
@Override
public TableDataInfo<HisShip> list(HisShipQuery query, PageQuery pageQuery) {
Page<HisShip> page = this.lambdaQuery()
.eq(HisShip::getMmsi, query.getMmsi())
.ge(HisShip::getCreateTime, query.getStartDate())
.le(HisShip::getCreateTime, query.getEndDate())
.page(pageQuery.build());
return TableDataInfo.build(page);
}
/**
* 船舶历史信息 查询列表
*
* @param query
* @return List<com.harbour.history.domain.HisShip>
* @author DingXintao
* @date 2022/3/28 21:45
**/
@Override
public List<HisShip> list(HisShipQuery query) {
return this.lambdaQuery()
.eq(HisShip::getMmsi, query.getMmsi())
.ge(HisShip::getCreateTime, query.getStartDate())
.le(HisShip::getCreateTime, query.getEndDate()).list();
}
/**
* 基础画像管理2张图表,尺度分析和类型分析
**/
@Override
public AjaxResult<ShipBasePortraitVo> charts(PortraitQuery query) {
ShipBasePortraitVo shipBasePortraitVo = new ShipBasePortraitVo();
//TODO 1.sql语句的left join取消,在查找字段添加type
List<HisShip> hisShips = baseMapper.charts(query);
if (StringUtils.isEmpty(hisShips)) {
return AjaxResult.success(shipBasePortraitVo);
}
//总数
Long totalCount = hisShips.stream().count();
List<ShipBasePortraitVo.ShipBase> length = new ArrayList<ShipBasePortraitVo.ShipBase>();
List<ShipBasePortraitVo.ShipBase> type = new ArrayList<ShipBasePortraitVo.ShipBase>();
log.info(query.getStartDate() + " " + query.getEndDate() + "的数据共有" + totalCount);
//尺度分析
Map<String, Long> listLength = hisShips.stream()
.collect(Collectors.groupingBy((Function<HisShip, String>) ship -> {
String key;
if (ObjectUtils.isEmpty(ship.getLength())) {
key = "未知";
} else if (ship.getLength() < 10) {
key = "less10";
} else if (ship.getLength() < 20) {
key = "less20";
} else if (ship.getLength() < 50) {
key = "less50";
} else if (ship.getLength() < 100) {
key = "less100";
} else if (ship.getLength() < 200) {
key = "less200";
} else {
key = "more200";
}
return key;
}, Collectors.counting()));
for (Map.Entry<String, Long> item : listLength.entrySet()) {
ShipBasePortraitVo.ShipBase shipBase = new ShipBasePortraitVo.ShipBase();
shipBase.setType(item.getKey());
Long count = item.getValue();
shipBase.setCount(count);
shipBase.setCountPercent(String.format("%.4f", count.intValue() == 0 ? 0.00 : count.doubleValue() / totalCount.doubleValue()));
length.add(shipBase);
}
//类型分析
Map<String, Long> collect = hisShips.stream()
.collect(Collectors.groupingBy((Function<HisShip, String>) ship -> {
String key;
String shipType = ship.getType();
if (ObjectUtils.isEmpty(shipType)) {
key = ShowShipType.OTHER.getName();
} else if (shipType.equals(ShowShipType.CARGO_SHIP.getName())) {
key = ShowShipType.CARGO_SHIP.getName();
} else if (shipType.equals(ShowShipType.PASSENGER_SHIP.getName())) {
key = ShowShipType.PASSENGER_SHIP.getName();
} else if (shipType.equals(ShowShipType.FISHING_VESSEL.getName())) {
key = ShowShipType.FISHING_VESSEL.getName();
} else if (shipType.equals(ShowShipType.TUGBOAT.getName())) {
key = ShowShipType.TUGBOAT.getName();
} else if (shipType.equals(ShowShipType.TANKER.getName())) {
key = ShowShipType.TANKER.getName();
} else {
key = ShowShipType.OTHER.getName();
}
return key;
}, Collectors.counting()));
//ShowShipType
for (Map.Entry<String, Long> item : collect.entrySet()) {
ShipBasePortraitVo.ShipBase shipBase = new ShipBasePortraitVo.ShipBase();
shipBase.setType(item.getKey());
Long count = item.getValue();
shipBase.setCount(count);
shipBase.setCountPercent(String.format("%.4f", count.intValue() == 0 ? 0.00 : count.doubleValue() / totalCount.doubleValue()));
type.add(shipBase);
}
shipBasePortraitVo.setLengthStatistic(length);
shipBasePortraitVo.setTypeStatistic(type);
return AjaxResult.success(shipBasePortraitVo);
}
/**
* 基础画像管理2张图表,平均速度和目的地分析
**/
@Override
public AjaxResult<ShipBehavPortraitVo> behavior(PortraitQuery query) {
//TODO 平均速度和目的地需要写定时任务,查询数据库里面的所有数据
ShipBehavPortraitVo shipBehavPortraitVo = new ShipBehavPortraitVo();
List<HisShip> hisShips = baseMapper.charts(query);
if (StringUtils.isEmpty(hisShips)) {
return AjaxResult.success(shipBehavPortraitVo);
}
//总数
Integer destinaTotalCount = Math.toIntExact(hisShips.stream().count());
List<ShipBehavPortraitVo.ShipBeahavior> speed = new ArrayList<ShipBehavPortraitVo.ShipBeahavior>();
List<ShipBehavPortraitVo.ShipBeahavior> destina = new ArrayList<ShipBehavPortraitVo.ShipBeahavior>();
List<ShipInfoBaseVo> speedList = new ArrayList<ShipInfoBaseVo>();
//按照船先分类,然后计算平均速度再分类
//尺度分析
Map<Long, List<HisShip>> mmsiList = hisShips.stream()
.collect(Collectors.groupingBy(HisShip::getMmsi, Collectors.toList()));
for (Map.Entry<Long, List<HisShip>> item : mmsiList.entrySet()) {
ShipInfoBaseVo shipInfoBaseVo = new ShipInfoBaseVo();
shipInfoBaseVo.setMmsi(item.getKey());
//平均速度
shipInfoBaseVo.setSpeed(item.getValue().stream().collect(Collectors.averagingDouble(HisShip::getSpeedOverGround)));
speedList.add(shipInfoBaseVo);
}
//获取每种船对应的平均速度
Integer totalCount = speedList.size();
//平均速度分组
final Map<String, List<ShipInfoBaseVo>> collect1 = speedList.stream()
.collect(Collectors.groupingBy((Function<ShipInfoBaseVo, String>) ship -> {
String key;
if (ship.getSpeed() < 5) {
key = "less5";
} else if (ship.getSpeed() < 10) {
key = "less10";
} else if (ship.getSpeed() < 15) {
key = "less15";
} else if (ship.getSpeed() < 20) {
key = "less20";
} else {
key = "more20";
}
return key;
}, Collectors.toList()));
for (Map.Entry<String, List<ShipInfoBaseVo>> item : collect1.entrySet()) {
ShipBehavPortraitVo.ShipBeahavior shipBeahavior = new ShipBehavPortraitVo.ShipBeahavior();
shipBeahavior.setType(item.getKey());
Long count = item.getValue().stream().count();
shipBeahavior.setCount(count);
shipBeahavior.setCountPercent(String.format("%.4f", count.intValue() == 0 ? 0.00 : count.doubleValue() / totalCount.doubleValue()));
speed.add(shipBeahavior);
}
//从船舶目的地分析,前十的目的地,top10
Map<String, Long> collect = hisShips
.stream()
.collect(Collectors.groupingBy(HisShip::getDestination, Collectors.counting()));
for (Map.Entry<String, Long> item : collect.entrySet()) {
ShipBehavPortraitVo.ShipBeahavior shipBeahavior = new ShipBehavPortraitVo.ShipBeahavior();
shipBeahavior.setType(item.getKey());
Long count = item.getValue();
shipBeahavior.setCount(count);
shipBeahavior.setCountPercent(String.format("%.4f", count.intValue() == 0 ? 0.00 : count.doubleValue() / destinaTotalCount.doubleValue()));
destina.add(shipBeahavior);
}
List<ShipBehavPortraitVo.ShipBeahavior> collect2 = destina.stream()
.sorted(Comparator.comparing(ShipBehavPortraitVo.ShipBeahavior::getCount)
.reversed())
.limit(10)
.collect(Collectors.toList());
shipBehavPortraitVo.setSpeedStatistic(speed);
shipBehavPortraitVo.setDestinaStatistic(collect2);
return AjaxResult.success(shipBehavPortraitVo);
}
/**
* 基础画像管理2张图表,平均速度和目的地分析
**/
@Override
public AjaxResult<ShipBehavPortraitVo> trace(PortraitQuery query) {
//TODO 所有船轨迹
ShipBehavPortraitVo shipBehavPortraitVo = new ShipBehavPortraitVo();
return AjaxResult.success(shipBehavPortraitVo);
}
@Override
public HisShipSpeed getShipAvgSpeed(Long mmsi) {
return this.baseMapper.getShipAvgSpeed(mmsi);
}
@Override
public List<HisShipSpeed> getAllShipAvgSpeed() {
return this.baseMapper.getAllShipAvgSpeed();
}
@Override
public List<HisShipMmsi> getShipMmsi() {
return this.baseMapper.getShipMmsi();
}
}