From 4063537f628d90c5f61eadb5ed73d1423972a69f Mon Sep 17 00:00:00 2001
From: Armand Bahi <armand.bahi@veremes.com>
Date: Fri, 2 Nov 2018 16:06:06 +0100
Subject: [PATCH] Add diff_geometry request

---
 web_service/ws/Querys.class.inc | 156 +++++++++++++++++++++++++++++++-
 1 file changed, 153 insertions(+), 3 deletions(-)

diff --git a/web_service/ws/Querys.class.inc b/web_service/ws/Querys.class.inc
index a5e4b7de..1850b33b 100644
--- a/web_service/ws/Querys.class.inc
+++ b/web_service/ws/Querys.class.inc
@@ -515,14 +515,54 @@ class Querys extends Vmap {
      *     )
      *  )
      */
+    /**
+     * @SWG\Get(path="/querys/{business_object_id}/diff_geometry",
+     *   tags={"Querys"},
+     *   summary="Get business object form querys",
+     *   description="Get the difference geom between intersect_geom and the BO using st_difference",
+     *   operationId="GET",
+     *   produces={"application/json", "application/x-vm-json"},
+     *  @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="business_object_id",
+     *     in="path",
+     *     description="business object id",
+     *     required=true,
+     *     type="integer"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="intersect_geom",
+     *     in="query",
+     *     description="EWKT intersect geometry",
+     *     required=true,
+     *     type="integer"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/users")
+     *     )
+     *  )
+     */
 
     /**
      * get Querys
      * @return  Querys
      */
     function GET($bOnlyReturnStatus = FALSE) {
-        if (isset($this->aPath[3]) && ($this->aPath[3] == 'geometry')) {
-            return $this->getBoGeomsFromIntersect($this->aPath[2]);
+        if (($this->aPath[3] == 'geometry') || ($this->aPath[3] == 'diff_geometry')) {
+            if (($this->aPath[3] == 'geometry')) {
+                return $this->getBoGeomsFromIntersect($this->aPath[2]);
+            }
+            if (($this->aPath[3] == 'diff_geometry')) {
+                return $this->getBoDiffGeomFromIntersect($this->aPath[2]);
+            }
         } else if (isset($this->aPath[3])) {
             return $this->queryBusinessObject($this->aPath[3]);
         } else {
@@ -597,7 +637,6 @@ class Querys extends Vmap {
 
         // Valeurs par défaut
         $intersect_column = empty($intersect_column) ? $geom_column : $intersect_column;
-//        $intersect_buffer = empty($intersect_buffer) ? 0.01 : $intersect_buffer;
         $geom_field = empty($geom_field) ? $intersect_column : $geom_field;
         $get_geom = empty($geom_field) || empty($get_geom) ? false : $get_geom;
         $use_intersect = empty($intersect_geom) || empty($intersect_column) ? false : true;
@@ -1205,6 +1244,117 @@ class Querys extends Vmap {
         }
     }
 
+    /**
+     * Get the difference geometry with a business object intersecting intersect_geom
+     */
+    function getBoDiffGeomFromIntersect($sBusinessObjectId) {
+
+        if (!empty($this->oConnection->oError)) {
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $this->oConnection->oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            $aReturn = array('sStatus' => $aXmlRacineAttribute['status'], "sMessage" => $sMessage);
+            return $aReturn['sMessage'];
+        }
+        if (empty($sBusinessObjectId) || empty($this->aValues['intersect_geom'])) {
+            $oError = new VitisError(0, 'Parameters business_object_id, intersect_geom required');
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            $aReturn = array('sStatus' => $aXmlRacineAttribute['status'], "sMessage" => $sMessage);
+            return $aReturn['sMessage'];
+        }
+
+        // Objet BusinessObject correspondant
+        $aPath = array('vmap', 'businessobjects', $sBusinessObjectId);
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => 'application/json',
+            'sEncoding' => 'UTF-8',
+            'sSourceEncoding' => 'UTF-8',
+            'my_vitis_id' => $sBusinessObjectId,
+            'module' => 'vmap',
+        );
+        $oBusinessObject = new BusinessObject($aPath, $aValues, $this->aProperties, $this->oConnection);
+        $oBusinessObject->GET();
+
+        // Vérifie l'éxistance de l'objet métier
+        if (empty($oBusinessObject->aFields['business_object_id'])) {
+            $oError = new VitisError(0, 'Business object ' . $sBusinessObjectId . ' not founded');
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            $aReturn = array('sStatus' => $aXmlRacineAttribute['status'], "sMessage" => $sMessage);
+            return $aReturn['sMessage'];
+        }
+
+        // Paramètres retenus dans l'url
+        $sSchema = $oBusinessObject->aFields['schema'];
+        $sTable = $oBusinessObject->aFields['table'];
+        $sIntersectGeom = $this->aValues['intersect_geom'];
+
+        // Paramètres retenus dans le business object
+        $sGeomColumn = $oBusinessObject->aFields['geom_column'];
+        $sDatabase = $oBusinessObject->aFields['database'];
+
+        // Base de données
+        if (!empty($sDatabase) && $sDatabase != $this->oConnection->oBd->base) {
+            $this->oConnection->oBd = new Vm($this->oConnection->oBd->login, $this->oConnection->oBd->mdp, $sDatabase, $this->oConnection->oBd->serveur, $this->oConnection->oBd->port, $this->oConnection->oBd->sgbd, $this->oConnection->oBd->sPageEncoding);
+        }
+
+        // Projection de la colonne intersectée
+        $iColumnProj = $this->oConnection->oBd->getColumnSRID($sSchema, $sTable, $sGeomColumn);
+        if (empty($iColumnProj)) {
+            $iColumnProj = '2154';
+        }
+
+        // Paramètres de la requête
+        $aParams = array();
+        $aParams['sSchema'] = array('value' => $sSchema, 'type' => 'schema_name');
+        $aParams['sTable'] = array('value' => $sTable, 'type' => 'table_name');
+        $aParams['sGeomColumn'] = array('value' => $sGeomColumn, 'type' => 'column_name');
+        $aParams['sIntersectGeom'] = array('value' => $sIntersectGeom, 'type' => 'geometry');
+
+        // Filtre
+        $aFilter = array(
+            'column' => $sGeomColumn,
+            'compare_operator' => 'intersect',
+            'compare_operator_options' => array(
+                'source_proj' => $iColumnProj,
+            ),
+            'value' => $sIntersectGeom
+        );
+        $aDecodedFilter = $this->decodeJSONFilter($aFilter, $sSchema, $sTable);
+
+        $sSecuredFilter = $aDecodedFilter['request'];
+        foreach ($aDecodedFilter['params'] as $key => $value) {
+            $aParams[$key] = $value;
+        }
+
+        $sSql = '
+            WITH geoms AS (
+                SELECT (ST_Dump(st_difference(
+            				ST_GeomFromEWKT([sIntersectGeom]),
+            				ST_Union([sGeomColumn])
+            			))).geom AS geom
+                FROM [sSchema].[sTable] WHERE ' . $sSecuredFilter . '
+            )
+            SELECT ST_AsEWKT(geom) as diff_geom
+            FROM geoms
+            ORDER BY ST_Area(geom) DESC
+            LIMIT 1
+        ';
+
+        $oResult = $this->oConnection->oBd->executeWithParams($sSql, $aParams);
+        if ($this->oConnection->oBd->enErreur()) {
+            $aXmlRacineAttribute['status'] = 0;
+            writeToErrorLog($this->oConnection->oBd->getBDMessage());
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            $aReturn = array('sStatus' => $aXmlRacineAttribute['status'], "sMessage" => $sMessage);
+            return $aReturn['sMessage'];
+        } else {
+            $aResult = $this->oConnection->oBd->getResultTableAssoc($oResult);
+            return json_encode($aResult);
+        }
+    }
+
     /**
      * @SWG\Put(path="/querys/{business_object_id}",
      *   tags={"Querys"},
-- 
GitLab