|
@@ -0,0 +1,112 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+namespace FTTHBundle\Controller;
|
|
|
+
|
|
|
+use FTTHBundle\Entity\NAP;
|
|
|
+use FTTHBundle\Entity\ONU;
|
|
|
+use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
|
|
+use FOS\RestBundle\Controller\Annotations\RouteResource;
|
|
|
+use Symfony\Component\HttpFoundation\JsonResponse;
|
|
|
+use Symfony\Component\HttpFoundation\Request;
|
|
|
+
|
|
|
+/**
|
|
|
+ * ONU controller.
|
|
|
+ * @RouteResource("ONU")
|
|
|
+ */
|
|
|
+class ONUController extends Controller
|
|
|
+{
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param Request $request
|
|
|
+ * @return JsonResponse
|
|
|
+ */
|
|
|
+ public function getDistanceNapOnuAction(Request $request)
|
|
|
+ {
|
|
|
+ $lat = $request->query->get('lat', '');
|
|
|
+ $lng = $request->query->get('lng', '');
|
|
|
+ if (isset($lat) && isset($lng)) {
|
|
|
+ // calculo las distancias
|
|
|
+ $naps = $this->calculateDistance($lat, $lng);
|
|
|
+ // ordeno las distancias con valores positivos
|
|
|
+ usort($naps, array($this, "orderDistances"));
|
|
|
+ } else {
|
|
|
+ $naps = [];
|
|
|
+ }
|
|
|
+
|
|
|
+ $response = new JsonResponse();
|
|
|
+ $response->setData(['results' => json_encode($naps)]);
|
|
|
+
|
|
|
+ return $response;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Calcula la distancia cartografica (NO TOPOGRAFICA) entre 2 coordenadas.
|
|
|
+ * @param $lat1
|
|
|
+ * @param $lng1
|
|
|
+ * @param $lat2
|
|
|
+ * @param $lng2
|
|
|
+ * @param bool $km Me dice si quiero la distancia en kilometros. Por defecto esta en metros.
|
|
|
+ * @return float|int Retorna la distancia en metros
|
|
|
+ */
|
|
|
+ private function distanceGeoPoints($lat1, $lng1, $lat2, $lng2, $km = false)
|
|
|
+ {
|
|
|
+ // curvatura de la tierra
|
|
|
+ $earthRadius = 3958.75;
|
|
|
+
|
|
|
+ $dLat = deg2rad($lat2 - $lat1);
|
|
|
+ $dLng = deg2rad($lng2 - $lng1);
|
|
|
+
|
|
|
+ $a = sin($dLat / 2) * sin($dLat / 2) +
|
|
|
+ cos(deg2rad($lat1)) * cos(deg2rad($lat2)) *
|
|
|
+ sin($dLng / 2) * sin($dLng / 2);
|
|
|
+ $c = 2 * atan2(sqrt($a), sqrt(1 - $a));
|
|
|
+ $dist = $earthRadius * $c;
|
|
|
+
|
|
|
+ // from miles
|
|
|
+ $meterConversion = 1609;
|
|
|
+ $geopointDistance = $dist * $meterConversion;
|
|
|
+
|
|
|
+ return round(($km ? ($geopointDistance / 1000) : $geopointDistance), 3, PHP_ROUND_HALF_UP);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Calcula la distancia de los NAP al punto pasado.
|
|
|
+ * @param $lat
|
|
|
+ * @param $lng
|
|
|
+ * @return array Retorna una array con los datos de los NAP y con las distancias calculadas.
|
|
|
+ */
|
|
|
+ private function calculateDistance($lat, $lng)
|
|
|
+ {
|
|
|
+ $naps = array();
|
|
|
+ $em = $this->container->get("doctrine.orm.entity_manager");
|
|
|
+ $qb = $em->createQueryBuilder();
|
|
|
+ $query = $qb->select('n')
|
|
|
+ ->from(NAP::class, 'n');
|
|
|
+ $napsQuery = $query->getQuery()->execute();
|
|
|
+ foreach ($napsQuery as $nap) {
|
|
|
+ $extraData = $nap->getExtraData();
|
|
|
+ if ($extraData) {
|
|
|
+ $extraData = json_decode($extraData, true);
|
|
|
+ $nap->setContainer($this->container);
|
|
|
+ if (isset($extraData['lat']) && isset($extraData['lng'])) {
|
|
|
+ $distance = $this->distanceGeoPoints($lat, $lng, $extraData['lat'], $extraData['lng'], true);
|
|
|
+ // divido por 1000 para pasarlo de metros a kilometros
|
|
|
+ $naps[$nap->getId()] = ['id' => $nap->getId(), 'name' => $nap->getName(), 'distance' => $distance, 'freePort'=>$nap->getFreePort()];
|
|
|
+ } else {
|
|
|
+ $naps[$nap->getId()] = ['id' => $nap->getId(), 'name' => $nap->getName(), 'distance' => -1, 'freePort'=>$nap->getFreePort()];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return $naps;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Ordena por las distancias, poniendo los -1 al final.
|
|
|
+ * @param $a
|
|
|
+ * @param $b
|
|
|
+ */
|
|
|
+ public function orderDistances($a, $b)
|
|
|
+ {
|
|
|
+ return $a["distance"] - $b["distance"];
|
|
|
+ }
|
|
|
+}
|