+ * @Rest\Get("/api/person/{id}/localisations")
+ * @Rest\View()
+ */
+ public function getLocalisationsAction(Request $request)
+ {
+ //TODO: Check that the authenticated user is allowed to see the localisation
+ $em = $this->getDoctrine()->getManager();
+ $localisations = $em->getRepository('App:Localisation')->findBy(['person' => $request->get('id')]);
+
+ if (empty($localisations)) {
+ return $this->PersonLocalisationsNotFound();
+ }
+
+ return $localisations;
+ }
+
+ /**
+ * @Rest\Get(
+ * path = "/api/person/{id}/localisations/fuzzy/{distance}",
+ * name = "person_localisations_fuzzy",
+ * requirements = {"id"="\d+", "distance"="\d+"}
+ * )
+ * @Rest\View()
+ */
+ public function getLocalisationsFuzzyAction(Request $request)
+ {
+ //TODO: Check that the authenticated user is allowed to see the localisation
+ $em = $this->getDoctrine()->getManager();
+ $localisations = $em->getRepository('App:Localisation')->findBy(['person' => $request->get('id')]);
+
+ if (empty($localisations)) {
+ return $this->PersonLocalisationsNotFound();
+ }
+
+ if (!$this->chk_distance($request->get('distance'), 200, 500)) {
+ return $this->PersonLocalisationFuzzyWrongDistance();
+ }
+
+ $fuzzy_localisations = array_map(function($item) use ($request) { return $this->randomizeLocation($item, $request->get('distance'), 200, 500); }, $localisations);
+
+ return $fuzzy_localisations;
+ }
+
+ private function getLastLocalisation($em, $id) {
+ $query = $em->createQuery("SELECT l1 FROM App\Entity\Localisation l1
+ WHERE l1.person = :person and l1.timestamp =
+ (SELECT MAX(l2.timestamp) FROM App\Entity\Localisation l2
+ WHERE l2.person = l1.person)");
+ $query->setParameter('person', $id);
+ $result = $query->getResult();
+ if (!empty($result)) {
+ return $result[0];
+ }
+ }
+
+ /**
+ * @Rest\Get("/api/person/{id}/localisation")
+ * @Rest\View()
+ */
+ public function getLocalisationAction(Request $request)
+ {
+ //TODO: Check that the authenticated user is allowed to see the localisation
+ $em = $this->getDoctrine()->getManager();
+
+ $localisation = $this->getLastLocalisation($em, $request->get('id'));
+
+ if (empty($localisation)) {
+ return $this->PersonLocalisationNotFound();
+ }
+
+ return $localisation;
+ }
+
+ private function chk_distance($distance, $min, $max) {
+ if ($distance >= $min && $distance <= $max) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ private function randomizeLocation($localisation, $distance, $min, $max) {
+ // Generate random float in [0, 1[, [0, 1)
+ $u = rand(0, getrandmax() - 1) / getrandmax();
+ $v = rand(0, getrandmax() - 1) / getrandmax();
+
+ if ($this->chk_distance($distance, $min, $max)) {
+ $r = $distance / 111300;
+ } else {
+ return $this->PersonLocalisationFuzzyWrongDistance();
+ }
+
+ $w = $r * sqrt($u);
+ $t = 2 * pi() * $v;
+
+ $x = $w * cos($t);
+ $lng_off = $x / cos(deg2rad($localisation->getLatitude()));
+ $lat_off = $w * sin($t);
+
+ $fuzzy_localisation = new Localisation();
+ $fuzzy_localisation->setTimestamp($localisation->getTimestamp());
+ $fuzzy_localisation->setLatitude($localisation->getLatitude() + $lat_off);
+ $fuzzy_localisation->setLongitude($localisation->getLongitude() + $lng_off);
+ return $fuzzy_localisation;
+ }
+
+ /**
+ * @Rest\Get(
+ * path = "/api/person/{id}/localisation/fuzzy/{distance}",
+ * name = "person_localisation_fuzzy",
+ * requirements = {"id"="\d+", "distance"="\d+"}
+ * )
+ * @Rest\View()
+ */
+ public function getLocalisationFuzzyAction(Request $request)
+ {
+ //TODO: Check that the authenticated user is allowed to see the localisation
+ $em = $this->getDoctrine()->getManager();
+
+ $localisation = $this->getLastLocalisation($em, $request->get('id'));
+
+ if (empty($localisation)) {
+ return $this->PersonLocalisationNotFound();
+ }
+
+ return $this->randomizeLocation($localisation, $request->get('distance'), 200, 500);
+ }
+
+ /**
+ * @Rest\Post("/api/person/{id}/localisation")
+ * @Rest\View(StatusCode = Response::HTTP_CREATED)