Browse Source

Agregado del location al NAP

Agregado del ONU Controller para calcular la distancia y los puertos libres

Agregado del sql mode en doctrine para poder utilizar el group by por campos independientes
gabriel 7 years ago
parent
commit
ea31d2bfd6

+ 3 - 1
app/config/config.yml

@@ -79,7 +79,9 @@ doctrine:
         user:     "%database_user%"
         password: "%database_password%"
         charset:  UTF8
-
+        options:
+            # PDO::MYSQL_ATTR_INIT_COMMAND
+            1002: "SET sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''))"
     orm:
         auto_generate_proxy_classes: "%kernel.debug%"
         naming_strategy: doctrine.orm.naming_strategy.underscore

+ 3 - 3
composer.json

@@ -127,7 +127,7 @@
         "voryx/restgeneratorbundle": "dev-master",
         "ik/base-admin-bundle": "dev-master",
         "ik/oauthclient-bundle": "dev-master",
-        "ik/webservice-bundle": "dev-master",
+        "ik/webservice-bundle": "dev-FD3-247",
         "hwi/oauth-bundle": "^0.5.3",
         "ik/workflow-bundle": "dev-master",
         "php-amqplib/rabbitmq-bundle": "^1.12",
@@ -138,8 +138,8 @@
         "doctrine/doctrine-migrations-bundle": "^1.2",
         "ik/migrations-bundle": "dev-master",
         "samsonasik/package-versions": "1.1.0",
-        "ik/leaflet-bundle": "dev-master",
-        "ik/map-bundle": "dev-master",
+        "ik/leaflet-bundle": "dev-FD3-247",
+        "ik/map-bundle": "dev-FD3-247",
         "ik/auth-bundle": "dev-master",
         "ik/audit-bundle": "dev-master"
     },

+ 8 - 1
src/FTTHBundle/Admin/ONUAdmin.php

@@ -75,7 +75,9 @@ class ONUAdmin extends WorkflowBaseAdmin
             ->add('mac')
             ->add('olt')
             ->end()
-            ->end();
+            ->end()
+            ->setHelps(array(
+                'nap' => $this->trans("helps.check_address")));
     }
 
     /**
@@ -112,4 +114,9 @@ class ONUAdmin extends WorkflowBaseAdmin
             ->end();
     }
 
+    public function configure()
+    {
+        $this->setTemplate('create', 'FTTHBundle:ONU:form.html.twig');
+        $this->setTemplate('edit', 'FTTHBundle:ONU:form.html.twig');
+    }
 }

+ 112 - 0
src/FTTHBundle/Controller/ONUController.php

@@ -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"];
+    }
+}

+ 42 - 1
src/FTTHBundle/Entity/NAP.php

@@ -6,18 +6,22 @@ use Base\AdminBundle\Traits\TenancyIdTrait;
 use Base\AdminBundle\Traits\TenancyIdTraitInterface;
 use Doctrine\ORM\Mapping as ORM;
 use ExtraDataBundle\Entity\Traits\ExtraDataWithParentTrait;
+use MapBundle\Entity\Interfaces\LocationInterface;
+use MapBundle\Entity\Traits\LocationTrait;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\Validator\Constraints as Assert;
 
 /**
  * @ORM\Table
  * @ORM\Entity
  */
-class NAP implements TenancyIdTraitInterface
+class NAP implements TenancyIdTraitInterface, LocationInterface
 {
 
     use ExtraDataWithParentTrait;
     use ONUTrait;
     use TenancyIdTrait;
+    use LocationTrait;
 
     // Cantidad máxima de ONU por NAP
     const MAX_NUMBER_ONU = 64;
@@ -49,6 +53,10 @@ class NAP implements TenancyIdTraitInterface
      * @ORM\OneToMany(targetEntity="ONU", mappedBy="nap", fetch="EXTRA_LAZY")
      */
     protected $onus;
+    /**
+     * @var ContainerInterface
+     */
+    private $container;
 
 
     /**
@@ -109,4 +117,37 @@ class NAP implements TenancyIdTraitInterface
         return $this;
     }
 
+    /**
+     * @return ContainerInterface
+     */
+    public function getContainer(): ContainerInterface
+    {
+        return $this->container;
+    }
+
+    /**
+     * @param ContainerInterface $container
+     */
+    public function setContainer(ContainerInterface $container)
+    {
+        $this->container = $container;
+    }
+
+
+    /**
+     * @return int Retorna la cantidad de puertos libres.
+     */
+    public function getFreePort()
+    {
+        $em = $this->getContainer()->get("doctrine.orm.entity_manager");
+        $query = $em->createQuery('SELECT n.id, COUNT(DISTINCT n.id) AS usedPort FROM ' . ONU::class . ' o JOIN o.nap n where n.id = ' . $this->getId());
+        $onusQuery = $query->getResult();
+        $freePort = $this::MAX_NUMBER_ONU;
+        foreach ($onusQuery as $key => $nap) {
+            if (is_numeric($nap['usedPort'])) {
+                $freePort = NAP::MAX_NUMBER_ONU - $nap['usedPort'];
+            }
+        }
+        return $freePort;
+    }
 }

