我有以下问题:
我有以下方法来获取船只的GPS点:
/**
* @param array $mmsids
* @param unknown $longituteMin
* @param unknown $longtitudeMax
* @param unknown $latitudeMin
* @param unknown $latitudeMax
* @param \Datetime $timeInterval
*
* @throws EmptyParamGivenException
* @throws Exception
*
* @return Vesel[] with their routes
*/
public function getRoutes(array $mmsids=[],
$longituteMin=null,
$longtitudeMax=null,
$latitudeMin=null,
$latitudeMax=null,
\DateTime $fromDate=null,
\DateTime $toDate=null
) {
$em=$this->getEntityManager();
$query=$em->createQueryBuilder('v')
->from('AppBundle:Vesel', 'v')
->innerJoin('v.veselMoveStatuses','m')
->select('v.mmsi,m.logtitude,m.latitude,m.timestamp')
->addOrderBy('v.mmsi','ASC')
->addOrderBy('m.timestamp','DESC');
if(!empty($longituteMin)){
$query->andWhere('m.logtitude >= :long_min')->setParameter(':long_min',$longituteMin);
}
if(!empty($longtitudeMax)) {
$query->andWhere('m.logtitude <= :long_max')->setParameter(':long_max',$longituteMax);
}
if(!empty($latitudeMin)){
$query->andWhere('m.latitude >= :lat_min')->setParameter(':lat_min',$latitudeMin);
}
if(!empty($latitudeMax)){
$query->andWhere('m.latitude <= :lat_max')->setParameter(':lat_max',$latitudeMin);
}
if(!empty($mmsids)){
$query->andWhere('v.mmsi IN (:mmsids)')->setParameter('mmsids', $mmsids,\Doctrine\DBAL\Connection::PARAM_STR_ARRAY);
}
$paramsToValidate=[RouteInputParameter::PARAM_DATE_FROM=>$fromDate,RouteInputParameter::PARAM_DATE_TO=>$toDate];
if($fromDate!==null && $toDate!==null){
InputValidator::dateRangeValidation($paramsToValidate,RouteInputParameter::PARAM_DATE_FROM,RouteInputParameter::PARAM_DATE_TO);
$query->andWhere('m.timestamp BETWEEN :date_min AND :date_max')
->setParameters(['date_min'=>$fromDate,'date_max'=>$toDate]);
} else if($fromDate!==null) {
$query->andWhere('m.timestamp <= :date_min')
->setParameters(['date_min'=>$fromDate]);
} else if($toDate!==null) {
$query->where('m.timestamp >= :date_max')
->setParameters(['date_max'=>$toDate]);
}
$query = $query->getQuery();
return $query->getResult();
}
我想要实现它,我想以嵌套的方式生成结果:
[
[
"mmsi"=>"^somevalue^"
points=>[
"longtitude":"^longtitude_value^",
"latitude":"^latitude_value^",
"time":"^time_value^"
],
....
],
....
]
你知道是否有一个允许我这样做的内部Doctrine机制,或者我应该实现自己的机制吗?
Vessel
实体是:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="vessel",indexes={
* @ORM\Index(name="mmsi",columns={"mmsi"})
* })
*/
class Vesel
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
* @var integer
*/
private $id;
/**
* @ORM\Column(type="integer",name="mmsi")
* @var integer
*/
private $mmsi;
/**
* @ORM\OneToMany(targetEntity="VesselMoveStatus",mappedBy="vesel")
* @var \Doctrine\Common\Collections\Collection
*/
private $veselMoveStatuses;
/**
* Constructor
*/
public function __construct($mmsi)
{
$this->veselMoveStatuses = new \Doctrine\Common\Collections\ArrayCollection();
$this->setMmsi($mmsi);
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set mmsi
*
* @param integer $mmsi
*
* @return Vesel
*/
public function setMmsi($mmsi)
{
$this->mmsi = $mmsi;
return $this;
}
/**
* Get mmsi
*
* @return integer
*/
public function getMmsi()
{
return $this->mmsi;
}
/**
* Add veselMoveStatus
*
* @param \AppBundle\Entity\VesselMoveStatus $veselMoveStatus
*
* @return Vesel
*/
public function addVeselMoveStatus(\AppBundle\Entity\VesselMoveStatus $veselMoveStatus)
{
$this->veselMoveStatuses[] = $veselMoveStatus;
return $this;
}
/**
* Remove veselMoveStatus
*
* @param \AppBundle\Entity\VesselMoveStatus $veselMoveStatus
*/
public function removeVeselMoveStatus(\AppBundle\Entity\VesselMoveStatus $veselMoveStatus)
{
$this->veselMoveStatuses->removeElement($veselMoveStatus);
}
/**
* Get veselMoveStatuses
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getVeselMoveStatuses()
{
return $this->veselMoveStatuses;
}
}
与VesselMoveStatus
实体相关:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use AppBundle\Entity\Vesel;
/**
* @ORM\Entity(repositoryClass="AppBundle\Repository\VeselRouteRepository")
* @ORM\Table(name="vessel_position_status",indexes={
* @ORM\Index(name="position",columns={"long","lat"})
* })
*/
class VesselMoveStatus
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id=null;
/**
* @ORM\ManyToOne(targetEntity="Vesel",inversedBy="veselMoveStatuses")
* @ORM\JoinColumn(name="vesel_id", referencedColumnName="id")
* @var Vesel
*/
private $vesel=null;
/**
* @ORM\Column(name="status",type="integer")
* @var integer|null
*/
private $status=null;
/**
* @ORM\Column(name="speed",type="integer")
* @var integer|null
*/
private $speed=null;
/**
* @ORM\Column(name="long",type="float")
* @var float|null
*/
private $logtitude=null;
/**
* @ORM\Column(name="lat",type="float")
* @var float|null
*/
private $latitude=null;
/**
* @ORM\Column(name="course",type="integer")
* @var integer|null
*/
private $course=null;
/**
* @ORM\Column(name="heading",type="integer")
* @var integer|null
*/
private $heading=null;
/**
* @ORM\Column(name="rotation",type="integer")
* @var integer|null
*/
private $rotation=null;
/**
* @ORM\Column(name="timestamp",type="datetime")
* @var Datetime|null
*/
private $timestamp=null;
public function __construct(
Vesel $vesel=null,
$status=null,
$speed=null,
$long=null,
$lat=null,
$course=null,
$heading=null,
$rotation=null,
$timestamp=null
){
$this->setVesel($vesel)
->setStatus($status)
->setSpeed($speed)
->setLogtitude($long)
->setLatitude($lat)
->setCourse($course)
->setHeading($heading)
->setRotation($rotation)
->setTimestamp($timestamp);
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set mmsi
*
* @param integer $mmsi
*
* @return VesselMoveStatus
*/
public function setMmsi($mmsi)
{
$this->mmsi = $mmsi;
return $this;
}
/**
* Get mmsi
*
* @return integer
*/
public function getMmsi()
{
return $this->mmsi;
}
/**
*
* @param integer $status
* @return \AppBundle\Entity\VesselMoveStatus
*/
public function setStatus($status)
{
$this->status=$status;
return $this;
}
/**
*
* @return \AppBundle\Entity\integer|NULL
*/
public function getStatus()
{
return $this->status;
}
/**
* Set speed
*
* @param integer $speed
*
* @return VesselMoveStatus
*/
public function setSpeed($speed)
{
$this->speed = $speed;
return $this;
}
/**
* Get speed
*
* @return float
*/
public function getSpeed()
{
return $this->speed/10;
}
/**
* Set logtitude
*
* @param integer $logtitude
*
* @return VesselMoveStatus
*/
public function setLogtitude($logtitude)
{
$this->logtitude = $this->sanitizeGpsCoordinate($logtitude);
return $this;
}
/**
* Get logtitude
*
* @return float
*/
public function getLogtitude()
{
return $this->logtitude;
}
/**
* Set latitude
*
* @param integer $latitude
*
* @return VesselMoveStatus
*/
public function setLatitude($latitude)
{
$this->latitude = $this->sanitizeGpsCoordinate($latitude);
return $this;
}
/**
* Get latitude
*
* @return float
*/
public function getLatitude()
{
$latitude=$this->latitude;
return $latitude;
}
/**
* Set course
*
* @param integer $course
*
* @return VesselMoveStatus
*/
public function setCourse($course)
{
$this->course = $course;
return $this;
}
/**
* Get course
*
* @return integer
*/
public function getCourse()
{
return $this->course;
}
/**
* Set heading
*
* @param integer $heading
*
* @return VesselMoveStatus
*/
public function setHeading($heading)
{
$this->heading = $heading;
return $this;
}
/**
* Get heading
*
* @return integer
*/
public function getHeading()
{
return $this->heading;
}
/**
* Set rotation
*
* @param integer $rotation
*
* @return VesselMoveStatus
*/
public function setRotation($rotation)
{
$this->rotation = $rotation;
return $this;
}
/**
* Get rotation
*
* @return integer
*/
public function getRotation()
{
return $this->rotation;
}
/**
* Set timesptamp
*
* @param string $timesptamp
*
* @return VesselMoveStatus
*/
public function setTimestamp($timesptamp)
{
$this->timestamp = date_create_from_format("Y-m-d H:i:s.u",$timesptamp);
return $this;
}
/**
* Get timesptamp
*
* @return \DateTime
*/
public function getTimestamp()
{
return $this->timestamp;
}
/**
* Set vesel
*
* @param \AppBundle\Entity\Vesel $vesel
*
* @return VesselMoveStatus
*/
public function setVesel(\AppBundle\Entity\Vesel $vesel = null)
{
$this->vesel = $vesel;
return $this;
}
/**
* Get vesel
*
* @return \AppBundle\Entity\Vesel
*/
public function getVesel()
{
return $this->vesel;
}
/**
* Sometimes a GPS Coordinate may have the following format:
* 1,234532 if inserted as is then itn WONT be retreived correctly.
* Please use this method to sanitize the gps coordinate on setter method.
*
* @param string | float $coordinate
* @return number
*/
private function sanitizeGpsCoordinate($coordinate)
{
if(is_string($coordinate))
{
$coordinate=str_replace(',','.',$coordinate);
}
return (float)$coordinate;
}
}
答案 0 :(得分:2)
您想要转换数据的方式不是标准的,因此Doctrine中没有任何通用的方法可以这样做。但实现您想要的目标仍然非常简单。
然而,恕我直言,最简单的解决方案是使用闭包来转换结果:
$result = $query->getResult();
$formatter = function($row) {
return [
"mmsi" => $row['mmsi']
"points" => [
"longtitude" => $row['logtitude'],
"latitude" => $row['latitude'],
"time" => $row['timestamp']
]
];
};
return array_map($formatter, $result);
最终数组每个点有一个元素(veselMoveStatuses)。如果您真正想要的是每个vesel有一个元素,请考虑更改SELECT并相应地调整格式化程序。
->select('v,m')
结果将是一个Vesel对象数组,其中已经加载了veselMoveStatuses关联(请参阅this doc - 部分“检索CmsUser并获取加入他所有的所有语音”)。