+ 3 - 0
src/FTTHBundle/Resources/config/routing.yml

@@ -0,0 +1,3 @@
+ajax_distance_nap_onu:
+    path:      /ajax_distance_nap_onu
+    defaults:  { _controller: FTTHBundle:ONU:getDistanceNapOnu }

+ 6 - 1
src/FTTHBundle/Resources/translations/FTTHBundle.es.yml

@@ -168,7 +168,12 @@ show:
     label_onus: ONUs
     label_extra_data: Extra Data
     label_library: Librería
-
+helps:
+    check_address: Verifique la dirección para el cálculo de distancias.
+error:
+    address_not_found: Dirección no encontrada.
+Distance: Distancia
+Free Port: Puertos Libres
 Incorrect State: Estado erróneo
 Undefined State: Estado no definido
 Undefined Workflow: Workflow no definido

+ 96 - 0
src/FTTHBundle/Resources/views/ONU/form.html.twig

@@ -0,0 +1,96 @@
+{% extends 'SonataAdminBundle:CRUD:base_edit.html.twig' %}
+
+
+{% block javascripts %}
+    {{ parent() }}
+    <script type="text/javascript">
+        $(function () {
+            // buscar la direccion del cliente y la muestra en el mapa.
+            $('select[id$="clientId"]').change(function () {
+                $.ajax({
+                    url: '{{ path('ajax_client_data') }}',
+                    dataType: 'json',
+                    delay: 250,
+                    data: {
+                        q: $(this).val()
+                    }
+                }).done(function (data) {
+                    googleSearchDirectionAndShowMaps(data.results[0].address);
+                });
+            });
+        });
+
+        /**
+         * funcion que busca una direccion y la muestra en el mapa.
+         * @param address Contiene la direccion.
+         */
+        function googleSearchDirectionAndShowMaps(address) {
+            $('input[class="search-input"]').val(address + ", Gálvez, Santa Fe, Argentina");
+            $.ajax({
+                url: "http://maps.googleapis.com/maps/api/geocode/json?address='" + address + ", Gálvez, Santa Fe, Argentina'",
+                type: "POST"
+            }).done(function (res) {
+                if (res != undefined) {
+                    if (res.status == google.maps.GeocoderStatus.OK) {
+                        loc = new L.latLng(res.results[0].geometry.location.lat, res.results[0].geometry.location.lng);
+                        drawMarker();
+                        setDataValue();
+                    } else {
+                        alert(res.status);
+                    }
+                } else {
+                    alert("{{ 'error.address_not_found'|trans({}, 'FTTHBundle') }}");
+                }
+            }).error(function (res) {
+                console.log("ERROR: ");
+                console.log(res);
+                alert("{{ 'error.address_not_found'|trans({}, 'FTTHBundle') }}");
+            });
+        }
+
+        /**
+         * Busca y calcula la distancia a los nap y la cantidad de puertos libres.
+         */
+        function calcularDistanciaNap() {
+            var origin = JSON.parse($("input[id*='_location_extraData']").attr('value'));
+            $.ajax({
+                url: '{{ path('ajax_distance_nap_onu') }}',
+                dataType: 'json',
+                type: "GET",
+                data: {
+                    lat: origin.lat,
+                    lng: origin.lng
+                }
+            }).done(function (res) {
+                var select = $("select[id*='_nap']");
+                select.find("option").remove().end();
+                $.each(res, function (i, obj) {
+                    obj = JSON.parse(obj);
+                    for (var i = 0; i < obj.length; i++) {
+                        if (obj[i].distance != -1) {
+                            select.append(
+                                '<option value="' + obj[i].id + '">' +
+                                obj[i].name + " ({{ 'Free Port'|trans({}, 'FTTHBundle') }}: " + obj[i].freePort + " - " +
+                                "{{ 'Distance'|trans({}, 'FTTHBundle') }}: " + obj[i].distance + " KM.)" +
+                                '</option>'
+                            );
+                        }
+                    }
+                    for (var i = 0; i < obj.length; i++) {
+                        if (obj[i].distance == -1) {
+                            select.append(
+                                '<option value="' + obj[i].id + '">' +
+                                obj[i].name + " ({{ 'Free Port'|trans({}, 'FTTHBundle') }}: " + obj[i].freePort + ")" +
+                                '</option>'
+                            );
+                        }
+                    }
+                });
+            }).error(function (res) {
+                console.log("ERROR: ");
+                console.log(res);
+            });
+        }
+    </script>
+
+{% endblock %}