diff --git a/vmap/vas/rest/ws/vmap/BusinessObject.class.inc b/vmap/vas/rest/ws/vmap/BusinessObject.class.inc
new file mode 100644
index 0000000000000000000000000000000000000000..838695456b28ba3e788ac2d04fc1ed36444d0a87
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/BusinessObject.class.inc
@@ -0,0 +1,201 @@
+<?php
+
+require_once 'Vmap.class.inc';
+require_once 'Layers.class.inc';
+require_once 'BusinessObjectEvent.class.inc';
+require_once 'PrintReports.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+
+/**
+ * \file BusinessObject.class.inc
+ * \class BusinessObject
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * 	\brief This file contains the BusinessObject php class
+ *
+ * This class defines operation for one BusinessObject
+ *
+ */
+class BusinessObject extends Vmap {
+
+    public $oError;
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("business_object_id", "title", "formtitle", "summarytitle", "id_field", "database", "schema", "table", "sql_summary", "sql_list", "sorted_by", "geom_column", "search_field", "result_field", "search_use_strict", "event_id", "index", "add_form_size", "edit_form_size", "display_form_size", "selection_buffer", "user_rights", "max_edition_scale", "min_edition_scale");
+    }
+
+    /**
+     * @SWG\Get(path="/businessobjects/{business_object_id}",
+     *   tags={"BusinessObjects"},
+     *   summary="Get BusinessObject",
+     *   description="Request to get BusinessObject by mode id",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="business_object_id",
+     *     in="path",
+     *     description="id",
+     *     required=true,
+     *     type="string",
+     *   ),
+     *   @SWG\Parameter(
+     *     name="attributs",
+     *     in="query",
+     *     description="list of attributs",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/businessobjects")
+     *     )
+     *  )
+     */
+
+    /**
+     * get informations about table businessobjects
+     */
+    function GET() {
+
+        require $this->sRessourcesFile;
+        $this->aFields = $this->getFields($this->aProperties['schema_vmap'], "business_object", "business_object_id");
+
+        // Formulaire JSON
+        $this->aFields['json_form'] = array();
+        if (!empty($this->aFields['business_object_id']))
+            $businessObjectId = $this->aFields['business_object_id'];
+        else
+            $businessObjectId = '';
+        if (file_exists($this->aProperties['ws_data_dir'] . '/vmap/business_object/' . $businessObjectId . '/forms/published.json')) {
+            $form = file_get_contents($this->aProperties['ws_data_dir'] . '/vmap/business_object/' . $businessObjectId . '/forms/published.json');
+            array_push($this->aFields['json_form'], json_decode($form));
+        }
+        if (file_exists($this->aProperties['ws_data_dir'] . '/vmap/business_object/' . $businessObjectId . '/forms/ressources/published.js')) {
+            $this->aFields['json_form_js'] = $this->aProperties['web_server_name'] . '/' . $this->aProperties['ws_data_alias'] . '/vmap/business_object/' . $businessObjectId . '/forms/ressources/published.js';
+        }
+        if (file_exists($this->aProperties['ws_data_dir'] . '/vmap/business_object/' . $businessObjectId . '/forms/ressources/published.css')) {
+            $this->aFields['json_form_js'] = $this->aProperties['web_server_name'] . '/' . $this->aProperties['ws_data_alias'] . '/vmap/business_object/' . $businessObjectId . '/forms/ressources/published.js';
+        }
+        if (!empty($this->aFields['database']) && $this->aFields['database'] != $this->oConnection->oBd->base) {
+            $sLogin = $this->oConnection->oBd->login;
+            $sPassword = $this->oConnection->oBd->mdp;
+            $this->oConnection->oBd = new Vm($sLogin, $sPassword, $this->aFields['database'], $this->oConnection->oBd->serveur, $this->oConnection->oBd->port, $this->oConnection->oBd->sgbd, $this->oConnection->oBd->sPageEncoding);
+        }
+
+        if (!$this->oConnection->oBd->enErreur()) {
+            if (!empty($this->aFields['geom_column'])) {
+                $aGeomColumnsInfos = $this->getTableGeomColumnsInfos($this->aFields['schema'], $this->aFields['table']);
+                for ($i = 0; $i < count($aGeomColumnsInfos); $i++) {
+                    if ($aGeomColumnsInfos[$i]['f_geometry_column'] === $this->aFields['geom_column']) {
+                        $this->aFields['geom_type'] = $aGeomColumnsInfos[$i]['type'];
+                    }
+                }
+            }
+            $this->aFields['user_rights'] = $this->oConnection->getTableRights($this->aFields['schema'], $this->aFields['table']);
+            $this->aFields['list_fields'] = $this->getListFields();
+        }
+
+        if (!empty($sLogin) && isset($sPassword)) {
+            $this->oConnection->oBd = new Vm($sLogin, $sPassword, $this->aProperties['database'], $this->aProperties['server'], $this->aProperties['port'], $this->aProperties['sgbd'], $this->aProperties['page_encoding']);
+        }
+    }
+
+    /**
+     * Get the fields from the list
+     * @return array
+     */
+    function getListFields() {
+        $aFields = array();
+        if (!empty($this->aFields['sql_list'])) {
+            $sSql = $this->aFields['sql_list'] . ' limit 1';
+            $oResult = $this->oConnection->oBd->executeWithParams($sSql, array());
+            if (!$this->oConnection->oBd->enErreur()) {
+                while ($aLigne = $this->oConnection->oBd->ligneSuivante($oResult)) {
+                    foreach ($aLigne as $key => $value) {
+                        array_push($aFields, $key);
+                    }
+                }
+            }
+        }
+        return $aFields;
+    }
+
+    /**
+     * delete a business_object
+     */
+    function DELETE() {
+
+        $this->GET();
+        $bEventExists = false;
+        $bReportExists = false;
+        $bLayerExists = false;
+
+        // Test existance rapports
+        $aPath = Array('vmap', 'printreports');
+        $aValues = $this->aValues;
+        unset($aValues['my_vitis_id']);
+        // $aValues['filter'] = "business_object_id='" . $this->aFields['business_object_id'] . "'";
+        $aValues['filter'] = '{"column":"business_object_id","compare_operator":"=","value":"' . $this->aFields['business_object_id'] . '"}';
+        $oPrintReports = new PrintReports($aPath, $aValues, $this->aProperties, $this->oConnection);
+        $oPrintReports->GET();
+        if (count($oPrintReports->aObjects) > 0) {
+            $this->oError = new VitisError(1, 'ERROR_BO_DELETE_REPPORT');
+            $bReportExists = true;
+        }
+
+        // Test existance événement
+        if (isset($this->aFields['event_id']) && !empty($this->aFields['event_id'])) {
+            $aPath = Array('vmap', 'businessobjectevents', $this->aFields['event_id']);
+            $aValues = $this->aValues;
+            $aValues['my_vitis_id'] = $this->aFields['event_id'];
+            $oEvent = new BusinessObjectEvent($aPath, $aValues, $this->aProperties, $this->oConnection);
+            $oEvent->GET();
+
+            // L'événement existe
+            if (isset($oEvent->aFields['event_id']) && !empty($oEvent->aFields['event_id'])) {
+                $this->oError = new VitisError(1, 'ERROR_BO_DELETE_EVENT');
+                $bEventExists = true;
+            }
+        }
+
+        // Des-associe les objets métiers de la couche
+        require $this->sRessourcesFile;
+        $aSQLParams = array(
+            'sSchemaVmap' => array('value' => $this->aProperties['schema_vmap'], 'type' => 'column_name'),
+            'business_object_id' => array('value' => $this->aValues['my_vitis_id'], 'type' => 'number')
+        );
+        $oResult = $this->oConnection->oBd->executeWithParams($aSql['deleteAssociatedLayers'], $aSQLParams);
+
+        // Suppression objet
+        if (!$bEventExists && !$bReportExists && !$bLayerExists) {
+            $this->aFields = array();
+            $this->oConnection->oBd->delete($this->aProperties['schema_vmap'], 'business_object', 'business_object_id', $this->aValues['my_vitis_id'], 'text');
+            if ($this->oConnection->oBd->enErreur()) {
+                $this->oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+            } else {
+                $this->aFields['business_object_id'] = $this->aValues['my_vitis_id'];
+            }
+        }
+    }
+
+}
+
+?>
diff --git a/vmap/vas/rest/ws/vmap/BusinessObjectEvent.class.inc b/vmap/vas/rest/ws/vmap/BusinessObjectEvent.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..8de888db4dc8008b65224bdbaf5f069cdeaae0cb
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/BusinessObjectEvent.class.inc
@@ -0,0 +1,86 @@
+<?php
+
+require_once 'Vmap.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+
+/**
+ * \file BusinessObjectEvent.class.inc
+ * \class BusinessObjectEvent
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * \brief This file contains the BusinessObjectEvent php class
+ *
+ * This class defines operation for one BusinessObjectEvent
+ * 
+ */
+class BusinessObjectEvent extends Vmap {
+
+    public $oError;
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("event_id", "description");
+    }
+
+    /**
+     * @SWG\Get(path="/businessobjectevents/{event_id}", 
+     *   tags={"BusinessObjectEvents"},
+     *   summary="Get BusinessObjectEvent",
+     *   description="Request to get event of business object by id",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="event_id",
+     *     in="path",
+     *     description="event id",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/businessobjectevent")
+     *     )
+     *  )
+     */
+
+    /**
+     * get informations about businessobjectevents
+     */
+    function GET() {
+        require $this->sRessourcesFile;
+        $this->aFields = $this->getFields($this->aProperties['schema_vmap'], 'event', 'event_id');
+    }
+
+    /**
+     * delete a businessobjectevent
+     */
+    function DELETE() {
+        $this->oConnection->oBd->delete($this->aProperties['schema_vmap'], 'event', 'event_id', $this->aValues['my_vitis_id'], 'text');
+        if ($this->oConnection->oBd->enErreur()) {
+            $this->oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+            $this->oConnection->oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+        } else {
+            $this->aFields['event_id'] = $this->aValues['my_vitis_id'];
+        }
+    }
+
+}
+
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/BusinessObjectEvents.class.inc b/vmap/vas/rest/ws/vmap/BusinessObjectEvents.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..059fe3dbfdad20fb1c3a70926af3de1ae0529052
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/BusinessObjectEvents.class.inc
@@ -0,0 +1,289 @@
+<?php
+
+/**
+ * \file BusinessObjectEvents.class.inc
+ * \class BusinessObjectEvents
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * \brief This file contains the BusinessObjectEvents php class
+ *
+ * This class defines Rest Api to Vmap BusinessObjectEvents
+ * 
+ */
+require_once 'Vmap.class.inc';
+require_once 'BusinessObjectEvent.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+require_once __DIR__ . '/../../class/vmlib/BdDataAccess.inc';
+
+class BusinessObjectEvents extends Vmap {
+    /**
+     * @SWG\Definition(
+     *   definition="/businessobjectevents",
+     *   allOf={
+     *     @SWG\Schema(ref="#/definitions/businessobjectevents")
+     *   }
+     * )
+     * * @SWG\Tag(
+     *   name="BusinessObjectEvents",
+     *   description=""
+     * )
+     */
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("event_id", "description");
+    }
+
+    /**
+     * @SWG\Get(path="/businessobjectevents",
+     *   tags={"BusinessObjectEvents"},
+     *   summary="Get BusinessObjectEvents",
+     *   description="Request to get BusinessObjectEvents",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="order_by",
+     *     in="query",
+     *     description="list of ordering fields",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="sort_order",
+     *     in="query",
+     *     description="sort order",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="limit",
+     *     in="query",
+     *     description="number of element",
+     *     required=false,
+     *     type="integer"
+     *   ),
+     * @SWG\Parameter(
+     *     name="offset",
+     *     in="query",
+     *     description="index of first element",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="attributs",
+     *     in="query",
+     *     description="list of attributs",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="filter",
+     *     in="query",
+     *     description="filter results",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="distinct",
+     *     in="query",
+     *     description="delete duplicates",
+     *     required=false,
+     *     type="boolean"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/businessobjectevents")
+     *     )
+     *  )
+     */
+
+    /**
+     * get BusinessObjectEvents
+     * @return the array of objects
+     */
+    function GET() {
+        $aReturn = $this->genericGet($this->aProperties['schema_vmap'], 'event', 'event_id');
+        return $aReturn['sMessage'];
+    }
+
+    /**
+     * @SWG\Post(path="/businessobjectevents",
+     *   tags={"BusinessObjectEvents"},
+     *   summary="Add businessobjectevent",
+     *   description="Request to add a businessobjectevent",
+     *   operationId="POST",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="formData",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="event_id",
+     *     in="formData",
+     *     description="event id",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="description",
+     *     in="formData",
+     *     description="event description",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/businessobjectevents")
+     *     )
+     *
+     *  )
+     * 
+     * )
+     */
+
+    /**
+     * insert businessobjectevent
+     * @return array containing the status and the message
+     */
+    function POST() {
+        $aReturn = $this->genericPost($this->aProperties['schema_vmap'], 'event', '', 'event_id');
+        return $aReturn['sMessage'];
+    }
+    
+    /**
+     * @SWG\Put(path="/businessobjectevents/{event_id}",
+     *   tags={"BusinessObjectEvents"},
+     *   summary="Update BusinessObjectEvent",
+     *   description="Request to update businessobjectevent",
+     *   operationId="PUT",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="event_id",
+     *     in="path",
+     *     description="event id",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="description",
+     *     in="query",
+     *     description="event description",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/businessobjectevents")
+     *     ),
+     * 
+     *  )
+     */
+
+    /**
+     * modify businessobjectevent
+     * @return array containing the status and the message
+     */
+    function PUT() {        
+        $aReturn = $this->genericPut($this->aProperties['schema_vmap'], 'event', 'event_id');
+        return $aReturn['sMessage'];
+    }
+    
+    /**
+     * @SWG\Delete(path="/businessobjectevents/",
+     *   tags={"BusinessObjectEvents"},
+     *   summary="delete BusinessObjectEvent",
+     *   description="Request to delete BusinessObjectEvent",
+     *   operationId="DELETE",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="idList",
+     *     in="query",
+     *     description="event id",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/businessobjectevents")
+     *     )
+     *  )
+     */
+    /**
+     * @SWG\Delete(path="/businessobjectevents/{event_id}",
+     *   tags={"BusinessObjectEvents"},
+     *   summary="delete BusinessObjectEvent",
+     *   description="Request to delete BusinessObjectEvent",
+     *   operationId="DELETE",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="event_id",
+     *     in="path",
+     *     description="event id",
+     *     required=true,
+     *     type="integer",
+     *     format = "int32"
+     *   ),
+     * @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/businessobjectevents")
+     *     )
+     *  )
+     */
+    
+    /**
+     * delete businessobjectevent
+     * @return id of businessobjectevent deleted or error object if a businessobjectevent is not deleted
+     */
+    function DELETE() {        
+        $aReturn = $this->genericDelete($this->aProperties['schema_vmap'], 'event', 'event_id');
+        return $aReturn['sMessage'];
+    }
+
+}
+
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/BusinessObjects.class.inc b/vmap/vas/rest/ws/vmap/BusinessObjects.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..6fa5a44be559e96821500c33498e2b11783d2663
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/BusinessObjects.class.inc
@@ -0,0 +1,1491 @@
+<?php
+
+/**
+ * \file BusinessObjects.class.inc
+ * \class BusinessObjects
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * 	\brief This file contains the BusinessObjects php class
+ *
+ * This class defines Rest Api to Vitis businessobjects
+ *
+ */
+require_once 'Vmap.class.inc';
+require_once 'BusinessObject.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Form.class.inc';
+require_once __DIR__ . '/../../class/vmlib/BdDataAccess.inc';
+require_once 'vmlib/logUtil.inc';
+
+class BusinessObjects extends Vmap {
+    /**
+     * @SWG\Definition(
+     *   definition="/businessobjects",
+     *   allOf={
+     *     @SWG\Schema(ref="#/definitions/businessobjects")
+     *   }
+     * )
+     * * @SWG\Tag(
+     *   name="BusinessObjects",
+     *   description=""
+     * )
+     */
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("business_object_id", "title", "formtitle", "summarytitle", "id_field", "database", "schema", "table", "sql_summary", "sql_list", "sorted_by", "geom_column", "search_field", "result_field", "search_use_strict", "event_id", "index", "add_form_size", "edit_form_size", "display_form_size", "selection_buffer", "user_rights", "max_edition_scale", "min_edition_scale");
+    }
+
+    /**
+     * @SWG\Get(path="/businessobjects",
+     *   tags={"BusinessObjects"},
+     *   summary="Get BusinessObjects",
+     *   description="Request to get BusinessObjects",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="order_by",
+     *     in="query",
+     *     description="list of ordering fields",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="sort_order",
+     *     in="query",
+     *     description="sort order",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="limit",
+     *     in="query",
+     *     description="number of element",
+     *     required=false,
+     *     type="integer"
+     *   ),
+     * @SWG\Parameter(
+     *     name="offset",
+     *     in="query",
+     *     description="index of first element",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="attributs",
+     *     in="query",
+     *     description="list of attributs",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="filter",
+     *     in="query",
+     *     description="filter results",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="distinct",
+     *     in="query",
+     *     description="delete duplicates",
+     *     required=false,
+     *     type="boolean"
+     *   ),
+     * @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/users")
+     *     )
+     *  )
+     */
+    /**
+     * @SWG\Get(path="/businessobjects/{business_object_id}/fields",
+     *   tags={"BusinessObjects"},
+     *   summary="BusinessObject table fields",
+     *   description="Request to get the business object table fields",
+     *   operationId="GET",
+     *   produces={"application/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\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/businessobjects")
+     *     )
+     *  )
+     */
+    /**
+     * @SWG\Get(path="/businessobjects/{business_object_id}/form/{form}",
+     *   tags={"BusinessObjects"},
+     *   summary="Query BusinessObject",
+     *   description="Request to query the business object",
+     *   operationId="GET",
+     *   produces={"application/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="form",
+     *     in="path",
+     *     description="form name (default, published, custom)",
+     *     required=true,
+     *     type="integer"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/businessobjects")
+     *     )
+     *  )
+     */
+
+    /**
+     * get BusinessObjects
+     * @return BusinessObjects
+     */
+    function GET() {
+
+        // /businessobjects/{business_object_id}/form/{form}
+        if (isset($this->aPath[4])) {
+            $businessObjectId = $this->aPath[2];
+            $formName = $this->aPath[4];
+            $form = file_get_contents($this->aProperties['ws_data_dir'] . '/vmap/business_object/' . $businessObjectId . '/forms/' . $formName . '.json');
+
+            if (is_file($this->aProperties['ws_data_dir'] . '/vmap/business_object/' . $businessObjectId . '/forms/ressources/' . $formName . '.js')) {
+                $jsContent = file_get_contents($this->aProperties['ws_data_dir'] . '/vmap/business_object/' . $businessObjectId . '/forms/ressources/' . $formName . '.js');
+            } else {
+                $jsContent = false;
+            }
+            if (is_file($this->aProperties['ws_data_dir'] . '/vmap/business_object/' . $businessObjectId . '/forms/ressources/' . $formName . '.css')) {
+                $cssContent = file_get_contents($this->aProperties['ws_data_dir'] . '/vmap/business_object/' . $businessObjectId . '/forms/ressources/' . $formName . '.css');
+            } else {
+                $cssContent = false;
+            }
+
+            $output = array(json_decode($form), $jsContent, $cssContent);
+            return json_encode($output);
+        }
+        // /businessobjects/{business_object_id}/fields
+        else if (isset($this->aPath[3])) {
+
+            // Objet BusinessObject correspondant
+            $oBusinessObject = new BusinessObject($this->aPath, $this->aValues, $this->aProperties, $this->oConnection);
+            $oBusinessObject->GET();
+
+            // Paramètres retenus dans le business object
+            $bo_title = $oBusinessObject->aFields['title'];
+            $bo_database = $oBusinessObject->aFields['database'];
+            $bo_schema = $oBusinessObject->aFields['schema'];
+            $bo_table = $oBusinessObject->aFields['table'];
+            $bo_id_field = $oBusinessObject->aFields['id_field'];
+            $geom_column = $oBusinessObject->aFields['geom_column'];
+
+            // Connexion à la base de donées
+            if (!empty($bo_database) && $bo_database != $this->oConnection->oBd->base) {
+                $sLogin = $this->oConnection->oBd->login;
+                $sPassword = $this->oConnection->oBd->mdp;
+                $this->oConnection->oBd = new Vm($sLogin, $sPassword, $bo_database, $this->oConnection->oBd->serveur, $this->oConnection->oBd->port, $this->oConnection->oBd->sgbd, $this->oConnection->oBd->sPageEncoding);
+            }
+
+            $oForm = new Form($this->aProperties, $this->oConnection);
+            $aTableColumns = $oForm->getTableColumns($bo_schema, $bo_table);
+            $aRows = $oForm->generateRowsByTableColumns($aTableColumns);
+
+            return json_encode($aRows);
+        }
+        // /businessobjects/{business_object_id}
+        else {
+            $aReturn = $this->genericGet($this->aProperties['schema_vmap'], "business_object", "business_object_id");
+            return $aReturn['sMessage'];
+        }
+    }
+
+    /**
+     * @SWG\Post(path="/businessobjects",
+     *   tags={"BusinessObjects"},
+     *   summary="Add business_object",
+     *   description="Request to add a business_object",
+     *   operationId="POST",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="formData",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="business_object_id",
+     *     in="formData",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="title",
+     *     in="formData",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="database",
+     *     in="formData",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="schema",
+     *     in="formData",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="table",
+     *     in="formData",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="id_field",
+     *     in="formData",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="sql_summary",
+     *     in="formData",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="sql_list",
+     *     in="formData",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="sorted_by",
+     *     in="formData",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="geom_column",
+     *     in="formData",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="search_field",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="result_field",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="search_use_strict",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="event_id",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="index",
+     *     in="query",
+     *     description="",
+     *     required=true,
+     *     type="integer"
+     *   ),
+     * @SWG\Parameter(
+     *     name="add_form_size",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="edit_form_size",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="display_form_size",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/businessobjects")
+     *     )
+     *  )
+     * )
+     */
+    /**
+     * @SWG\Post(path="/businessobjects/package_definition",
+     *   tags={"BusinessObjects"},
+     *   summary="Add business_object",
+     *   description="Request to add a business_object",
+     *   operationId="POST",
+     *   produces={"application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="package_definition",
+     *     in="formData",
+     *     description="",
+     *     required=true,
+     *     type="file"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/businessobjects")
+     *     )
+     *  )
+     * )
+     */
+    /**
+     * @SWG\Post(path="/businessobjects/data_model",
+     *   tags={"BusinessObjects"},
+     *   summary="Add business_object",
+     *   description="Request to add a business_object",
+     *   operationId="POST",
+     *   produces={"application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="data_model",
+     *     in="formData",
+     *     description="",
+     *     required=true,
+     *     type="file"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/businessobjects")
+     *     )
+     *  )
+     * )
+     */
+    /**
+     * @SWG\Post(path="/businessobjects/{business_object_id}/form/{form}",
+     *   tags={"BusinessObjects"},
+     *   summary="Add business_object",
+     *   description="Request to generate a business_object form",
+     *   operationId="POST",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="formData",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="business_object_id",
+     *     in="path",
+     *     description="business_object_id",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="form",
+     *     in="path",
+     *     description="form name (default, published, custom)",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="fields",
+     *     in="formData",
+     *     description="list of fields separed by | ",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/businessobjects")
+     *     )
+     *  )
+     * )
+     */
+
+    /**
+     * insert business_object
+     * @return array containing the status and the message
+     */
+    function POST() {
+        if (isset($this->oConnection->oError) && !empty($this->oConnection->oError)) {
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $this->oConnection->oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        }
+        if (!in_array('vmap_admin', $this->oConnection->aPrivileges)) {
+            $oError = new VitisError(0, 'INSUFFICIENT_PRIVILEGES');
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        }
+        if (isset($this->aPath[4])) {
+            $sBusinessObjectId = $this->aPath[2];
+            $sFormName = $this->aPath[4];
+            $aFields = explode("|", $this->aValues['fields']);
+            return $this->generateBusinessObjectForm($sBusinessObjectId, $sFormName, $aFields, $this->aValues['label']);
+        } else {
+
+            if ($this->aPath[2] === 'package_definition') {
+                // Importe le dossier dans /tmp et renvoie son contenu
+                return $this->postPackageDefinition();
+            } else if ($this->aPath[2] === 'data_model') {
+                // Importe le modèle de données de l'objet métier
+                return $this->postDataModel();
+            } else {
+                if ($this->aValues['min_edition_scale'] == "") {
+                    $this->aValues['min_edition_scale'] = null;
+                }
+                if ($this->aValues['max_edition_scale'] == "") {
+                    $this->aValues['max_edition_scale'] = null;
+                }
+                $aReturn = $this->genericPost($this->aProperties['schema_vmap'], 'business_object', '', 'business_object_id');
+                return $aReturn['sMessage'];
+            }
+        }
+    }
+
+    /**
+     * Post the package definition
+     * @return type
+     */
+    function postPackageDefinition() {
+
+        if (!isset($_FILES['package_definition'])) {
+            $oError = new VitisError(0, 'package_definition not found');
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        }
+        if (!in_array('vitis_admin', $this->oConnection->aPrivileges) ||
+                !in_array('vmap_admin', $this->oConnection->aPrivileges) ||
+                !in_array('vm4ms_admin', $this->oConnection->aPrivileges)) {
+            $oError = new VitisError(0, 'insufficient privileges (needs to be vitis_admin, vmap_admin and vm4ms_admin)');
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        }
+
+        $sZipName = $_FILES['package_definition']['name'];
+        $sPackageFormat = substr($sZipName, -4);
+        $sFolderName = str_replace('.vex', '', $sZipName);
+
+        // Test format du package
+        if ($sPackageFormat !== '.vex') {
+            writeToErrorLog('getBusinessObjectPackage: package format not valid: ' . $sPackageFormat);
+            $oError = new VitisError(0, 'Package not valid');
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        }
+
+        // Dézippe le contennu dans un dossier dans tmp
+        $sDir = $this->UniqFileName();
+        $aReturn = $this->postFileSave('package_definition', '../../tmp/', $sDir);
+        $sPath = $this->aProperties['vas_home'] . '/tmp/' . $sDir;
+        unZip($sPath . '/' . $sZipName, $sPath . '/' . $sFolderName);
+
+        // Cas où il y ait dans le zip un dossier de même nom
+        $sFolderPath = $sPath . '/' . $sFolderName;
+        if (is_dir($sPath . '/' . $sFolderName . '/' . $sFolderName)) {
+            $sFolderPath = $sPath . '/' . $sFolderName . '/' . $sFolderName;
+        }
+
+        $aBoFolders = array();
+        // Récupère les repertoires contenant des objets métier
+        $aFolderPathContent = scandir($sFolderPath);
+        if (count($aFolderPathContent) > 2 && !is_dir($sFolderPath . '/json') && !is_dir($sFolderPath . '/forms') && !is_dir($sFolderPath . '/sql') && !is_file($sFolderPath . '/package.json')) {
+            for ($i = 0; $i < count($aFolderPathContent); $i++) {
+                if ($aFolderPathContent[$i] !== '..' && $aFolderPathContent[$i] !== '.') {
+                    array_push($aBoFolders, $sFolderPath . '/' . $aFolderPathContent[$i]);
+                }
+            }
+        } else {
+            array_push($aBoFolders, $sFolderPath);
+        }
+
+        $aReturn['status'] = 1;
+
+        $aTmpReturn = array();
+        for ($i = 0; $i < count($aBoFolders); $i++) {
+
+            // Récupère le contennu du package
+            $aResult = $this->getBusinessObjectPackage($aBoFolders[$i]);
+
+            if (!empty($aResult['sMessage'])) {
+                if ($this->isJson($aResult['sMessage'])) {
+                    $aResult = json_decode($aResult['sMessage'], true);
+                }
+            }
+            if (!empty($aResult['errorMessage'])) {
+                $aReturn['errorMessage'] = $aResult['errorMessage'];
+                $aReturn['status'] = 0;
+            }
+
+            if (!empty($aResult['status'])) {
+                if ($aResult['status'] != 1) {
+                    $aReturn['status'] = $aResult['status'];
+                }
+            } else {
+                $aReturn['status'] = 0;
+            }
+
+            array_push($aTmpReturn, $aResult);
+        }
+
+        if ($aReturn['status'] === 1) {
+            $aReturn['businessobjects'] = $aTmpReturn;
+        }
+
+        // Supprime le dossier précédemment uploadé
+        clearDir($sPath);
+
+        return json_encode($aReturn);
+    }
+
+    /**
+     * Post the data model
+     * @return type
+     */
+    function postDataModel() {
+
+        if (!isset($_FILES['data_model'])) {
+            $oError = new VitisError(0, 'data_model not found');
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        }
+        if (!in_array('vitis_admin', $this->oConnection->aPrivileges) ||
+                !in_array('vmap_admin', $this->oConnection->aPrivileges) ||
+                !in_array('vm4ms_admin', $this->oConnection->aPrivileges)) {
+            $oError = new VitisError(0, 'insufficient privileges (needs to be vitis_admin, vmap_admin and vm4ms_admin)');
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        }
+
+        $sFileName = $_FILES['data_model']['name'];
+        $sDir = $this->UniqFileName();
+        $this->postFileSave('data_model', '../../tmp/', $sDir);
+        $sPath = $this->aProperties['vas_home'] . '/tmp/' . $sDir;
+        $sFilePath = $sPath . '/' . $sFileName;
+
+        if (isset($this->aValues['database']) && !empty($this->aValues['database'])) {
+            $sDatabase = $this->aValues['database'];
+        } else {
+            $sDatabase = $this->aProperties['database'];
+        }
+
+        $sFileRequests = $this->getDataModelFileRequests($sFilePath);
+
+        // Execute le SQL
+        $aResults = $this->executeDataModelRequests($sFileRequests, $sDatabase);
+
+        // Supprime le dossier précédemment uploadé
+        clearDir($sPath);
+
+        if (isset($this->oError)) {
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $this->oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } else {
+            $aReturn = array('status' => 1);
+            return json_encode($aReturn);
+        }
+    }
+
+    /**
+     * Parse the data-model file contents and return an array of requests
+     * @param string $sFilePath
+     * @return string
+     */
+    function getDataModelFileRequests($sFilePath) {
+
+        // Travail sur chacune des lignes du fichier
+        $aFileContents = file($sFilePath);
+        $aFileContents = $this->cleanDataModelFileArray($aFileContents);
+
+        $sFileContents = '';
+        for ($i = 0; $i < count($aFileContents); $i++) {
+            $sFileContents .= $aFileContents[$i] . ' ';
+        }
+
+//        // Travail sur chacune des requêtes du fichier
+//        $aFileContents = explode(';', $sFileContents);
+//        $aFileContents = $this->cleanDataModelFileArray($aFileContents);
+
+        return $sFileContents;
+    }
+
+    /**
+     * Delete the white spaces and comments from the data-model file array vue
+     * @param array $aFileContents
+     * @return array
+     */
+    function cleanDataModelFileArray($aFileContents) {
+
+        for ($i = count($aFileContents); $i >= 0; $i--) {
+            // Supprime les espaces
+            $aFileContents[$i] = trim($aFileContents[$i]);
+            // Supprime les lignes vides
+            if ($aFileContents[$i] === '') {
+                unset($aFileContents[$i]);
+            }
+            // Supprime les commentaires
+            if (substr($aFileContents[$i], 0, 2) === '--') {
+                unset($aFileContents[$i]);
+            }
+        }
+        // Redonne les bons index
+        $aFileContents2 = Array();
+        foreach ($aFileContents as $key => $value) {
+            array_push($aFileContents2, $value);
+        }
+        $aFileContents = $aFileContents2;
+
+        return $aFileContents;
+    }
+
+    /**
+     * Execute the data-model requests
+     * @param array $aFileRequests
+     * @return array results
+     */
+    function executeDataModelRequests($sFileRequests, $sDatabase) {
+
+        // Connexion avec uVitis
+        $oBD = new Vm($this->aProperties['owner_login'], $this->aProperties['owner_pass'], $sDatabase, $this->aProperties['server'], $this->aProperties['port'], $this->aProperties['sgbd'], $this->aProperties['page_encoding']);
+        $this->oConnection->oBd = $oBD;
+
+        $this->oConnection->oBd->demarreTransaction();
+
+        $bError = false;
+        $oPDOresult = $this->oConnection->oBd->executeBlock($sFileRequests);
+
+        if ($this->oConnection->oBd->enErreur()) {
+            $this->oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+            $bError = true;
+        }else{
+            $aResults = $this->oConnection->oBd->getResultTableAssoc($oPDOresult);
+        }
+
+        if ($bError) {
+            $this->oConnection->oBd->annuleTransaction();
+        } else {
+            $this->oConnection->oBd->termineTransaction();
+        }
+
+        return $aResults;
+    }
+
+    /**
+     * Generate the form
+     * @param string $sBusinessObjectId
+     * @param string $sFormName
+     * @param array $aFields fields to use
+     * @return string jsonContent of the form
+     */
+    function generateBusinessObjectForm($sBusinessObjectId, $sFormName, $aFields, $oLabel) {
+
+        // Objet BusinessObject correspondant
+        $oBusinessObject = new BusinessObject($this->aPath, $this->aValues, $this->aProperties, $this->oConnection);
+        $oBusinessObject->GET();
+
+        // Paramètres retenus dans le business object
+        $bo_title = $oBusinessObject->aFields['title'];
+        $bo_database = $oBusinessObject->aFields['database'];
+        $bo_schema = $oBusinessObject->aFields['schema'];
+        $bo_table = $oBusinessObject->aFields['table'];
+        $bo_id_field = $oBusinessObject->aFields['id_field'];
+        $geom_column = $oBusinessObject->aFields['geom_column'];
+
+        $oForm = new Form($this->aProperties, $this->oConnection);
+        $aTableColumns = $oForm->getTableColumns($bo_schema, $bo_table);
+
+        // Supprime de la liste des champs générés ceux qui ne sont pas présents dans $aFields
+        $aColumnsToUse = array();
+        for ($i = 0; $i < count($aTableColumns); $i++) {
+            if (in_array($aTableColumns[$i]['column_name'], $aFields)) {
+                array_push($aColumnsToUse, $aTableColumns[$i]);
+            }
+        }
+
+        $aRows = $oForm->generateRowsByTableColumns($aColumnsToUse, array(), array(), json_decode(json_encode($oLabel), true));
+        $aForm = $oForm->generateFormByRows($aRows, $bo_title, $sFormName);
+
+        // création de l'arborescence si elle n'existe pas
+        $sDirPath = $this->createBoPath($sBusinessObjectId);
+
+        $JSONcontent = json_encode($aForm);
+
+        // écrit le fichier demandé
+        $formFile = fopen($sDirPath . '/forms/' . $sFormName . '.json', 'w');
+        fwrite($formFile, $JSONcontent);
+        fclose($formFile);
+
+        // écrit les autres fichiers si ils n'existent pas
+        if (!file_exists($sDirPath . '/forms/default.json')) {
+            $formFile = fopen($sDirPath . '/forms/default.json', 'w');
+            fwrite($formFile, $JSONcontent);
+            fclose($formFile);
+        }
+        if (!file_exists($sDirPath . '/forms/published.json')) {
+            $formFile = fopen($sDirPath . '/forms/published.json', 'w');
+            fwrite($formFile, $JSONcontent);
+            fclose($formFile);
+        }
+        if (!file_exists($sDirPath . '/forms/custom.json')) {
+            $formFile = fopen($sDirPath . '/forms/custom.json', 'w');
+            fwrite($formFile, $JSONcontent);
+            fclose($formFile);
+        }
+
+        return $JSONcontent;
+    }
+
+    /**
+     * Return the imported bo package content
+     * @param string $sFolderPath
+     * @return array
+     */
+    function getBusinessObjectPackage($sFolderPath) {
+
+        // Variables Path
+        $sPackagePath = $sFolderPath . '/package.json';
+        $sSQLPath = $sFolderPath . '/sql';
+        $sDefinitionPath = $sFolderPath . '/json';
+        $sFormsPath = $sFolderPath . '/forms';
+
+        // Retour
+        $aResult = array();
+
+        // Récupère la definition du packet
+        if (!is_file($sPackagePath)) {
+            writeToErrorLog('getBusinessObjectPackage: package.json not found');
+            $aReturn = array(status => 0, errorMessage => 'Package not valid');
+            return $aReturn;
+        }
+        $aResult['package'] = json_decode(file_get_contents($sPackagePath), true);
+
+        // Récupère les définitions json
+        if (!is_dir($sDefinitionPath)) {
+            writeToErrorLog('getBusinessObjectPackage: json folder not found');
+            $aReturn = array(status => 0, errorMessage => 'Package not valid');
+            return $aReturn;
+        }
+        $aResult['json'] = array(
+            'business_object' => json_decode(file_get_contents($sDefinitionPath . '/business_object.json'), true),
+            'mapserver_layers' => json_decode(file_get_contents($sDefinitionPath . '/mapserver_layers.json'), true),
+            'reports' => json_decode(file_get_contents($sDefinitionPath . '/reports.json'), true),
+            'event' => json_decode(file_get_contents($sDefinitionPath . '/event.json'), true)
+        );
+
+        // Récupère les définitions sql
+        if (!is_dir($sSQLPath)) {
+            writeToErrorLog('getBusinessObjectPackage: sql folder not found');
+            $aReturn = array(status => 0, errorMessage => 'Package not valid');
+            return $aReturn;
+        }
+        $aResult['sql'] = array(
+            'structure' => json_decode(file_get_contents($sSQLPath . '/structure.json'), true),
+            'table' => file_get_contents($sSQLPath . '/table.sql'),
+        );
+
+        // Récupère les formulaires json et leurs ressources
+        $aResult['forms'] = array(
+            'custom' => json_decode(file_get_contents($sFormsPath . '/custom.json'), true),
+            'default' => json_decode(file_get_contents($sFormsPath . '/default.json'), true),
+            'published' => json_decode(file_get_contents($sFormsPath . '/published.json'), true)
+        );
+        if (is_dir($sFormsPath . '/ressources')) {
+            $aResult['forms']['ressources'] = array();
+            if (is_file($sFormsPath . '/ressources/custom.js')) {
+                $aResult['forms']['ressources']['js']['custom'] = file_get_contents($sFormsPath . '/ressources/custom.js');
+            }
+            if (is_file($sFormsPath . '/ressources/default.js')) {
+                $aResult['forms']['ressources']['js']['default'] = file_get_contents($sFormsPath . '/ressources/default.js');
+            }
+            if (is_file($sFormsPath . '/ressources/published.js')) {
+                $aResult['forms']['ressources']['js']['published'] = file_get_contents($sFormsPath . '/ressources/published.js');
+            }
+            if (is_file($sFormsPath . '/ressources/custom.css')) {
+                $aResult['forms']['ressources']['css']['custom'] = file_get_contents($sFormsPath . '/ressources/custom.css');
+            }
+            if (is_file($sFormsPath . '/ressources/default.css')) {
+                $aResult['forms']['ressources']['css']['default'] = file_get_contents($sFormsPath . '/ressources/default.css');
+            }
+            if (is_file($sFormsPath . '/ressources/published.css')) {
+                $aResult['forms']['ressources']['css']['published'] = file_get_contents($sFormsPath . '/ressources/published.css');
+            }
+        }
+
+        // Vérification/erreurs
+        if ($aResult['package'] === null) {
+            writeToErrorLog('getBusinessObjectPackage: package.json not valid');
+            $aReturn = array(status => 0, errorMessage => 'Package not valid');
+            return $aReturn;
+        }
+        if ($aResult['json']['business_object'] === null) {
+            writeToErrorLog('getBusinessObjectPackage: business_object.json not valid');
+            $aReturn = array(status => 0, errorMessage => 'Package not valid');
+            return $aReturn;
+        }
+        if ($aResult['json']['mapserver_layers'] === null) {
+            writeToErrorLog('getBusinessObjectPackage: mapserver_layers.json not valid');
+            $aReturn = array(status => 0, errorMessage => 'Package not valid');
+            return $aReturn;
+        }
+        if ($aResult['sql']['structure'] === null) {
+            writeToErrorLog('getBusinessObjectPackage: structure.json not valid');
+            $aReturn = array(status => 0, errorMessage => 'Package not valid');
+            return $aReturn;
+        }
+        if ($aResult['sql']['table'] === null) {
+            writeToErrorLog('getBusinessObjectPackage: table.sql not valid');
+            $aReturn = array(status => 0, errorMessage => 'Package not valid');
+            return $aReturn;
+        }
+
+        $aResult['status'] = 1;
+
+        return $aResult;
+    }
+
+    /**
+     * Creates the business object forms directory path
+     * @param string $sBusinessObjectId
+     * @return string
+     */
+    function createBoPath($sBusinessObjectId) {
+
+        $sDirPath = $this->aProperties['ws_data_dir'] . '/vmap/business_object/' . $sBusinessObjectId;
+
+        // création de l'arborescence si elle n'existe pas
+        if (!is_dir($this->aProperties['ws_data_dir'] . '/vmap')) {
+            @mkdir($this->aProperties['ws_data_dir'] . '/vmap');
+        }
+        if (!is_dir($this->aProperties['ws_data_dir'] . '/vmap/business_object')) {
+            @mkdir($this->aProperties['ws_data_dir'] . '/vmap/business_object');
+        }
+        if (!is_dir($sDirPath)) {
+            @mkdir($sDirPath);
+        }
+        if (!is_dir($sDirPath . '/forms')) {
+            @mkdir($sDirPath . '/forms');
+        }
+        if (!is_dir($sDirPath . '/forms/ressources')) {
+            @mkdir($sDirPath . '/forms/ressources');
+        }
+
+        return $sDirPath;
+    }
+
+    /**
+     * Copy a folder
+     * @param string $src
+     * @param string $dst
+     */
+    function recurseCopy($src, $dst) {
+        $dir = opendir($src);
+        @mkdir($dst);
+        while (false !== ( $file = readdir($dir))) {
+            if (( $file != '.' ) && ( $file != '..' )) {
+                if (is_dir($src . '/' . $file)) {
+                    $this->recurseCopy($src . '/' . $file, $dst . '/' . $file);
+                } else {
+                    copy($src . '/' . $file, $dst . '/' . $file);
+                }
+            }
+        }
+        closedir($dir);
+    }
+
+    /**
+     *
+     * @param string $string
+     * @return boolean
+     */
+    function isJson($string) {
+        if (!is_string($string)) {
+            return false;
+        }
+        json_decode($string);
+        return (json_last_error() == JSON_ERROR_NONE);
+    }
+
+    /**
+     * @SWG\Put(path="/businessobjects/{business_object_id}",
+     *   tags={"BusinessObjects"},
+     *   summary="Update BusinessObject",
+     *   description="Request to update business_object",
+     *   operationId="PUT",
+     *   produces={"application/xml", "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",
+     *     format="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="title",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="database",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="schema",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="table",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="id_field",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="sql_summary",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="sql_list",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="sorted_by",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="geom_column",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="search_field",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="result_field",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="search_use_strict",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="event_id",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="index",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="integer"
+     *   ),
+     * @SWG\Parameter(
+     *     name="add_form_size",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="edit_form_size",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="display_form_size",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/businessobjects")
+     *     ),
+     *
+     *  )
+     */
+    /**
+     * @SWG\Put(path="/businessobjects/{business_object_id}/form/{form}",
+     *   tags={"BusinessObjects"},
+     *   summary="Update BusinessObject",
+     *   description="Request to update business_object form",
+     *   operationId="PUT",
+     *   produces={"application/xml", "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",
+     *     format="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="form",
+     *     in="path",
+     *     description="form name (default, published, custom)",
+     *     required=true,
+     *     type="integer",
+     *     format="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="json_file",
+     *     in="formData",
+     *     description="Wsubform.json",
+     *     required=false,
+     *     type="file"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="js_file",
+     *     in="formData",
+     *     description="Javascript file link with WSubform",
+     *     required=false,
+     *     type="file"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="css_file",
+     *     in="formData",
+     *     description="Css file link with WSubform",
+     *     required=false,
+     *     type="file"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="cmd",
+     *     in="query",
+     *     description="Save, Perso_Save, Perso_Published, Default_Published, Perso_Reset, Default_Reset",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/businessobjects")
+     *     ),
+     *
+     *  )
+     */
+
+    /**
+     * modify the business object
+     * @return array containing the status and the message
+     */
+    function PUT() {
+        if (isset($this->oConnection->oError) && !empty($this->oConnection->oError)) {
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $this->oConnection->oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        }
+        if (!in_array('vmap_admin', $this->oConnection->aPrivileges)) {
+            $oError = new VitisError(0, 'INSUFFICIENT_PRIVILEGES');
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        }
+        if (isset($this->aPath[4])) {
+            $sBusinessObjectId = $this->aPath[2];
+            $sFormName = $this->aPath[4];
+            $sComand = $this->aValues['cmd'];
+            $this->putForm($sBusinessObjectId, $sFormName, $sComand);
+            $aXmlRacineAttribute['status'] = 1;
+            $sMessage = $this->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } else {
+            if ($this->aValues['min_edition_scale'] == "") {
+                $this->aValues['min_edition_scale'] = null;
+            }
+            if ($this->aValues['max_edition_scale'] == "") {
+                $this->aValues['max_edition_scale'] = null;
+            }
+            $aReturn = $this->genericPut($this->aProperties['schema_vmap'], 'business_object', 'business_object_id');
+            return $aReturn['sMessage'];
+        }
+    }
+
+    /**
+     * Change the business object form using this->aValues
+     * @param string $sBusinessObjectId
+     * @param string $formName
+     * @param string $sComand
+     */
+    function putForm($sBusinessObjectId, $sFormName, $sComand) {
+
+        $sDirPath = $this->aProperties['ws_data_dir'] . '/vmap/business_object/' . $sBusinessObjectId;
+
+        // création de l'arborescence si elle n'existe pas
+        if (!is_dir($this->aProperties['ws_data_dir'] . '/vmap')) {
+            @mkdir($this->aProperties['ws_data_dir'] . '/vmap');
+        }
+        if (!is_dir($this->aProperties['ws_data_dir'] . '/vmap/business_object')) {
+            @mkdir($this->aProperties['ws_data_dir'] . '/vmap/business_object');
+        }
+        if (!is_dir($sDirPath)) {
+            @mkdir($sDirPath);
+        }
+        if (!is_dir($sDirPath . '/forms')) {
+            @mkdir($sDirPath . '/forms');
+        }
+        if (!is_dir($sDirPath . '/forms/ressources')) {
+            @mkdir($sDirPath . '/forms/ressources');
+        }
+
+        if ($this->aValues["cmd"]) {
+            switch ($this->aValues["cmd"]) {
+                case "Save":
+
+                    if (!empty($this->aValues['Json'])) {
+                        $pFile = fopen($sDirPath . '/forms/' . $sFormName . '.json', 'w');
+                        if (fwrite($pFile, $this->aValues["Json"]) == FALSE) {
+                            writeToErrorLog('ERROR: ' . $sFormName . '.json save failed');
+                        }
+                        fclose($pFile);
+                    }
+
+                    if ($this->aValues["Js"] != "") {
+                        $pFileJS = fopen($sDirPath . '/forms/ressources/' . $sFormName . '.js', 'w+');
+                        if (fwrite($pFileJS, $this->aValues["Js"]) == FALSE) {
+                            writeToErrorLog('ERROR: ' . $sFormName . '.js save failed');
+                        }
+                        fclose($pFileJS);
+                    }
+
+                    if ($this->aValues["Css"] != "") {
+                        $pFileCSS = fopen($sDirPath . '/forms/ressources/' . $sFormName . '.css', 'w+');
+                        if (fwrite($pFileCSS, $this->aValues["Css"]) == FALSE) {
+                            writeToErrorLog('ERROR: ' . $sFormName . '.css save failed');
+                        }
+                        fclose($pFileCSS);
+                    }
+
+                    break;
+                case "Perso_Save":
+
+                    if (!empty($this->aValues['Json'])) {
+                        $pFile = fopen($sDirPath . '/forms/' . $sFormName . '.json', 'w');
+                        if (fwrite($pFile, $this->aValues["Json"]) == FALSE) {
+                            writeToErrorLog('ERROR: ' . $sFormName . '.json save failed');
+                        }
+                        fclose($pFile);
+                    }
+
+                    if ($this->aValues["Js"] != "") {
+                        $pFileJS = fopen($sDirPath . '/forms/ressources/' . $sFormName . '.js', 'w+');
+                        if (fwrite($pFileJS, $this->aValues["Js"]) == FALSE) {
+                            writeToErrorLog('ERROR: ' . $sFormName . '.js save failed');
+                        }
+                        fclose($pFileJS);
+                    }
+
+                    if ($this->aValues["Css"] != "") {
+                        $pFileCSS = fopen($sDirPath . '/forms/ressources/' . $sFormName . '.css', 'w+');
+                        if (fwrite($pFileCSS, $this->aValues["Css"]) == FALSE) {
+                            writeToErrorLog('ERROR: ' . $sFormName . '.css save failed');
+                        }
+                        fclose($pFileCSS);
+                    }
+
+                    break;
+                case "Perso_Published":
+
+                    @unlink($sDirPath . "/forms/published.json");
+                    copy($sDirPath . "/forms/custom.json", $sDirPath . "/forms/published.json");
+
+                    if (file_exists($sDirPath . "/forms/ressources/custom.js")) {
+                        if (file_exists($sDirPath . "/forms/ressources/published.js")) {
+                            @unlink($sDirPath . "/forms/ressources/published.js");
+                        }
+                        copy($sDirPath . "/forms/ressources/custom.js", $sDirPath . "/forms/ressources/published.js");
+                    }
+                    if (file_exists($sDirPath . "/forms/ressources/custom.css")) {
+                        if (file_exists($sDirPath . "/forms/ressources/published.css")) {
+                            @unlink($sDirPath . "/forms/ressources/published.css");
+                        }
+                        copy($sDirPath . "/forms/ressources/custom.css", $sDirPath . "/forms/ressources/published.css");
+                    }
+
+                    break;
+                case "Default_Published":
+
+                    @unlink($sDirPath . "/forms/published.json");
+                    copy($sDirPath . "/forms/default.json", $sDirPath . "/forms/published.json");
+
+                    break;
+                case "Perso_Reset":
+
+                    @unlink($sDirPath . "/forms/custom.json");
+                    copy($sDirPath . "/forms/default.json", $sDirPath . "/forms/custom.json");
+
+                    break;
+                case "Default_Reset" :
+                    @unlink($sDirPath . "/forms/default.json");
+                    $aFields = explode("|", $this->aValues['field']);
+                    $this->generateBusinessObjectForm($sBusinessObjectId, $sFormName, $aFields, $this->aValues['label']);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * @SWG\Delete(path="/businessobjects",
+     *   tags={"BusinessObjects"},
+     *   summary="delete BusinessObject",
+     *   description="Request to delete BusinessObject",
+     *   operationId="DELETE",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="business_object token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="idList",
+     *     in="query",
+     *     description="id of the businessobjects",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/businessobjects")
+     *     )
+     *  )
+     */
+    /**
+     * @SWG\Delete(path="/businessobjects/{business_object_id}",
+     *   tags={"BusinessObjects"},
+     *   summary="delete BusinessObject",
+     *   description="Request to delete BusinessObject",
+     *   operationId="DELETE",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="business_object token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="business_object_id",
+     *     in="path",
+     *     description="id of the business_object",
+     *     required=true,
+     *     type="integer",
+     *     format = "int32"
+     *   ),
+     * @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/businessobjects")
+     *     )
+     *  )
+     */
+
+    /**
+     * delete business_object
+     * @return id of business_object deleted or error object if a business_object is not deleted
+     */
+    function DELETE() {
+        $aBos = array();
+
+        //forme 'veremes_cadastre_parcelle'|'veremes_cadatre_commune'
+        if (!empty($this->aValues['idList'])) {
+            $aBos = explode("|", $this->aValues['idList']);
+            for ($i = 0; $i < count($aBos); $i++) {
+                if (substr($aBos[$i], 0, 1) === "'") {
+                    $aBos[$i] = substr($aBos[$i], 1);
+                }
+                if (substr($aBos[$i], -1) === "'") {
+                    $aBos[$i] = substr($aBos[$i], 0, -1);
+                }
+            }
+        }
+        if (!empty($this->aPath[2])) {
+            array_push($aBos, $this->aPath[2]);
+        }
+
+        // Supprime les Bo un par un
+        for ($i = 0; $i < count($aBos); $i++) {
+            $aPath = Array('vmap', 'businessobjects', $aBos[$i]);
+            $aValues = $this->aValues;
+            $aValues['my_vitis_id'] = $aBos[$i];
+            $oBo = new BusinessObject($aPath, $aValues, $this->aProperties, $this->oConnection);
+
+            // Supprime l'objet métier
+            $oBo->DELETE();
+
+            if (isset($oBo->oError)) {
+                $aXmlRacineAttribute['status'] = 0;
+                $sMessage = $oBo->oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+                return $sMessage;
+            } else {
+                $this->removeBusinessObjectFiles($aBos[$i]);
+                $aXmlRacineAttribute['status'] = 1;
+                $sMessage = $this->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+                return $sMessage;
+            }
+        }
+    }
+
+    function removeBusinessObjectFiles($sBusinessObjectId) {
+
+        // Supprime les fichiers liés à l'objet métier
+        $sDirPath = $this->aProperties['ws_data_dir'] . '/vmap/business_object/' . $sBusinessObjectId;
+        clearDir($sDirPath);
+    }
+
+}
+
+?>
diff --git a/vmap/vas/rest/ws/vmap/CHANGE_LOG.txt b/vmap/vas/rest/ws/vmap/CHANGE_LOG.txt
new file mode 100755
index 0000000000000000000000000000000000000000..a9f29dc424dbd8bc44a08ace6105f16fa5bcd33d
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/CHANGE_LOG.txt
@@ -0,0 +1,8 @@
+
+              +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+              +                                                                                   +
+              +             			 VEREMES - Web Service vMap change log         		      +
+              +                                                                                   +
+              +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+
diff --git a/vmap/vas/rest/ws/vmap/CRS.class.inc b/vmap/vas/rest/ws/vmap/CRS.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..11b1f0534d54d47252c3808c098544beb539918f
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/CRS.class.inc
@@ -0,0 +1,73 @@
+<?php
+
+require_once 'Vmap.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+
+/**
+ * \file CRS.class.inc
+ * \class CRS
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * \brief This file contains the CRS php class
+ *
+ * This class defines operation for one CRS
+ * 
+ */
+class CRS extends Vmap {
+
+    public $oError;
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("crs_id", "name");
+    }
+
+    /**
+     * @SWG\Get(path="/crss/{crs_id}", 
+     *   tags={"CRSs"},
+     *   summary="Get CRS",
+     *   description="Request to get CRS by id",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="crs_id",
+     *     in="path",
+     *     description="",
+     *     required=true,
+     *     type="integer"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/crss")
+     *     )
+     *  )
+     */
+
+    /**
+     * get informations about crss
+     */
+    function GET() {
+        require $this->sRessourcesFile;
+        $this->aFields = $this->getFields($this->aProperties['schema_vmap'], 'rt_crs', 'crs_id');
+    }
+    
+}
+
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/CRSs.class.inc b/vmap/vas/rest/ws/vmap/CRSs.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..f5258bca4ffe53ddff6b9b7c7d52649c0873c598
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/CRSs.class.inc
@@ -0,0 +1,129 @@
+<?php
+
+/**
+ * \file CRSs.class.inc
+ * \class CRSs
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * \brief This file contains the CRSs php class
+ *
+ * This class defines Rest Api to Vmap CRSs
+ * 
+ */
+require_once 'Vmap.class.inc';
+require_once 'CRS.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+require_once __DIR__ . '/../../class/vmlib/BdDataAccess.inc';
+
+class CRSs extends Vmap {
+    /**
+     * @SWG\Definition(
+     *   definition="/crss",
+     *   allOf={
+     *     @SWG\Schema(ref="#/definitions/crss")
+     *   }
+     * )
+     * * @SWG\Tag(
+     *   name="CRSs",
+     *   description=""
+     * )
+     */
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("crs_id", "name", "description");
+    }
+
+    /**
+     * @SWG\Get(path="/crss",
+     *   tags={"CRSs"},
+     *   summary="Get CRSs",
+     *   description="Request to get CRSs",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="order_by",
+     *     in="query",
+     *     description="list of ordering fields",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="sort_order",
+     *     in="query",
+     *     description="sort order",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="limit",
+     *     in="query",
+     *     description="number of element",
+     *     required=false,
+     *     type="integer",
+     *     default="4"
+     *   ),
+     * @SWG\Parameter(
+     *     name="offset",
+     *     in="query",
+     *     description="index of first element",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="attributs",
+     *     in="query",
+     *     description="list of attributs",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="filter",
+     *     in="query",
+     *     description="filter results",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="distinct",
+     *     in="query",
+     *     description="delete duplicates",
+     *     required=false,
+     *     type="boolean"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/crss")
+     *     )
+     *  )
+     */
+
+    /**
+     * get CRSs
+     * @return the array of objects
+     */
+    function GET() {
+        $aReturn = $this->genericGet($this->aProperties['schema_vmap'], 'rt_crs', 'crs_id');
+        return $aReturn['sMessage'];
+    }
+
+}
+
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/Format.class.inc b/vmap/vas/rest/ws/vmap/Format.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..c890b6dd4012c129a0ae26b4cfd503e042c258a7
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/Format.class.inc
@@ -0,0 +1,41 @@
+<?php
+
+require_once 'Vmap.class.inc';
+require_once __DIR__.'/../../class/vitis_lib/Connection.class.inc';
+
+/**
+* \file Format.class.inc
+* \class Format
+*
+* \author Yoann Perollet <yoann.perollet@veremes.com>.
+*
+*	\brief This file contains the Format php class
+*
+* This class defines operation for one Format
+* 
+*/
+class Format extends Vmap {
+    
+    public $oError;
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array('rt_format_id');
+    }
+    
+    /**
+     * get informations about format
+     */
+    function GET(){
+        require $this->sRessourcesFile;
+        $this->aFields = $this->getFields($this->aProperties['schema_vmap'], "rt_format", "rt_format_id");
+    }
+}
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/Formats.class.inc b/vmap/vas/rest/ws/vmap/Formats.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..f1a4545d5c4c83cf20050e97ee85922bb9c0c538
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/Formats.class.inc
@@ -0,0 +1,125 @@
+<?php
+/**
+* \file Formats.class.inc
+* \class Formats
+*
+* \author Yoann Perollet <yoann.perollet@veremes.com>.
+*
+*	\brief This file contains the Formats php class
+*
+* This class defines Rest Api to Vmap order statutes
+* 
+*/
+require_once 'Vmap.class.inc';
+require_once __DIR__.'/../../class/vitis_lib/Connection.class.inc';
+require_once 'Format.class.inc';
+require_once(__DIR__.'/../../class/vmlib/BdDataAccess.inc');
+
+class Formats extends Vmap {
+    
+     /**
+     * @SWG\Definition(
+     *   definition="/formats",
+     *   allOf={
+     *     @SWG\Schema(ref="#/definitions/formats")
+     *   }
+     * )
+     * * @SWG\Tag(
+     *   name="Formats",
+     *   description="Operations about Formats"
+     * )
+     */
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array('rt_format_id');
+    }
+    
+    /**
+     * @SWG\Get(path="/formats",
+     *   tags={"Formats"},
+     *   summary="Get Formats",
+     *   description="Request to get Formats",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="order_by",
+     *     in="query",
+     *     description="list of ordering fields",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="sort_order",
+     *     in="query",
+     *     description="sort order",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="limit",
+     *     in="query",
+     *     description="number of element",
+     *     required=false,
+     *     type="integer"
+     *   ),
+     * @SWG\Parameter(
+     *     name="offset",
+     *     in="query",
+     *     description="index of first element",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="attributs",
+     *     in="query",
+     *     description="list of attributs",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="filter",
+     *     in="query",
+     *     description="filter results",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="distinct",
+     *     in="query",
+     *     description="delete duplicates",
+     *     required=false,
+     *     type="boolean"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/formats")
+     *     )
+     *  )
+     */
+    
+    /**
+     * get Formats
+     * @return  Formats
+     */
+    function GET() {
+        $aReturn = $this->genericGet($this->aProperties['schema_vmap'], "rt_format", "rt_format_id");
+        return $aReturn['sMessage'];
+    }
+}
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/Layer.class.inc b/vmap/vas/rest/ws/vmap/Layer.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..509353a28361802ab6b3b6b403ed218f874e6d05
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/Layer.class.inc
@@ -0,0 +1,162 @@
+<?php
+
+require_once 'Vmap.class.inc';
+require_once 'BusinessObject.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+
+/**
+ * \file Layer.class.inc
+ * \class Layer
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * \brief This file contains the Layer php class
+ *
+ * This class defines operation for one Layer
+ * 
+ */
+class Layer extends Vmap {
+
+    public $oError;
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        // Obligatoire pour utiliser sur oLayers->aObjects
+        if (empty($this->aValues)) {
+            $this->aValues = $aValues;
+        }
+        if (empty($this->aPath)) {
+            $this->aPath = $aPath;
+        }
+        if (empty($this->aProperties)) {
+            $this->aProperties = $properties;
+        }
+    }
+
+    /**
+     * @SWG\Get(path="/layers/{layer_id}", 
+     *   tags={"Layers"},
+     *   summary="Get Layer",
+     *   description="Request to get Layer by id",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="layer_id",
+     *     in="path",
+     *     description="layer id",
+     *     required=true,
+     *     type="integer"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/layers")
+     *     )
+     *  )
+     */
+
+    /**
+     * get informations about Layer
+     */
+    function GET() {
+
+        $this->aFields = $this->getFields($this->aProperties['schema_vmap'], 'v_layer', 'layer_id');
+
+        // Ajoute (si il existe le formulaire associé au calque)
+        $this->aFields['filter_form'] = $this->getFilterForm();
+        $this->aFields['crs_list_label'] = str_replace('|', ',', $this->aFields['crs_list']);
+
+        if (!empty($this->aFields['bo_id_list'])) {
+            $aBoIds = explode('|', $this->aFields['bo_id_list']);
+            $this->aFields['business_objects'] = $this->getBusinessObjectsInfos($aBoIds);
+        }
+    }
+
+    /**
+     * Return (is exists) the json form associate to the layer
+     * @return string JSON form
+     */
+    function getFilterForm() {
+        $filter_form = null;
+        if ($this->aFields['is_filtered'] === true) {
+            $formsPath = $this->aProperties['ws_data_dir'] . '/vmap/layer/' . $this->aFields['layer_id'] . '/forms';
+            if (file_exists($formsPath . '/published.json')) {
+                $filter_form = file_get_contents($formsPath . '/published.json');
+            }
+        }
+        return $filter_form;
+    }
+
+    /**
+     * Return (is exists) the embed js for form associate to the layer
+     * @return string JS code
+     */
+    function getFilterFormJs() {
+        $sFilterFormJs = null;
+        if ($this->aFields['is_filtered'] === true) {
+            $sFormsPath = $this->aProperties['ws_data_dir'] . '/vmap/layer/' . $this->aFields['layer_id'] . '/forms/ressources';
+            if (file_exists($sFormsPath . '/published.js')) {
+                $sFilterFormJs = file_get_contents($sFormsPath . '/published.js');
+            }
+        }
+        return $sFilterFormJs;
+    }
+
+    /**
+     * Get the infos from the business objects defined in $aBoIds
+     * @param array $aBoIds
+     * @return array
+     */
+    function getBusinessObjectsInfos($aBoIds) {
+        $aBoInfos = array();
+        for ($i = 0; $i < count($aBoIds); $i++) {
+            $aPath = array('vmap', 'businessobjects', $aBoIds[$i]);
+            $aValues = $this->aValues;
+            $aValues['my_vitis_id'] = $aBoIds[$i];
+            $oBo = new BusinessObject($aPath, $aValues, $this->aProperties, false, $this->oConnection);
+            $oBo->GET();
+            array_push($aBoInfos, $oBo->aFields);
+        }
+        return $aBoInfos;
+    }
+
+    /**
+     * delete a layer
+     */
+    function DELETE() {
+
+        // Des-associe les objets métiers de la couche
+        require $this->sRessourcesFile;
+        $aSQLParams = array(
+            'sSchemaVmap' => array('value' => $this->aProperties['schema_vmap'], 'type' => 'column_name'),
+            'layer_id' => array('value' => $this->aValues['my_vitis_id'], 'type' => 'number')
+        );
+        $oResult = $this->oConnection->oBd->executeWithParams($aSql['deleteAssociatedBos'], $aSQLParams);
+
+        // Supprime la couche en question
+        $this->oConnection->oBd->delete($this->aProperties['schema_vmap'], 'layer', 'layer_id', $this->aValues['my_vitis_id'], 'integer');
+        if ($this->oConnection->oBd->enErreur()) {
+            $this->oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+        } else {
+            $this->aFields['layer_id'] = $this->aValues['my_vitis_id'];
+        }
+    }
+
+}
+
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/LayerTheme.class.inc b/vmap/vas/rest/ws/vmap/LayerTheme.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..f7f818c51252bb0ac26532e76291fa1656002331
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/LayerTheme.class.inc
@@ -0,0 +1,84 @@
+<?php
+
+require_once 'Vmap.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+
+/**
+ * \file LayerTheme.class.inc
+ * \class LayerTheme
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * \brief This file contains the LayerTheme php class
+ *
+ * This class defines operation for one LayerTheme
+ * 
+ */
+class LayerTheme extends Vmap {
+
+    public $oError;
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("layertheme_id", "name", "description");
+    }
+
+    /**
+     * @SWG\Get(path="/layerthemes/{layertheme_id}", 
+     *   tags={"LayerThemes"},
+     *   summary="Get LayerTheme",
+     *   description="Request to get LayerTheme by id",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="layertheme_id",
+     *     in="path",
+     *     description="",
+     *     required=true,
+     *     type="integer"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/layerthemes")
+     *     )
+     *  )
+     */
+
+    /**
+     * get informations about layerthemes
+     */
+    function GET() {
+        require $this->sRessourcesFile;
+        $this->aFields = $this->getFields($this->aProperties['schema_vmap'], 'layertheme', 'layertheme_id');
+    }
+    
+    /**
+     * delete a layertheme
+     */
+    function DELETE(){
+        $this->oConnection->oBd->delete($this->aProperties['schema_vmap'], 'layertheme', 'layertheme_id', $this->aValues['my_vitis_id'], 'integer');
+        if ($this->oConnection->oBd->enErreur()) {
+                $this->oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+        } else {
+                $this->aFields['layertheme_id'] = $this->aValues['my_vitis_id'];
+        }
+    }
+}
+
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/LayerThemes.class.inc b/vmap/vas/rest/ws/vmap/LayerThemes.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..060661b7506f46e14d2f7ac2363f4639bb0622b7
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/LayerThemes.class.inc
@@ -0,0 +1,295 @@
+<?php
+
+/**
+ * \file LayerThemes.class.inc
+ * \class LayerThemes
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * \brief This file contains the LayerThemes php class
+ *
+ * This class defines Rest Api to Vmap LayerThemes
+ * 
+ */
+require_once 'Vmap.class.inc';
+require_once 'LayerTheme.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+require_once __DIR__ . '/../../class/vmlib/BdDataAccess.inc';
+
+class LayerThemes extends Vmap {
+    /**
+     * @SWG\Definition(
+     *   definition="/layerthemes",
+     *   allOf={
+     *     @SWG\Schema(ref="#/definitions/layerthemes")
+     *   }
+     * )
+     * * @SWG\Tag(
+     *   name="LayerThemes",
+     *   description=""
+     * )
+     */
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("layertheme_id", "name", "description");
+    }
+
+    /**
+     * @SWG\Get(path="/layerthemes",
+     *   tags={"LayerThemes"},
+     *   summary="Get LayerThemes",
+     *   description="Request to get LayerThemes",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="order_by",
+     *     in="query",
+     *     description="list of ordering fields",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="sort_order",
+     *     in="query",
+     *     description="sort order",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="limit",
+     *     in="query",
+     *     description="number of element",
+     *     required=false,
+     *     type="integer"
+     *   ),
+     * @SWG\Parameter(
+     *     name="offset",
+     *     in="query",
+     *     description="index of first element",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="attributs",
+     *     in="query",
+     *     description="list of attributs",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="filter",
+     *     in="query",
+     *     description="filter results",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="distinct",
+     *     in="query",
+     *     description="delete duplicates",
+     *     required=false,
+     *     type="boolean"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/layerthemes")
+     *     )
+     *  )
+     */
+
+    /**
+     * get LayerThemes
+     * @return the array of objects
+     */
+    function GET() {
+        $aReturn = $this->genericGet($this->aProperties['schema_vmap'], 'layertheme', 'layertheme_id');
+        return $aReturn['sMessage'];
+    }
+
+    /**
+     * @SWG\Post(path="/layerthemes",
+     *   tags={"LayerThemes"},
+     *   summary="Add layertheme",
+     *   description="Request to add a layertheme",
+     *   operationId="POST",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="formData",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="name",
+     *     in="formData",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="description",
+     *     in="formData",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/layerthemes")
+     *     )
+     *
+     *  )
+     * 
+     * )
+     */
+
+    /**
+     * insert layertheme
+     * @return array containing the status and the message
+     */
+    function POST() {
+        $aReturn = $this->genericPost($this->aProperties['schema_vmap'], 'layertheme', $this->aProperties['schema_vmap'].'.seq_common', 'layertheme_id');           
+        return $aReturn['sMessage'];
+    }
+    
+    /**
+     * @SWG\Put(path="/layerthemes/{layertheme_id}",
+     *   tags={"LayerThemes"},
+     *   summary="Update LayerTheme",
+     *   description="Request to update layertheme",
+     *   operationId="PUT",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="layertheme_id",
+     *     in="path",
+     *     description="user id",
+     *     required=true,
+     *     type="integer"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="name",
+     *     in="query",
+     *     description="layertheme description",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="description",
+     *     in="query",
+     *     description="layertheme description",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/layerthemes")
+     *     ),
+     * 
+     *  )
+     */
+
+    /**
+     * modify layertheme
+     * @return array containing the status and the message
+     */
+    function PUT() {        
+        $aReturn = $this->genericPut($this->aProperties['schema_vmap'], 'layertheme', 'layertheme_id');
+        return $aReturn['sMessage'];
+    }
+    
+    /**
+     * @SWG\Delete(path="/layerthemes/",
+     *   tags={"LayerThemes"},
+     *   summary="delete LayerTheme",
+     *   description="Request to delete LayerTheme",
+     *   operationId="DELETE",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="idList",
+     *     in="query",
+     *     description="id of the layerthemes",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/layerthemes")
+     *     )
+     *  )
+     */
+    /**
+     * @SWG\Delete(path="/layerthemes/{layertheme_id}",
+     *   tags={"LayerThemes"},
+     *   summary="delete LayerTheme",
+     *   description="Request to delete LayerTheme",
+     *   operationId="DELETE",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="layertheme_id",
+     *     in="path",
+     *     description="id of the layertheme",
+     *     required=true,
+     *     type="integer",
+     *     format = "int32"
+     *   ),
+     * @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/layerthemes")
+     *     )
+     *  )
+     */
+    
+    /**
+     * delete layertheme
+     * @return id of layertheme deleted or error object if a layertheme is not deleted
+     */
+    function DELETE() {
+        $aReturn = $this->genericDelete($this->aProperties['schema_vmap'], 'layertheme', 'layertheme_id');
+        return $aReturn['sMessage'];
+    }
+
+}
+
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/Layers.class.inc b/vmap/vas/rest/ws/vmap/Layers.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..9946932c274772406077b73b17be9031374e3cad
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/Layers.class.inc
@@ -0,0 +1,821 @@
+<?php
+
+/**
+ * \file Layers.class.inc
+ * \class Layers
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * \brief This file contains the Layers php class
+ *
+ * This class defines Rest Api to Vmap Layers
+ * 
+ */
+require_once 'Vmap.class.inc';
+require_once 'Layer.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Form.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+require_once __DIR__ . '/../../class/vmlib/BdDataAccess.inc';
+
+class Layers extends Vmap {
+    /**
+     * @SWG\Definition(
+     *   definition="/layers",
+     *   allOf={
+     *     @SWG\Schema(ref="#/definitions/layers")
+     *   }
+     * )
+     * * @SWG\Tag(
+     *   name="Layers",
+     *   description=""
+     * )
+     */
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+    }
+
+    /**
+     * @SWG\Get(path="/layers",
+     *   tags={"Layers"},
+     *   summary="Get Layers",
+     *   description="Request to get Layers",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="order_by",
+     *     in="query",
+     *     description="list of ordering fields",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="sort_order",
+     *     in="query",
+     *     description="sort order",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="limit",
+     *     in="query",
+     *     description="number of element",
+     *     required=false,
+     *     type="integer",
+     *     default="4"
+     *   ),
+     * @SWG\Parameter(
+     *     name="offset",
+     *     in="query",
+     *     description="index of first element",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="attributs",
+     *     in="query",
+     *     description="list of attributs",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="filter",
+     *     in="query",
+     *     description="filter results",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="distinct",
+     *     in="query",
+     *     description="delete duplicates",
+     *     required=false,
+     *     type="boolean"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/layers")
+     *     )
+     *  )
+     */
+    /**
+     * @SWG\Get(path="/layers/{layer_id}/form/{form}",
+     *   tags={"Layers"},
+     *   summary="Get Layers",
+     *   description="Request to get Layers",
+     *   operationId="GET",
+     *   produces={"application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="layer_id",
+     *     in="path",
+     *     description="Layer id",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="form",
+     *     in="path",
+     *     description="form",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/layers")
+     *     )
+     *  )
+     */
+
+    /**
+     * get Layers
+     * @return  Layers
+     */
+    function GET() {
+        // /layers/{layer_id}/form/{form}
+        if (isset($this->aPath[4])) {
+            $layerId = $this->aPath[2];
+            $formName = $this->aPath[4];
+            $form = file_get_contents($this->aProperties['ws_data_dir'] . '/vmap/layer/' . $layerId . '/forms/' . $formName . '.json');
+            $jsContent = file_get_contents($this->aProperties['ws_data_dir'] . '/vmap/layer/' . $layerId . '/forms/ressources/' . $formName . '.js');
+            $cssContent = file_get_contents($this->aProperties['ws_data_dir'] . '/vmap/layer/' . $layerId . '/forms/ressources/' . $formName . '.css');
+
+            $output = array(json_decode($form), $jsContent, $cssContent);
+            return json_encode($output);
+        }
+
+        $aReturn = $this->genericGet($this->aProperties['schema_vmap'], 'v_layer', 'layer_id');
+
+        // Récupère les informations des objets métiers correcpondants aux couches
+        if ($aReturn['sStatus'] === 1) {
+            $aReturn = $this->getLayersBusinessObjectsInfos();
+        }
+        return $aReturn['sMessage'];
+    }
+
+    /**
+     * Get the layers business objects infos
+     * @return array
+     */
+    function getLayersBusinessObjectsInfos() {
+
+        // Récupère les infos des objets métiers
+        for ($i = 0; $i < count($this->aObjects); $i++) {
+            if (!empty($this->aObjects[$i]->aFields['bo_id_list'])) {
+                $aBoIds = explode('|', $this->aObjects[$i]->aFields['bo_id_list']);
+//                $this->aObjects[$i]->aFields['business_objects'] = $this->aObjects[$i]->getBusinessObjectsInfos($aBoIds, $this->oConnection);
+                $this->aObjects[$i]->aFields['business_objects'] = $this->getBusinessObjectsInfos($aBoIds);
+            }
+        }
+
+        // Met le tout en forme
+        $sEncoding = isset($this->aValues['sEncoding']) ? $this->aValues['sEncoding'] : null;
+        $sSourceEncoding = isset($this->aValues['sSourceEncoding']) ? $this->aValues['sSourceEncoding'] : null;
+        $output = isset($this->aValues['output']) ? $this->aValues['output'] : null;
+        $aXmlRacineAttribute['status'] = 1;
+        $sMessage = $this->asDocument('', 'vitis', $sEncoding, True, $aXmlRacineAttribute, $sSourceEncoding, $output);
+        $aReturn = array('sStatus' => $aXmlRacineAttribute['status'], "sMessage" => $sMessage);
+
+        return $aReturn;
+    }
+
+    /**
+     * Get the infos from the business objects defined in $aBoIds
+     * @param array $aBoIds
+     * @return array
+     */
+    function getBusinessObjectsInfos($aBoIds) {
+        $aBoInfos = array();
+        for ($i = 0; $i < count($aBoIds); $i++) {
+            $aPath = array('vmap', 'businessobjects', $aBoIds[$i]);
+            $aValues = $this->aValues;
+            $aValues['my_vitis_id'] = $aBoIds[$i];
+            $oBo = new BusinessObject($aPath, $aValues, $this->aProperties, false, $this->oConnection);
+            $oBo->GET();
+            array_push($aBoInfos, $oBo->aFields);
+        }
+        return $aBoInfos;
+    }
+
+    /**
+     * @SWG\Post(path="/layers",
+     *   tags={"Layers"},
+     *   summary="Add layer",
+     *   description="Request to add a layer",
+     *   operationId="POST",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="formData",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="name",
+     *     in="formData",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="theme_id",
+     *     in="formData",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="service_id",
+     *     in="formData",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="description",
+     *     in="formData",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="visible",
+     *     in="formData",
+     *     description="",
+     *     required=false,
+     *     type="boolean"
+     *   ),
+     * @SWG\Parameter(
+     *     name="bo_id",
+     *     in="formData",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="layer_list",
+     *     in="formData",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/layers")
+     *     )
+     *
+     *  )
+     * 
+     * )
+     */
+    /**
+     * @SWG\Post(path="/layers/{layer_id}/form/{form}",
+     *   tags={"Layers"},
+     *   summary="Generates the layer form",
+     *   description="Request to add a layer form",
+     *   operationId="POST",
+     *   produces={"application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="formData",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="layer_id",
+     *     in="path",
+     *     description="Layer id",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="form",
+     *     in="path",
+     *     description="form",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/layers")
+     *     )
+     *  )
+     * )
+     */
+
+    /**
+     * insert layer
+     * @return array containing the status and the message
+     */
+    function POST() {
+
+        // /layers/{layer_id}/form/{form}
+        if (isset($this->aPath[4])) {
+            if (isset($this->oConnection->oError) && !empty($this->oConnection->oError)) {
+                $aXmlRacineAttribute['status'] = 0;
+                $sMessage = $this->oConnection->oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+                return $sMessage;
+            }
+            if (!in_array('vmap_admin', $this->oConnection->aPrivileges)) {
+                $oError = new VitisError(0, 'INSUFFICIENT_PRIVILEGES');
+                $aXmlRacineAttribute['status'] = 0;
+                $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+                return $sMessage;
+            }
+            $layerId = $this->aPath[2];
+            $sFormName = $this->aPath[4];
+            return $this->generateEmptyForm($layerId, $sFormName);
+        }
+        // Supprime le champ 'bo_id' à NULL si il est vide (sinon erreur avec la contrainte "fk_layer_business_object").
+        $sBoId = $this->aValues['bo_id'];
+        if (empty($sBoId))
+            unset($this->aValues['bo_id']);
+        $aReturn = $this->genericPost($this->aProperties['schema_vmap'], 'layer', $this->aProperties['schema_vmap'] . '.seq_common', 'layer_id');
+        if ($aReturn['sStatus'] == 1) {
+            // Met à jour le champ 'bo_id' à NULL.
+            if (empty($sBoId)) {
+                require $this->sRessourcesFile;
+                $aParams['sSchemaVmap'] = array('value' => $this->aProperties['schema_vmap'], 'type' => 'schema_name');
+                $aParams['layer_id'] = array('value' => $this->aValues['my_vitis_id'], 'type' => 'number');
+                $oPDOresult = $this->oConnection->oBd->executeWithParams($aSql['setLayerBoId'], $aParams);
+            }
+            // Associe les objets métiers à la couche
+            if (!empty($this->aValues['my_vitis_id'])) {
+                $aBoList = explode('|', $this->aValues['bo_id_list']);
+                $this->associateBusinessobjects($aBoList, $this->aValues['my_vitis_id']);
+            }
+        }
+        return $aReturn['sMessage'];
+    }
+
+    /**
+     * Generate the form
+     * @param string $layerId
+     * @param string $sFormName
+     * @return string jsonContent of the form
+     */
+    function generateEmptyForm($layerId, $sFormName) {
+
+        $oForm = new Form($this->aProperties, $this->oConnection);
+
+        $aRows = array();
+        $aForm = $oForm->generateFormByRows($aRows, $layerId, $sFormName);
+
+        $sDirPath = $this->aProperties['ws_data_dir'] . '/vmap/layer/' . $layerId;
+
+        // création de l'arborescence si elle n'existe pas
+        if (!is_dir($this->aProperties['ws_data_dir'] . '/vmap')) {
+            @mkdir($this->aProperties['ws_data_dir'] . '/vmap');
+        }
+        if (!is_dir($this->aProperties['ws_data_dir'] . '/vmap/layer')) {
+            @mkdir($this->aProperties['ws_data_dir'] . '/vmap/layer');
+        }
+        if (!is_dir($sDirPath)) {
+            @mkdir($sDirPath);
+        }
+        if (!is_dir($sDirPath . '/forms')) {
+            @mkdir($sDirPath . '/forms');
+        }
+        if (!is_dir($sDirPath . '/forms/ressources')) {
+            @mkdir($sDirPath . '/forms/ressources');
+        }
+
+        $JSONcontent = json_encode($aForm);
+
+        // écrit le fichier demandé
+        $formFile = fopen($sDirPath . '/forms/' . $sFormName . '.json', 'w');
+        fwrite($formFile, $JSONcontent);
+        fclose($formFile);
+
+        // écrit les autres fichiers si ils n'existent pas
+        if (!file_exists($sDirPath . '/forms/default.json')) {
+            $formFile = fopen($sDirPath . '/forms/default.json', 'w');
+            fwrite($formFile, $JSONcontent);
+            fclose($formFile);
+        }
+        if (!file_exists($sDirPath . '/forms/published.json')) {
+            $formFile = fopen($sDirPath . '/forms/published.json', 'w');
+            fwrite($formFile, $JSONcontent);
+            fclose($formFile);
+        }
+        if (!file_exists($sDirPath . '/forms/custom.json')) {
+            $formFile = fopen($sDirPath . '/forms/custom.json', 'w');
+            fwrite($formFile, $JSONcontent);
+            fclose($formFile);
+        }
+
+        return $JSONcontent;
+    }
+
+    /**
+     * @SWG\Put(path="/layers/{layer_id}",
+     *   tags={"Layers"},
+     *   summary="Update Layer",
+     *   description="Request to update layer",
+     *   operationId="PUT",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="layer_id",
+     *     in="path",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="name",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="theme_id",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="service_id",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="description",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="visible",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="boolean"
+     *   ),
+     * @SWG\Parameter(
+     *     name="bo_id",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="layer_list",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/layers")
+     *     ),
+     * 
+     *  )
+     */
+    /**
+     * @SWG\Put(path="/layers/{layer_id}/form/{form}",
+     *   tags={"Layers"},
+     *   summary="Modify layer form",
+     *   description="Request to modify a layer form",
+     *   operationId="PUT",
+     *   produces={"application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="layer_id",
+     *     in="path",
+     *     description="Layer id",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="form",
+     *     in="path",
+     *     description="form name (default, published, custom)",
+     *     required=true,
+     *     type="integer",
+     *     format="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="json_file",
+     *     in="formData",
+     *     description="Wsubform.json",
+     *     required=false,
+     *     type="file"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="js_file",
+     *     in="formData",
+     *     description="Javascript file link with WSubform",
+     *     required=false,
+     *     type="file"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="css_file",
+     *     in="formData",
+     *     description="Css file link with WSubform",
+     *     required=false,
+     *     type="file"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="cmd",
+     *     in="query",
+     *     description="Perso_Save, Perso_Published, Default_Published, Perso_Reset, Default_Reset",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/layers")
+     *     )
+     *  )
+     * )
+     */
+
+    /**
+     * modify layer
+     * @return array containing the status and the message
+     */
+    function PUT() {
+
+        // /layers/{layer_id}/form/{form}
+        if (isset($this->aPath[4])) {
+            if (isset($this->oConnection->oError) && !empty($this->oConnection->oError)) {
+                $aXmlRacineAttribute['status'] = 0;
+                $sMessage = $this->oConnection->oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+                return $sMessage;
+            }
+            if (!in_array('vmap_admin', $this->oConnection->aPrivileges)) {
+                $oError = new VitisError(0, 'INSUFFICIENT_PRIVILEGES');
+                $aXmlRacineAttribute['status'] = 0;
+                $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+                return $sMessage;
+            }
+            $layerId = $this->aPath[2];
+            $sFormName = $this->aPath[4];
+            $sComand = $this->aValues['cmd'];
+            $this->putForm($layerId, $sFormName, $sComand);
+        }
+        // Supprime le champ 'bo_id' à NULL si il est vide (sinon erreur avec la contrainte "fk_layer_business_object").
+        $sBoId = $this->aValues['bo_id'];
+        if (empty($sBoId))
+            unset($this->aValues['bo_id']);
+        $aReturn = $this->genericPut($this->aProperties['schema_vmap'], 'layer', 'layer_id');
+        if ($aReturn['sStatus'] == 1) {
+            // Met à jour le champ 'bo_id' à NULL.
+            if (empty($sBoId)) {
+                require $this->sRessourcesFile;
+                $aParams['sSchemaVmap'] = array('value' => $this->aProperties['schema_vmap'], 'type' => 'schema_name');
+                $aParams['layer_id'] = array('value' => $this->aValues['my_vitis_id'], 'type' => 'number');
+                $oPDOresult = $this->oConnection->oBd->executeWithParams($aSql['setLayerBoId'], $aParams);
+            }
+            // Associe les objets métiers à la couche
+            if (!empty($this->aValues['my_vitis_id'])) {
+                $aBoList = explode('|', $this->aValues['bo_id_list']);
+                $this->associateBusinessobjects($aBoList, $this->aValues['my_vitis_id']);
+            }
+        }
+        return $aReturn['sMessage'];
+    }
+
+    /**
+     * Change the business object form using this->aValues
+     * @param string $layerId
+     * @param string $formName
+     * @param string $sComand
+     */
+    function putForm($layerId, $sFormName, $sComand) {
+
+        $sDirPath = $this->aProperties['ws_data_dir'] . '/vmap/layer/' . $layerId;
+
+        // création de l'arborescence si elle n'existe pas
+        if (!is_dir($this->aProperties['ws_data_dir'] . '/vmap')) {
+            @mkdir($this->aProperties['ws_data_dir'] . '/vmap');
+        }
+        if (!is_dir($this->aProperties['ws_data_dir'] . '/vmap/layer')) {
+            @mkdir($this->aProperties['ws_data_dir'] . '/vmap/layer');
+        }
+        if (!is_dir($sDirPath)) {
+            @mkdir($sDirPath);
+        }
+        if (!is_dir($sDirPath . '/forms')) {
+            @mkdir($sDirPath . '/forms');
+        }
+        if (!is_dir($sDirPath . '/forms/ressources')) {
+            @mkdir($sDirPath . '/forms/ressources');
+        }
+
+        if ($this->aValues["cmd"]) {
+            switch ($this->aValues["cmd"]) {
+                case "Perso_Save":
+
+                    if (!empty($this->aValues['Json'])) {
+                        $pFile = fopen($sDirPath . '/forms/' . $sFormName . '.json', 'w');
+                        if (fwrite($pFile, $this->aValues["Json"]) == FALSE) {
+                            writeToErrorLog('ERROR: ' . $sFormName . '.json save failed');
+                        }
+                        fclose($pFile);
+                    }
+
+                    if ($this->aValues["Js"] != "") {
+                        $pFileJS = fopen($sDirPath . '/forms/ressources/' . $sFormName . '.js', 'w+');
+                        if (fwrite($pFileJS, $this->aValues["Js"]) == FALSE) {
+                            writeToErrorLog('ERROR: ' . $sFormName . '.js save failed');
+                        }
+                        fclose($pFileJS);
+                    }
+
+                    if ($this->aValues["Css"] != "") {
+                        $pFileCSS = fopen($sDirPath . '/forms/ressources/' . $sFormName . '.css', 'w+');
+                        if (fwrite($pFileCSS, $this->aValues["Css"]) == FALSE) {
+                            writeToErrorLog('ERROR: ' . $sFormName . '.css save failed');
+                        }
+                        fclose($pFileCSS);
+                    }
+
+                    break;
+                case "Perso_Published":
+
+                    @unlink($sDirPath . "/forms/published.json");
+                    copy($sDirPath . "/forms/custom.json", $sDirPath . "/forms/published.json");
+
+                    if (file_exists($sDirPath . "/forms/ressources/custom.js")) {
+                        if (file_exists($sDirPath . "/forms/ressources/published.js")) {
+                            @unlink($sDirPath . "/forms/ressources/published.js");
+                        }
+                        copy($sDirPath . "/forms/ressources/custom.js", $sDirPath . "/forms/ressources/published.js");
+                    }
+                    if (file_exists($sDirPath . "/forms/ressources/custom.css")) {
+                        if (file_exists($sDirPath . "/forms/ressources/published.css")) {
+                            @unlink($sDirPath . "/forms/ressources/published.css");
+                        }
+                        copy($sDirPath . "/forms/ressources/custom.css", $sDirPath . "/forms/ressources/published.css");
+                    }
+
+                    break;
+                case "Default_Published":
+
+                    @unlink($sDirPath . "/forms/published.json");
+                    copy($sDirPath . "/forms/default.json", $sDirPath . "/forms/published.json");
+
+                    break;
+                case "Perso_Reset":
+
+                    @unlink($sDirPath . "/forms/custom.json");
+                    copy($sDirPath . "/forms/default.json", $sDirPath . "/forms/custom.json");
+
+                    break;
+                case "Default_Reset" :
+                    @unlink($sDirPath . "/forms/default.json");
+                    $this->generateEmptyForm($layerId, $sFormName);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Associate the business objects to the layer
+     * @param array $aBoList
+     * @param integer $iLayerId
+     */
+    function associateBusinessobjects($aBoList, $iLayerId) {
+        require $this->sRessourcesFile;
+
+        if (count($aBoList) > 0) {
+            // Supprime les objets métiers actuellements liés à la couche
+            $aSQLParams = array(
+                'sSchemaVmap' => array('value' => $this->aProperties['schema_vmap'], 'type' => 'column_name'),
+                'layer_id' => array('value' => $iLayerId, 'type' => 'number')
+            );
+            $oResult = $this->oConnection->oBd->executeWithParams($aSql['deleteAssociatedBos'], $aSQLParams);
+
+            // Ajoute les objets métiers à la couche
+            for ($i = 0; $i < count($aBoList); $i++) {
+                if (!empty($aBoList[$i])) {
+                    $aSQLParams = array(
+                        'sSchemaVmap' => array('value' => $this->aProperties['schema_vmap'], 'type' => 'column_name'),
+                        'business_object_id' => array('value' => $aBoList[$i], 'type' => 'string'),
+                        'layer_id' => array('value' => $iLayerId, 'type' => 'number')
+                    );
+                    $oResult = $this->oConnection->oBd->executeWithParams($aSql['addAssociatedBos'], $aSQLParams);
+                }
+            }
+        }
+    }
+
+    /**
+     * @SWG\Delete(path="/layers/",
+     *   tags={"Layers"},
+     *   summary="delete Layer",
+     *   description="Request to delete Layer",
+     *   operationId="DELETE",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="layer token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="idList",
+     *     in="query",
+     *     description="id of the layers",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/layers")
+     *     )
+     *  )
+     */
+    /**
+     * @SWG\Delete(path="/layers/{layer_id}",
+     *   tags={"Layers"},
+     *   summary="delete Layer",
+     *   description="Request to delete Layer",
+     *   operationId="DELETE",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="layer token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="layer_id",
+     *     in="path",
+     *     description="id of the layer",
+     *     required=true,
+     *     type="integer",
+     *     format = "int32"
+     *   ),
+     * @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/layers")
+     *     )
+     *  )
+     */
+
+    /**
+     * delete layer
+     * @return id of layer deleted or error object if a layer is not deleted
+     */
+    function DELETE() {
+        $aReturn = $this->genericDelete($this->aProperties['schema_vmap'], 'layer', 'layer_id');
+        return $aReturn['sMessage'];
+    }
+
+}
+
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/Map.class.inc b/vmap/vas/rest/ws/vmap/Map.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..ddfbd2786744831edda77eb143588b20de89ddf9
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/Map.class.inc
@@ -0,0 +1,119 @@
+<?php
+
+require_once 'Vmap.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+
+/**
+ * \file Map.class.inc
+ * \class Map
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * \brief This file contains the Map php class
+ *
+ * This class defines operation for one Map
+ * 
+ */
+class Map extends Vmap {
+
+    public $oError;
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+		$this->aSelectedFields = Array("map_id", "crs_id", "name", "description", "crs_name", "extent", "catalog_index", "thumbnail", "theme_name", "theme_description", "maptheme_id", "groups");
+    }
+
+    /**
+     * @SWG\Get(path="/maps/{map_id}", 
+     *   tags={"Maps"},
+     *   summary="Get Map",
+     *   description="Request to get Map by id",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="map_id",
+     *     in="path",
+     *     description="map id",
+     *     required=true,
+     *     type="integer"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/maps")
+     *     )
+     *  )
+     */
+
+    /**
+     * get informations about Map
+     */
+    function GET() {
+        require $this->sRessourcesFile;
+        $this->aFields = $this->getFields($this->aProperties['schema_vmap'], 'v_map', 'map_id');
+        $this->getGroups();
+    }
+
+    /**
+     *  get groups of map
+     */
+    function getGroups() {
+        require $this->sRessourcesFile;
+        if (in_array("groups", $this->aSelectedFields)){
+            $aParams['sSchemaFramework'] = array('value' => $this->aProperties['schema_framework'], 'type' => 'schema_name');
+            $aParams['sSchemaVmap'] = array('value' => $this->aProperties['schema_vmap'], 'type' => 'schema_name');
+            $aParams['map_id'] = array('value' => $this->aValues['my_vitis_id'], 'type' => 'number');
+            $oPDOresult = $this->oConnection->oBd->executeWithParams($aSql['getMapGroups'], $aParams);
+            $sListGroupId = "";
+            $aListGroupName = array();
+            while($aLigne=$this->oConnection->oBd->ligneSuivante ($oPDOresult)) {
+                    if ($sListGroupId == ""){
+                            $sListGroupId = $aLigne["group_id"];
+                    }else{
+                            $sListGroupId .= "|".$aLigne["group_id"];
+                    }
+                    $aListGroupName[] = $aLigne["name"];
+            }
+            $oPDOresult=$this->oConnection->oBd->fermeResultat();
+            $this->aFields['groups'] = $sListGroupId;
+            $this->aFields['groups_label'] = implode(',', $aListGroupName);
+        }
+    }
+    
+    /**
+     * delete a map
+     */
+    function DELETE() {
+        // Supprime la vignette.
+        $oMap = new Map($this->aPath, $this->aValues, $this->aProperties, $this->oConnection);
+        $oMap->GET();
+        if (!empty($oMap->aFields['thumbnail'])) {
+            $sFile = $oMap->aProperties['dir_export'] . '/vmap/' . $oMap->aFields['thumbnail'];
+            if (file_exists($sFile))
+                unlink($sFile);
+        }
+        $this->oConnection->oBd->delete($this->aProperties['schema_vmap'], 'map', 'map_id', $this->aValues['my_vitis_id'], 'integer');
+        if ($this->oConnection->oBd->enErreur()) {
+                $this->oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+        } else {
+                $this->aFields['map_id'] = $this->aValues['my_vitis_id'];
+        }
+    }
+}
+
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/MapCatalog.class.inc b/vmap/vas/rest/ws/vmap/MapCatalog.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..aef8d600ec030e2cd85fc621996c7bef08191fd1
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/MapCatalog.class.inc
@@ -0,0 +1,265 @@
+<?php
+
+require_once 'Vmap.class.inc';
+require_once 'Maps.class.inc';
+require_once 'Services.class.inc';
+require_once 'Layers.class.inc';
+require_once __DIR__ . '/../vitis/Users.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+
+/**
+ * \file Map.class.inc
+ * \class Map
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * \brief This file contains the Map php class
+ *
+ * This class defines operation for one Map
+ * 
+ */
+class MapCatalog extends Vmap {
+
+    public $oError;
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        $this->aValues = $aValues;
+        $this->aPath = $aPath;
+        $this->aProperties = $properties;
+        $this->aValues['getGroup'] = true;
+        $this->oConnection = new Connection($this->aValues, $this->aProperties);
+    }
+
+    /**
+     * @SWG\Get(path="/mapcatalog", 
+     *   tags={"Catalog"},
+     *   summary="Get Map",
+     *   description="Request to get Map by id",
+     *   operationId="GET",
+     *   produces={"application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/mapcatalog")
+     *     )
+     *  )
+     */
+
+    /**
+     * get informations about Map
+     */
+    function GET() {
+        require $this->sRessourcesFile;
+
+        $aValues = $this->aValues;
+        $aPath = $this->aPath;
+        $properties = $this->aProperties;
+        $oConnection = $this->oConnection;
+
+        // Récupère les groupes correspondants
+        $sGroups = $this->oConnection->sesGroup;
+
+        // Récupère les cartes correspondante      
+        $aMaps = $this->getMaps($sGroups);
+
+        // Récupère les services correspondants
+        $aServices = $this->getServices();
+
+        $MapCatalog['usedMap'] = 0;
+        $MapCatalog['maps'] = $aMaps;
+        $MapCatalog['services'] = $aServices;
+
+        $this->aFields = $MapCatalog;
+
+        $aXmlRacineAttribute['status'] = 1;
+        $sMessage = $this->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+
+        // Génération du flux wms privé.
+        if (!empty($properties["use_veremap_api"]) && $properties["use_veremap_api"] === true) {
+            // 1- Récupère le token veremap 2015
+            $params = array(
+                "user" => $oConnection->oBd->login,
+                "password" => $oConnection->oBd->mdp,
+                "duration" => 600
+            );
+            $oVeremap = json_decode($this->httpPost($properties["api_veremap"] . "/vitis/privatetoken", $params));
+            if (is_object($oVeremap)) {
+                $veremapToken = $oVeremap->token;
+                // 2- Génère le flux privé qui aura pour nom de mapFile le token de vitis 2016
+                $params = array(
+                    "token" => $veremapToken,
+                    "fileName" => hash('sha256', $aValues['token'])
+                );
+                $this->httpPost($properties["api_veremap"] . "/veremap/WMS", $params);
+            }
+        }
+        // Création du fichier ".map" du flux wms privé de Vmap4MapServer (nom du fichier = token de l'utilisateur connecté).
+        if (!empty($properties["use_vm4ms_api"]) && $properties["use_vm4ms_api"] === true && file_exists(__DIR__ . '/../vm4ms/WmsServices.class.inc')) {
+            require_once __DIR__ . '/../vm4ms/WmsServices.class.inc';
+
+            $aPath = array('vm4ms', 'wmsservices', 'private', 'MapFile');
+
+            $aValues = array(
+                'token' => $this->aValues['token'],
+                'my_vitis_id' => $properties['private_wms_service'],
+                'creation' => 'true',
+                'type' => 'prod'
+            );
+
+            $oWmsServices = new WmsServices($aPath, $aValues, $this->aProperties, $this->oConnection);
+            $oWmsServices->GET();
+            $oWmsServices->createMapFile();
+        }
+        return $sMessage;
+    }
+
+    /**
+     * Get the maps for the group_id
+     * @param string $sGroups
+     * @return array
+     */
+    function getMaps($sGroups) {
+
+        if (empty($sGroups)) {
+            return array();
+        }
+
+        $sGroups = str_replace(',', '|', $sGroups);
+
+        $aValues = $this->aValues;
+        $aPath = $this->aPath;
+        $properties = $this->aProperties;
+        $oConnection = $this->oConnection;
+        $filterList = '';
+
+        $aSQLParams = array(
+            'sSchema' => array('value' => $this->aProperties['schema_vmap'], 'type' => 'column_name'),
+            'sGroups' => array('value' => $sGroups, 'type' => 'group')
+        );
+        $sSql = "SELECT map_id, group_id FROM [sSchema].map_group WHERE \"group_id\" in ([sGroups])";
+
+        $oResult = $this->oConnection->oBd->executeWithParams($sSql, $aSQLParams);
+        if (gettype($oResult) == 'object') {
+            $aLayers_infos = Array();
+            while ($aLigne = $this->oConnection->oBd->ligneSuivante($oResult)) {
+                // stocke le layer id dans la chaine de caractères
+                if ($filterList == '')
+                    $filterList .= $aLigne['map_id'];
+                else
+                    $filterList .= ',' . $aLigne['map_id'];
+            }
+        } else {
+            return Array();
+        }
+
+        unset($aValues['my_vitis_id']);
+        $aValues['filter'] = '{"column":"map_id","compare_operator":"IN","value":[' . $filterList . ']}';
+        $aValues['attributs'] = 'name|description|theme_name|theme_description|extent_crs_id|map_id|thumbnail|catalog_index';
+        $aValues['order_by'] = 'catalog_index';
+
+        $oMaps = new Maps(Array('vmap', 'map'), $aValues, $this->aProperties);
+        $oMaps->GET();
+
+        // Transforme $oMaps en tableau de Map
+        $aMaps = Array();
+        foreach ($oMaps->aObjects as $oMap) {
+            $oMap->aFields['url'] = $properties['web_server_name'] . '/' . $properties['services_alias'] . '/vmap/mapjsons/' . $oMap->aFields['map_id'];
+            array_push($aMaps, $oMap->aFields);
+        }
+
+        return $aMaps;
+    }
+
+    /**
+     * Get the services avaliables (with the layers params for bing and ign)
+     * @return array
+     */
+    function getServices() {
+
+        $aValues = $this->aValues;
+        $aPath = $this->aPath;
+        $properties = $this->aProperties;
+        $oConnection = $this->oConnection;
+
+        unset($aValues['my_vitis_id']);
+        $oServices = new Services(Array('vmap', 'services'), $aValues, $this->aProperties);
+        $oServices->GET();
+
+        $aServices['wms'] = Array();
+        $aServices['osm'] = Array();
+        $aServices['bing'] = Array();
+        $aServices['ign'] = Array();
+        $aServices['wmts'] = Array();
+        $aServices['xyz'] = Array();
+        foreach ($oServices->aObjects as $oService) {
+            switch ($oService->aFields['service_type_id']) {
+                case 'tilewms':
+                case 'imagewms':
+                    $oService->aFields['url'] = str_replace('[token]', hash('sha256', $aValues['token']), $oService->aFields['url']);
+                    if (isset($this->aProperties['ms_cgi_url'])) {
+                        $oService->aFields['url'] = str_replace('[ms_cgi_url]', $this->aProperties['ms_cgi_url'], $oService->aFields['url']);
+                    }
+                    array_push($aServices['wms'], $oService->aFields);
+                    break;
+                case 'wmts':
+                    array_push($aServices['wmts'], $oService->aFields);
+                    break;
+                case 'xyz':
+                    array_push($aServices['xyz'], $oService->aFields);
+                    break;
+                case 'osm':
+                    array_push($aServices['osm'], $oService->aFields);
+                    break;
+                case 'bing':
+                    $oService->aFields['imagerySet'] = $oService->aFields['imagery'];
+                    $oService->aFields['culture'] = $oService->aFields['lang'];
+                    array_push($aServices['bing'], $oService->aFields);
+                    break;
+                case 'geoportail':
+                    break;
+            }
+        }
+
+        return $aServices;
+    }
+
+    function httpPost($url, $params) {
+        $postData = '';
+        //create name value pairs seperated by &
+        foreach ($params as $k => $v) {
+            $postData .= $k . '=' . $v . '&';
+        }
+        $postData = rtrim($postData, '&');
+
+        $ch = curl_init();
+
+        curl_setopt($ch, CURLOPT_URL, $url);
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+        curl_setopt($ch, CURLOPT_HEADER, false);
+        curl_setopt($ch, CURLOPT_POST, count($postData));
+        curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
+
+        $output = curl_exec($ch);
+
+        curl_close($ch);
+        return $output;
+    }
+
+}
+
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/MapCatalogs.class.inc b/vmap/vas/rest/ws/vmap/MapCatalogs.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..15b31c91e1f3a4eda67a2fae78d6f79d2a636ddb
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/MapCatalogs.class.inc
@@ -0,0 +1,40 @@
+<?php
+/**
+* \file Maps.class.inc
+* \class Maps
+*
+* \author Armand Bahi <armand.bahi@veremes.com>.
+*
+* \brief This file contains the Maps php class
+*
+* This class defines Rest Api to Vmap Maps
+* 
+*/
+require_once 'Vmap.class.inc';
+require_once 'MapCatalog.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+require_once __DIR__ . '/../../class/vmlib/BdDataAccess.inc';
+
+class MapCatalogs extends Vmap {
+    
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+    }
+    /**
+     * get Maps
+     * @return  Maps
+     */
+    function GET() {
+        $aReturn = $this->genericGet($this->aProperties['schema_vmap'], 'v_map', 'map_id');        
+        return $aReturn['sMessage'];
+    }
+}
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/MapJSON.class.inc b/vmap/vas/rest/ws/vmap/MapJSON.class.inc
new file mode 100644
index 0000000000000000000000000000000000000000..533a6b90b2334274400e352edfe0f13510fde768
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/MapJSON.class.inc
@@ -0,0 +1,351 @@
+<?php
+
+require_once 'Vmap.class.inc';
+require_once 'Map.class.inc';
+require_once 'Layers.class.inc';
+require_once 'BusinessObject.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+
+/**
+ * \file Map.class.inc
+ * \class Map
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * \brief This file contains the Map php class
+ *
+ * This class defines operation for one Map
+ *
+ */
+class MapJSON extends Vmap {
+
+    public $oError;
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+    }
+
+    /**
+     * @SWG\Get(path="/mapjsons/{map_id}",
+     *   tags={"MapJSON"},
+     *   summary="Get Map",
+     *   description="Request to get Map by id",
+     *   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="map_id",
+     *     in="path",
+     *     description="map id",
+     *     required=true,
+     *     type="integer"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/mapjsons")
+     *     )
+     *  )
+     */
+
+    /**
+     * get informations about Map
+     */
+    function GET() {
+        require $this->sRessourcesFile;
+
+        $aValues = $this->aValues;
+        $aPath = $this->aPath;
+        $properties = $this->aProperties;
+        $oConnection = $this->oConnection;
+
+        // Récupère la carte correspondante
+        $oMap = new Map(Array('vmap', 'maps'), $aValues, $properties, $oConnection);
+        $oMap->GET();
+
+        // Récupère les calques correspondants
+        $aLayers = $this->getMapLayers($aPath[2]);
+
+        for ($i = 0; $i < count($aLayers); $i++) {
+            $aLayers[$i]->aFields['events'] = $this->getLayersEvents($aLayers[$i]->aFields['layer_id']);
+        }
+
+        // Forme l'objet mapjson
+        $oMapJSON['name'] = 'Tree';
+        $oMapJSON['children'] = Array();
+
+        $extent = explode('|', $oMap->aFields['extent']);
+
+        foreach ($extent as $key => $value) {
+            $extent[$key] = floatval($value);
+        }
+
+        $oMapJSON['children'][0]['view']['extent'] = $extent;
+        $oMapJSON['children'][0]['view']['projection'] = $oMap->aFields['crs_id'];
+
+        // Réordonne les calques pour qu'ils correspondent à la définition vmap
+        $aThemes = $this->reorderLayers($aLayers);
+
+        $i = 1;
+        foreach ($aThemes as $themeName => $themeParams) {
+            $oMapJSON['children'][$i]['name'] = $themeName;
+            $oMapJSON['children'][$i]['children'] = $themeParams;
+            $i++;
+        }
+
+        // Écrit dans les log de vMap
+        $this->writeMapToVMapLog($oMap->aFields['map_id'], $oMap->aFields['name']);
+
+        $this->aFields = $oMapJSON;
+    }
+
+    /**
+     * Get an array of layers (with state infos like opacity etc..) by map_id
+     * @param number $map_id
+     * @return array aLayers
+     */
+    function getMapLayers($map_id) {
+
+        $aValues = $this->aValues;
+        $aPath = $this->aPath;
+        $properties = $this->aProperties;
+        $oConnection = $this->oConnection;
+        $filterList = '';
+
+        $aSQLParams = array(
+            'sSchema' => array('value' => $this->aProperties['schema_vmap'], 'type' => 'column_name'),
+            'sMapId' => array('value' => $map_id, 'type' => 'number')
+        );
+        $sSql = "SELECT * FROM [sSchema].map_layer WHERE \"map_id\" = [sMapId]";
+
+        $oResult = $this->oConnection->oBd->executeWithParams($sSql, $aSQLParams);
+        if (gettype($oResult) == 'object') {
+            $aLayers_infos = Array();
+            while ($aLigne = $this->oConnection->oBd->ligneSuivante($oResult)) {
+                // stocke le layer id dans la chaine de caractères
+                if ($filterList == '')
+                    $filterList .= $aLigne['layer_id'];
+                else
+                    $filterList .= ',' . $aLigne['layer_id'];
+
+                // stocke les infos complémentaires du calque (visible, opacity etc...)
+                $tmp['layer_index'] = $aLigne['layer_index'];
+                $tmp['layer_visible'] = $aLigne['layer_visible'];
+                $tmp['layer_opacity'] = $aLigne['layer_opacity'];
+                $aLayers_infos[$aLigne['layer_id']] = $tmp;
+                unset($tmp);
+            }
+        } else {
+            return Array();
+        }
+
+        if (empty($filterList)) {
+            return Array();
+        }
+
+        unset($aValues['my_vitis_id']);
+        $aValues['filter'] = '{"column":"layer_id","compare_operator":"IN","value":[' . $filterList . ']}';
+        $aValues['order_by'] = 'name';
+
+        $oLayers = new Layers(Array('vmap', 'layer'), $aValues, $this->aProperties);
+        $oLayers->GET();
+
+        // Transforme oLayers en tableau de Layer
+        $aLayers = Array();
+        foreach ($oLayers->aObjects as $oLayer) {
+            // Rajoute les informations sur l'état du calque
+            foreach ($aLayers_infos[$oLayer->aFields['layer_id']] as $key => $value) {
+                $oLayer->aFields[$key] = $value;
+            }
+            $oLayer->aFields['filter_form'] = $oLayer->getFilterForm();
+            $oLayer->aFields['filter_form_embedjs'] = $oLayer->getFilterFormJs();
+            array_push($aLayers, $oLayer);
+        }
+
+        return $aLayers;
+    }
+
+    /**
+     * Get the events from a layer
+     * @param string $layer_id
+     * @return array
+     */
+    function getLayersEvents($layer_id) {
+
+        $aSQLParams = array(
+            'sSchema' => array('value' => $this->aProperties['schema_vmap'], 'type' => 'column_name'),
+            'sLayerId' => array('value' => $layer_id, 'type' => 'number')
+        );
+        $sSql = "SELECT * FROM [sSchema].layer_event WHERE \"layer_id\" = [sLayerId]";
+        $oResult = $this->oConnection->oBd->executeWithParams($sSql, $aSQLParams);
+        if (gettype($oResult) == 'object') {
+            $aEvents = Array();
+            while ($aLigne = $this->oConnection->oBd->ligneSuivante($oResult)) {
+                array_push($aEvents, $aLigne['event_id']);
+            }
+        }
+
+        return $aEvents;
+    }
+
+    /**
+     * Reorder the layers like vmap definition
+     * @param array $aLayers
+     * @return array
+     */
+    function reorderLayers($aLayers) {
+
+        $aThemes = Array();
+        foreach ($aLayers as $oLayer) {
+
+            if (!isset($oLayer->aFields['theme_name']))
+                $oLayer->aFields['theme_name'] = $oLayer->aFields['service_name'];
+
+            if (!isset($aThemes[$oLayer->aFields['theme_name']]))
+                $aThemes[$oLayer->aFields['theme_name']] = Array();
+
+            if (!empty($oLayer->aFields['name']))
+                $tmp['name'] = $oLayer->aFields['name'];
+            else
+                continue;
+
+            if (!empty($oLayer->aFields['service_type_id']))
+                $tmp['layerType'] = $oLayer->aFields['service_type_id'];
+            else
+                continue;
+
+            if (!empty($oLayer->aFields['service_url'])) {
+                $tmp['url'] = $oLayer->aFields['service_url'];
+                $tmp['url'] = str_replace('[token]', hash('sha256', $this->aValues['token']), $tmp['url']);
+                if (isset($this->aProperties['ms_cgi_url'])) {
+                    $tmp['url'] = str_replace('[ms_cgi_url]', $this->aProperties['ms_cgi_url'], $tmp['url']);
+                }
+            }
+
+            if (!empty($oLayer->aFields['layer_index']))
+                $tmp['index'] = $oLayer->aFields['layer_index'];
+            else
+                $tmp['index'] = 0;
+
+            if (!empty($oLayer->aFields['service_key']))
+                $tmp['key'] = $oLayer->aFields['service_key'];
+
+            $tmp['visible'] = $oLayer->aFields['layer_visible'];
+
+            if (!empty($oLayer->aFields['layer_opacity']))
+                $tmp['opacity'] = $oLayer->aFields['layer_opacity'] / 100;
+
+            if (!empty($oLayer->aFields['events']))
+                $tmp['events'] = $oLayer->aFields['events'];
+
+            if (!empty($oLayer->aFields['is_dynamic']))
+                $tmp['is_dynamic'] = $oLayer->aFields['is_dynamic'];
+            else
+                $tmp['is_dynamic'] = false;
+
+            if (!empty($oLayer->aFields['is_bo_filtered']))
+                $tmp['is_bo_filtered'] = $oLayer->aFields['is_bo_filtered'];
+            else
+                $tmp['is_bo_filtered'] = false;
+
+            if (!empty($oLayer->aFields['is_queryable_getfeatureinfo']))
+                $tmp['is_queryable_getfeatureinfo'] = $oLayer->aFields['is_queryable_getfeatureinfo'];
+            else
+                $tmp['is_queryable_getfeatureinfo'] = false;
+
+            if (!empty($oLayer->aFields['is_filtered']) && !empty($oLayer->aFields['filter_form']))
+                $tmp['is_filtered'] = $oLayer->aFields['is_filtered'];
+            else
+                $tmp['is_filtered'] = false;
+
+            if (!empty($oLayer->aFields['filter_form']))
+                $tmp['filter_form'] = $oLayer->aFields['filter_form'];
+
+            if (!empty($oLayer->aFields['filter_form_embedjs']))
+                $tmp['filter_form_embedjs'] = $oLayer->aFields['filter_form_embedjs'];
+
+            if (!empty($oLayer->aFields['matrix_set']))
+                $tmp['matrixSet'] = $oLayer->aFields['matrix_set'];
+
+            if (!empty($oLayer->aFields['layer_style']))
+                $tmp['style'] = $oLayer->aFields['layer_style'];
+
+            if (!empty($oLayer->aFields['layer_format']))
+                $tmp['format'] = $oLayer->aFields['layer_format'];
+
+            // Problèmes en cas de rest
+            if (!empty($oLayer->aFields['service_type_type']))
+                $tmp['requestEncoding'] = $oLayer->aFields['service_type_type'];
+
+            if (!empty($oLayer->aFields['layer_options']))
+                $tmp['layer_options'] = $oLayer->aFields['layer_options'];
+
+            if (!empty($oLayer->aFields['service_options']))
+                $tmp['service_options'] = $oLayer->aFields['service_options'];
+
+            if (!empty($oLayer->aFields['service_login']))
+                $tmp['service_login'] = $oLayer->aFields['service_login'];
+
+            if (!empty($oLayer->aFields['service_password']))
+                $tmp['service_password'] = $oLayer->aFields['service_password'];
+
+            if (!empty($oLayer->aFields['service_type_version']))
+                $tmp['version'] = $oLayer->aFields['service_type_version'];
+
+            if ($oLayer->aFields['service_type_id'] == 'imagewms') {
+                $tmp['ratio'] = 1;
+            }
+
+            if ($oLayer->aFields['service_type_id'] == 'tilewms' || $oLayer->aFields['service_type_id'] == 'imagewms') {
+                if (!empty($oLayer->aFields['layer_list']))
+                    $tmp['params']['LAYERS'] = $oLayer->aFields['layer_list'];
+                if (!empty($oLayer->aFields['service_type_version']))
+                    $tmp['params']['VERSION'] = $oLayer->aFields['service_type_version'];
+            } else if ($oLayer->aFields['service_type_id'] == 'bing') {
+                $tmp['imagerySet'] = $oLayer->aFields['service_imagery'];
+                $tmp['culture'] = $oLayer->aFields['service_lang'];
+            } else {
+                if (!empty($oLayer->aFields['layer_list']))
+                    $tmp['layer'] = $oLayer->aFields['layer_list'];
+            }
+
+            // Définit si le calque est interrogeable en consultation
+            if (!empty($oLayer->aFields['business_objects'])) {
+                // selection_buffer par défaut
+                for ($i = 0; $i < count($oLayer->aFields['business_objects']); $i++) {
+                    if (!isset($oLayer->aFields['business_objects'][$i]['selection_buffer'])) {
+                        $oLayer->aFields['business_objects'][$i]['selection_buffer'] = 5;
+                    }
+                }
+                $tmp['bo_queryable'] = true;
+                $tmp['business_objects'] = $oLayer->aFields['business_objects'];
+            } else {
+                $tmp['bo_queryable'] = false;
+            }
+
+            $tmp['layer_id'] = $oLayer->aFields['layer_id'];
+
+            array_push($aThemes[$oLayer->aFields['theme_name']], $tmp);
+            unset($tmp);
+        }
+
+        return $aThemes;
+    }
+
+}
+
+?>
diff --git a/vmap/vas/rest/ws/vmap/MapJSONs.class.inc b/vmap/vas/rest/ws/vmap/MapJSONs.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..d23347e37833350c4b9c3679571806f09babc529
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/MapJSONs.class.inc
@@ -0,0 +1,41 @@
+<?php
+/**
+* \file Maps.class.inc
+* \class Maps
+*
+* \author Armand Bahi <armand.bahi@veremes.com>.
+*
+* \brief This file contains the Maps php class
+*
+* This class defines Rest Api to Vmap Maps
+* 
+*/
+require_once 'Vmap.class.inc';
+require_once 'MapJSON.class.inc';
+require_once 'BusinessObject.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+require_once __DIR__ . '/../../class/vmlib/BdDataAccess.inc';
+
+class MapJSONs extends Vmap {
+    
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+    }
+    /**
+     * get Maps
+     * @return  Maps
+     */
+    function GET() {
+        $aReturn = $this->genericGet($this->aProperties['schema_vmap'], 'v_map', 'map_id');
+        return $aReturn['sMessage'];
+    }
+}
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/MapLayer.class.inc b/vmap/vas/rest/ws/vmap/MapLayer.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..c27f9d001d93078e26118041839be2028087eda6
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/MapLayer.class.inc
@@ -0,0 +1,57 @@
+<?php
+
+require_once 'Vmap.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+
+/**
+ * \file MapLayer.class.inc
+ * \class MapLayer
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * \brief This file contains the MapLayer php class
+ *
+ * This class defines operation for one MapLayer
+ * 
+ */
+class MapLayer extends Vmap {
+
+    public $oError;
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+		$this->aSelectedFields = Array("layer_id", "name", "theme_name", "layer_visible", "map_id", "layer_opacity", "layer_index");
+    }
+
+    /**
+     * get informations about MapLayer
+     */
+    function GET() {
+        require $this->sRessourcesFile;
+        $this->aFields = $this->getFields($this->aProperties['schema_vmap'], 'v_map_layer', 'map_id');
+    }
+
+    /**
+     * delete a map
+     */
+    function DELETE(){
+        /*
+        $this->oConnection->oBd->delete($this->aProperties['schema_vmap'], 'v_map_layer', 'map_id', $this->aValues['my_vitis_id'], 'integer');
+        if ($this->oConnection->oBd->enErreur()) {
+                $this->oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+        } else {
+                $this->aFields[map_id] = $this->aValues['my_vitis_id'];
+        }
+        */
+    }
+}
+
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/MapLayers.class.inc b/vmap/vas/rest/ws/vmap/MapLayers.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..1ce7decaab4818364c969a8a8832f86eb898515d
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/MapLayers.class.inc
@@ -0,0 +1,448 @@
+<?php
+
+/**
+ * \file MapLayers.class.inc
+ * \class MapLayers
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * \brief This file contains the MapLayers php class
+ *
+ * This class defines Rest Api to Vmap MapLayers
+ * 
+ */
+require_once 'Vmap.class.inc';
+require_once 'MapLayer.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+require_once __DIR__ . '/../../class/vmlib/BdDataAccess.inc';
+
+class MapLayers extends Vmap {
+    /**
+     * @SWG\Definition(
+     *   definition="/maplayers",
+     *   allOf={
+     *     @SWG\Schema(ref="#/definitions/maplayers")
+     *   }
+     * )
+     * * @SWG\Tag(
+     *   name="MapLayers",
+     *   description=""
+     * )
+     */
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("layer_id", "name", "theme_name", "layer_visible", "map_id", "layer_opacity", "layer_index");
+    }
+
+    /**
+     * @SWG\Get(path="/mapLayers",
+     *   tags={"MapLayers"},
+     *   summary="Get map layers",
+     *   description="Request to get map layers",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="order_by",
+     *     in="query",
+     *     description="list of ordering fields",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="sort_order",
+     *     in="query",
+     *     description="sort order",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="limit",
+     *     in="query",
+     *     description="number of element",
+     *     required=false,
+     *     type="integer"
+     *   ),
+     * @SWG\Parameter(
+     *     name="offset",
+     *     in="query",
+     *     description="index of first element",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="attributs",
+     *     in="query",
+     *     description="list of attributs",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="filter",
+     *     in="query",
+     *     description="filter results",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="distinct",
+     *     in="query",
+     *     description="delete duplicates",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Porperties Response",
+     *         @SWG\Schema(ref="#/definitions/maplayers")
+     *     )
+     *  )
+     */
+
+    /**
+     * get MapLayers
+     * @return  MapLayers
+     */
+    function GET() {
+        $aReturn = $this->genericGet($this->aProperties['schema_vmap'], 'v_map_layer', 'map_id');
+        return $aReturn['sMessage'];
+    }
+
+    /**
+     * @SWG\Put(path="/maplayers/{map_id}",
+     *   tags={"MapLayers"},
+     *   summary="Update map layers",
+     *   description="Request to update the layers of a map",
+     *   operationId="PUT",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="map_id",
+     *     in="path",
+     *     description="Id of the map",
+     *     required=true,
+     *     type="integer"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="map_layers",
+     *     in="query",
+     *     description="Layers of the map",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Properties Response",
+     *         @SWG\Schema(ref="#/definitions/maplayers")
+     *     ),
+     * 
+     *  )
+     */
+    /**
+     * @SWG\Put(path="/maplayers/{map_id}/visibility",
+     *   tags={"MapLayers"},
+     *   summary="Update visibility of map layers",
+     *   description="Request to update the visibility of the layers of a map",
+     *   operationId="PUT",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="map_id",
+     *     in="path",
+     *     description="Id of the map",
+     *     required=true,
+     *     type="integer"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="map_layers",
+     *     in="query",
+     *     description="Layers of the map",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="visibility",
+     *     in="query",
+     *     description="Visibility of the layers",
+     *     required=true,
+     *     type="boolean"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Properties Response",
+     *         @SWG\Schema(ref="#/definitions/maplayers")
+     *     ),
+     * 
+     *  )
+     */
+    /**
+     * @SWG\Put(path="/maplayers/{map_id}/sorting",
+     *   tags={"MapLayers"},
+     *   summary="Sort map layers",
+     *   description="Request to sort the layers of a map",
+     *   operationId="PUT",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="map_id",
+     *     in="path",
+     *     description="Id of the map",
+     *     required=true,
+     *     type="integer"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="map_layers",
+     *     in="query",
+     *     description="Layers of the map",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Properties Response",
+     *         @SWG\Schema(ref="#/definitions/maplayers")
+     *     ),
+     *  )
+     */
+    /**
+     * @SWG\Put(path="/maplayers/{map_id}/opacity",
+     *   tags={"MapLayers"},
+     *   summary="Set opacity of a map layer",
+     *   description="Request to set the opacity of a map layer",
+     *   operationId="PUT",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="map_id",
+     *     in="path",
+     *     description="Id of the map",
+     *     required=true,
+     *     type="integer"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="layer_id",
+     *     in="query",
+     *     description="Layer of the map",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="layer_opacity",
+     *     in="query",
+     *     description="Opacity of the layer",
+     *     required=true,
+     *     type="integer"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Properties Response",
+     *         @SWG\Schema(ref="#/definitions/maplayers")
+     *     ),
+     *  )
+     */
+
+    /**
+     * modify map
+     * @return array containing the status and the message
+     */
+    function PUT() {
+        require $this->sRessourcesFile;
+        if (!empty($this->aPath[3])) {
+            if ($this->aPath[3] == "visibility") {
+                // Calques dont la définition doit changer ?
+                if (!empty($this->aValues['map_layers'])) {
+                    $sSql = $aSql['updateMapLayersVisibility'];
+                    $aSQLParams = array(
+                        'sSchemaVmap' => array('value' => $this->aProperties['schema_vmap'], 'type' => 'column_name'),
+                        'visibility' => array('value' => $this->aValues['visibility'], 'type' => 'string'),
+                        'map_id' => array('value' => $this->aValues['my_vitis_id'], 'type' => 'number'),
+                        'map_layers' => array('value' => $this->aValues['map_layers'], 'type' => 'group'),
+                    );
+                    $resultat = $this->oConnection->oBd->executeWithParams($sSql, $aSQLParams);
+                    if ($this->oConnection->oBd->enErreur()) {
+                        $this->oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+                        $oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+                        $aXmlRacineAttribute['status'] = 0;
+                        $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+                    } else {
+                        $aXmlRacineAttribute['status'] = 1;
+                        $sMessage = $this->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+                    }
+                }
+            } else if ($this->aPath[3] == "sorting") {
+                if (!empty($this->aValues['map_layers'])) {
+                    $aXmlRacineAttribute['status'] = 1;
+                    $sMessage = $this->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+                    $aLayers = explode('|', $this->aValues['map_layers']);
+                    $i = 1;
+                    foreach ($aLayers as $iLayerId) {
+                        $sSql = $aSql['updateMapLayerIndex'];
+                        $aSQLParams = array(
+                            'sSchemaVmap' => array('value' => $this->aProperties['schema_vmap'], 'type' => 'column_name'),
+                            'index' => array('value' => $i, 'type' => 'number'),
+                            'map_id' => array('value' => $this->aValues["my_vitis_id"], 'type' => 'number'),
+                            'layer_id' => array('value' => $iLayerId, 'type' => 'number')
+                        );
+                        $resultat = $this->oConnection->oBd->executeWithParams($sSql, $aSQLParams);
+                        if ($this->oConnection->oBd->enErreur()) {
+                            $this->oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+                            $oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+                            $aXmlRacineAttribute['status'] = 0;
+                            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+                            break;
+                        }
+                        $i++;
+                    }
+                }
+            } else if ($this->aPath[3] == "opacity") {
+                $aXmlRacineAttribute['status'] = 1;
+                $sMessage = $this->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+                $sSql = $aSql['updateMapLayerOpacity'];
+                $aSQLParams = array(
+                    'sSchemaVmap' => array('value' => $this->aProperties['schema_vmap'], 'type' => 'column_name'),
+                    'map_id' => array('value' => $this->aValues["my_vitis_id"], 'type' => 'number'),
+                    'layer_opacity' => array('value' => $this->aValues['layer_opacity'], 'type' => 'number'),
+                    'layer_id' => array('value' => $this->aValues['layer_id'], 'type' => 'number')
+                );
+                $resultat = $this->oConnection->oBd->executeWithParams($sSql, $aSQLParams);
+                if ($this->oConnection->oBd->enErreur()) {
+                    $this->oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+                    $oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+                    $aXmlRacineAttribute['status'] = 0;
+                    $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+                }
+            }
+        } else {
+            // Calques à rattacher à la carte ?
+            if (!empty($this->aValues['map_layers'])) {
+                $aLayers = explode('|', $this->aValues['map_layers']);
+                foreach ($aLayers as $iLayerId) {
+                    $sSql = $aSql['insertMapLayers'];
+                    $aSQLParams = array(
+                        'sSchemaVmap' => array('value' => $this->aProperties['schema_vmap'], 'type' => 'column_name'),
+                        'map_id' => array('value' => $this->aValues["my_vitis_id"], 'type' => 'number'),
+                        'layer_id' => array('value' => $iLayerId, 'type' => 'number')
+                    );
+                    $resultat = $this->oConnection->oBd->executeWithParams($sSql, $aSQLParams);
+                    if ($this->oConnection->oBd->enErreur()) {
+                        $this->oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+                        $oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+                        $aXmlRacineAttribute['status'] = 0;
+                        $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+                    } else {
+                        $aXmlRacineAttribute['status'] = 1;
+                        $sMessage = $this->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+                    }
+                }
+            }
+        }
+        return $sMessage;
+    }
+
+    /**
+     * @SWG\Delete(path="/maplayers/{map_id}",
+     *   tags={"MapLayers"},
+     *   summary="Delete map layers",
+     *   description="Request to delete layers of a map",
+     *   operationId="DELETE",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="map token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="map_id",
+     *     in="path",
+     *     description="id of the map",
+     *     required=true,
+     *     type="integer",
+     *     format = "int32"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="idList",
+     *     in="query",
+     *     description="id of the map layers",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/maplayers")
+     *     )
+     *  )
+     */
+
+    /**
+     * delete map
+     * @return id of map deleted or error object if a map is not deleted
+     */
+    function DELETE() {
+        require $this->sRessourcesFile;
+        // Calques à supprimer ?
+        if (!empty($this->aValues['idList'])) {
+            $sSql = $aSql['deleteMapLayers'];
+            $aSQLParams = array(
+                'sSchemaVmap' => array('value' => $this->aProperties['schema_vmap'], 'type' => 'column_name'),
+                'map_id' => array('value' => $this->aValues["my_vitis_id"], 'type' => 'number'),
+                'idList' => array('value' => $this->aValues['idList'], 'type' => 'group')
+            );            
+            $resultat = $this->oConnection->oBd->executeWithParams($sSql, $aSQLParams);
+            if ($this->oConnection->oBd->enErreur()) {
+                $this->oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+                $oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+                $aXmlRacineAttribute['status'] = 0;
+                $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            } else {
+                $aXmlRacineAttribute['status'] = 1;
+                $sMessage = $this->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            }
+        }
+        return $sMessage;
+    }
+
+}
+
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/MapTheme.class.inc b/vmap/vas/rest/ws/vmap/MapTheme.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..84b46b03ae15dfb56ec5d2c15ed9f4aa7177fe88
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/MapTheme.class.inc
@@ -0,0 +1,84 @@
+<?php
+
+require_once 'Vmap.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+
+/**
+ * \file MapTheme.class.inc
+ * \class MapTheme
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * \brief This file contains the MapTheme php class
+ *
+ * This class defines operation for one MapTheme
+ * 
+ */
+class MapTheme extends Vmap {
+
+    public $oError;
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("maptheme_id", "name", "description");
+    }
+
+    /**
+     * @SWG\Get(path="/mapthemes/{maptheme_id}", 
+     *   tags={"MapThemes"},
+     *   summary="Get MapTheme",
+     *   description="Request to get MapTheme by id",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="maptheme_id",
+     *     in="path",
+     *     description="",
+     *     required=true,
+     *     type="integer"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/mapthemes")
+     *     )
+     *  )
+     */
+
+    /**
+     * get informations about mapthemes
+     */
+    function GET() {
+        require $this->sRessourcesFile;
+        $this->aFields = $this->getFields($this->aProperties['schema_vmap'], 'maptheme', 'maptheme_id');
+    }
+    
+    /**
+     * delete a maptheme
+     */
+    function DELETE(){
+        $this->oConnection->oBd->delete($this->aProperties['schema_vmap'], 'maptheme', 'maptheme_id', $this->aValues['my_vitis_id'], 'integer');
+        if ($this->oConnection->oBd->enErreur()) {
+                $this->oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+        } else {
+                $this->aFields['maptheme_id'] = $this->aValues['my_vitis_id'];
+        }
+    }
+}
+
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/MapThemes.class.inc b/vmap/vas/rest/ws/vmap/MapThemes.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..d0d11d77972365a6c7427d5a65a43764a618bdbd
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/MapThemes.class.inc
@@ -0,0 +1,296 @@
+<?php
+
+/**
+ * \file MapThemes.class.inc
+ * \class MapThemes
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * \brief This file contains the MapThemes php class
+ *
+ * This class defines Rest Api to Vmap MapThemes
+ * 
+ */
+require_once 'Vmap.class.inc';
+require_once 'MapTheme.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+require_once __DIR__ . '/../../class/vmlib/BdDataAccess.inc';
+
+class MapThemes extends Vmap {
+    /**
+     * @SWG\Definition(
+     *   definition="/mapthemes",
+     *   allOf={
+     *     @SWG\Schema(ref="#/definitions/mapthemes")
+     *   }
+     * )
+     * * @SWG\Tag(
+     *   name="MapThemes",
+     *   description=""
+     * )
+     */
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("maptheme_id", "name", "description");
+    }
+
+    /**
+     * @SWG\Get(path="/mapthemes",
+     *   tags={"MapThemes"},
+     *   summary="Get MapThemes",
+     *   description="Request to get MapThemes",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="order_by",
+     *     in="query",
+     *     description="list of ordering fields",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="sort_order",
+     *     in="query",
+     *     description="sort order",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="limit",
+     *     in="query",
+     *     description="number of element",
+     *     required=false,
+     *     type="integer"
+     *   ),
+     * @SWG\Parameter(
+     *     name="offset",
+     *     in="query",
+     *     description="index of first element",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="attributs",
+     *     in="query",
+     *     description="list of attributs",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="filter",
+     *     in="query",
+     *     description="filter results",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="distinct",
+     *     in="query",
+     *     description="delete duplicates",
+     *     required=false,
+     *     type="boolean"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/mapthemes")
+     *     )
+     *  )
+     */
+
+    /**
+     * get MapThemes
+     * @return the array of objects
+     */
+    function GET() {
+        $aReturn = $this->genericGet($this->aProperties['schema_vmap'], 'maptheme', 'maptheme_id');
+        return $aReturn['sMessage'];
+    }
+
+    /**
+     * @SWG\Post(path="/mapthemes",
+     *   tags={"MapThemes"},
+     *   summary="Add maptheme",
+     *   description="Request to add a maptheme",
+     *   operationId="POST",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="formData",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="name",
+     *     in="formData",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="description",
+     *     in="formData",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/mapthemes")
+     *     )
+     *
+     *  )
+     * 
+     * )
+     */
+
+    /**
+     * insert maptheme
+     * @return array containing the status and the message
+     */
+    function POST() {
+        $aReturn = $this->genericPost($this->aProperties['schema_vmap'], 'maptheme', $this->aProperties['schema_vmap'].'.seq_common', 'maptheme_id');           
+        return $aReturn['sMessage'];
+    }
+    
+    /**
+     * @SWG\Put(path="/mapthemes/{maptheme_id}",
+     *   tags={"MapThemes"},
+     *   summary="Update MapTheme",
+     *   description="Request to update maptheme",
+     *   operationId="PUT",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="maptheme_id",
+     *     in="path",
+     *     description="user id",
+     *     required=true,
+     *     type="integer"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="name",
+     *     in="query",
+     *     description="maptheme description",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="description",
+     *     in="query",
+     *     description="maptheme description",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/mapthemes")
+     *     ),
+     * 
+     *  )
+     */
+
+    /**
+     * modify maptheme
+     * @return array containing the status and the message
+     */
+    function PUT() {        
+        $aReturn = $this->genericPut($this->aProperties['schema_vmap'], 'maptheme', 'maptheme_id');
+        return $aReturn['sMessage'];
+    }
+    
+    /**
+     * @SWG\Delete(path="/mapthemes/",
+     *   tags={"MapThemes"},
+     *   summary="delete MapTheme",
+     *   description="Request to delete MapTheme",
+     *   operationId="DELETE",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="idList",
+     *     in="query",
+     *     description="id of the mapthemes",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/mapthemes")
+     *     )
+     *  )
+     */
+    /**
+     * @SWG\Delete(path="/mapthemes/{maptheme_id}",
+     *   tags={"MapThemes"},
+     *   summary="delete MapTheme",
+     *   description="Request to delete MapTheme",
+     *   operationId="DELETE",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="maptheme_id",
+     *     in="path",
+     *     description="id of the maptheme",
+     *     required=true,
+     *     type="integer",
+     *     format = "int32"
+     *   ),
+     * @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/mapthemes")
+     *     )
+     *  )
+     */
+    
+    /**
+     * delete maptheme
+     * @return id of maptheme deleted or error object if a maptheme is not deleted
+     */
+    function DELETE() {
+        $aReturn = $this->genericDelete($this->aProperties['schema_vmap'], 'maptheme', 'maptheme_id');
+        return $aReturn['sMessage'];
+    }
+
+}
+
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/Maps.class.inc b/vmap/vas/rest/ws/vmap/Maps.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..39b73ee53147468bf41a9c613dc271cc7aca9b45
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/Maps.class.inc
@@ -0,0 +1,495 @@
+<?php
+
+/**
+ * \file Maps.class.inc
+ * \class Maps
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * \brief This file contains the Maps php class
+ *
+ * This class defines Rest Api to Vmap Maps
+ * 
+ */
+require_once 'Vmap.class.inc';
+require_once 'Map.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+require_once __DIR__ . '/../../class/vmlib/BdDataAccess.inc';
+
+class Maps extends Vmap {
+    /**
+     * @SWG\Definition(
+     *   definition="/maps",
+     *   allOf={
+     *     @SWG\Schema(ref="#/definitions/maps")
+     *   }
+     * )
+     * * @SWG\Tag(
+     *   name="Maps",
+     *   description=""
+     * )
+     */
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("map_id", "crs_id", "name", "description", "crs_name", "extent", "catalog_index", "thumbnail", "theme_name", "theme_description", "maptheme_id", "groups");
+    }
+
+    /**
+     * @SWG\Get(path="/maps",
+     *   tags={"Maps"},
+     *   summary="Get Maps",
+     *   description="Request to get Maps",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="order_by",
+     *     in="query",
+     *     description="list of ordering fields",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="sort_order",
+     *     in="query",
+     *     description="sort order",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="limit",
+     *     in="query",
+     *     description="number of element",
+     *     required=false,
+     *     type="integer"
+     *   ),
+     * @SWG\Parameter(
+     *     name="offset",
+     *     in="query",
+     *     description="index of first element",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="attributs",
+     *     in="query",
+     *     description="list of attributs",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="filter",
+     *     in="query",
+     *     description="filter results",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="distinct",
+     *     in="query",
+     *     description="delete duplicates",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/maps")
+     *     )
+     *  )
+     */
+
+    /**
+     * get Maps
+     * @return  Maps
+     */
+    function GET() {
+        $aReturn = $this->genericGet($this->aProperties['schema_vmap'], 'v_map', 'map_id', false, 'vmap_admin_map_vmap_admin_map');
+        return $aReturn['sMessage'];
+    }
+
+    /**
+     * @SWG\Post(path="/maps",
+     *   tags={"Maps"},
+     *   summary="Add map",
+     *   description="Request to add a map",
+     *   operationId="POST",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="formData",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="name",
+     *     in="formData",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="extent",
+     *     in="formData",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="crs_id",
+     *     in="formData",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="description",
+     *     in="formData",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="catalog_index",
+     *     in="formData",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="thumbnail",
+     *     in="formData",
+     *     description="Thumbnail of the map",
+     *     required=false,
+     *     type="file"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/maps")
+     *     )
+     *  )
+     * )
+     */
+
+    /**
+     * insert map
+     * @return array containing the status and the message
+     */
+    function POST() {
+        require $this->sRessourcesFile;
+
+        // Vignette à uploader ?
+        if (!empty($_FILES['thumbnail'])) {
+            // la colonne thumbnail vaudra le nom du fichier
+            $this->aValues["thumbnail"] = $_FILES['thumbnail']["name"];
+        }
+
+        // Redimmensionnement de l'image.
+        if (!empty($this->aValues['thumbnail_width']) && !empty($this->aValues['thumbnail_height'])) {
+            // Renomme l'image en jpg
+            $aPointsArray = explode('.', $this->aValues["thumbnail"]);
+            $aPointsArray[count($aPointsArray) - 1] = 'jpg';
+            $this->aValues["thumbnail"] = join('.', $aPointsArray);
+        }
+
+        // Création de la carte.
+        $aReturn = $this->genericPost($this->aProperties['schema_vmap'], 'map', $this->aProperties['schema_vmap'] . '.seq_common', 'map_id');
+
+        // Vignette à uploader ?
+        if (!empty($_FILES['thumbnail'])) {
+            $sImageDir = $this->aProperties['ws_data_dir'] . '/vitis/vmap_admin_map_vmap_admin_map/documents/' . $this->aValues["my_vitis_id"] . '/thumbnail/' . $_FILES['thumbnail']["name"];
+
+            // Crée les répertoires si ils n'existent pas
+            $sDirPath = $this->createElementFilesFolder('vmap_admin_map_vmap_admin_map', $this->aValues["my_vitis_id"]);
+            $sDirColumnPath = $sDirPath . '/thumbnail';
+            if (!is_dir($sDirColumnPath)) {
+                mkdir($sDirColumnPath, 0777, true);
+            }
+
+            $sErrorMessage = uploadFile("thumbnail", "", $sImageDir, $_FILES['thumbnail']['size'] + 1);
+
+            if ($sErrorMessage != "") {
+                writeToErrorLog($sErrorMessage);
+            } else {
+                // Redimmensionnement de l'image.
+                if (!empty($this->aValues['thumbnail_width']) && !empty($this->aValues['thumbnail_height'])) {
+                    $this->pictureResampler($sImageDir, $this->aValues['thumbnail_width'], $this->aValues['thumbnail_height']);
+                }
+            }
+        }
+
+        // Si création OK -> maj des groupes rattachés à la carte.
+        if ($aReturn['sStatus'] == 1) {
+            $aXmlRacineAttribute['status'] = 1;
+            $sMessage = $this->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            $oMap = new Map($this->aPath, $this->aValues, $this->aProperties, $this->oConnection);
+            $oMap->GET();
+            // Groupes à rattacher à la carte ?
+            if (!empty($this->aValues['groups'])) {
+                $aGroups = explode('|', $this->aValues['groups']);
+                foreach ($aGroups as $iGroupId) {
+                    $sSql = $aSql['insertMapGroups'];
+                    $aSQLParams = array(
+                        'sSchemaVmap' => array('value' => $this->aProperties['schema_vmap'], 'type' => 'column_name'),
+                        'map_id' => array('value' => $this->aValues["my_vitis_id"], 'type' => 'number'),
+                        'group_id' => array('value' => $iGroupId, 'type' => 'number')
+                    );
+                    $resultat = $this->oConnection->oBd->executeWithParams($sSql, $aSQLParams);
+                    if ($this->oConnection->oBd->enErreur()) {
+                        $this->oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+                        $oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+                        $aXmlRacineAttribute['status'] = 0;
+                        $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+                    }
+                }
+            }
+        } else {
+            $sMessage = $aReturn['sMessage'];
+        }
+        return $sMessage;
+    }
+
+    /**
+     * @SWG\Put(path="/maps/{map_id}",
+     *   tags={"Maps"},
+     *   summary="Update Map",
+     *   description="Request to update map",
+     *   operationId="PUT",
+     *   produces={"application/xml", "application/json"},
+     *   consumes= { "multipart/form-data"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="map_id",
+     *     in="path",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="extent_id",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="crs_id",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="name",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="description",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="catalog_index",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="id_theme",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="thumbnail",
+     *     in="formData",
+     *     description="Thumbnail of the map",
+     *     required=false,
+     *     type="file"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/maps")
+     *     ),
+     * 
+     *  )
+     */
+
+    /**
+     * modify map
+     * @return array containing the status and the message
+     */
+    function PUT() {
+        require $this->sRessourcesFile;
+        // Vignette à uploader ?
+        if (!empty($this->aValues["thumbnail_file"])) {
+
+            $sImageDir = $this->aProperties['ws_data_dir'] . '/vitis/vmap_admin_map_vmap_admin_map/documents/' . $this->aValues["my_vitis_id"] . '/thumbnail/' . $this->aValues["thumbnail_name"];
+
+            // Crée les répertoires si ils n'existent pas
+            $sDirPath = $this->createElementFilesFolder('vmap_admin_map_vmap_admin_map', $this->aValues["my_vitis_id"]);
+            $sDirColumnPath = $sDirPath . '/thumbnail';
+            if (!is_dir($sDirColumnPath)) {
+                mkdir($sDirColumnPath, 0777, true);
+            }
+
+            // la colonne thumbnail vaudra le nom du fichier
+            $this->aValues["thumbnail"] = $this->aValues["thumbnail_name"];
+            $fp = fopen($sImageDir, "w");
+            fwrite($fp, $this->aValues["thumbnail_file"]);
+            fclose($fp);
+
+            // Redimmensionnement de l'image.
+            if (!empty($this->aValues['thumbnail_width']) && !empty($this->aValues['thumbnail_height'])) {
+                $this->pictureResampler($sImageDir, $this->aValues['thumbnail_width'], $this->aValues['thumbnail_height']);
+                // Renomme l'image en jpg
+                $aPointsArray = explode('.', $this->aValues["thumbnail"]);
+                $aPointsArray[count($aPointsArray) - 1] = 'jpg';
+                $this->aValues["thumbnail"] = join('.', $aPointsArray);
+            }
+        }
+        // Mise à jour.
+        $aReturn = $this->genericPut($this->aProperties['schema_vmap'], 'map', 'map_id');
+        // Si mise à jour OK -> maj des groupes rattachés à la carte.
+        if ($aReturn['sStatus'] == 1) {
+            $aXmlRacineAttribute['status'] = 1;
+            $sMessage = $this->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            // Supprime les groupes rattachés à la carte.
+            $this->oConnection->oBd->delete($this->aProperties['schema_vmap'], 'map_group', 'map_id', $this->aValues["my_vitis_id"]);
+            // Groupes à rattacher à la carte ?
+            if (!empty($this->aValues['groups'])) {
+                $aGroups = explode('|', $this->aValues['groups']);
+                foreach ($aGroups as $iGroupId) {
+                    $sSql = $aSql['insertMapGroups'];
+                    $aSQLParams = array(
+                        'sSchemaVmap' => array('value' => $this->aProperties['schema_vmap'], 'type' => 'column_name'),
+                        'map_id' => array('value' => $this->aValues["my_vitis_id"], 'type' => 'number'),
+                        'group_id' => array('value' => $iGroupId, 'type' => 'number')
+                    );
+                    $resultat = $this->oConnection->oBd->executeWithParams($sSql, $aSQLParams);
+                    if ($this->oConnection->oBd->enErreur()) {
+                        $this->oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+                        $oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+                        $aXmlRacineAttribute['status'] = 0;
+                        $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+                    }
+                }
+            }
+        } else {
+            $sMessage = $aReturn['sMessage'];
+        }
+        return $sMessage;
+    }
+
+    /**
+     * @SWG\Delete(path="/maps/",
+     *   tags={"Maps"},
+     *   summary="delete Map",
+     *   description="Request to delete Map",
+     *   operationId="DELETE",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="map token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="idList",
+     *     in="query",
+     *     description="id of the maps",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/maps")
+     *     )
+     *  )
+     */
+    /**
+     * @SWG\Delete(path="/maps/{map_id}",
+     *   tags={"Maps"},
+     *   summary="delete Map",
+     *   description="Request to delete Map",
+     *   operationId="DELETE",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="map token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="map_id",
+     *     in="path",
+     *     description="id of the map",
+     *     required=true,
+     *     type="integer",
+     *     format = "int32"
+     *   ),
+     * @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/maps")
+     *     )
+     *  )
+     */
+
+    /**
+     * delete map
+     * @return id of map deleted or error object if a map is not deleted
+     */
+    function DELETE() {
+        if (!empty($this->aValues['idList'])) {
+            $aIdList = explode("|", $this->aValues['idList']);
+        }
+        if (!empty($this->aPath['2'])) {
+            $aIdList = array($this->aPath['2']);
+        }
+
+        $aReturn = $this->genericDelete($this->aProperties['schema_vmap'], 'map', 'map_id');
+
+        // Supprime les fichiers uploadés
+        $this->deleteElementsDocuments('vmap_admin_map_vmap_admin_map', $aIdList);
+
+        return $aReturn['sMessage'];
+    }
+
+}
+
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/Module.class.inc b/vmap/vas/rest/ws/vmap/Module.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..8ac78dc4f47977cba47a1eb715e20e917d2221c9
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/Module.class.inc
@@ -0,0 +1,73 @@
+<?php
+
+require_once 'Vmap.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+
+/**
+ * \file Module.class.inc
+ * \class Module
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * \brief This file contains the Module php class
+ *
+ * This class defines operation for one Module
+ * 
+ */
+class Module extends Vmap {
+
+    public $oError;
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("module_id", "label", "description", "rolname", "rolname_list");
+    }
+
+    /**
+     * @SWG\Get(path="/modules/{module_id}", 
+     *   tags={"Modules"},
+     *   summary="Get Module",
+     *   description="Request to get Module by id",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="module_id",
+     *     in="path",
+     *     description="module id",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/modules")
+     *     )
+     *  )
+     */
+
+    /**
+     * get informations about Module
+     */
+    function GET() {
+        require $this->sRessourcesFile;
+        $this->aFields = $this->getFields($this->aProperties['schema_vmap'], 'module', 'module_id');
+    }
+
+}
+
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/Modules.class.inc b/vmap/vas/rest/ws/vmap/Modules.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..f8a91b70955bbd7c8a630fe22c550303b1dea413
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/Modules.class.inc
@@ -0,0 +1,177 @@
+<?php
+/**
+* \file Modules.class.inc
+* \class Modules
+*
+* \author Armand Bahi <armand.bahi@veremes.com>.
+*
+* \brief This file contains the Modules php class
+*
+* This class defines Rest Api to Vmap Modules
+* 
+*/
+require_once 'Vmap.class.inc';
+require_once 'Module.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+require_once __DIR__ . '/../../class/vmlib/BdDataAccess.inc';
+
+class Modules extends Vmap {
+    
+     /**
+     * @SWG\Definition(
+     *   definition="/modules",
+     *   allOf={
+     *     @SWG\Schema(ref="#/definitions/modules")
+     *   }
+     * )
+     * * @SWG\Tag(
+     *   name="Modules",
+     *   description=""
+     * )
+     */
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+		$this->aSelectedFields = Array("module_id", "label", "description", "rolname", "rolname_list");
+    }
+    /**
+     * @SWG\Get(path="/modules",
+     *   tags={"Modules"},
+     *   summary="Get Modules",
+     *   description="Request to get Modules",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="order_by",
+     *     in="query",
+     *     description="list of ordering fields",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="sort_order",
+     *     in="query",
+     *     description="sort order",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="limit",
+     *     in="query",
+     *     description="number of element",
+     *     required=false,
+     *     type="integer"
+     *   ),
+     * @SWG\Parameter(
+     *     name="offset",
+     *     in="query",
+     *     description="index of first element",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="attributs",
+     *     in="query",
+     *     description="list of attributs",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="filter",
+     *     in="query",
+     *     description="filter results",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="distinct",
+     *     in="query",
+     *     description="delete duplicates",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/modules")
+     *     )
+     *  )
+     */
+    /**
+     * get Modules
+     * @return  Modules
+     */
+    function GET() {
+        $aReturn = $this->genericGet($this->aProperties['schema_vmap'], 'module', 'module_id');
+        return $aReturn['sMessage'];
+    }
+    
+    /**
+     * @SWG\Put(path="/modules/{module_id}",
+     *   tags={"Modules"},
+     *   summary="Update Module",
+     *   description="Request to update module",
+     *   operationId="PUT",
+     *   produces={"application/xml", "application/json"},
+     *   consumes= { "multipart/form-data"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="module_id",
+     *     in="path",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="label",
+     *     in="query",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="description",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/modules")
+     *     ),
+     * 
+     *  )
+     */
+
+    /**
+     * modify module
+     * @return array containing the status and the message
+     */
+    function PUT() {
+        $aReturn = $this->genericPut($this->aProperties['schema_vmap'], 'module', 'module_id');
+        return $aReturn['sMessage'];
+    }
+}
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/Orientation.class.inc b/vmap/vas/rest/ws/vmap/Orientation.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..b88d4206afe9dbf228fa3606ce77c46d65aacf79
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/Orientation.class.inc
@@ -0,0 +1,41 @@
+<?php
+
+require_once 'Vmap.class.inc';
+require_once __DIR__.'/../../class/vitis_lib/Connection.class.inc';
+
+/**
+* \file Orientation.class.inc
+* \class Orientation
+*
+* \author Yoann Perollet <yoann.perollet@veremes.com>.
+*
+*	\brief This file contains the Orientation php class
+*
+* This class defines operation for one Orientation
+* 
+*/
+class Orientation extends Vmap {
+    
+    public $oError;
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array('rt_orientation_id');
+    }
+    
+    /**
+     * get informations about orientation
+     */
+    function GET(){
+        require $this->sRessourcesFile;
+        $this->aFields = $this->getFields($this->aProperties['schema_vmap'], "rt_orientation", "rt_orientation_id");
+    }
+}
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/Orientations.class.inc b/vmap/vas/rest/ws/vmap/Orientations.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..b23539d935fc623dabb1820dfe976bb594c09167
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/Orientations.class.inc
@@ -0,0 +1,125 @@
+<?php
+/**
+* \file Orientations.class.inc
+* \class Orientations
+*
+* \author Yoann Perollet <yoann.perollet@veremes.com>.
+*
+*	\brief This file contains the Orientations php class
+*
+* This class defines Rest Api to Vmap order statutes
+* 
+*/
+require_once 'Vmap.class.inc';
+require_once __DIR__.'/../../class/vitis_lib/Connection.class.inc';
+require_once 'Orientation.class.inc';
+require_once(__DIR__.'/../../class/vmlib/BdDataAccess.inc');
+
+class Orientations extends Vmap {
+    
+     /**
+     * @SWG\Definition(
+     *   definition="/orientations",
+     *   allOf={
+     *     @SWG\Schema(ref="#/definitions/orientations")
+     *   }
+     * )
+     * * @SWG\Tag(
+     *   name="Orientations",
+     *   description="Operations about Orientations"
+     * )
+     */
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array('rt_orientation_id');
+    }
+    
+    /**
+     * @SWG\Get(path="/orientations",
+     *   tags={"Orientations"},
+     *   summary="Get Orientations",
+     *   description="Request to get Orientations",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="order_by",
+     *     in="query",
+     *     description="list of ordering fields",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="sort_order",
+     *     in="query",
+     *     description="sort order",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="limit",
+     *     in="query",
+     *     description="number of element",
+     *     required=false,
+     *     type="integer"
+     *   ),
+     * @SWG\Parameter(
+     *     name="offset",
+     *     in="query",
+     *     description="index of first element",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="attributs",
+     *     in="query",
+     *     description="list of attributs",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="filter",
+     *     in="query",
+     *     description="filter results",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="distinct",
+     *     in="query",
+     *     description="delete duplicates",
+     *     required=false,
+     *     type="boolean"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/orientations")
+     *     )
+     *  )
+     */
+    
+    /**
+     * get Orientations
+     * @return  Orientations
+     */
+    function GET() {
+        $aReturn = $this->genericGet($this->aProperties['schema_vmap'], "rt_orientation", "rt_orientation_id");
+        return $aReturn['sMessage'];
+    }
+}
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/OutputFormat.class.inc b/vmap/vas/rest/ws/vmap/OutputFormat.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..552d0bfab17b519acfeaa93a5efa36f9f3b3f683
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/OutputFormat.class.inc
@@ -0,0 +1,41 @@
+<?php
+
+require_once 'Vmap.class.inc';
+require_once __DIR__.'/../../class/vitis_lib/Connection.class.inc';
+
+/**
+* \file OutputFormat.class.inc
+* \class OutputFormat
+*
+* \author Yoann Perollet <yoann.perollet@veremes.com>.
+*
+*	\brief This file contains the OutputFormat php class
+*
+* This class defines operation for one OutputFormat
+* 
+*/
+class OutputFormat extends Vmap {
+    
+    public $oError;
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array('outputformats_id');
+    }
+    
+    /**
+     * get inoutputformations about outputformat
+     */
+    function GET(){
+        require $this->sRessourcesFile;
+        $this->aFields = $this->getFields($this->aProperties['schema_vmap'], "rt_outputformats", "outputformats_id");
+    }
+}
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/OutputFormats.class.inc b/vmap/vas/rest/ws/vmap/OutputFormats.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..ab45f1e2e3bfa7831dc208b253b82d398f02ddde
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/OutputFormats.class.inc
@@ -0,0 +1,125 @@
+<?php
+/**
+* \file OutputFormats.class.inc
+* \class OutputFormats
+*
+* \author Yoann Perollet <yoann.perollet@veremes.com>.
+*
+*	\brief This file contains the OutputFormats php class
+*
+* This class defines Rest Api to Vmap order statutes
+* 
+*/
+require_once 'Vmap.class.inc';
+require_once __DIR__.'/../../class/vitis_lib/Connection.class.inc';
+require_once 'OutputFormat.class.inc';
+require_once(__DIR__.'/../../class/vmlib/BdDataAccess.inc');
+
+class OutputFormats extends Vmap {
+    
+     /**
+     * @SWG\Definition(
+     *   definition="/outputformats",
+     *   allOf={
+     *     @SWG\Schema(ref="#/definitions/outputformats")
+     *   }
+     * )
+     * * @SWG\Tag(
+     *   name="OutputFormats",
+     *   description="Operations about OutputFormats"
+     * )
+     */
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array('outputformats_id');
+    }
+    
+    /**
+     * @SWG\Get(path="/outputformats",
+     *   tags={"OutputFormats"},
+     *   summary="Get OutputFormats",
+     *   description="Request to get OutputFormats",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="order_by",
+     *     in="query",
+     *     description="list of ordering fields",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="sort_order",
+     *     in="query",
+     *     description="sort order",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="limit",
+     *     in="query",
+     *     description="number of element",
+     *     required=false,
+     *     type="integer"
+     *   ),
+     * @SWG\Parameter(
+     *     name="offset",
+     *     in="query",
+     *     description="index of first element",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="attributs",
+     *     in="query",
+     *     description="list of attributs",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="filter",
+     *     in="query",
+     *     description="filter results",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="distinct",
+     *     in="query",
+     *     description="delete duplicates",
+     *     required=false,
+     *     type="boolean"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/outputformats")
+     *     )
+     *  )
+     */
+    
+    /**
+     * get OutputFormats
+     * @return  OutputFormats
+     */
+    function GET() {
+        $aReturn = $this->genericGet($this->aProperties['schema_vmap'], "rt_outputformats", "outputformats_id");
+        return $aReturn['sMessage'];
+    }
+}
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/PrintMapServices.class.inc b/vmap/vas/rest/ws/vmap/PrintMapServices.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..cf8ffd1181cc69d7148abf5b7b7eb98249c980ed
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/PrintMapServices.class.inc
@@ -0,0 +1,346 @@
+<?php
+
+require_once 'Map.class.inc';
+require_once 'PrintServices.class.inc';
+require_once __DIR__ . '/../vitis/Vitis.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+require_once __DIR__ . '/../../class/vmlib/BdDataAccess.inc';
+
+/**
+ * \file printmapservices.class.inc
+ * \class PrintMapServices
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ *  \brief This file contains the PrintMapServices php class
+ *
+ * This class defines the rest api for printmapservices
+ * 
+ */
+class PrintMapServices extends PrintServices {
+    /**
+     * @SWG\Definition(
+     *   definition="/printmapservices",
+     *   allOf={
+     *     @SWG\Schema(ref="#/definitions/printmapservices")
+     *   }
+     * )
+     * * @SWG\Tag(
+     *   name="printmapservices",
+     *   description="Operations about printmapservices"
+     * )
+     */
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        $this->aValues = $aValues;
+        $this->aPath = $aPath;
+        $this->aProperties = $properties;
+//        $this->oConnection = new Connection($this->aValues, $this->aProperties);
+    }
+
+    /**
+     * @SWG\Post(path="/printmapservices",
+     *   tags={"PrintServices"},
+     *   summary="Creates a map print",
+     *   description="Creates a map print",
+     *   operationId="POST",
+     *   produces={"application/json"},
+     * @SWG\Parameter(
+     *     name="token",
+     *     in="formData",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="map_id",
+     *     in="formData",
+     *     description="map to print out, not required if passed map_json",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="map_json",
+     *     in="formData",
+     *     description="map to print out",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="image_size",
+     *     in="formData",
+     *     description="image resolution splited by |",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="resolution_coeff",
+     *     in="formData",
+     *     description="image size multiplicator",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="extent",
+     *     in="formData",
+     *     description="map extent, not required if passed features splited by |",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="features",
+     *     in="formData",
+     *     description="Array of EWKT features to add splited by |",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="features_zoom",
+     *     in="formData",
+     *     description="percentage of zooming",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="resolution_coeff",
+     *     in="formData",
+     *     description="size multiplicator",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="quality",
+     *     in="formData",
+     *     description="image quality",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="PrintMapServices Response",
+     *         @SWG\Schema(ref="#/definitions/printmapservices")
+     *     )
+     *  )
+     */
+    function POST() {
+
+        $aReturn = Array();
+
+        // Vérification des valeurs
+        if (empty($this->aValues['map_id']) && empty($this->aValues['map_json'])) {
+            $aReturn['error']['errorMessage'] .= " neither map_id nor map_json defined";
+            return json_encode($aReturn);
+        }
+        if (empty($this->aValues['extent']) && empty($this->aValues['features'])) {
+            $aReturn['error']['errorMessage'] .= " neither extent not features defined";
+            return json_encode($aReturn);
+        }
+        if (empty($this->aValues['image_size'])) {
+            $aReturn['error']['errorMessage'] .= " image_size not defined";
+            return json_encode($aReturn);
+        }
+
+        /**
+         * Files to delete after print
+         */
+        $this->aFilesToDelete = array();
+
+        /**
+         * The image name
+         */
+        $sTimestamp = date("YmdHis", time());
+
+        /**
+         * Map id
+         */
+        $sMapId = $this->aValues['map_id'];
+
+        /**
+         * Map id
+         */
+        $sMapJSON = $this->aValues['map_json'];
+
+        /**
+         * API URL
+         */
+        $RestUrl = $this->aProperties['web_server_name'] . '/' . $this->aProperties['services_alias'];
+
+        /**
+         * Token to use
+         */
+        $sToken = $this->aValues['token'];
+
+        /**
+         * Map extent
+         */
+        $sExtent = $this->aValues['extent'];
+
+        /**
+         * Image size
+         */
+        $sImageSize = $this->aValues['image_size'];
+
+        /**
+         * Map features
+         */
+        $sFeatures = $this->aValues['features'];
+
+        /**
+         * Map features zoom
+         */
+        $sFeaturesZoom = $this->aValues['features_zoom'];
+
+        /**
+         * Map features zoom
+         */
+        $sResolutionCoeff = $this->aValues['resolution_coeff'];
+
+        /**
+         * Image quality
+         */
+        $sQuality = $this->aProperties['print']['quality'];
+
+        /**
+         * Path to the PhantomJS .exe
+         */
+        $sPhantomjsPath = $this->aProperties['phantomjs_root_path'];
+
+        /**
+         * Path to the .js
+         */
+        $sProjectPath = $this->aProperties['vas_home'] . '/util/printserver/server/printmap.js';
+
+        /**
+         * Path to the client
+         */
+        $sPrintClientrUrl = $this->aProperties['web_server_name'] . '/' . $this->aProperties['printserver_alias'] . '/client/map/index.html';
+
+        /**
+         * Path to the output file
+         */
+        $sOutputFile = $this->aProperties['vas_home'] . '/public/vmap/prints/print_map_' . $sTimestamp . '.jpeg';
+
+        /**
+         * The image URL
+         */
+        $sImageUrl = $this->aProperties['web_server_name'] . '/' . $this->aProperties['public_alias'] . '/vmap/prints/print_map_' . $sTimestamp . '.jpeg';
+
+        // Vérifie que la carte existe bien
+        if (!empty($sMapId)) {
+            if (!$this->checkMapId($sMapId)) {
+                $oError = new VitisError(0, 'map_id (' . $sMapId . ') not founded');
+                return json_encode($oError->aFields);
+            }
+        }
+
+        // Change la taille de l'image en fonction de la résolution
+        if (isset($this->aValues['resolution_coeff'])) {
+            $aImageSize = explode('|', $sImageSize);
+            $aImageSize[0] = $aImageSize[0] * $this->aValues['resolution_coeff'];
+            $aImageSize[1] = $aImageSize[1] * $this->aValues['resolution_coeff'];
+            $sImageSize = implode('|', $aImageSize);
+        }
+
+        // Écrit les paramètres gros dans des fichiers
+        if (is_dir($this->aProperties['vas_home'])) {
+            if (!is_dir($this->aProperties['vas_home'] . '/public')) {
+                mkdir($this->aProperties['vas_home'] . '/public', 0777, true);
+            }
+            if (!is_dir($this->aProperties['vas_home'] . '/public/vmap')) {
+                mkdir($this->aProperties['vas_home'] . '/public/vmap', 0777, true);
+            }
+            if (!is_dir($this->aProperties['vas_home'] . '/public/vmap/prints')) {
+                mkdir($this->aProperties['vas_home'] . '/public/vmap/prints', 0777, true);
+            }
+        }
+        $sMapJSONPath = $this->writeToFile($this->aProperties['vas_home'] . '/public/vmap/prints', 'map_json_' . $sTimestamp, $sMapJSON);
+        $sFeaturesPath = $this->writeToFile($this->aProperties['vas_home'] . '/public/vmap/prints', 'features_' . $sTimestamp, $sFeatures);
+
+        // Arguments de la ligne de commande
+        $aArguments = array($sProjectPath, $sPrintClientrUrl, $RestUrl, $sToken, $sOutputFile, $sMapId, $sMapJSONPath, $sImageSize, $sExtent, $sFeaturesPath, $sFeaturesZoom, $this->aValues['resolution_coeff'], $sQuality);
+
+        // Commande à lancer
+        $sCommand = '"' . $sPhantomjsPath . '" --ignore-ssl-errors=yes --ssl-protocol=any';
+
+        // Ajoute les argumants à a commande
+        for ($i = 0; $i < count($aArguments); $i++) {
+            $sCommand .= ' "' . $aArguments[$i] . '"';
+        }
+
+        // Ferme la session php (pour que phantomJS puisse faire des requetes Ajax avec ce token)
+        session_write_close();
+
+        $aCommand = array();
+        exec($sCommand, $aCommand);
+
+        $sScale = $this->getMapScale($aCommand);
+
+        $aReturn['printmapservices']['image'] = $sImageUrl;
+        $aReturn['printmapservices']['imagePath'] = $sOutputFile;
+        $aReturn['printmapservices']['command'] = $sCommand;
+        $aReturn['printmapservices']['logs'] = $aCommand;
+        $aReturn['printmapservices']['scale'] = $sScale !== null ? $sScale : null;
+        $aReturn['printmapservices']['result'] = $aCommand[count($aCommand) - 1];
+        $aReturn['status'] = $aReturn['printmapservices']['result'] === "Done" ? 1 : 0;
+
+        // Supprime les fichiers générés pendant l'impression
+        $this->deleteFiles($this->aFilesToDelete);
+
+        return json_encode($aReturn);
+    }
+
+    /**
+     * Get the map scale
+     * @param array $aCommand
+     * @return string
+     */
+    function getMapScale($aCommand) {
+
+        $sScale = null;
+
+        for ($i = 0; $i < count($aCommand); $i++) {
+            if (strlen($aCommand[$i]) > 5) {
+                if (substr($aCommand[$i], 0, 5) === 'scale') {
+                    $sScale = substr($aCommand[$i], 6);
+                }
+            }
+        }
+
+        return $sScale;
+    }
+
+    function checkMapId($sMapId) {
+
+        $aPath = array('vmap', 'maps', $sMapId);
+
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => 'application/json',
+            'sEncoding' => 'UTF-8',
+            'sSourceEncoding' => 'UTF-8',
+            'xslstylesheet' => '',
+            'my_vitis_id' => $sMapId,
+            'module' => 'vmap'
+        );
+
+        $oMap = new Map($aPath, $aValues, $this->aProperties);
+        $oMap->GET();
+
+        if (!empty($oMap->aFields['map_id'])) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+}
+
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/PrintParameter.class.inc b/vmap/vas/rest/ws/vmap/PrintParameter.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..654234e7d7e15799b2ff068ba5610eaddbca5a44
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/PrintParameter.class.inc
@@ -0,0 +1,83 @@
+<?php
+
+require_once 'Vmap.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+
+/**
+ * \file PrintParameter.class.inc
+ * \class PrintParameter
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * \brief This file contains the PrintParameter php class
+ *
+ * This class defines operation for one PrintParameter
+ * 
+ */
+class PrintParameter extends Vmap {
+
+    public $oError;
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("printparameter_id", "printtemplate_id", "name", "editable", "label", "placeholder", "defaultvalue", "print_template");
+    }
+
+    /**
+     * @SWG\Get(path="/printparameters/{printparameter_id}", 
+     *   tags={"PrintParameters"},
+     *   summary="Get PrintParameter",
+     *   description="Request to get PrintParameter by id",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="printparameter_id",
+     *     in="path",
+     *     description="printparameter id",
+     *     required=true,
+     *     type="integer"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/printparameters")
+     *     )
+     *  )
+     */
+
+    /**
+     * get informations about PrintParameter
+     */
+    function GET() {
+        $this->aFields = $this->getFields($this->aProperties['schema_vmap'], 'v_print_parameter', 'printparameter_id');
+    }
+    
+    /**
+     * delete a printparameter
+     */
+    function DELETE(){
+        $this->oConnection->oBd->delete($this->aProperties['schema_vmap'], 'printparameter', 'printparameter_id', $this->aValues['my_vitis_id'], 'integer');
+        if ($this->oConnection->oBd->enErreur()) {
+                $this->oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+        } else {
+                $this->aFields['printparameter_id'] = $this->aValues['my_vitis_id'];
+        }
+    }
+}
+
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/PrintParameters.class.inc b/vmap/vas/rest/ws/vmap/PrintParameters.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..def8fceed35524b053d933e09c71e803e400728c
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/PrintParameters.class.inc
@@ -0,0 +1,351 @@
+<?php
+
+/**
+ * \file PrintParameters.class.inc
+ * \class PrintParameters
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * \brief This file contains the PrintParameters php class
+ *
+ * This class defines Rest Api to Vmap PrintParameters
+ * 
+ */
+require_once 'Vmap.class.inc';
+require_once 'PrintParameter.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+require_once __DIR__ . '/../../class/vmlib/BdDataAccess.inc';
+
+class PrintParameters extends Vmap {
+    /**
+     * @SWG\Definition(
+     *   definition="/printparameters",
+     *   allOf={
+     *     @SWG\Schema(ref="#/definitions/printparameters")
+     *   }
+     * )
+     * * @SWG\Tag(
+     *   name="PrintParameters",
+     *   description=""
+     * )
+     */
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("printparameter_id", "printtemplate_id", "name", "editable", "label", "placeholder", "defaultvalue", "print_template");
+    }
+
+    /**
+     * @SWG\Get(path="/printparameters",
+     *   tags={"PrintParameters"},
+     *   summary="Get PrintParameters",
+     *   description="Request to get PrintParameters",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="order_by",
+     *     in="query",
+     *     description="list of ordering fields",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="sort_order",
+     *     in="query",
+     *     description="sort order",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="limit",
+     *     in="query",
+     *     description="number of element",
+     *     required=false,
+     *     type="integer"
+     *   ),
+     * @SWG\Parameter(
+     *     name="offset",
+     *     in="query",
+     *     description="index of first element",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="attributs",
+     *     in="query",
+     *     description="list of attributs",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="filter",
+     *     in="query",
+     *     description="filter results",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="distinct",
+     *     in="query",
+     *     description="delete duplicates",
+     *     required=false,
+     *     type="boolean"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/printparameters")
+     *     )
+     *  )
+     */
+
+    /**
+     * get PrintParameters
+     * @return  PrintParameters
+     */
+    function GET() {
+        $aReturn = $this->genericGet($this->aProperties['schema_vmap'], 'v_print_parameter', 'printparameter_id');
+        return $aReturn['sMessage'];
+    }
+
+    /**
+     * @SWG\Post(path="/printparameters",
+     *   tags={"PrintParameters"},
+     *   summary="Add printparameter",
+     *   description="Request to add a printparameter",
+     *   operationId="POST",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="formData",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="printtemplate_id",
+     *     in="formData",
+     *     description="Print template id",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="name",
+     *     in="formData",
+     *     description="Name",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="editable",
+     *     in="formData",
+     *     description="editable",
+     *     required=false,
+     *     type="boolean"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="label",
+     *     in="formData",
+     *     description="Label",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="placeholder",
+     *     in="formData",
+     *     description="Placeholder",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="defaultvalue",
+     *     in="formData",
+     *     description="Default Value",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/printparameters")
+     *     )
+     *
+     *  )
+     * 
+     * )
+     */
+
+    /**
+     * insert printparameter
+     * @return array containing the status and the message
+     */
+    function POST() {
+        $aReturn = $this->genericPost($this->aProperties['schema_vmap'], 'printparameter', $this->aProperties['schema_vmap'].'.seq_common', 'printparameter_id');
+        return $aReturn['sMessage'];
+    }
+
+    /**
+     * @SWG\Put(path="/printparameters/{printparameter_id}",
+     *   tags={"PrintParameters"},
+     *   summary="Update PrintParameter",
+     *   description="Request to update printparameter",
+     *   operationId="PUT",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="printparameter_id",
+     *     in="path",
+     *     description="Print parameter id",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="printtemplate_id",
+     *     in="query",
+     *     description="Print template id",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="name",
+     *     in="query",
+     *     description="Name",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="editable",
+     *     in="query",
+     *     description="editable",
+     *     required=false,
+     *     type="boolean"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="label",
+     *     in="query",
+     *     description="Label",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="placeholder",
+     *     in="query",
+     *     description="Placeholder",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="defaultvalue",
+     *     in="query",
+     *     description="Default Value",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/printparameters")
+     *     ),
+     * 
+     *  )
+     */
+
+    /**
+     * modify printparameter
+     * @return array containing the status and the message
+     */
+    function PUT() {
+        $aReturn = $this->genericPut($this->aProperties['schema_vmap'], 'printparameter', 'printparameter_id');
+        return $aReturn['sMessage'];
+    }
+
+    /**
+     * @SWG\Delete(path="/printparameters/",
+     *   tags={"PrintParameters"},
+     *   summary="delete PrintParameter",
+     *   description="Request to delete PrintParameter",
+     *   operationId="DELETE",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="printparameter token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="idList",
+     *     in="query",
+     *     description="id of the printparameters",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/printparameters")
+     *     )
+     *  )
+     */
+    /**
+     * @SWG\Delete(path="/printparameters/{printparameter_id}",
+     *   tags={"PrintParameters"},
+     *   summary="delete PrintParameter",
+     *   description="Request to delete PrintParameter",
+     *   operationId="DELETE",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="printparameter token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="printparameter_id",
+     *     in="path",
+     *     description="id of the printparameter",
+     *     required=true,
+     *     type="integer",
+     *     format = "int32"
+     *   ),
+     * @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/printparameters")
+     *     )
+     *  )
+     */
+
+    /**
+     * delete printparameter
+     * @return id of printparameter deleted or error object if a printparameter is not deleted
+     */
+    function DELETE() {
+        $aReturn = $this->genericDelete($this->aProperties['schema_vmap'], 'printparameter', 'printparameter_id');
+        return $aReturn['sMessage'];
+    }
+
+}
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/PrintReport.class.inc b/vmap/vas/rest/ws/vmap/PrintReport.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..42ab3acdb7958bc8bafc277eeb0caabf3f589f26
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/PrintReport.class.inc
@@ -0,0 +1,83 @@
+<?php
+
+require_once 'Vmap.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+
+/**
+ * \file PrintReport.class.inc
+ * \class PrintReport
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * \brief This file contains the PrintReport php class
+ *
+ * This class defines operation for one PrintReport
+ * 
+ */
+class PrintReport extends Vmap {
+
+    public $oError;
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("printreport_id", "name", "rt_format_id", "rt_orientation_id", "outputformats_id", "business_object_id", "multiobject", "htmldefinition", "jsonobjects", "business_object_title", "business_object_id_field", "business_object_database", "business_object_schema", "business_object_table", "business_object_geom_column");
+    }
+
+    /**
+     * @SWG\Get(path="/printreports/{printreport_id}", 
+     *   tags={"PrintReports"},
+     *   summary="Get PrintReport",
+     *   description="Request to get PrintReport by id",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="printreport_id",
+     *     in="path",
+     *     description="printreport id",
+     *     required=true,
+     *     type="integer"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/printreports")
+     *     )
+     *  )
+     */
+
+    /**
+     * get informations about PrintReport
+     */
+    function GET() {        
+        $this->aFields = $this->getFields($this->aProperties['schema_vmap'], 'v_printreport', 'printreport_id');        
+    }
+    
+    /**
+     * delete a printreport
+     */
+    function DELETE(){
+        $this->oConnection->oBd->delete($this->aProperties['schema_vmap'], 'printreport', 'printreport_id', $this->aValues['my_vitis_id'], 'integer');
+        if ($this->oConnection->oBd->enErreur()) {
+                $this->oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+        } else {
+                $this->aFields[printreport_id] = $this->aValues['id'];
+        }
+    }
+}
+
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/PrintReportServices.class.inc b/vmap/vas/rest/ws/vmap/PrintReportServices.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..3fd045e83b9e4543d9001770e6daa35062a97eeb
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/PrintReportServices.class.inc
@@ -0,0 +1,934 @@
+<?php
+
+require_once 'PrintServices.class.inc';
+require_once 'PrintReports.class.inc';
+require_once 'Querys.class.inc';
+require_once 'PrintMapServices.class.inc';
+require_once __DIR__ . '/../vitis/Vitis.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+require_once __DIR__ . '/../../class/vmlib/BdDataAccess.inc';
+require_once __DIR__ . '/../../class/vmlib/phpUtil.inc';
+
+/**
+ * \file printreportservices.class.inc
+ * \class PrintReportServices
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ *  \brief This file contains the PrintReportServices php class
+ *
+ * This class defines the rest api for printreportservices
+ * 
+ */
+class PrintReportServices extends PrintServices {
+    /**
+     * @SWG\Definition(
+     *   definition="/printreportservices",
+     *   allOf={
+     *     @SWG\Schema(ref="#/definitions/printreportservices")
+     *   }
+     * )
+     * * @SWG\Tag(
+     *   name="printreportservices",
+     *   description="Operations about printreportservices"
+     * )
+     */
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+    }
+
+    /**
+     * @SWG\Post(path="/printreportservices",
+     *   tags={"PrintServices"},
+     *   summary="Creates a map print",
+     *   description="Creates a map print",
+     *   operationId="POST",
+     *   produces={"application/json"},
+     * @SWG\Parameter(
+     *     name="token",
+     *     in="formData",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="printreport_id",
+     *     in="formData",
+     *     description="report to print out",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="ids",
+     *     in="formData",
+     *     description="id(s) of the business object element(s) to use in the scope",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="scope_json",
+     *     in="formData",
+     *     description="scope to incorpore",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="includes_json",
+     *     in="formData",
+     *     description="files to include",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="quality",
+     *     in="formData",
+     *     description="image quality",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="PrintReportServices Response",
+     *         @SWG\Schema(ref="#/definitions/printreportservices")
+     *     )
+     *  )
+     */
+    function POST() {
+
+        $this->aReturn = Array();
+
+        // Vérification des valeurs
+        if (empty($this->aValues['printreport_id'])) {
+            $this->aReturn['error']['errorMessage'] .= " printreport_id not defined";
+            return json_encode($this->aReturn);
+        }
+
+        /**
+         * Files to delete after print
+         */
+        $this->aFilesToDelete = array();
+
+        /**
+         * Logs to show
+         */
+        $this->aLogs = array();
+
+        /**
+         * Report id
+         */
+        $this->sReportId = $this->aValues['printreport_id'];
+
+        /**
+         * ids
+         */
+        $this->aIds = explode('|', $this->aValues['ids']);
+
+        /**
+         * JSON
+         */
+        $this->sJsonScope = $this->aValues['scope_json'];
+
+        /**
+         * API URL
+         */
+        $this->sRestUrl = $this->aProperties['web_server_name'] . '/' . $this->aProperties['services_alias'];
+
+        /**
+         * Declare where to include images and html definitions
+         */
+        $this->sJsonIncludes = $this->aValues['includes_json'];
+
+        /**
+         * Token to use
+         */
+        $this->sToken = $this->aValues['token'];
+
+        /**
+         * Image quality
+         */
+        $this->sQuality = $this->aProperties['print']['quality'];
+
+        /**
+         * Path to the PhantomJS .exe
+         */
+        $this->sPhantomjsPath = $this->aProperties['phantomjs_root_path'];
+
+        /**
+         * Path to the .js
+         */
+        $this->sProjectPath = $this->aProperties['vas_home'] . '/util/printserver/server/printreport.js';
+
+        /**
+         * Path to the client
+         */
+        $this->sPrintClientrUrl = $this->aProperties['web_server_name'] . '/' . $this->aProperties['printserver_alias'] . '/client/report/index.html';
+
+        /**
+         * The image name
+         */
+        $this->sFileName = 'rapport_' . date("YmdHis", time()) . '_' . rand();
+
+        // Effectue la requête permettant de récupérer les infos sur le printreport
+        $aPrintReport = $this->getPrintReport($this->sReportId);
+
+        $this->sOrientation = $aPrintReport['rt_orientation_id'];
+
+        $this->sFormat = $aPrintReport['rt_format_id'];
+
+        $this->sOutputFormat = $aPrintReport['outputformats_id'];
+
+        $this->bMultiObject = $aPrintReport['multiobject'];
+
+        $this->sBusinessObjectId = $aPrintReport['business_object_id'];
+
+        $this->sIdField = $aPrintReport['business_object_id_field'];
+
+        $this->sGeomColumn = $aPrintReport['business_object_geom_column'];
+
+        $this->sJsonObjects = $aPrintReport['jsonobjects'];
+
+        $this->sHtmlDef = $aPrintReport['htmldefinition'];
+
+        // En cas de simple objet, mais plusieurs id
+        if (!$this->bMultiObject && count($this->aIds) > 1) {
+            // Génère un rapport pour chaque identifiant
+            return $this->generateManyReports();
+        }
+
+        if ($this->sOutputFormat === 'pdf') {
+
+            $this->sFileDirectory = $this->aProperties['vas_home'] . '/public/vmap/prints';
+
+            $this->sOutputFile = $this->sFileDirectory . '/' . $this->sFileName . '.pdf';
+
+            $this->sFileUrl = $this->aProperties['web_server_name'] . '/' . $this->aProperties['public_alias'] . '/vmap/prints/' . $this->sFileName . '.pdf';
+
+            $this->sFilePath = $this->sOutputFile;
+        } else if ($this->sOutputFormat === 'doc') {
+
+            // Si format doc, alors création d'un dossier qui sera zippé
+            mkdir($this->aProperties['vas_home'] . '/public/vmap/prints/' . $this->sFileName);
+
+            $this->sFileDirectory = $this->aProperties['vas_home'] . '/public/vmap/prints/' . $this->sFileName;
+
+            $this->sOutputFile = $this->sFileDirectory . '/' . $this->sFileName . '.doc';
+
+            $this->sFileUrl = $this->aProperties['web_server_name'] . '/' . $this->aProperties['public_alias'] . '/vmap/prints/' . $this->sFileName . '/' . $this->sFileName . '.doc';
+
+            $this->sFilePath = $this->sOutputFile;
+        }
+
+        // Effectue la requête permettant de récupérer les infos des objets séléctionnés
+        $this->aQuerys = $this->getQuerys($this->aIds);
+
+        // Ajoute le résultat de getQuerys au scope
+        $this->addToScope('BO', $this->aQuerys);
+
+        // Rrécupère les features contenues dans querys
+        $this->sFeatures = $this->getEWKTFeatures($this->aQuerys);
+
+        // Ajoute les images des cartes de sJsonObjects à $this->sJsonIncludes
+        $this->sJsonIncludes = $this->addJsonIncludes($this->sJsonIncludes, $this->sJsonObjects);
+
+        // Écrit les paramètres gros dans des fichiers
+        if (is_dir($this->aProperties['vas_home'])) {
+            if (!is_dir($this->aProperties['vas_home'] . '/public')) {
+                mkdir($this->aProperties['vas_home'] . '/public', 0777, true);
+            }
+            if (!is_dir($this->aProperties['vas_home'] . '/public/vmap')) {
+                mkdir($this->aProperties['vas_home'] . '/public/vmap', 0777, true);
+            }
+            if (!is_dir($this->aProperties['vas_home'] . '/public/vmap/prints')) {
+                mkdir($this->aProperties['vas_home'] . '/public/vmap/prints', 0777, true);
+            }
+        }
+        $sIncludesPath = $this->writeToFile($this->aProperties['vas_home'] . '/public/vmap/prints', 'includes_' . $this->sFileName, $this->sJsonIncludes);
+        $sScopePath = $this->writeToFile($this->aProperties['vas_home'] . '/public/vmap/prints', 'scope_' . $this->sFileName, $this->sJsonScope);
+
+        // Arguments de la ligne de commande
+        $aArguments = array($this->sProjectPath, $this->sPrintClientrUrl, $this->sRestUrl, $this->sToken, $this->sOutputFile, $this->sReportId, $this->sFormat, $this->sOrientation, $this->sOutputFormat, $sIncludesPath, $sScopePath, $this->sQuality);
+
+        // Commande à lancer
+        $sCommand = '"' . $this->sPhantomjsPath . '" --ignore-ssl-errors=true --ssl-protocol=any --web-security=false --local-to-remote-url-access=true';
+
+        // Ajoute les arguments à a commande
+        for ($i = 0; $i < count($aArguments); $i++) {
+            $sCommand .= ' "' . $aArguments[$i] . '"';
+        }
+
+        session_write_close();
+
+        $aCommand = array();
+        exec($sCommand, $aCommand);
+
+        for ($i = 0; $i < count($aCommand); $i++) {
+            array_push($this->aLogs, $aCommand[$i]);
+        }
+
+        $this->oConnection = new Connection($this->aValues, $this->aProperties);
+
+        if ($this->sOutputFormat === 'doc') {
+            // Crée l'arboresance de retour au format zip si plusieurs fichiers
+            $this->zipFileDirectory();
+        }
+
+        // Supprime les fichiers générés pendant l'impression
+        $this->deleteFiles($this->aFilesToDelete);
+
+        $this->aReturn['printreportservices']['fileurl'] = $this->sFileUrl;
+        $this->aReturn['printreportservices']['filepath'] = $this->sFilePath;
+        $this->aReturn['printreportservices']['command'] = $sCommand;
+        $this->aReturn['printreportservices']['logs'] = $this->aLogs;
+        $this->aReturn['printreportservices']['result'] = $aCommand[count($aCommand) - 1];
+        $this->aReturn['status'] = $this->aReturn['printreportservices']['result'] === "Done" ? 1 : 0;
+
+        return json_encode($this->aReturn);
+    }
+
+    /**
+     * Get the print report def
+     * @param string $printRportId
+     * @return array
+     */
+    function getPrintReport($printRportId) {
+
+        $aValues = $this->aValues;
+        $aPath = $this->aPath;
+        $properties = $this->aProperties;
+        $oConnection = $this->oConnection;
+
+        $aPath[2] = $printRportId;
+        $aValues['my_vitis_id'] = $printRportId;
+
+        $oPrintReport = new PrintReport($aPath, $aValues, $properties, $oConnection);
+        $oPrintReport->GET();
+
+        return $oPrintReport->aFields;
+    }
+
+    /**
+     * Query the objects and return the result
+     * @param array $aIds
+     * @return array
+     */
+    function getQuerys($aIds) {
+
+        $aQuerys = array();
+
+        $aValues = $this->aValues;
+        $aPath = $this->aPath;
+        $properties = $this->aProperties;
+
+        $aFilter = array(
+            'relation' => 'OR',
+            'operators' => array()
+        );
+        for ($i = 0; $i < count($aIds); $i++) {
+            array_push($aFilter['operators'], array('column' => $this->sIdField, 'compare_operator' => '=', 'value' => $aIds[$i]));
+        }
+        $sFilter = json_encode($aFilter);
+//        for ($i = 0; $i < count($aIds); $i++) {
+//            if ($i > 0) {
+//                $sFilter .= ' OR ';
+//            }
+//            $sFilter .= '("' . $this->sIdField . '"= \'' . $aIds[$i] . '\')';
+//        }
+
+        $aPath[2] = $this->sBusinessObjectId;
+
+        $aValues['get_geom'] = 'true';
+        $aValues['filter'] = $sFilter;
+        $aValues['my_vitis_id'] = $this->sBusinessObjectId;
+
+        $oQuerys = new Querys($aPath, $aValues, $properties);
+        $oQuerys->GET();
+
+        for ($i = 0; $i < count($oQuerys->aObjects); $i++) {
+            array_push($aQuerys, $oQuerys->aObjects[$i]->aFields);
+        }
+        return $aQuerys;
+    }
+
+    /**
+     * Add $aQuerys to $this->sJsonScope
+     * @param string $sType
+     * @param array $aQuerys
+     */
+    function addToScope($sType, $aQuerys) {
+
+        $aJsonScope = json_decode($this->sJsonScope, true);
+
+        if ($sType === 'BO') {
+            if ($this->bMultiObject) {
+                $aJsonScope['BO'] = $aQuerys;
+            } else {
+                $aJsonScope['BO'] = $aQuerys[0];
+            }
+        }
+
+        $this->sJsonScope = json_encode($aJsonScope);
+    }
+
+    /**
+     * Get the features separed by "|" from $aQuerys
+     * @param array $aQuerys
+     * @return string
+     */
+    function getEWKTFeatures($aQuerys) {
+        $sFeatures = '';
+        for ($i = 0; $i < count($aQuerys); $i++) {
+            if (!empty($aQuerys[$i][$this->sGeomColumn])) {
+                if ($sFeatures != '') {
+                    $sFeatures .= '|';
+                }
+                $sFeatures .= $aQuerys[$i][$this->sGeomColumn];
+            }
+        }
+        return $sFeatures;
+    }
+
+    /**
+     * Add to the $sJsonIncludes the elements defined in $sJsonObjects
+     * @param string $sJsonIncludes
+     * @param string $sJsonObjects
+     * @return string
+     */
+    function addJsonIncludes($sJsonIncludes, $sJsonObjects) {
+
+        $aJsonObjects = json_decode($sJsonObjects, true);
+        $aIncludes = json_decode($sJsonIncludes, true);
+        $aJsonScope = json_decode($this->sJsonScope, true);
+
+        if (!empty($sJsonObjects) && !is_array($aJsonObjects)) {
+            $this->aReturn['error']['errorMessage'] = "JsonObjects has not a valid JSON definition";
+        }
+
+        if (empty($aIncludes)) {
+            $aIncludes = array();
+        }
+
+        // Valeurs par défaut
+        $date = getdate();
+        $aJsonScope['date'] = $date['mday'] . '/' . $date['mon'] . '/' . $date['year'];
+
+        for ($i = 0; $i < count($aJsonObjects); $i++) {
+            // Type Carte
+            if ($aJsonObjects[$i]['type'] === 'map') {
+
+                $aMapDefinition = array();
+                $aMapDefinition['token'] = $this->sToken;
+
+                if (isset($aJsonObjects[$i]['target'])) {
+                    $sTarget = $aJsonObjects[$i]['target'];
+                } else {
+                    $this->aReturn['error']['errorMessage'] .= "JsonObjects: target not defined";
+                }
+
+                $sImageSize = $this->getTargetSize($sTarget);
+
+                if (isset($aJsonObjects[$i]['map_id'])) {
+                    $aMapDefinition['map_id'] = $aJsonObjects[$i]['map_id'];
+                } else {
+                    $this->aReturn['error']['errorMessage'] = "JsonObjects: map_id not defined";
+                }
+
+                if (!empty($sImageSize) && $sImageSize != null) {
+                    $aMapDefinition['image_size'] = $sImageSize;
+                } else {
+                    $this->aReturn['error']['errorMessage'] = "JsonObjects: can't get the image size map_id: " . $aJsonObjects[$i]['map_id'];
+                }
+
+                if (!empty($this->sFeatures)) {
+                    $aMapDefinition['features'] = $this->sFeatures;
+                }
+
+                if (isset($aJsonObjects[$i]['resolution_coeff'])) {
+                    $aMapDefinition['resolution_coeff'] = $aJsonObjects[$i]['resolution_coeff'];
+                }
+                if (isset($aJsonObjects[$i]['scale_target'])) {
+                    $aMapDefinition['scale_target'] = $aJsonObjects[$i]['scale_target'];
+                }
+                if (isset($aJsonObjects[$i]['features_zoom'])) {
+                    $aMapDefinition['features_zoom'] = $aJsonObjects[$i]['features_zoom'];
+                }
+
+                $aMapPrintResult = $this->printMapImage($aMapDefinition);
+
+                $this->oConnection = new Connection($this->aValues, $this->aProperties);
+
+                if (!empty($aMapPrintResult['printmapservices'])) {
+                    // Échelle
+                    if (!empty($aMapDefinition['scale_target']) && !empty($aMapPrintResult['printmapservices']['scale'])) {
+                        $aJsonScope[$aMapDefinition['scale_target']] = $aMapPrintResult['printmapservices']['scale'];
+                    }
+                    // Image
+                    if ($this->sOutputFormat === 'pdf') {
+                        if (!empty($aMapPrintResult['printmapservices']['imagePath'])) {
+                            array_push($this->aFilesToDelete, $aMapPrintResult['printmapservices']['imagePath']);
+                        }
+                        if ($aMapPrintResult['status'] == 1 && !empty($aMapPrintResult['printmapservices']['image'])) {
+                            $sImageUrl = $aMapPrintResult['printmapservices']['image'];
+                        }
+                    }
+                    if ($this->sOutputFormat === 'doc') {
+                        if ($aMapPrintResult['status'] == 1 && !empty($aMapPrintResult['printmapservices']['imagePath'])) {
+                            $sFileName = basename($aMapPrintResult['printmapservices']['imagePath']);
+                            // Copie l'image dans le dossier
+                            copy($aMapPrintResult['printmapservices']['imagePath'], $this->sFileDirectory . '/' . $sFileName);
+                            // Ajoute l'image de base à la liste des fichiers à supprimer
+                            array_push($this->aFilesToDelete, $aMapPrintResult['printmapservices']['imagePath']);
+                            $sImageUrl = $sFileName;
+                        }
+                    }
+                }
+
+                if (isset($sImageUrl)) {
+                    array_push($aIncludes, array(
+                        'target' => $sTarget,
+                        'imageUrl' => $sImageUrl
+                    ));
+                }
+            }
+            // Type Webservice
+            if ($aJsonObjects[$i]['type'] === 'webservice') {
+
+                if (!isset($aJsonObjects[$i]['ressource'])) {
+                    $this->aReturn['error']['errorMessage'] = "JsonObjects type webservice: ressource not defined";
+                    continue;
+                }
+                if (!isset($aJsonObjects[$i]['target'])) {
+                    $this->aReturn['error']['errorMessage'] = "JsonObjects type webservice: target not defined";
+                    continue;
+                }
+
+                // Regarde si il y a un id dans la ressource et stoque son identifiant dans $sIdIndex
+                $aTmp = explode('/', $aJsonObjects[$i]['ressource']);
+                for ($ii = count($aTmp); $ii >= 0; $ii--) {
+                    if (is_numeric(strpos($aTmp[$ii], '{'))) {
+                        if (is_numeric(strpos($aTmp[$ii], '}', strpos($aTmp[$ii], '{')))) {
+                            $sIdIndex = $ii;
+                        }
+                    }
+                }
+
+                // Regarde si il y a des valeurs entre {...} à changer
+                $aJsonObjects[$i]['ressource'] = $this->replaceStringValueByScope($aJsonObjects[$i]['ressource']);
+
+                // aPath
+                $aPath = explode('/', $aJsonObjects[$i]['ressource']);
+
+                // Identifiant
+                $sId = '';
+                if (isset($sIdIndex)) {
+                    $sId = $aPath[$sIdIndex];
+                }
+
+                // $aParams
+                if (isset($aJsonObjects[$i]['params'])) {
+                    if (is_array($aJsonObjects[$i]['params'])) {
+                        $aParams = $aJsonObjects[$i]['params'];
+                        // Vérifie si il y a des valeurs entre {...} à changer
+                        $aParams = $this->replaceArrayValueByScope($aParams);
+                    }
+                }
+
+                $aQueryResult = $this->queryRessource($aPath, $aParams, $sId);                
+                $aJsonScope[$aJsonObjects[$i]['target']] = $aQueryResult;
+            }
+            // Type Objet
+            if ($aJsonObjects[$i]['type'] === 'object') {
+
+                if (!isset($aJsonObjects[$i]['target'])) {
+                    $this->aReturn['error']['errorMessage'] = "JsonObjects type object: target not defined";
+                    continue;
+                }
+                if (!isset($aJsonObjects[$i]['content'])) {
+                    $this->aReturn['error']['errorMessage'] = "JsonObjects type object: content not defined";
+                    continue;
+                }
+                if (!is_array($aJsonObjects[$i]['content'])) {
+                    $this->aReturn['error']['errorMessage'] = "JsonObjects type object: content not an object";
+                    continue;
+                }
+
+                $aJsonScope[$aJsonObjects[$i]['target']] = $aJsonObjects[$i]['content'];
+            }
+            // Type Image
+            if ($aJsonObjects[$i]['type'] === 'image') {
+
+                if (!isset($aJsonObjects[$i]['imageUrl'])) {
+                    $this->aReturn['error']['errorMessage'] = "JsonObjects type image: imageUrl not defined";
+                    continue;
+                }
+                if (!isset($aJsonObjects[$i]['target'])) {
+                    $this->aReturn['error']['errorMessage'] = "JsonObjects type image: target not defined";
+                    continue;
+                }
+
+                $sFileName = $aJsonObjects[$i]['imageUrl'];
+
+                // Sauvvegarde l'image au format png pour faire le lien en cas de .doc
+                if ($this->sOutputFormat === 'doc') {
+                    $sFileName = 'image_' . $i . '.png';
+                    $sOutputFile = $this->sFileDirectory . '/' . $sFileName;
+                    $this->saveImage($aJsonObjects[$i]['imageUrl'], $sOutputFile);
+                }
+
+                array_push($aIncludes, array(
+                    'target' => $aJsonObjects[$i]['target'],
+                    'imageUrl' => $sFileName
+                ));
+            }
+        }
+
+        $this->sJsonScope = json_encode($aJsonScope, true);
+        return json_encode($aIncludes);
+    }
+
+    /**
+     * Replace the {...} values by the scope value
+     * @param string $sString
+     * @return string
+     */
+    function replaceStringValueByScope($sString) {
+        $aJsonScope = json_decode($this->sJsonScope, true);
+
+        $sReplaceChain = '';
+        if (is_numeric(strpos($sString, '{{'))) {
+            if (is_numeric(strpos($sString, '}}', strpos($sString, '{{')))) {
+                $sReplaceChain = substr($sString, strpos($sString, '{{') + 2, strpos($sString, '}}') - strpos($sString, '{{') - 2);
+            } else {
+                return $sString;
+            }
+        } else {
+            return $sString;
+        }
+
+        // Mots clés
+        if ($sReplaceChain === 'id') {
+            $sReplaceValue = $this->aIds[0];
+        } else if ($sReplaceChain === 'ids') {
+            $sReplaceValue = implode('|', $this->aIds);
+        } else if ($sReplaceChain === "'ids'") {
+            $sReplaceValue = "";
+            for ($i = 0; $i < count($this->aIds); $i++) {
+                if ($i > 0) {
+                    $sReplaceValue .= ",";
+                }
+                $sReplaceValue .= "'" . $this->aIds[$i] . "'";
+            }
+        }
+
+        // Récupère la valeur de l'identifiant dans $aJsonObjects
+        if ($sReplaceChain !== '') {
+            $aReplaceChain = explode('.', $sReplaceChain);
+
+            if (isset($aJsonScope[$aReplaceChain[0]])) {
+                if (!empty($aJsonScope[$aReplaceChain[0]][$aReplaceChain[1]])) {
+                    $sReplaceValue = $aJsonScope[$aReplaceChain[0]][$aReplaceChain[1]];
+                }
+            }
+        }
+
+        $sString = str_replace('{{' . $sReplaceChain . '}}', $sReplaceValue, $sString);
+
+        // Récursive si il en reste encore
+        if (strpos($sString, '{{') > 0) {
+            if (strpos($sString, '}}', strpos($sString, '{{')) > 1) {
+                return $this->replaceStringValueByScope($sString);
+            }
+        }
+
+        return $sString;
+    }
+
+    /**
+     * Replace the {...} values by the scope value
+     * @param array $aArray
+     * @return array
+     */
+    function replaceArrayValueByScope($aArray) {
+        foreach ($aArray as $key => $value) {
+            if (is_string($value)) {
+                $aArray[$key] = $this->replaceStringValueByScope($value);
+            }
+            if (is_array($value)) {
+                // Récursive si il s'agit d'un tableau imbriqué
+                $aArray[$key] = $this->replaceArrayValueByScope($value);
+            }
+        }
+        return $aArray;
+    }
+
+    /**
+     * Get a template target size using PhantomJS
+     * @param string $sTarget
+     * @return string
+     */
+    function getTargetSize($sTarget) {
+
+        session_write_close();
+
+        $sTargetSize = null;
+
+        // Chemin du fichier PhantonJS
+        $sProjectPath = $this->aProperties['vas_home'] . '/util/printserver/server/targetsize.js';
+
+        // Arguments de la ligne de commande
+        $aArguments = array($sProjectPath, $this->sPrintClientrUrl, $this->sRestUrl, $this->sToken, $this->sReportId, $this->sFormat, $this->sOrientation, $sTarget);
+
+        // Commande à lancer
+        $sCommand = '"' . $this->sPhantomjsPath . '" --ignore-ssl-errors=true --ssl-protocol=any --web-security=false --local-to-remote-url-access=true';
+
+        // Ajoute les argumants à a commande
+        for ($i = 0; $i < count($aArguments); $i++) {
+            $sCommand .= ' "' . $aArguments[$i] . '"';
+        }
+
+        $aCommand = array();
+        exec($sCommand, $aCommand);
+
+        if (substr($aCommand[count($aCommand) - 1], 0, 4) == 'Done') {
+            $sTargetSize = substr($aCommand[count($aCommand) - 1], 6);
+        }
+        $this->oConnection = new Connection($this->aValues, $this->aProperties);
+
+        return $sTargetSize;
+    }
+
+    /**
+     * Save the image set on the given sImageUrl on the given sOutputFile
+     * @param string $sImageUrl
+     * @param string $sOutputFile
+     */
+    function saveImage($sImageUrl, $sOutputFile) {
+
+        // Chemin du fichier PhantonJS
+        $sProjectPath = $this->aProperties['vas_home'] . '/util/printserver/server/saveimage.js';
+
+        // Arguments de la ligne de commande
+        $aArguments = array($sProjectPath, $sImageUrl, $sOutputFile);
+
+        // Commande à lancer
+        $sCommand = '"' . $this->sPhantomjsPath . '" --ignore-ssl-errors=true --ssl-protocol=any --web-security=false --local-to-remote-url-access=true';
+
+        // Ajoute les argumants à a commande
+        for ($i = 0; $i < count($aArguments); $i++) {
+            $sCommand .= ' "' . $aArguments[$i] . '"';
+        }
+
+        $aCommand = array();
+        exec($sCommand, $aCommand);
+    }
+
+    /**
+     * Print a map and return the definition
+     * @param array $aMapDefinition
+     * @return string image url
+     */
+    function printMapImage($aMapDefinition) {
+
+        session_write_close();
+
+        $oMapPrint = new PrintMapServices($this->aPath, $aMapDefinition, $this->aProperties);
+        $sMapPrintResult = $oMapPrint->POST();
+        array_push($this->aLogs, $sMapPrintResult);
+        $aMapPrintResult = json_decode($sMapPrintResult, true);
+
+        return $aMapPrintResult;
+    }
+
+    /**
+     * Query a webservice ressource
+     * @param array $aPath
+     * @param array $aParams
+     * @param string $sId
+     */
+    function queryRessource($aPath, $aParams = array(), $sId = "") {
+
+        $sWebService = $aPath[0];
+        $sRessource = $aPath[1];
+
+        // Vérifie que le webservice existe
+        if (!is_dir(__DIR__ . '/../' . $sWebService)) {
+            $this->aReturn['error']['errorMessage'] = ' Webservice ' . $sWebService . ' does not exists';
+            return null;
+        }
+
+        // Trouve le nom du fichier correspondant à la ressource
+        $aFiles = scandir(__DIR__ . '/../' . $sWebService);
+
+        for ($i = 0; $i < count($aFiles); $i++) {
+            if (strtolower($aFiles[$i]) === $sRessource . '.class.inc') {
+                $sClassName = substr($aFiles[$i], 0, strpos($aFiles[$i], '.class.inc'));
+            }
+        }
+
+        if (!isset($sClassName)) {
+            $this->aReturn['error']['errorMessage'] = ' Ressource ' . $sRessource . ' does not exists in the webservice ' . $sWebService . '';
+            return null;
+        }
+
+        // Vérifie que la ressource existe
+        if (!is_file(__DIR__ . '/../' . $sWebService . '/' . $sClassName . '.class.inc')) {
+            $this->aReturn['error']['errorMessage'] = ' unable to find file ' . $sWebService . '/' . $sClassName . '.class.inc';
+            return null;
+        }
+
+        require_once __DIR__ . '/../' . $sWebService . '/' . $sClassName . '.class.inc';
+
+        $aValues = $this->aValues;
+        unset($aValues['printreport_id']);
+        unset($aValues['ids']);
+        unset($aValues['module']);
+        if (!empty($sId)) {
+            $aValues['my_vitis_id'] = $sId;
+        }
+        if (count($aParams) > 0) {
+            foreach ($aParams as $key => $value) {
+                $aValues[$key] = $value;
+            }
+        }
+
+        $oRessource = new $sClassName($aPath, $aValues, $this->aProperties, $this->oConnection);
+        $oRessource->GET();
+
+        $aQuery = array();
+
+        // Objet simple
+        if (isset($oRessource->aFields)) {
+            $aQuery = $oRessource->aFields;
+        }
+        // Objet multiple
+        if (isset($oRessource->aObjects)) {
+            for ($i = 0; $i < count($oRessource->aObjects); $i++) {
+                array_push($aQuery, $oRessource->aObjects[$i]->aFields);
+            }
+        }
+
+        return $aQuery;
+    }
+
+    /**
+     * Create zip by $this->sFileDirectory
+     * If only one file is found inside $this->sFileDirectory, the directory will be deleted and the file copied on the parent's
+     * The one or more files are already zipped, the function will unzip them: we don't want a zip inside an other zip
+     * and the file copied on the vmap/prints folder
+     */
+    function zipFileDirectory() {
+        $aScanedFiles = scandir($this->sFileDirectory);
+        $aFiles = array();
+
+        for ($i = 0; $i < count($aScanedFiles); $i++) {
+            if ($aScanedFiles[$i] != '.' && $aScanedFiles[$i] != '..') {
+                array_push($aFiles, $aScanedFiles[$i]);
+            }
+        }
+
+        // Si il y a plus d'un fichier, crée un zip qui sera donné en sortie
+        if (count($aFiles) > 1) {
+
+            // Dézippe les fihiers zippés (on ne ve pas un zip dans un zip)
+            for ($i = 0; $i < count($aFiles); $i++) {
+                $ext = pathinfo($aFiles[$i], PATHINFO_EXTENSION);
+                $dir = pathinfo($aFiles[$i], PATHINFO_BASENAME);
+                $sFile = pathinfo($aFiles[$i], PATHINFO_FILENAME);
+
+                if ($ext == 'zip') {
+
+                    unZip($this->sFileDirectory . '/' . $sFile . '.zip', $this->sFileDirectory . '/' . $sFile);
+
+                    // Supprime le fichier zippé
+                    unlink($this->sFileDirectory . '/' . $sFile . '.zip');
+                }
+            }
+
+            $test = createZip($this->sFileDirectory, $this->sFileDirectory . '.zip');
+            $this->sFileUrl = $this->aProperties['web_server_name'] . '/' . $this->aProperties['public_alias'] . '/vmap/prints/' . $this->sFileName . '.zip';
+            $this->sFilePath = $this->sFileDirectory . '.zip';
+
+            // Ajoute aux fichiers à supprimer le dossier crée
+            array_push($this->aFilesToDelete, $this->sFileDirectory);
+        } else {
+
+            // Copie le fichier dans le fichier au dessus (car pas besoin de zip)
+            copy($this->sFileDirectory . '/' . $this->sFileName . '.' . $this->sOutputFormat, $this->sFileDirectory . '.' . $this->sOutputFormat);
+
+            $this->sFileUrl = $this->aProperties['web_server_name'] . '/' . $this->aProperties['public_alias'] . '/vmap/prints/' . $this->sFileName . '.' . $this->sOutputFormat;
+            $this->sFilePath = $this->sFileDirectory . '.' . $this->sOutputFormat;
+
+            // Ajoute aux fichiers à supprimer le dossier crée
+            array_push($this->aFilesToDelete, $this->sFileDirectory);
+        }
+    }
+
+    /**
+     * Function that calls this->POST for each id in aValues['ids']
+     * @return string
+     */
+    function generateManyReports() {
+
+        $aValues = $this->aValues;
+        $aPath = $this->aPath;
+
+        $this->aReturn['printreportservices'] = array();
+        $this->aReturn['printreportservices']['printreports'] = array();
+        $this->aReturn['printreportservices']['result'] = 'Done';
+
+        // Crée un dossier dans lequel placer les fichiers
+        mkdir($this->aProperties['vas_home'] . '/public/vmap/prints/' . $this->sFileName);
+        $this->sFileDirectory = $this->aProperties['vas_home'] . '/public/vmap/prints/' . $this->sFileName;
+
+        // Génère les fichiers
+        for ($i = 0; $i < count($this->aIds); $i++) {
+
+            $aValues['ids'] = $this->aIds[$i];
+
+            $oPrintReport = new PrintReportServices($aPath, $aValues, $this->aProperties);
+            $oPrintReportResult = json_decode($oPrintReport->POST(), true);
+
+            if (isset($oPrintReportResult['printreportservices'])) {
+                if (isset($oPrintReportResult['printreportservices']['filepath'])) {
+
+                    // Ajoute le résultat dans printreportservices.printreports
+                    array_push($this->aReturn['printreportservices']['printreports'], $oPrintReportResult['printreportservices']);
+
+                    // Copie l'image dans le dossier et l'ajoute à la liste des fichiers à supprimer
+                    $sGeneratedFile = $oPrintReportResult['printreportservices']['filepath'];
+
+                    $sGeneratedFileExt = pathinfo($sGeneratedFile, PATHINFO_EXTENSION);
+
+                    copy($sGeneratedFile, $this->sFileDirectory . '/' . $this->aIds[$i] . '.' . $sGeneratedFileExt);
+                    array_push($this->aFilesToDelete, $sGeneratedFile);
+
+                    // Dit si tout c'est bien passé
+                    if ($oPrintReportResult['printreportservices']['result'] !== "Done") {
+                        $this->aReturn['printreportservices']['result'] .= " Error with id:" . $this->aIds[$i];
+                    }
+                }
+            }
+        }
+        // Crée l'arboresance de retour au format zip si plusieurs fichiers
+        $this->zipFileDirectory();
+
+        // Supprime les fichiers générés pendant l'impression
+        $this->deleteFiles($this->aFilesToDelete);
+        // Valeurs retour
+        $this->aReturn['printreportservices']['fileurl'] = $this->sFileUrl;
+        $this->aReturn['status'] = $this->aReturn['printreportservices']['result'] === "Done" ? 1 : 0;
+
+        return json_encode($this->aReturn);
+    }
+
+}
+
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/PrintReports.class.inc b/vmap/vas/rest/ws/vmap/PrintReports.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..04005168547cafb610eb9617709921a91519fc8d
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/PrintReports.class.inc
@@ -0,0 +1,373 @@
+<?php
+
+/**
+ * \file PrintReports.class.inc
+ * \class PrintReports
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * \brief This file contains the PrintReports php class
+ *
+ * This class defines Rest Api to Vmap PrintReports
+ * 
+ */
+require_once 'Vmap.class.inc';
+require_once 'PrintReport.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+require_once __DIR__ . '/../../class/vmlib/BdDataAccess.inc';
+
+class PrintReports extends Vmap {
+    /**
+     * @SWG\Definition(
+     *   definition="/printreports",
+     *   allOf={
+     *     @SWG\Schema(ref="#/definitions/printreports")
+     *   }
+     * )
+     * * @SWG\Tag(
+     *   name="PrintReports",
+     *   description=""
+     * )
+     */
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("printreport_id", "name", "rt_format_id", "rt_orientation_id", "outputformats_id", "business_object_id", "multiobject", "htmldefinition", "jsonobjects", "business_object_title", "business_object_id_field", "business_object_database", "business_object_schema", "business_object_table", "business_object_geom_column");
+    }
+
+    /**
+     * @SWG\Get(path="/printreports",
+     *   tags={"PrintReports"},
+     *   summary="Get PrintReports",
+     *   description="Request to get PrintReports",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="order_by",
+     *     in="query",
+     *     description="list of ordering fields",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="sort_order",
+     *     in="query",
+     *     description="sort order",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="limit",
+     *     in="query",
+     *     description="number of element",
+     *     required=false,
+     *     type="integer"
+     *   ),
+     * @SWG\Parameter(
+     *     name="offset",
+     *     in="query",
+     *     description="index of first element",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="attributs",
+     *     in="query",
+     *     description="list of attributs",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="filter",
+     *     in="query",
+     *     description="filter results",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="distinct",
+     *     in="query",
+     *     description="delete duplicates",
+     *     required=false,
+     *     type="boolean"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/printreports")
+     *     )
+     *  )
+     */
+    
+    /**
+     * get PrintReports
+     * @return  PrintReports
+     */
+    function GET() {
+        $aReturn = $this->genericGet($this->aProperties['schema_vmap'], 'v_printreport', 'printreport_id');
+        return $aReturn['sMessage'];
+    }
+
+    /**
+     * @SWG\Post(path="/printreports",
+     *   tags={"PrintReports"},
+     *   summary="Add printreport",
+     *   description="Request to add a printreport",
+     *   operationId="POST",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="formData",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="name",
+     *     in="formData",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="rt_format_id",
+     *     in="formData",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="rt_orientation_id",
+     *     in="formData",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="outputformats_id",
+     *     in="formData",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="business_object_id",
+     *     in="formData",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="htmldefinition",
+     *     in="formData",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="jsonobjects",
+     *     in="formData",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="multiobject",
+     *     in="formData",
+     *     description="",
+     *     required=true,
+     *     type="boolean"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/printreports")
+     *     )
+     *
+     *  )
+     * 
+     * )
+     */
+
+    /**
+     * insert printreport
+     * @return array containing the status and the message
+     */
+    function POST() {
+        $aReturn = $this->genericPost($this->aProperties['schema_vmap'], 'printreport', $this->aProperties['schema_vmap'].'.seq_common', 'printreport_id');
+        return $aReturn['sMessage'];
+    }
+
+    /**
+     * @SWG\Put(path="/printreports/{printreport_id}",
+     *   tags={"PrintReports"},
+     *   summary="Update PrintReport",
+     *   description="Request to update printreport",
+     *   operationId="PUT",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="printreport_id",
+     *     in="path",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="name",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="rt_format_id",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="rt_orientation_id",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="outputformats_id",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="business_object_id",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="htmldefinition",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="jsonobjects",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/printreports")
+     *     ),
+     * 
+     *  )
+     */
+
+    /**
+     * modify printreport
+     * @return array containing the status and the message
+     */
+    function PUT() {
+        $aReturn = $this->genericPut($this->aProperties['schema_vmap'], 'printreport', 'printreport_id');
+        return $aReturn['sMessage'];
+    }
+
+    /**
+     * @SWG\Delete(path="/printreports/",
+     *   tags={"PrintReports"},
+     *   summary="delete PrintReport",
+     *   description="Request to delete PrintReport",
+     *   operationId="DELETE",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="printreport token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="idList",
+     *     in="query",
+     *     description="id of the printreports",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/printreports")
+     *     )
+     *  )
+     */
+    /**
+     * @SWG\Delete(path="/printreports/{printreport_id}",
+     *   tags={"PrintReports"},
+     *   summary="delete PrintReport",
+     *   description="Request to delete PrintReport",
+     *   operationId="DELETE",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="printreport token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="printreport_id",
+     *     in="path",
+     *     description="id of the printreport",
+     *     required=true,
+     *     type="integer",
+     *     format = "int32"
+     *   ),
+     * @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/printreports")
+     *     )
+     *  )
+     */
+
+    /**
+     * delete printreport
+     * @return id of printreport deleted or error object if a printreport is not deleted
+     */
+    function DELETE() {
+        $aReturn = $this->genericDelete($this->aProperties['schema_vmap'], 'printreport', 'printreport_id');
+        return $aReturn['sMessage'];
+    }
+
+}
+
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/PrintServices.class.inc b/vmap/vas/rest/ws/vmap/PrintServices.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..e69330e585a07c587d684a631decd48c0e0656f4
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/PrintServices.class.inc
@@ -0,0 +1,66 @@
+<?php
+
+require_once 'Vmap.class.inc';
+require_once __DIR__ . '/../vitis/Vitis.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+require_once __DIR__ . '/../../class/vmlib/BdDataAccess.inc';
+
+/**
+ * \file printservices.class.inc
+ * \class PrintServices
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ *  \brief This file contains the PrintServices php class
+ * 
+ */
+class PrintServices extends Vmap {
+
+    /**
+     * Write a param into a file
+     * @param string $sPath
+     * @param string $sFileName
+     * @param string $sParam
+     * @return string
+     */
+    function writeToFile($sPath, $sFileName, $sParam) {
+        $sFile = $sPath . '/' . $sFileName . '.txt';
+        file_put_contents($sFile, $sParam);
+        array_push($this->aFilesToDelete, $sFile);
+        return $sFile;
+    }
+
+    function rrmdir($dir) {
+        if (is_dir($dir)) {
+            $objects = scandir($dir);
+            foreach ($objects as $object) {
+                if ($object != "." && $object != "..") {
+                    if (is_dir($dir . "/" . $object))
+                        $this->rrmdir($dir . "/" . $object);
+                    else
+                        unlink($dir . "/" . $object);
+                }
+            }
+            rmdir($dir);
+        }
+    }
+
+    /**
+     * Supprime les fichiers passés en argument
+     * @param array $aFilesToDelete
+     */
+    function deleteFiles($aFilesToDelete) {
+        for ($i = 0; $i < count($aFilesToDelete); $i++) {
+            if (is_dir($aFilesToDelete[$i])) {
+//                array_map('unlink', glob("$aFilesToDelete[$i]/*.*"));
+                $this->rrmdir($aFilesToDelete[$i]);
+            }
+            if (is_file($aFilesToDelete[$i])) {
+                unlink($aFilesToDelete[$i]);
+            }
+        }
+    }
+
+}
+
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/PrintStyle.class.inc b/vmap/vas/rest/ws/vmap/PrintStyle.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..952b3e82af0324de28b146077a206a1666657b5e
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/PrintStyle.class.inc
@@ -0,0 +1,114 @@
+<?php
+
+require_once 'Vmap.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+
+/**
+ * \file PrintStyle.class.inc
+ * \class PrintStyle
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * \brief This file contains the PrintStyle php class
+ *
+ * This class defines operation for one PrintStyle
+ * 
+ */
+class PrintStyle extends Vmap {
+
+    public $oError;
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("printstyle_id", "name", "definition", "users");
+    }
+
+    /**
+     * @SWG\Get(path="/printstyles/{printstyle_id}", 
+     *   tags={"PrintStyles"},
+     *   summary="Get PrintStyle",
+     *   description="Request to get PrintStyle by id",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="printstyle_id",
+     *     in="path",
+     *     description="printstyle id",
+     *     required=true,
+     *     type="integer"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/printstyles")
+     *     )
+     *  )
+     */
+
+    /**
+     * get informations about PrintStyle
+     */
+    function GET() {
+        $this->aFields = $this->getFields($this->aProperties['schema_vmap'], 'printstyle', 'printstyle_id');
+        $this->getUsers();
+    }
+
+    /**
+     *  get users of user
+     */
+    function getUsers() {
+        require $this->sRessourcesFile;
+        if (in_array("users", $this->aSelectedFields)) {
+            $aParams['sSchemaFramework'] = array('value' => $this->aProperties['schema_framework'], 'type' => 'schema_name');
+            $aParams['sSchemaVmap'] = array('value' => $this->aProperties['schema_vmap'], 'type' => 'schema_name');
+            $aParams['printstyle_id'] = array('value' => $this->aValues['my_vitis_id'], 'type' => 'number');
+            $oPDOresult = $this->oConnection->oBd->executeWithParams($aSql['getPrintStyleUsers'], $aParams);
+            $sListUserId = "";
+            $aListUserLogin = array();
+            while ($aLigne = $this->oConnection->oBd->ligneSuivante($oPDOresult)) {
+                if ($sListUserId == "") {
+                    $sListUserId = $aLigne["user_id"];
+                } else {
+                    $sListUserId .= "|" . $aLigne["user_id"];
+                }
+                $aListUserLogin[] = $aLigne["login"];
+            }
+            $oPDOresult = $this->oConnection->oBd->fermeResultat();
+            $this->aFields['users'] = $sListUserId;
+            $this->aFields['users_label'] = implode(',', $aListUserLogin);
+        }
+    }
+
+    /**
+     * delete a printstyle
+     */
+    function DELETE() {
+        // Supprime les utilisateurs rattachés au style.
+        $this->oConnection->oBd->delete($this->aProperties['schema_vmap'], 'user_printstyle', 'printstyle_id', $this->aValues["my_vitis_id"]);
+        // Supprime le style
+        $this->oConnection->oBd->delete($this->aProperties['schema_vmap'], 'printstyle', 'printstyle_id', $this->aValues['my_vitis_id'], 'integer');
+        if ($this->oConnection->oBd->enErreur()) {
+            $this->oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+        } else {
+            $this->aFields[printstyle_id] = $this->aValues['my_vitis_id'];
+        }
+    }
+
+}
+
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/PrintStyles.class.inc b/vmap/vas/rest/ws/vmap/PrintStyles.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..448c13b219d45b788d15703599f4b448ddc9c808
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/PrintStyles.class.inc
@@ -0,0 +1,355 @@
+<?php
+
+/**
+ * \file PrintStyles.class.inc
+ * \class PrintStyles
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * \brief This file contains the PrintStyles php class
+ *
+ * This class defines Rest Api to Vmap PrintStyles
+ * 
+ */
+require_once 'Vmap.class.inc';
+require_once 'PrintStyle.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+require_once __DIR__ . '/../../class/vmlib/BdDataAccess.inc';
+
+class PrintStyles extends Vmap {
+    /**
+     * @SWG\Definition(
+     *   definition="/printstyles",
+     *   allOf={
+     *     @SWG\Schema(ref="#/definitions/printstyles")
+     *   }
+     * )
+     * * @SWG\Tag(
+     *   name="PrintStyles",
+     *   description=""
+     * )
+     */
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("printstyle_id", "name", "definition", "users");
+    }
+
+    /**
+     * @SWG\Get(path="/printstyles",
+     *   tags={"PrintStyles"},
+     *   summary="Get PrintStyles",
+     *   description="Request to get PrintStyles",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="order_by",
+     *     in="query",
+     *     description="list of ordering fields",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="sort_order",
+     *     in="query",
+     *     description="sort order",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="limit",
+     *     in="query",
+     *     description="number of element",
+     *     required=false,
+     *     type="integer"
+     *   ),
+     * @SWG\Parameter(
+     *     name="offset",
+     *     in="query",
+     *     description="index of first element",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="attributs",
+     *     in="query",
+     *     description="list of attributs",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="filter",
+     *     in="query",
+     *     description="filter results",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="distinct",
+     *     in="query",
+     *     description="delete duplicates",
+     *     required=false,
+     *     type="boolean"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/printstyles")
+     *     )
+     *  )
+     */
+
+    /**
+     * get PrintStyles
+     * @return  PrintStyles
+     */
+    function GET() {
+        $aReturn = $this->genericGet($this->aProperties['schema_vmap'], 'printstyle', 'printstyle_id');
+        return $aReturn['sMessage'];
+    }
+
+    /**
+     * @SWG\Post(path="/printstyles",
+     *   tags={"PrintStyles"},
+     *   summary="Add printstyle",
+     *   description="Request to add a printstyle",
+     *   operationId="POST",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="formData",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="name",
+     *     in="formData",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="definition",
+     *     in="formData",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/printstyles")
+     *     )
+     *
+     *  )
+     * 
+     * )
+     */
+
+    /**
+     * insert printstyle
+     * @return array containing the status and the message
+     */
+    function POST() {
+        $aReturn = $this->genericPost($this->aProperties['schema_vmap'], 'printstyle', $this->aProperties['schema_vmap'].'.seq_common', 'printstyle_id');
+        // Si création OK -> maj des utilisateurs rattachés à au style.
+        if ($aReturn['sStatus'] == 1){
+            $aXmlRacineAttribute['status'] = 1;
+            $sMessage = $this->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            $oPrintStyle = new PrintStyle($this->aPath, $this->aValues, $this->aProperties, $this->oConnection);
+            $oPrintStyle->GET();
+            // Utilisateurs à rattacher au style ?
+            if (!empty($this->aValues['users'])) {
+                require $this->sRessourcesFile;
+                $aUsers = explode('|', $this->aValues['users']);
+                foreach ($aUsers as $iUserId) {                    
+                    $sSql = $aSql['insertPrintStyleUsers'];
+                    $aSQLParams = array(
+                        'sSchemaVmap' => array('value' => $this->aProperties['schema_vmap'], 'type' => 'column_name'),
+                        'printstyle_id' => array('value' => $this->aValues["my_vitis_id"], 'type' => 'number'),
+                        'user_id' => array('value' => $iUserId, 'type' => 'number')
+                    );
+                    $resultat = $this->oConnection->oBd->executeWithParams($sSql, $aSQLParams);
+                    if ($this->oConnection->oBd->enErreur()) {
+                        $this->oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+                        $oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+                        $aXmlRacineAttribute['status'] = 0;
+                        $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+                    }
+                }
+            }
+        }
+        else{
+            $sMessage = $aReturn['sMessage'];
+        }
+        return $aReturn['sMessage'];
+    }
+
+    /**
+     * @SWG\Put(path="/printstyles/{printstyle_id}",
+     *   tags={"PrintStyles"},
+     *   summary="Update PrintStyle",
+     *   description="Request to update printstyle",
+     *   operationId="PUT",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="printstyle_id",
+     *     in="path",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="name",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="definition",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/printstyles")
+     *     ),
+     * 
+     *  )
+     */
+
+    /**
+     * modify printstyle
+     * @return array containing the status and the message
+     */
+    function PUT() {
+        $aReturn = $this->genericPut($this->aProperties['schema_vmap'], 'printstyle', 'printstyle_id');
+        // Si création OK -> maj des utilisateurs rattachés à au style.
+        if ($aReturn['sStatus'] == 1){
+            $aXmlRacineAttribute['status'] = 1;
+            $sMessage = $this->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            // Supprime les utilisateurs rattachés au style.
+            $this->oConnection->oBd->delete($this->aProperties['schema_vmap'], 'user_printstyle', 'printstyle_id', $this->aValues["my_vitis_id"]);
+            // Utilisateurs à rattacher au style ?
+            if (!empty($this->aValues['users'])) {
+                require $this->sRessourcesFile;
+                $aUsers = explode('|', $this->aValues['users']);
+                foreach ($aUsers as $iUserId) {                    
+                    $sSql = $aSql['insertPrintStyleUsers'];
+                    $aSQLParams = array(
+                        'sSchemaVmap' => array('value' => $this->aProperties['schema_vmap'], 'type' => 'column_name'),
+                        'printstyle_id' => array('value' => $this->aValues["my_vitis_id"], 'type' => 'number'),
+                        'user_id' => array('value' => $iUserId, 'type' => 'number')
+                    );
+                    $resultat = $this->oConnection->oBd->executeWithParams($sSql, $aSQLParams);
+                    if ($this->oConnection->oBd->enErreur()) {
+                        $this->oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+                        $oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+                        $aXmlRacineAttribute['status'] = 0;
+                        $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+                    }
+                }
+            }
+        }
+        else{
+            $sMessage = $aReturn['sMessage'];
+        }
+        return $aReturn['sMessage'];
+    }
+
+    /**
+     * @SWG\Delete(path="/printstyles/",
+     *   tags={"PrintStyles"},
+     *   summary="delete PrintStyle",
+     *   description="Request to delete PrintStyle",
+     *   operationId="DELETE",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="printstyle token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="idList",
+     *     in="query",
+     *     description="id of the printstyles",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/printstyles")
+     *     )
+     *  )
+     */
+    /**
+     * @SWG\Delete(path="/printstyles/{printstyle_id}",
+     *   tags={"PrintStyles"},
+     *   summary="delete PrintStyle",
+     *   description="Request to delete PrintStyle",
+     *   operationId="DELETE",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="printstyle token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="printstyle_id",
+     *     in="path",
+     *     description="id of the printstyle",
+     *     required=true,
+     *     type="integer",
+     *     format = "int32"
+     *   ),
+     * @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/printstyles")
+     *     )
+     *  )
+     */
+
+    /**
+     * delete printstyle
+     * @return id of printstyle deleted or error object if a printstyle is not deleted
+     */
+    function DELETE() {
+        $aReturn = $this->genericDelete($this->aProperties['schema_vmap'], 'printstyle', 'printstyle_id');
+        return $aReturn['sMessage'];
+    }
+
+}
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/PrintTemplate.class.inc b/vmap/vas/rest/ws/vmap/PrintTemplate.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..b787f46ea25fb387defc0f07ad89a052ad0989cb
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/PrintTemplate.class.inc
@@ -0,0 +1,110 @@
+<?php
+
+require_once 'Vmap.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+
+/**
+ * \file PrintTemplate.class.inc
+ * \class PrintTemplate
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * \brief This file contains the PrintTemplate php class
+ *
+ * This class defines operation for one PrintTemplate
+ * 
+ */
+class PrintTemplate extends Vmap {
+
+    public $oError;
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("printtemplate_id", "name", "rt_format_id", "rt_orientation_id", "definition", "outputformats_id", "groups");        
+    }
+
+    /**
+     * @SWG\Get(path="/printtemplates/{printtemplate_id}", 
+     *   tags={"PrintTemplates"},
+     *   summary="Get PrintTemplate",
+     *   description="Request to get PrintTemplate by id",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="printtemplate_id",
+     *     in="path",
+     *     description="printtemplate id",
+     *     required=true,
+     *     type="integer"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/printtemplates")
+     *     )
+     *  )
+     */
+
+    /**
+     * get informations about PrintTemplate
+     */
+    function GET() {        
+        $this->aFields = $this->getFields($this->aProperties['schema_vmap'], 'v_template', 'printtemplate_id');        
+        $this->getGroups();
+    }
+    
+    /**
+     *  get groups of print template
+     */
+    function getGroups() {
+        require $this->sRessourcesFile;
+        if (in_array("groups", $this->aSelectedFields)){
+            $aParams['sSchemaFramework'] = array('value' => $this->aProperties['schema_framework'], 'type' => 'schema_name');
+            $aParams['sSchemaVmap'] = array('value' => $this->aProperties['schema_vmap'], 'type' => 'schema_name');
+            $aParams['printtemplate_id'] = array('value' => $this->aValues['my_vitis_id'], 'type' => 'number');
+            $oPDOresult = $this->oConnection->oBd->executeWithParams($aSql['getPrintTemplateGroups'], $aParams);
+            $sListGroupId = "";
+            $aListGroupName = array();
+            while($aLigne=$this->oConnection->oBd->ligneSuivante ($oPDOresult)) {
+                    if ($sListGroupId == ""){
+                            $sListGroupId = $aLigne["group_id"];
+                    }else{
+                            $sListGroupId .= "|".$aLigne["group_id"];
+                    }
+                    $aListGroupName[] = $aLigne["name"];
+            }
+            $oPDOresult=$this->oConnection->oBd->fermeResultat();
+            $this->aFields['groups'] = $sListGroupId;
+            $this->aFields['groups_label'] = implode(',', $aListGroupName);
+        }
+    }
+    
+    /**
+     * delete a printtemplate
+     */
+    function DELETE(){
+        $this->oConnection->oBd->delete($this->aProperties['schema_vmap'], 'printtemplate', 'printtemplate_id', $this->aValues['my_vitis_id'], 'integer');
+        if ($this->oConnection->oBd->enErreur()) {
+                $this->oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+        } else {
+                $this->aFields['printtemplate_id'] = $this->aValues['my_vitis_id'];
+        }
+    }
+}
+
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/PrintTemplateServices.class.inc b/vmap/vas/rest/ws/vmap/PrintTemplateServices.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..7e585d297a99bb84cd7527392d0f50d2e54ef87a
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/PrintTemplateServices.class.inc
@@ -0,0 +1,405 @@
+<?php
+
+require_once 'PrintTemplate.class.inc';
+require_once 'UserPrintTemplate.class.inc';
+require_once 'PrintServices.class.inc';
+require_once 'PrintMapServices.class.inc';
+require_once __DIR__ . '/../vitis/Vitis.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+require_once __DIR__ . '/../../class/vmlib/BdDataAccess.inc';
+
+/**
+ * \file printtemplateservices.class.inc
+ * \class PrintTemplateServices
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ *  \brief This file contains the PrintTemplateServices php class
+ *
+ * This class defines the rest api for printtemplateservices
+ * 
+ */
+class PrintTemplateServices extends PrintServices {
+    /**
+     * @SWG\Definition(
+     *   definition="/printtemplateservices",
+     *   allOf={
+     *     @SWG\Schema(ref="#/definitions/printtemplateservices")
+     *   }
+     * )
+     * * @SWG\Tag(
+     *   name="printtemplateservices",
+     *   description="Operations about printtemplateservices"
+     * )
+     */
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+    }
+
+    /**
+     * @SWG\Post(path="/printtemplateservices",
+     *   tags={"PrintServices"},
+     *   summary="Creates a map print",
+     *   description="Creates a map print",
+     *   operationId="POST",
+     *   produces={"application/json"},
+     * @SWG\Parameter(
+     *     name="token",
+     *     in="formData",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="printtemplate_id",
+     *     in="formData",
+     *     description="template to print out",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="printstyle_id",
+     *     in="formData",
+     *     description="template to print out",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="maps_json",
+     *     in="formData",
+     *     description="target + map_definition",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="includes_json",
+     *     in="formData",
+     *     description="target + imageUrl|base64Image|html",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="scope_json",
+     *     in="formData",
+     *     description="scope to incorpore",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="quality",
+     *     in="formData",
+     *     description="image quality",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="PrintTemplateServices Response",
+     *         @SWG\Schema(ref="#/definitions/printtemplateservices")
+     *     )
+     *  )
+     */
+    function POST() {
+
+        $aReturn = Array();
+
+        // Vérification des valeurs
+        if (empty($this->aValues['printtemplate_id'])) {
+            $aReturn['error']['errorMessage'] .= " printtemplate_id not defined";
+            return json_encode($aReturn);
+        }
+
+        /**
+         * Files to delete after print
+         */
+        $this->aFilesToDelete = array();
+
+        /**
+         * Logs to show
+         */
+        $this->aLogs = array();
+
+        /**
+         * Template id
+         */
+        $sTemplateId = $this->aValues['printtemplate_id'];
+
+        $aPrintTemplate = $this->getPrintTemplate($sTemplateId);
+
+        /**
+         * Template id
+         */
+        $sPrintStyleId = $this->aValues['printstyle_id'];
+
+        /**
+         * 'A3', 'A4', 'A5', 'Legal', 'Letter', 'Tabloid'
+         */
+        $sFormat = $aPrintTemplate['rt_format_id'];
+
+        /**
+         * portrait/paysage
+         */
+        $sOrientation = $aPrintTemplate['rt_orientation_id'];
+
+        /**
+         * Declare where to include images and html definitions
+         */
+        $sJsonIncludes = $this->aValues['includes_json'];
+
+        /**
+         * Declare where to include maps
+         */
+        $sJsonMaps = $this->aValues['maps_json'];
+
+        /**
+         * JSON
+         */
+        $this->sJsonScope = $this->aValues['scope_json'];
+
+        /**
+         * API URL
+         */
+        $RestUrl = $this->aProperties['web_server_name'] . '/' . $this->aProperties['services_alias'];
+
+        /**
+         * Token to use
+         */
+        $sToken = $this->aValues['token'];
+
+        /**
+         * Image quality
+         */
+        $sQuality = $this->aProperties['print']['quality'];
+
+        /**
+         * Path to the PhantomJS .exe
+         */
+        $sPhantomjsPath = $this->aProperties['phantomjs_root_path'];
+
+        /**
+         * Path to the .js
+         */
+        $sProjectPath = $this->aProperties['vas_home'] . '/util/printserver/server/printtemplate.js';
+
+        /**
+         * Path to the client
+         */
+        $sPrintClientrUrl = $this->aProperties['web_server_name'] . '/' . $this->aProperties['printserver_alias'] . '/client/template/index.html';
+
+        /**
+         * The image name
+         */
+        $sFileName = 'impression_' . date("YmdHis", time()) . '_' . rand();
+
+        /**
+         * Path to the output file
+         */
+        $sOutputFile = $this->aProperties['vas_home'] . '/public/vmap/prints/' . $sFileName . '.pdf';
+
+        /**
+         * The image URL
+         */
+        $sImageUrl = $this->aProperties['web_server_name'] . '/' . $this->aProperties['public_alias'] . '/vmap/prints/' . $sFileName . '.pdf';
+
+        // Ajoute les images des cartes de $sJsonMaps à $sJsonIncludes
+        $sJsonIncludes = $this->addMapsToIncludes($sJsonIncludes, $sJsonMaps);
+
+        // EncodeUriComponent les définitions html
+        $sJsonIncludes = $this->encodeHtmlIncludes($sJsonIncludes);
+
+        // Écrit les paramètres gros dans des fichiers
+        if (is_dir($this->aProperties['vas_home'])) {
+            if (!is_dir($this->aProperties['vas_home'] . '/public')) {
+                mkdir($this->aProperties['vas_home'] . '/public', 0777, true);
+            }
+            if (!is_dir($this->aProperties['vas_home'] . '/public/vmap')) {
+                mkdir($this->aProperties['vas_home'] . '/public/vmap', 0777, true);
+            }
+            if (!is_dir($this->aProperties['vas_home'] . '/public/vmap/prints')) {
+                mkdir($this->aProperties['vas_home'] . '/public/vmap/prints', 0777, true);
+            }
+        }
+        $sIncludesPath = $this->writeToFile($this->aProperties['vas_home'] . '/public/vmap/prints', 'includes_' . $sFileName, $sJsonIncludes);
+        $sScopePath = $this->writeToFile($this->aProperties['vas_home'] . '/public/vmap/prints', 'scope_' . $sFileName, $this->sJsonScope);
+
+        // Arguments de la ligne de commande
+        $aArguments = array($sProjectPath, $sPrintClientrUrl, $RestUrl, $sToken, $sOutputFile, $sTemplateId, $sPrintStyleId, $sFormat, $sOrientation, $sIncludesPath, $sScopePath, $sQuality);
+
+        // Commande à lancer
+        $sCommand = '"' . $sPhantomjsPath . '" --ignore-ssl-errors=true --ssl-protocol=any --web-security=false --local-to-remote-url-access=true';
+
+        // Ajoute les argumants à a commande
+        for ($i = 0; $i < count($aArguments); $i++) {
+            $sCommand .= ' "' . $aArguments[$i] . '"';
+        }
+
+        // Ferme la session php (pour que phantomJS puisse faire des requetes Ajax avec ce token)
+        session_write_close();
+
+        $aCommand = array();
+        exec($sCommand, $aCommand);
+
+        for ($i = 0; $i < count($aCommand); $i++) {
+            array_push($this->aLogs, $aCommand[$i]);
+        }
+
+        $aReturn['printtemplateservices']['image'] = $sImageUrl;
+        $aReturn['printtemplateservices']['command'] = $sCommand;
+        $aReturn['printtemplateservices']['logs'] = $this->aLogs;
+        $aReturn['printtemplateservices']['result'] = $aCommand[count($aCommand) - 1];
+        $aReturn['status'] = $aReturn['printtemplateservices']['result'] === "Done" ? 1 : 0;
+
+        // Supprime les fichiers générés pendant l'impression
+        $this->deleteFiles($this->aFilesToDelete);
+
+        return json_encode($aReturn);
+    }
+
+    function getPrintTemplate($sPrintTemplateId) {
+
+        $aValues = $this->aValues;
+        $aPath = $this->aPath;
+        $properties = $this->aProperties;
+        $oConnection = $this->oConnection;
+
+        $aPath[2] = $sPrintTemplateId;
+        $aValues['my_vitis_id'] = $sPrintTemplateId;
+
+        $aPrintTemplate = new UserPrintTemplate($aPath, $aValues, $properties, $oConnection);
+        $aPrintTemplate->GET();
+
+        return $aPrintTemplate->aFields;
+    }
+
+    /**
+     * Encode the includes that use html definitions
+     * @param string $sJsonIncludes
+     * @return string
+     */
+    function encodeHtmlIncludes($sJsonIncludes) {
+
+        $aIncludes = json_decode($sJsonIncludes, true);
+
+        for ($i = 0; $i < count($aIncludes); $i++) {
+            if (!empty($aIncludes[$i]['html'])) {
+                $aIncludes[$i]['html'] = rawurlencode($aIncludes[$i]['html']);
+            }
+        }
+
+        return json_encode($aIncludes);
+    }
+
+    /**
+     * Effectue les impressions des cartes définies dans $sJsonMaps
+     * et les ajoute à la défintion $sJsonIncludes
+     * @param string $sJsonIncludes
+     * @param string $sJsonMaps
+     * reutn string
+     */
+    function addMapsToIncludes($sJsonIncludes, $sJsonMaps) {
+
+        $aMapsDefinition = json_decode($sJsonMaps, true);
+        $aIncludes = json_decode($sJsonIncludes, true);
+
+        if (empty($aIncludes)) {
+            $aIncludes = array();
+        }
+
+        $aMapIncludes = $this->getMapIncludes($aMapsDefinition);
+
+        for ($i = 0; $i < count($aMapIncludes); $i++) {
+            array_push($aIncludes, $aMapIncludes[$i]);
+        }
+
+        return json_encode($aIncludes);
+    }
+
+    /**
+     * Effectue les impressions des cartes et retourne leur définition target/imageUrl
+     * @param array $aMapsDefinition
+     * @return array
+     */
+    function getMapIncludes($aMapsDefinition) {
+
+        $aMapsIncludes = array();
+
+        // Ajoute à $aMapsIncludes les définitions des cartes
+        for ($i = 0; $i < count($aMapsDefinition); $i++) {
+
+            if (empty($aMapsDefinition[$i]['target']))
+                continue;
+            if (empty($aMapsDefinition[$i]['map_definition']))
+                continue;
+
+            // Cas ou map_json soit un objet au lieu d'une chaine
+            if (!empty($aMapsDefinition[$i]['map_definition']['map_json'])) {
+                if (gettype($aMapsDefinition[$i]['map_definition']['map_json']) == 'array' || gettype($aMapsDefinition[$i]['map_definition']['map_json']) == 'object') {
+                    $aMapsDefinition[$i]['map_definition']['map_json'] = json_encode($aMapsDefinition[$i]['map_definition']['map_json']);
+                }
+            }
+
+            // Ajout du token
+            $aMapsDefinition[$i]['map_definition']['token'] = $this->aValues['token'];
+
+            $oTmpMapPrint = new PrintMapServices($this->aPath, $aMapsDefinition[$i]['map_definition'], $this->aProperties);
+            $sTmpMapPrintResult = $oTmpMapPrint->POST();
+
+            // Ajoute la définition si tout est ok
+            if (!empty($sTmpMapPrintResult)) {
+
+                $oTmpMapPrintResult = json_decode($sTmpMapPrintResult);
+                array_push($this->aLogs, $oTmpMapPrintResult);
+
+                if ($oTmpMapPrintResult->status == 1) {
+                    if (!empty($oTmpMapPrintResult->printmapservices->image)) {
+
+                        $oMapInclude = array(
+                            'target' => $aMapsDefinition[$i]['target'],
+                            'imageUrl' => $oTmpMapPrintResult->printmapservices->image
+                        );
+
+                        if ($oTmpMapPrintResult->printmapservices->scale !== null && $aMapsDefinition[$i]['target'] == '#map_image') {
+                            $this->setMapScale($oTmpMapPrintResult->printmapservices->scale);
+                        }
+
+                        array_push($aMapsIncludes, $oMapInclude);
+                        array_push($this->aFilesToDelete, $oTmpMapPrintResult->printmapservices->imagePath);
+                    }
+                } else {
+                    writeToErrorLog('Print map error: ' . $sTmpMapPrintResult);
+                }
+            }
+
+            unset($oMapInclude);
+            unset($oTmpMapPrint);
+            unset($sTmpMapPrintResult);
+        }
+
+        return $aMapsIncludes;
+    }
+
+    /**
+     * Set the map scale in the JsonScope if JsonScope.map_scale is NaN
+     * @param string $sScale
+     */
+    function setMapScale($sScale) {
+
+        $aJsonScope = json_decode($this->sJsonScope, true);
+
+        $aJsonScope['map_scale'] = $sScale;
+
+        $this->sJsonScope = json_encode($aJsonScope);
+    }
+
+}
+
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/PrintTemplates.class.inc b/vmap/vas/rest/ws/vmap/PrintTemplates.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..05e63f98475d0f3a55cf98c232937f88508728e9
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/PrintTemplates.class.inc
@@ -0,0 +1,380 @@
+<?php
+
+/**
+ * \file PrintTemplates.class.inc
+ * \class PrintTemplates
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * \brief This file contains the PrintTemplates php class
+ *
+ * This class defines Rest Api to Vmap PrintTemplates
+ * 
+ */
+require_once 'Vmap.class.inc';
+require_once 'PrintTemplate.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+require_once __DIR__ . '/../../class/vmlib/BdDataAccess.inc';
+
+class PrintTemplates extends Vmap {
+    /**
+     * @SWG\Definition(
+     *   definition="/printtemplates",
+     *   allOf={
+     *     @SWG\Schema(ref="#/definitions/printtemplates")
+     *   }
+     * )
+     * * @SWG\Tag(
+     *   name="PrintTemplates",
+     *   description=""
+     * )
+     */
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("printtemplate_id", "name", "rt_format_id", "rt_orientation_id", "definition", "outputformats_id");
+    }
+
+    /**
+     * @SWG\Get(path="/printtemplates",
+     *   tags={"PrintTemplates"},
+     *   summary="Get PrintTemplates",
+     *   description="Request to get PrintTemplates",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="order_by",
+     *     in="query",
+     *     description="list of ordering fields",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="sort_order",
+     *     in="query",
+     *     description="sort order",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="limit",
+     *     in="query",
+     *     description="number of element",
+     *     required=false,
+     *     type="integer"
+     *   ),
+     * @SWG\Parameter(
+     *     name="offset",
+     *     in="query",
+     *     description="index of first element",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="attributs",
+     *     in="query",
+     *     description="list of attributs",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="filter",
+     *     in="query",
+     *     description="filter results",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="distinct",
+     *     in="query",
+     *     description="delete duplicates",
+     *     required=false,
+     *     type="boolean"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/printtemplates")
+     *     )
+     *  )
+     */
+
+    /**
+     * get PrintTemplates
+     * @return  PrintTemplates
+     */
+    function GET() {
+        $aReturn = $this->genericGet($this->aProperties['schema_vmap'], 'v_template', 'printtemplate_id');
+        return $aReturn['sMessage'];
+    }
+
+    /**
+     * @SWG\Post(path="/printtemplates",
+     *   tags={"PrintTemplates"},
+     *   summary="Add printtemplate",
+     *   description="Request to add a printtemplate",
+     *   operationId="POST",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="formData",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="name",
+     *     in="formData",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="rt_format_id",
+     *     in="formData",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="rt_orientation_id",
+     *     in="formData",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="definition",
+     *     in="formData",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="outputformats_id",
+     *     in="formData",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/printtemplates")
+     *     )
+     *
+     *  )
+     * 
+     * )
+     */
+
+    /**
+     * insert printtemplate
+     * @return array containing the status and the message
+     */
+    function POST() {
+        $aReturn = $this->genericPost($this->aProperties['schema_vmap'], 'printtemplate', $this->aProperties['schema_vmap'] . '.seq_common', 'printtemplate_id');
+        // Groupes à rattacher à la carte ?
+        if (!empty($this->aValues['groups'])) {
+            require $this->sRessourcesFile;
+            $aGroups = explode('|', $this->aValues['groups']);
+            foreach ($aGroups as $iGroupId) {
+                $sSql = $aSql['insertPrintTemplateGroups'];
+                $aSQLParams = array(
+                    'sSchemaVmap' => array('value' => $this->aProperties['schema_vmap'], 'type' => 'column_name'),
+                    'printtemplate_id' => array('value' => $this->aValues["my_vitis_id"], 'type' => 'number'),
+                    'group_id' => array('value' => $iGroupId, 'type' => 'number')
+                );
+                $resultat = $this->oConnection->oBd->executeWithParams($sSql, $aSQLParams);
+                if ($this->oConnection->oBd->enErreur()) {
+                    $this->oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+                    $oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+                    $aXmlRacineAttribute['status'] = 0;
+                    $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+                }
+            }
+        }
+        return $aReturn['sMessage'];
+    }
+
+    /**
+     * @SWG\Put(path="/printtemplates/{printtemplate_id}",
+     *   tags={"PrintTemplates"},
+     *   summary="Update PrintTemplate",
+     *   description="Request to update printtemplate",
+     *   operationId="PUT",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="printtemplate_id",
+     *     in="path",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="name",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="rt_format_id",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="rt_orientation_id",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="definition",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="outputformats_id",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/printtemplates")
+     *     ),
+     * 
+     *  )
+     */
+
+    /**
+     * modify printtemplate
+     * @return array containing the status and the message
+     */
+    function PUT() {
+        $aReturn = $this->genericPut($this->aProperties['schema_vmap'], 'printtemplate', 'printtemplate_id');
+        // Supprime les groupes rattachés au modèle.
+        $this->oConnection->oBd->delete($this->aProperties['schema_vmap'], 'printtemplate_group', 'printtemplate_id', $this->aValues["my_vitis_id"]);
+        // Groupes à rattacher à la carte ?
+        if (!empty($this->aValues['groups'])) {
+            require $this->sRessourcesFile;
+            $aGroups = explode('|', $this->aValues['groups']);
+            foreach ($aGroups as $iGroupId) {                
+                $sSql = $aSql['insertPrintTemplateGroups'];
+                $aSQLParams = array(
+                    'sSchemaVmap' => array('value' => $this->aProperties['schema_vmap'], 'type' => 'column_name'),
+                    'printtemplate_id' => array('value' => $this->aValues["my_vitis_id"], 'type' => 'number'),
+                    'group_id' => array('value' => $iGroupId, 'type' => 'number')
+                );
+                $resultat = $this->oConnection->oBd->executeWithParams($sSql, $aSQLParams);
+                if ($this->oConnection->oBd->enErreur()) {
+                    $this->oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+                    $oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+                    $aXmlRacineAttribute['status'] = 0;
+                    $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+                }
+            }
+        }
+        return $aReturn['sMessage'];
+    }
+
+    /**
+     * @SWG\Delete(path="/printtemplates/",
+     *   tags={"PrintTemplates"},
+     *   summary="delete PrintTemplate",
+     *   description="Request to delete PrintTemplate",
+     *   operationId="DELETE",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="printtemplate token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="idList",
+     *     in="query",
+     *     description="id of the printtemplates",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/printtemplates")
+     *     )
+     *  )
+     */
+    /**
+     * @SWG\Delete(path="/printtemplates/{printtemplate_id}",
+     *   tags={"PrintTemplates"},
+     *   summary="delete PrintTemplate",
+     *   description="Request to delete PrintTemplate",
+     *   operationId="DELETE",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="printtemplate token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="printtemplate_id",
+     *     in="path",
+     *     description="id of the printtemplate",
+     *     required=true,
+     *     type="integer",
+     *     format = "int32"
+     *   ),
+     * @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/printtemplates")
+     *     )
+     *  )
+     */
+
+    /**
+     * delete printtemplate
+     * @return id of printtemplate deleted or error object if a printtemplate is not deleted
+     */
+    function DELETE() {
+        $aReturn = $this->genericDelete($this->aProperties['schema_vmap'], 'printtemplate', 'printtemplate_id');
+        return $aReturn['sMessage'];
+    }
+
+}
+
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/Query.class.inc b/vmap/vas/rest/ws/vmap/Query.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..41899ea4b8124161af905450071380053493ea37
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/Query.class.inc
@@ -0,0 +1,43 @@
+<?php
+
+require_once 'Vmap.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+
+/**
+ * \file Query.class.inc
+ * \class Query
+ *
+ * \author Yoann Perollet <armand.bahi@veremes.com>.
+ *
+ * 	\brief This file contains the Query php class
+ *
+ * This class defines operation for one Query
+ * 
+ */
+class Query extends Vmap {
+
+    public $oError;
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array();
+    }
+
+    /**
+     * get informations about query
+     */
+    function GET() {
+
+    }
+
+}
+
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/Querys.class.inc b/vmap/vas/rest/ws/vmap/Querys.class.inc
new file mode 100644
index 0000000000000000000000000000000000000000..27cb5b0fa0d346f75d228b7109c0b27a6a9231e5
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/Querys.class.inc
@@ -0,0 +1,1627 @@
+<?php
+
+/**
+ * \file Querys.class.inc
+ * \class Querys
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * 	\brief This file contains the Querys php class
+ *
+ * This class defines Rest Api to Vitis querys
+ *
+ */
+require_once 'Vmap.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+require_once 'Query.class.inc';
+require_once 'BusinessObject.class.inc';
+require_once(__DIR__ . '/../../class/vmlib/BdDataAccess.inc');
+require_once(__DIR__ . '/../../class/vmlib/phpUtil.inc');
+require_once 'vmlib/logUtil.inc';
+
+require_once __DIR__ . '/../../class/vmlib/Vm.class.inc';
+require_once __DIR__ . '/../../class/vmlib/BD.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+
+class Querys extends Vmap {
+    /**
+     * @SWG\Definition(
+     *   definition="/Querys",
+     *   allOf={
+     *     @SWG\Schema(ref="#/definitions/Querys")
+     *   }
+     * )
+     * * @SWG\Tag(
+     *   name="Querys",
+     *   description="Operations about querying business objects"
+     * )
+     */
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        $this->aValues = $aValues;
+        $this->aPath = $aPath;
+        $this->aProperties = $properties;
+        $this->aValues['getGroup'] = false;
+        $this->oConnection = new Connection($this->aValues, $this->aProperties);
+    }
+
+    /**
+     * @SWG\Get(path="/querys/{business_object_id}/summary",
+     *   tags={"Querys"},
+     *   summary="Get business object summary querys",
+     *   description="Request to get summary querys of a business object",
+     *   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="filter",
+     *     in="query",
+     *     description="filter",
+     *     required=false,
+     *     type="string",
+     *     format="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="intersect_geom",
+     *     in="query",
+     *     description="geom to intersect",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="intersect_column",
+     *     in="query",
+     *     description="column to intersect | Undefined",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="intersect_buffer",
+     *     in="query",
+     *     description="intersection buffer",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="get_geom",
+     *     in="query",
+     *     description="true if you want to get the geometry",
+     *     required=false,
+     *     type="boolean",
+     *   ),
+     * @SWG\Parameter(
+     *     name="get_image",
+     *     in="query",
+     *     description="true if you want to get the image",
+     *     required=false,
+     *     type="boolean",
+     *   ),
+     * @SWG\Parameter(
+     *     name="geom_field",
+     *     in="query",
+     *     description="geom to return | Undefined",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="result_srid",
+     *     in="query",
+     *     description="geom projetion in result | Undefined",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="limit",
+     *     in="query",
+     *     description="number of element",
+     *     required=false,
+     *     type="integer"
+     *   ),
+     * @SWG\Parameter(
+     *     name="offset",
+     *     in="query",
+     *     description="index of first element",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/users")
+     *     )
+     *  )
+     */
+    /**
+     * @SWG\Get(path="/querys/{business_object_id}/list",
+     *   tags={"Querys"},
+     *   summary="Get business object list querys",
+     *   description="Request to get list querys of a business object",
+     *   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="filter",
+     *     in="query",
+     *     description="filter",
+     *     required=false,
+     *     type="string",
+     *     format="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="intersect_geom",
+     *     in="query",
+     *     description="geom to intersect",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="intersect_column",
+     *     in="query",
+     *     description="column to intersect | Undefined",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="intersect_buffer",
+     *     in="query",
+     *     description="intersection buffer",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="get_geom",
+     *     in="query",
+     *     description="true if you want to get the geometry",
+     *     required=false,
+     *     type="boolean",
+     *   ),
+     * @SWG\Parameter(
+     *     name="get_image",
+     *     in="query",
+     *     description="true if you want to get the image",
+     *     required=false,
+     *     type="boolean",
+     *   ),
+     * @SWG\Parameter(
+     *     name="geom_field",
+     *     in="query",
+     *     description="geom to return | Undefined",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="result_srid",
+     *     in="query",
+     *     description="geom projetion in result | Undefined",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="limit",
+     *     in="query",
+     *     description="number of element",
+     *     required=false,
+     *     type="integer",
+     *     default="4"
+     *   ),
+     * @SWG\Parameter(
+     *     name="offset",
+     *     in="query",
+     *     description="index of first element",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/users")
+     *     )
+     *  )
+     */
+    /**
+     * @SWG\Get(path="/querys/{business_object_id}/form",
+     *   tags={"Querys"},
+     *   summary="Get business object form querys",
+     *   description="Request to get the form querys of a business object",
+     *   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="attributs",
+     *     in="query",
+     *     description="attributs",
+     *     required=false,
+     *     type="string",
+     *     format="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="filter",
+     *     in="query",
+     *     description="filter",
+     *     required=false,
+     *     type="string",
+     *     format="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="intersect_geom",
+     *     in="query",
+     *     description="geom to intersect",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="intersect_column",
+     *     in="query",
+     *     description="column to intersect | Undefined",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="intersect_buffer",
+     *     in="query",
+     *     description="intersection buffer",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="get_geom",
+     *     in="query",
+     *     description="true if you want to get the geometry",
+     *     required=false,
+     *     type="boolean",
+     *   ),
+     * @SWG\Parameter(
+     *     name="get_image",
+     *     in="query",
+     *     description="true if you want to get the image",
+     *     required=false,
+     *     type="boolean",
+     *   ),
+     * @SWG\Parameter(
+     *     name="geom_field",
+     *     in="query",
+     *     description="geom to return | Undefined",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="result_srid",
+     *     in="query",
+     *     description="geom projetion in result | Undefined",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="limit",
+     *     in="query",
+     *     description="number of element",
+     *     required=false,
+     *     type="integer"
+     *   ),
+     * @SWG\Parameter(
+     *     name="offset",
+     *     in="query",
+     *     description="index of first element",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/users")
+     *     )
+     *  )
+     */
+    /**
+     * @SWG\Get(path="/querys/{business_object_id}/table",
+     *   tags={"Querys"},
+     *   summary="Get business object form querys",
+     *   description="Request to get the form querys of a business object",
+     *   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="attributs",
+     *     in="query",
+     *     description="attributs",
+     *     required=false,
+     *     type="string",
+     *     format="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="filter",
+     *     in="query",
+     *     description="filter",
+     *     required=false,
+     *     type="string",
+     *     format="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="intersect_geom",
+     *     in="query",
+     *     description="geom to intersect",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="intersect_column",
+     *     in="query",
+     *     description="column to intersect | Undefined",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="intersect_buffer",
+     *     in="query",
+     *     description="intersection buffer",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="get_geom",
+     *     in="query",
+     *     description="true if you want to get the geometry",
+     *     required=false,
+     *     type="boolean",
+     *   ),
+     * @SWG\Parameter(
+     *     name="get_image",
+     *     in="query",
+     *     description="true if you want to get the image",
+     *     required=false,
+     *     type="boolean",
+     *   ),
+     * @SWG\Parameter(
+     *     name="geom_field",
+     *     in="query",
+     *     description="geom to return | Undefined",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="result_srid",
+     *     in="query",
+     *     description="geom projetion in result | Undefined",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="limit",
+     *     in="query",
+     *     description="number of element",
+     *     required=false,
+     *     type="integer"
+     *   ),
+     * @SWG\Parameter(
+     *     name="offset",
+     *     in="query",
+     *     description="index of first element",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/users")
+     *     )
+     *  )
+     */
+    /**
+     * @SWG\Get(path="/querys/{business_object_id}/geometry",
+     *   tags={"Querys"},
+     *   summary="Get business object form querys",
+     *   description="Request to get the form querys of a business object",
+     *   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\Parameter(
+     *     name="snapping_mode",
+     *     in="query",
+     *     description="Snapping mode (segment_edge_node, edge_node, node)",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="snapping_limit",
+     *     in="query",
+     *     description="Returned objets limit",
+     *     required=false,
+     *     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]);
+        } else if (isset($this->aPath[3])) {
+            return $this->queryBusinessObject($this->aPath[3]);
+        } else {
+            return $this->queryBusinessObject('form', true);
+        }
+    }
+
+    /**
+     * Query the business object
+     * @param string $type
+     * @param boolean $bOnlyResult
+     * @return array
+     */
+    function queryBusinessObject($type, $bOnlyResult = false) {
+        require $this->sRessourcesFile;
+
+        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'];
+        }
+
+        // Objet BusinessObject correspondant
+        $oBusinessObject = new BusinessObject($this->aPath, $this->aValues, $this->aProperties, $this->oConnection);
+        $oBusinessObject->GET();
+
+        $date = new DateTime();
+
+        // Paramètres retenus dans l'url
+        $filter = !empty($this->aValues['filter']) ? $this->aValues['filter'] : '';
+        $intersect_geom = !empty($this->aValues['intersect_geom']) ? $this->aValues['intersect_geom'] : '';
+        $intersect_column = !empty($this->aValues['intersect_column']) ? $this->aValues['intersect_column'] : '';
+        $intersect_buffer = !empty($this->aValues['intersect_buffer']) ? $this->aValues['intersect_buffer'] : '';
+        $get_geom = !empty($this->aValues['get_geom']) ? $this->aValues['get_geom'] : '';
+        $get_image = !empty($this->aValues['get_image']) ? $this->aValues['get_image'] : '';
+        $result_srid = !empty($this->aValues['result_srid']) ? $this->aValues['result_srid'] : '';
+        $geom_field = !empty($this->aValues['geom_field']) ? $this->aValues['geom_field'] : '';
+        $limit = !empty($this->aValues['limit']) ? $this->aValues['limit'] : '';
+        $offset = !empty($this->aValues['offset']) ? $this->aValues['offset'] : '';
+        $order_by = !empty($this->aValues['order_by']) ? $this->aValues['order_by'] : '';
+        $sort_order = !empty($this->aValues['sort_order']) ? $this->aValues['sort_order'] : '';
+
+        // Paramètres retenus dans le business object
+        $geom_column = $oBusinessObject->aFields['geom_column'];
+        $bo_id_field = $oBusinessObject->aFields['id_field'];
+        $bo_title = $oBusinessObject->aFields['title'];
+        $bo_formtitle = $oBusinessObject->aFields['formtitle'];
+        $bo_summarytitle = $oBusinessObject->aFields['summarytitle'];
+        $bo_id = $oBusinessObject->aFields['business_object_id'];
+        $database = $oBusinessObject->aFields['database'];
+        $schema = $oBusinessObject->aFields['schema'];
+        $table = $oBusinessObject->aFields['table'];
+        $add_form_size = $oBusinessObject->aFields['add_form_size'];
+        $edit_form_size = $oBusinessObject->aFields['edit_form_size'];
+        $display_form_size = $oBusinessObject->aFields['display_form_size'];
+        $aParams = array();
+
+        // Base de données
+        if (!empty($database) && $database != $this->oConnection->oBd->base) {
+            $this->oConnection->oBd = new Vm($this->oConnection->oBd->login, $this->oConnection->oBd->mdp, $database, $this->oConnection->oBd->serveur, $this->oConnection->oBd->port, $this->oConnection->oBd->sgbd, $this->oConnection->oBd->sPageEncoding);
+        }
+
+        // Chaine sql
+        if ($type === 'form' || $type === 'table') {
+            $sSql = 'SELECT * FROM "[sSchema]"."[sTable]"';
+            $aParams['sSchema'] = array('value' => $schema, 'type' => 'schema_name');
+            $aParams['sTable'] = array('value' => $table, 'type' => 'table_name');
+        } else {
+            $sSql = $oBusinessObject->aFields['sql_' . $type];
+        }
+
+        // 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;
+        $get_image = empty($get_image) ? false : $get_image;
+
+        if (isset($oError)) {
+            $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'];
+        }
+
+        // Position des attributs dans la requête
+        $iAttributesPos = $this->getAttributsPosition($sSql);
+
+        // Colonne utilisée pour [bo_image]
+        $sBoImageColumn = $this->getBOImageColumn($sSql);
+
+        // Intersection
+        if ($use_intersect === true) {
+
+            // Projection de la colonne intersectée
+            $intersect_column_proj = $this->getColumnProjection($sSql, $iAttributesPos, $intersect_column);
+
+            if (empty($intersect_column_proj)) {
+                $intersect_column_proj = '2154';
+            }
+
+            $aIntersectOperator = array(
+                'column' => $intersect_column,
+                'compare_operator' => 'intersect',
+                'compare_operator_options' => array(
+                    'source_proj' => $intersect_column_proj,
+                    'intersect_buffer' => $intersect_buffer,
+                    'intersect_buffer_geom_type' => "point|line",
+                ),
+                'value' => $intersect_geom
+            );
+
+            $filter = $this->addFilterOperator($filter, $aIntersectOperator);
+        }
+
+        // filtre
+        $aDecodedFilter = $this->decodeJSONFilter($filter, $schema, $table);
+
+        // Ajout dans la requête
+        $sSecuredFilter = $aDecodedFilter['request'];
+        // Ajout des paramètres
+        foreach ($aDecodedFilter['params'] as $key => $value) {
+            $aParams[$key] = $value;
+        }
+
+        // Début de la requête
+        $aParams['bo_id_field'] = array('value' => $bo_id_field, 'type' => 'column_name');
+        $sSql = substr_replace($sSql, ' "[bo_id_field]" as bo_id_value,', $iAttributesPos, 0);
+
+        if ($get_geom === true || $get_geom === 'true') {
+            $aParams['geom_field'] = array('value' => $geom_field, 'type' => 'column_name');
+            if (!empty($result_srid)) {
+                $aParams['result_srid'] = array('value' => $result_srid, 'type' => 'integer');
+                $geom_field_geojson = 'ST_AsEWKT(ST_Transform([geom_field], [result_srid]::integer)) as bo_intersect_geom';
+            } else {
+                $geom_field_geojson = 'ST_AsEWKT([geom_field]) as bo_intersect_geom';
+            }
+            $sSql = substr_replace($sSql, ' ' . $geom_field_geojson . ',', $iAttributesPos, 0);
+        }
+
+        // Récupère le nombre d'enregistrements disponibles avec ce filtre
+        $iTotalRowNumber = $this->getTotalRowNumber($schema, $table, $sSecuredFilter, $aParams);
+
+        // Fin de la requête
+        if (!empty($sSecuredFilter) && strlen($sSecuredFilter) > 1) {
+            $sSql .= ' WHERE ' . $sSecuredFilter;
+        }
+        if (!empty($order_by)) {
+            $sSql .= ' ORDER BY [order_by]';
+            $aParams['order_by'] = array('value' => $order_by, 'type' => 'double_quote');
+            if (!empty($sort_order)) {
+                $sSql .= ' [sort_order]';
+                $aParams['sort_order'] = array('value' => $sort_order, 'type' => 'column_name');
+            }
+        }
+        if (!empty($limit)) {
+            $sSql .= ' LIMIT [limit]';
+            $aParams['limit'] = array('value' => $limit, 'type' => 'string');
+        }
+        if (!empty($offset)) {
+            $sSql .= ' OFFSET [offset]';
+            $aParams['offset'] = array('value' => $offset, 'type' => 'string');
+        }
+
+        // Execute la requête
+        $this->aValues['my_vitis_id'] = "";
+
+        $oResult = $this->oConnection->oBd->executeWithParams($sSql, $aParams);
+
+        if ($this->oConnection->oBd->enErreur()) {
+            $aXmlRacineAttribute['status'] = 0;
+            writeToErrorLog($this->oConnection->oBd->getBDMessage());
+            $oError = new VitisError(2, $this->oConnection->oBd->getBDMessage());
+        } else {
+            if (!$this->oConnection->oBd->enErreur() && $this->oConnection->oBd->nombreLigne($oResult) > 0) {
+                while ($aLigne = $this->oConnection->oBd->ligneSuivante($oResult)) {
+
+                    if ($type !== 'table') {
+
+                        // Image à la une
+                        if ($get_image === true || $get_image === 'true') {
+                            if (isset($aLigne['[bo_image]'])) {
+                                if (!empty($sBoImageColumn)) {
+                                    $aLigne['bo_image_path'] = $this->aProperties['web_server_name'] . '/' . $this->aProperties['ws_data_alias'] . '/vitis/' . $bo_id . '/documents/' . $aLigne['bo_id_value'] . '/' . $sBoImageColumn . '/' . $aLigne['[bo_image]'] . "?d=" . $date->getTimestamp();
+                                    unset($aLigne['[bo_image]']);
+                                } else {
+                                    $aLigne['bo_image_path'] = $this->aProperties['web_server_name'] . '/' . $this->aProperties['ws_data_alias'] . '/vitis/' . $bo_id . '/documents/' . $aLigne['bo_id_value'] . '/image/' . $aLigne['[bo_image]'] . "?d=" . $date->getTimestamp();
+                                    unset($aLigne['[bo_image]']);
+                                }
+                            }
+                        }
+
+                        // Permet de récupérer la liste des éléments, leur ordre et leur valeur
+                        $aLigne['bo_' . $type . '_attributs'] = Array();
+                        $aLigne['bo_' . $type] = Array();
+                        foreach ($aLigne as $key => $value) {
+                            if (substr($key, 0, 3) !== 'bo_') {
+                                array_push($aLigne['bo_' . $type . '_attributs'], $key);
+                                $aLigne['bo_' . $type][$key] = $value;
+                                unset($aLigne[$key]);
+                            }
+                        }
+
+                        if (isset($aLigne['bo_' . $type][$geom_column])) {
+                            unset($aLigne['bo_' . $type][$geom_column]);
+                        }
+
+                        // Si on désire uniquement le résultat
+                        if ($bOnlyResult === true) {
+                            $aResult = $aLigne['bo_' . $type];
+                            if (isset($aLigne['bo_intersect_geom'])) {
+                                $aResult[$geom_column] = $aLigne['bo_intersect_geom'];
+                            }
+                            $aLigne = $aResult;
+                        } else {
+
+
+                            // Récupère le forulaire JSON
+                            if ($type === 'form') {
+                                $jsonContent = file_get_contents($this->aProperties['ws_data_dir'] . '/vmap/business_object/' . $bo_id . '/forms/published.json');
+                                if (is_file($this->aProperties['ws_data_dir'] . '/vmap/business_object/' . $bo_id . '/forms/ressources/published.js')) {
+                                    $jsContent = file_get_contents($this->aProperties['ws_data_dir'] . '/vmap/business_object/' . $bo_id . '/forms/ressources/published.js');
+                                } else {
+                                    $jsContent = false;
+                                }
+                                if (is_file($this->aProperties['ws_data_dir'] . '/vmap/business_object/' . $bo_id . '/forms/ressources/published.css')) {
+                                    $cssContent = file_get_contents($this->aProperties['ws_data_dir'] . '/vmap/business_object/' . $bo_id . '/forms/ressources/published.css');
+                                } else {
+                                    $cssContent = false;
+                                }
+
+                                if ($jsContent !== false)
+                                    $js = $this->aProperties['web_server_name'] . '/' . $this->aProperties['ws_data_alias'] . '/vmap/business_object/' . $bo_id . '/forms/ressources/published.js' . "?d=" . $date->getTimestamp();
+                                if ($cssContent !== false)
+                                    $css = $this->aProperties['web_server_name'] . '/' . $this->aProperties['ws_data_alias'] . '/vmap/business_object/' . $bo_id . '/forms/ressources/published.css' . "?d=" . $date->getTimestamp();
+
+                                $aLigne['bo_json_form'] = json_decode($jsonContent);
+                                $aLigne['bo_json_form_js'] = $js;
+                                $aLigne['bo_json_form_css'] = $css;
+                            }
+
+                            // Attributs métier
+                            $aLigne['bo_type'] = $bo_id;
+                            $aLigne['bo_title'] = $bo_title;
+                            $aLigne['bo_formtitle'] = $bo_formtitle;
+                            $aLigne['bo_summarytitle'] = $bo_summarytitle;
+                            $aLigne['add_form_size'] = $add_form_size;
+                            $aLigne['edit_form_size'] = $edit_form_size;
+                            $aLigne['display_form_size'] = $display_form_size;
+
+                            if (!empty($oBusinessObject->aFields['id_field']))
+                                $aLigne['bo_id_field'] = $oBusinessObject->aFields['id_field'];
+
+                            if (!empty($geom_column))
+                                $aLigne['geom_column'] = $geom_column;
+
+                            $aRights = $this->oConnection->getTableRights($schema, $table);
+
+                            $aLigne['have_update_rights'] = $this->haveUpdateRights($aRights, $schema, $table, $bo_id, $oBusinessObject->aFields['id_field']);
+                            $aLigne['have_card_rights'] = $this->haveCardRights($aRights, $schema, $table, $bo_id);
+                            $aLigne['have_delete_rights'] = $this->haveDeleteRights($aRights);
+                            $aLigne['have_insert_rights'] = $this->haveInsertRights($aRights);
+
+                            // Enlève les arguments non demandés
+                            foreach ($aLigne as $key => $value) {
+                                if ($this->isAttribute($key) === false) {
+                                    unset($aLigne[$key]);
+                                }
+                            }
+                        }
+
+                        // Fichiers à récupérer ?
+                        $sDataDir = $this->aProperties['ws_data_dir'] . "/vitis/" . $bo_id . "/documents/" . $aLigne['bo_id_value'];
+                        $sDataUrl = $this->aProperties['web_server_name'] . "/" . $this->aProperties['ws_data_alias'] . "/vitis/" . $bo_id . "/documents/" . $aLigne['bo_id_value'];
+
+                        foreach ($aLigne['bo_' . $type] as $key => $value) {
+                            if (is_dir($sDataDir . "/" . $key)) {
+                                $aLigne['bo_' . $type][$key] = $sDataUrl . "/" . $key . "/" . $value . "?d=" . $date->getTimestamp();
+                            }
+                        }
+                    }
+
+                    // Nombre total d'éléments dans la table
+                    if (!empty($iTotalRowNumber)) {
+                        $this->aFields['total_row_number'] = $iTotalRowNumber;
+                    }
+
+                    // Attributs récupérés
+                    $oObject = new QueryResponse();
+                    $oObject->aFields = $aLigne;
+                    array_push($this->aObjects, $oObject);
+                }
+            }
+        }
+
+        // Message de sortie
+        if (isset($oError)) {
+            $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'];
+        } else {
+            $aXmlRacineAttribute['status'] = 1;
+            $sMessage = $this->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            $aReturn = array('sStatus' => $aXmlRacineAttribute['status'], "sMessage" => $sMessage);
+            return $aReturn['sMessage'];
+        }
+    }
+
+    /**
+     * Get the [bo_image] column from SQL, return false if not founded
+     * @param string $sSQL
+     *
+     * @return string
+     */
+    function getBOImageColumn($sSQL){
+
+        $sImageColumn = false;
+        $aSQL = explode(',', $sSQL);
+
+        for ($i=0; $i < count($aSQL); $i++) {
+            if (strpos($aSQL[$i], '[bo_image]') !== false) {
+                $aBoLinkSQL = explode(' ', trim($aSQL[$i]));
+                if (!empty(trim($aBoLinkSQL[0]))) {
+                    $sImageColumn = trim($aBoLinkSQL[0]);
+                    $sImageColumn = str_replace('"', '', $sImageColumn);
+                    $sImageColumn = str_replace("'", '', $sImageColumn);
+                }
+            }
+        }
+
+        return $sImageColumn;
+    }
+
+    /**
+     * Add a filter operator
+     * @param string $sFilter
+     * @param array $aOperator
+     * @return string
+     */
+    function addFilterOperator($sFilter, $aOperator) {
+
+        if (is_object($sFilter) || is_array($sFilter)) {
+            $sFilter = json_encode($sFilter);
+        }
+
+        try {
+            $aJSONFilter = json_decode($sFilter, true);
+        } catch (Exception $ex) {
+            $aJSONFilter = null;
+        }
+
+        if (is_array($aJSONFilter)) {
+            if (is_array($aJSONFilter['operators'])) {
+                array_push($aJSONFilter['operators'], $aOperator);
+            } else {
+                $aJSONFilter['operators'] = array($aOperator);
+            }
+        } else {
+            $aJSONFilter = array(
+                'relation' => 'AND',
+                'operators' => array($aOperator)
+            );
+        }
+
+        return json_encode($aJSONFilter);
+    }
+
+    /**
+     *
+     * @param string $schema
+     * @param string $table
+     * @param string $sSecuredFilter
+     * @param array $aParams
+     * @return string
+     */
+    function getTotalRowNumber($schema, $table, $sSecuredFilter, $aParams) {
+
+        $aParams['sSchema'] = array('value' => $schema, 'type' => 'schema_name');
+        $aParams['sTable'] = array('value' => $table, 'type' => 'table_name');
+
+        $sSql = 'SELECT count(*) as total_row_number FROM "[sSchema]"."[sTable]"';
+        if (!empty($sSecuredFilter) && strlen($sSecuredFilter) > 1) {
+            $sSql .= ' WHERE ' . $sSecuredFilter;
+        }
+
+        $oPDOresult = $this->oConnection->oBd->executeWithParams($sSql, $aParams);
+        $aResult = $this->oConnection->oBd->getResultTableAssoc($oPDOresult);
+
+        if (!empty($aResult[0])) {
+            if (!empty($aResult[0]['total_row_number'])) {
+                return $aResult[0]['total_row_number'];
+            }
+        }
+    }
+
+    /**
+     * Check if the attr has to be returned
+     * @param string $sElement
+     * @return boolean
+     */
+    function isAttribute($sElement) {
+        if (!isset($this->aValues['attributs'])) {
+            return true;
+        }
+        if (empty($this->aValues['attributs'])) {
+            return true;
+        }
+
+        $aAttributs = explode('|', $this->aValues['attributs']);
+
+        if (!is_array($aAttributs)) {
+            return true;
+        }
+        if (count($aAttributs) == 0) {
+            return true;
+        }
+        if (array_search($sElement, $aAttributs) === 0) {
+            return true;
+        }
+        if (array_search($sElement, $aAttributs) == null) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Check if connection rights contains update and if the form is present
+     * @param string $aRights
+     * @param string $schema
+     * @param string $table
+     * @param string $bo_id
+     * @param string $bo_id_field
+     * @return string true if the update is possible, false if is not
+     */
+    function haveUpdateRights($aRights, $schema, $table, $bo_id, $bo_id_field) {
+        if (!file_exists($this->aProperties['ws_data_dir'] . '/vmap/business_object/' . $bo_id . '/forms/published.json'))
+            return "false";
+
+        if (in_array("UPDATE", $aRights))
+            return "true";
+        else
+            return "false";
+    }
+
+    /**
+     * heck if connection rights contains select and if the form is present
+     * @param string $aRights
+     * @param string $schema
+     * @param string $table
+     * @param string $bo_id
+     * @return string true if the card is visible, false if is not
+     */
+    function haveCardRights($aRights, $schema, $table, $bo_id) {
+        if (!file_exists($this->aProperties['ws_data_dir'] . '/vmap/business_object/' . $bo_id . '/forms/published.json'))
+            return "false";
+
+        if (in_array("SELECT", $aRights))
+            return "true";
+        else
+            return "false";
+    }
+
+    /**
+     * heck if connection rights contains delete
+     * @param string $aRights
+     * @return string true if the object is deletable
+     */
+    function haveDeleteRights($aRights) {
+        if (in_array("DELETE", $aRights))
+            return "true";
+        else
+            return "false";
+    }
+
+    /**
+     * heck if connection rights contains insert
+     * @param string $aRights
+     * @return string true if the object is deletable
+     */
+    function haveInsertRights($aRights) {
+        if (in_array("INSERT", $aRights))
+            return "true";
+        else
+            return "false";
+    }
+
+    /**
+     * Get the position of the firt attribute in a SQL request
+     * @param string $sSql
+     * @return int the position of the firt attribute
+     */
+    function getAttributsPosition($sSql) {
+        // Position du permier select de la requête
+        $iSelectPos = strpos(strtoupper($sSql), 'SELECT');
+        $iSelectPos = is_numeric($iSelectPos) ? $iSelectPos + 6 : 0;
+
+        // Position du permier distinct de la requête
+        $iDistinctPos = strpos(strtoupper($sSql), 'SELECT DISTINCT', $iSelectPos);
+        $iDistinctPos = is_numeric($iDistinctPos) ? $iDistinctPos + 9 : 0;
+
+        // Position du permier all de la requête
+        $iALLPos = strpos(strtoupper($sSql), 'SELECT ALL', $iSelectPos);
+        $iALLPos = is_numeric($iALLPos) ? $iALLPos + 4 : 0;
+
+        // Position des attributs dans la requête
+        $iAttributesPos = $iSelectPos + $iDistinctPos + $iALLPos;
+
+        return $iAttributesPos;
+    }
+
+    /**
+     * Get the projection of a column from an SQL request
+     * @param type $sSql SQL request witch contains the table, schema etc..
+     * @param type $columnName name of the column to look the projection
+     */
+    function getColumnProjection($sSql, $iAttributesPos, $columnName) {
+        $sSql_tmp = substr_replace($sSql, ' ST_SRID([intersect_column]) as bo_intersect_column_srid,', $iAttributesPos, 0) . ' where ST_SRID([intersect_column]) != 0 limit 1';
+
+        $aParams = array(
+            'intersect_column' => array('value' => $columnName, 'type' => 'column_name')
+        );
+
+        $oResult = $this->oConnection->oBd->executeWithParams($sSql_tmp, $aParams);
+
+
+        if ($this->oConnection->oBd->enErreur()) {
+            writeToErrorLog($this->oConnection->oBd->getBDMessage());
+        } else {
+            if (!isset($this->oConnection->oBd->enErreur)) {
+                $this->oConnection->oBd->enErreur = false;
+            }
+            if (!$this->oConnection->oBd->enErreur && $this->oConnection->oBd->nombreLigne($oResult) > 0) {
+                $aData = array();
+                while ($aObject = $this->oConnection->oBd->ligneSuivante($oResult)) {
+                    foreach ($aObject as $sParamKey => $sParamValue) {
+                        if ($sParamKey === 'bo_intersect_column_srid')
+                            $intersect_column_proj = $sParamValue;
+                    }
+                }
+            }
+        }
+        return $intersect_column_proj;
+    }
+
+    /**
+     * Get the geometries from a business object intersecting intersect_geom
+     */
+    function getBoGeomsFromIntersect($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']) || empty($this->aValues['snapping_mode'])) {
+            $oError = new VitisError(0, 'Parameters business_object_id, intersect_geom, snapping_mode 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'];
+        $intersectGeom = $this->aValues['intersect_geom'];
+        $sSnapMode = $this->aValues['snapping_mode'];
+        $iSnappingLimit = !empty($this->aValues['snapping_limit']) ? $this->aValues['snapping_limit'] : 100000;
+
+        // 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);
+        }
+
+        // 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['iSnappingLimit'] = array('value' => $iSnappingLimit, 'type' => 'integer');
+
+        // Projection de la colonne intersectée
+        $iColumnProj = $this->oConnection->oBd->getColumnSRID($sSchema, $sTable, $sGeomColumn);
+        if (empty($iColumnProj)) {
+            $iColumnProj = '2154';
+        }
+
+        // Filtre
+        $aFilter = array(
+            'column' => $sGeomColumn,
+            'compare_operator' => 'intersect',
+            'compare_operator_options' => array(
+                'source_proj' => $iColumnProj,
+            ),
+            'value' => $intersectGeom
+        );
+        $aDecodedFilter = $this->decodeJSONFilter($aFilter, $sSchema, $sTable);
+
+        $sSecuredFilter = $aDecodedFilter['request'];
+        foreach ($aDecodedFilter['params'] as $key => $value) {
+            $aParams[$key] = $value;
+        }
+
+        // Compte le nomber d'éléments qui seront affichés
+        $sSqlCount = 'SELECT COUNT(ST_NPoints([sGeomColumn])) FROM "[sSchema]"."[sTable]" AS geom WHERE ' . $sSecuredFilter . ' AND [sGeomColumn] IS NOT NULL';
+        $oResult = $this->oConnection->oBd->executeWithParams($sSqlCount, $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 {
+            $aCountResult = $this->oConnection->oBd->getResultTableAssoc($oResult);
+        }
+
+        // Si le nombre d'éléments est correct, alors effectue la vraie requête
+        if ($aCountResult[0]['count'] < $iSnappingLimit) {
+
+            // Mise en place de la requête
+            switch ($sSnapMode) {
+                case 'segment_edge_node':
+                case 'edge_node':
+                    $sSql = 'SELECT ST_AsEWKT([sGeomColumn])';
+                    break;
+                case 'node':
+                    $sSql = 'SELECT ST_AsEWKT(ST_Collect(ST_StartPoint([sGeomColumn]), ST_EndPoint([sGeomColumn])))';
+                    break;
+                default:
+                    $sSql = 'SELECT ST_AsEWKT([sGeomColumn])';
+                    break;
+            }
+            $sSql .= ' AS geom FROM "[sSchema]"."[sTable]" WHERE ' . $sSecuredFilter . ' AND [sGeomColumn] IS NOT NULL';
+
+            // Execution de la requête
+            $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);
+        } else {
+            return json_encode($aCountResult);
+        }
+    }
+
+    /**
+     * @SWG\Put(path="/querys/{business_object_id}",
+     *   tags={"Querys"},
+     *   summary="Update an element of a business object",
+     *   description="Request to update an element of a business object",
+     *   operationId="PUT",
+     *   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",
+     *     format="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="body",
+     *     in="body",
+     *     description="",
+     *     required=false,
+     *     type="body",
+     *     format="string",
+     *     @SWG\Schema(ref="#/definitions/businessobjects")
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/businessobjects")
+     *     ),
+     *
+     *  )
+     */
+
+    /**
+     * modify an element by business_object_id
+     * @return array containing the status and the message
+     */
+    function PUT() {
+
+        $sBusinessObjectId = $this->aPath['2'];
+
+        if (!isset($sBusinessObjectId)) {
+            return 'business_object_id required';
+        }
+
+        $this->aPath['3'] = $sBusinessObjectId;
+        $this->aValues['my_vitis_id'] = $sBusinessObjectId;
+
+        $oBusinessObject = new BusinessObject($this->aPath, $this->aValues, $this->aProperties, $this->oConnection);
+        $oBusinessObject->GET();
+
+        $bo_database = $oBusinessObject->aFields['database'];
+        $bo_schema = $oBusinessObject->aFields['schema'];
+        $bo_table = $oBusinessObject->aFields['table'];
+        $bo_id_field = $oBusinessObject->aFields['id_field'];
+        $bo_event = $oBusinessObject->aFields['event_id'];
+
+        if (!empty($bo_database) && $bo_database != $this->oConnection->oBd->base) {
+            $this->oConnection->oBd = new Vm($this->oConnection->oBd->login, $this->oConnection->oBd->mdp, $bo_database, $this->oConnection->oBd->serveur, $this->oConnection->oBd->port, $this->oConnection->oBd->sgbd, $this->oConnection->oBd->sPageEncoding);
+        }
+
+        $this->aValues['my_vitis_id'] = $this->aValues[$bo_id_field];
+
+        // Définit si il a des fichiers a uploader
+        $bUploadFiles = false;
+        foreach ($this->aValues as $key => $value) {
+            if (strrpos($key, '_file')) {
+                $sName = substr($key, 0, strrpos($key, '_file'));
+                if (isset($this->aValues[$sName . '_name'])) {
+                    $bUploadFiles = true;
+                }
+            }
+        }
+
+        // Fichiers à uploader ?
+        if ($bUploadFiles) {
+            // Création du dossier contenneur si il n'existe pas
+            $sDirPath = $this->createElementFilesFolder($sBusinessObjectId, $this->aValues['my_vitis_id']);
+            if (!is_dir($sDirPath)) {
+                $oError = new VitisError(1, "Unable to acces to the business object direrctory :" . $sDirPath);
+                $aXmlRacineAttribute['status'] = 0;
+                $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+                return $sMessage;
+            }
+            // Mise en place des fichiers
+            $this->aValues = $this->extractFilesFromValues($this->aValues, $sDirPath);
+        }
+
+        $aReturn = $this->genericPut($bo_schema, $bo_table, $bo_id_field);
+
+        // Lance l'évènement webSocket
+        if (!empty($bo_event)) {
+            sendWebsocketMessage($this->aProperties['websocket_server'], $this->aProperties['websocket_port'], $this->aProperties['websocket_alias'], array(
+                'action' => 'event',
+                'service' => 'VmapEvents',
+                'data' => $bo_event
+            ));
+        }
+        return $aReturn['sMessage'];
+    }
+
+    /**
+     * Extract the files from aValues and modify the paths
+     * @param array $aValues
+     * @param string $sDirPath
+     * @param string $sFilePrefix
+     * @return array Parsed $aValues
+     */
+    function extractFilesFromValues($aValues, $sDirPath) {
+
+        foreach ($aValues as $key => $value) {
+            if (strrpos($key, '_file')) {
+
+                $sName = substr($key, 0, strrpos($key, '_file'));
+                $sFileName = $aValues[$sName . '_name'];
+
+                if (!empty($sFileName)) {
+
+                    $sDirColumnPath = $sDirPath . '/' . $sName;
+                    if (!is_dir($sDirColumnPath)) {
+                        mkdir($sDirColumnPath, 0777, true);
+                    }
+
+                    // Cŕee le fichier sur le serveur
+                    $fp = fopen($sDirColumnPath . '/' . $sFileName, "w");
+                    fwrite($fp, $value);
+                    fclose($fp);
+
+                    // Mise en place pour la base de données
+                    $aValues[$sName] = $aValues[$sName . '_name'];
+                    unset($aValues[$sName . '_file']);
+                    unset($aValues[$sName . '_name']);
+                }
+            }
+        }
+
+        return $aValues;
+    }
+
+    /**
+     * Create the element files container
+     * @param string $sBoId
+     * @param string $sId
+     * @return string Path to the created directory
+     */
+    function createElementFilesFolder($sBoId, $sId) {
+
+        // Répertoires présents ?
+        if (is_dir($this->aProperties['ws_data_dir'])) {
+            $sDirPath = $this->aProperties['ws_data_dir'] . '/vitis';
+            if (!is_dir($sDirPath)) {
+                mkdir($sDirPath, 0777, true);
+            }
+            $sDirPath = $sDirPath . '/' . $sBoId;
+            if (!is_dir($sDirPath)) {
+                mkdir($sDirPath, 0777, true);
+            }
+            $sDirPath = $sDirPath . '/documents';
+            if (!is_dir($sDirPath)) {
+                mkdir($sDirPath, 0777, true);
+            }
+            $sDirPath = $sDirPath . '/' . $sId;
+            if (!is_dir($sDirPath)) {
+                mkdir($sDirPath, 0777, true);
+            }
+        }
+
+        return $sDirPath;
+    }
+
+    /**
+     * @SWG\Post(path="/querys/{business_object_id}",
+     *   tags={"Querys"},
+     *   summary="Insert an element of a business object",
+     *   description="Request to insert an element of a business object",
+     *   operationId="POST",
+     *   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",
+     *     format="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="body",
+     *     in="body",
+     *     description="",
+     *     required=false,
+     *     type="body",
+     *     format="string",
+     *     @SWG\Schema(ref="#/definitions/businessobjects")
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/businessobjects")
+     *     ),
+     *
+     *  )
+     */
+
+    /**
+     * modify an element by business_object_id
+     * @return array containing the status and the message
+     */
+    function POST() {
+
+        $sBusinessObjectId = $this->aPath['2'];
+
+        if (!isset($sBusinessObjectId)) {
+            return 'business_object_id required';
+        }
+
+        $this->aPath['3'] = $sBusinessObjectId;
+        $this->aValues['my_vitis_id'] = $sBusinessObjectId;
+
+        $oBusinessObject = new BusinessObject($this->aPath, $this->aValues, $this->aProperties, $this->oConnection);
+        $oBusinessObject->GET();
+
+        $bo_database = $oBusinessObject->aFields['database'];
+        $bo_schema = $oBusinessObject->aFields['schema'];
+        $bo_table = $oBusinessObject->aFields['table'];
+        $bo_id_field = $oBusinessObject->aFields['id_field'];
+        $bo_event = $oBusinessObject->aFields['event_id'];
+
+        if (!empty($bo_database) && $bo_database != $this->oConnection->oBd->base) {
+            $this->oConnection->oBd = new Vm($this->oConnection->oBd->login, $this->oConnection->oBd->mdp, $bo_database, $this->oConnection->oBd->serveur, $this->oConnection->oBd->port, $this->oConnection->oBd->sgbd, $this->oConnection->oBd->sPageEncoding);
+        }
+
+        // $this->aValues['my_vitis_id'] = $this->aValues[$bo_id_field];
+        unset($this->aValues['my_vitis_id']);
+
+        $aReturn = $this->genericPost($bo_schema, $bo_table, '', $bo_id_field);
+
+        // Fichiers à uploader ?
+        if (!empty($_FILES) && !empty($this->aValues['my_vitis_id'])) {
+
+            // Création du dossier contenneur
+            $sDirPath = $this->createElementFilesFolder($sBusinessObjectId, $this->aValues['my_vitis_id']);
+            if (!is_dir($sDirPath)) {
+                $oError = new VitisError(1, "Unable to acces to the business object direrctory :" . $sDirPath);
+                $aXmlRacineAttribute['status'] = 0;
+                $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+                return $sMessage;
+            }
+            // Écriture du fichier
+            foreach ($_FILES as $sName => $aFile) {
+
+                $sDirColumnPath = $sDirPath . '/' . $sName;
+                if (!is_dir($sDirColumnPath)) {
+                    mkdir($sDirColumnPath, 0777, true);
+                }
+
+                $this->aValues[$sName] = $aFile['name'];
+
+                // Écrit le fichier dans son enplacement
+                uploadFile($sName, "", $sDirColumnPath . "/" . $aFile['name'], $aFile['size'] + 1);
+            }
+            $this->genericPut($bo_schema, $bo_table, $bo_id_field);
+        }
+
+        // Lance l'évènement webSocket
+        if (!empty($bo_event)) {
+            sendWebsocketMessage($this->aProperties['websocket_server'], $this->aProperties['websocket_port'], $this->aProperties['websocket_alias'], array(
+                'action' => 'event',
+                'service' => 'VmapEvents',
+                'data' => $bo_event
+            ));
+        }
+        return $aReturn['sMessage'];
+    }
+
+    /**
+     * @SWG\Delete(path="/querys/{business_object_id}",
+     *   tags={"Querys"},
+     *   summary="delete elements of a business object",
+     *   description="Request to delete elements of a business object",
+     *   operationId="DELETE",
+     *   produces={"application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="business_object token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="business_object_id",
+     *     in="path",
+     *     description="id of the businessobjects",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="idList",
+     *     in="query",
+     *     description="id list of the elements to delete separed by |",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/businessobjects")
+     *     )
+     *  )
+     */
+
+    /**
+     * delete business_object
+     * @return id of business_object deleted or error object if a business_object is not deleted
+     */
+    function DELETE() {
+
+        $sBusinessObjectId = $this->aPath['2'];
+
+        if (!isset($sBusinessObjectId)) {
+            return 'business_object_id required';
+        }
+
+        if (empty($this->aValues['idList']) && !empty($this->aPath['3'])) {
+            $this->aValues['idList'] = $this->aPath['3'];
+        }
+
+        $this->aPath['3'] = $sBusinessObjectId;
+        $this->aValues['my_vitis_id'] = $sBusinessObjectId;
+
+        $oBusinessObject = new BusinessObject($this->aPath, $this->aValues, $this->aProperties, $this->oConnection);
+        $oBusinessObject->GET();
+
+        $bo_database = $oBusinessObject->aFields['database'];
+        $bo_schema = $oBusinessObject->aFields['schema'];
+        $bo_table = $oBusinessObject->aFields['table'];
+        $bo_id_field = $oBusinessObject->aFields['id_field'];
+        $bo_event = $oBusinessObject->aFields['event_id'];
+
+        $aIdList = explode("|", $this->aValues['idList']);
+
+        $sIdList = "";
+        for ($i = 0; $i < count($aIdList); $i++) {
+            if ($i > 0)
+                $sIdList .= ", ";
+            $sIdList .= "'" . $aIdList[$i] . "'";
+        }
+
+        if (!empty($bo_database) && $bo_database != $this->oConnection->oBd->base) {
+            $this->oConnection->oBd = new Vm($this->oConnection->oBd->login, $this->oConnection->oBd->mdp, $bo_database, $this->oConnection->oBd->serveur, $this->oConnection->oBd->port, $this->oConnection->oBd->sgbd, $this->oConnection->oBd->sPageEncoding);
+        }
+
+        $this->oConnection->oBd->delete($bo_schema, $bo_table, $bo_id_field, $this->aValues['idList']);
+
+        if ($this->oConnection->oBd->enErreur()) {
+            $aXmlRacineAttribute['status'] = 0;
+            $oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+        } else {
+            $this->deleteElementsDocuments($sBusinessObjectId, $aIdList);
+            $this->aFields['idList'] = $sIdList;
+            $aXmlRacineAttribute['status'] = 1;
+            $sMessage = $this->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+        }
+
+        $aReturn = array('sStatus' => $aXmlRacineAttribute['status'], "sMessage" => $sMessage);
+        $sMessage = $aReturn['sMessage'];
+
+        // Lance l'évènement webSocket
+        if (!empty($bo_event)) {
+            sendWebsocketMessage($this->aProperties['websocket_server'], $this->aProperties['websocket_port'], $this->aProperties['websocket_alias'], array(
+                'action' => 'event',
+                'service' => 'VmapEvents',
+                'data' => $bo_event
+            ));
+        }
+
+        return $sMessage;
+    }
+
+    /**
+     * Delete the documents binded to the elements specified in $aIds
+     * @param string $sBusinessObjectId
+     * @param array $aIds
+     */
+    function deleteElementsDocuments($sBusinessObjectId, $aIds) {
+        for ($i = 0; $i < count($aIds); $i++) {
+            if (!empty($aIds[$i])) {
+                $sDir = $this->aProperties['ws_data_dir'] . '/vitis/' . $sBusinessObjectId . '/documents/' . $aIds[$i];
+                if (is_dir($sDir)) {
+                    clearDir($sDir);
+                }
+            }
+        }
+    }
+
+}
+
+class QueryResponse extends Vitis {
+
+    function __construct() {
+
+    }
+
+}
+
+?>
diff --git a/vmap/vas/rest/ws/vmap/Service.class.inc b/vmap/vas/rest/ws/vmap/Service.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..4f3edad7ca847491ea656e00b87bd448417f0590
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/Service.class.inc
@@ -0,0 +1,96 @@
+<?php
+
+require_once 'Vmap.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+
+/**
+ * \file Service.class.inc
+ * \class Service
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * \brief This file contains the Service php class
+ *
+ * This class defines operation for one Service
+ * 
+ */
+class Service extends Vmap {
+
+    public $oError;
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("service_id", "name", "service_type_id", "description", "url", "key", "thumbnail", "lang", "imagery", "service_type_version", "service_type_type", "service_options", "service_vm4ms", "service_login", "service_password");
+    }
+
+    /**
+     * @SWG\Get(path="/services/{service_id}", 
+     *   tags={"Services"},
+     *   summary="Get Service",
+     *   description="Request to get Service by id",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="service_id",
+     *     in="path",
+     *     description="",
+     *     required=true,
+     *     type="integer"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/services")
+     *     )
+     *  )
+     */
+
+    /**
+     * get informations about Service
+     */
+    function GET() {
+        require $this->sRessourcesFile;
+        $this->aFields = $this->getFields($this->aProperties['schema_vmap'], 'service', 'service_id');
+
+        // Remplace les balises
+        $this->aFields['url'] = str_replace('[ms_cgi_url]', $this->aProperties['ms_cgi_url'], $this->aFields['url']);
+    }
+
+    /**
+     * delete a theme
+     */
+    function DELETE() {
+        // Supprime la vignette.
+        $oService = new Service($this->aPath, $this->aValues, $this->aProperties, $this->oConnection);
+        $oService->GET();
+        if (!empty($oService->aFields['thumbnail'])) {
+            $sFile = $oService->aProperties['dir_export'] . '/vmap/' . $oService->aFields['thumbnail'];
+            if (file_exists($sFile))
+                unlink($sFile);
+        }
+        $this->oConnection->oBd->delete($this->aProperties['schema_vmap'], 'service', 'service_id', $this->aValues['my_vitis_id'], 'integer');
+        if ($this->oConnection->oBd->enErreur()) {
+            $this->oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+        } else {
+            $this->aFields['theme_id'] = $this->aValues['my_vitis_id'];
+        }
+    }
+
+}
+
+?>
diff --git a/vmap/vas/rest/ws/vmap/ServiceType.class.inc b/vmap/vas/rest/ws/vmap/ServiceType.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..8248a30f12ca45867b63e7211a6564d297017cb9
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/ServiceType.class.inc
@@ -0,0 +1,71 @@
+<?php
+
+require_once 'Vmap.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+
+/**
+ * \file ServiceType.class.inc
+ * \class ServiceType
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * \brief This file contains the ServiceType php class
+ *
+ * This class defines operation for one ServiceType
+ * 
+ */
+class ServiceType extends Vmap {
+
+    public $oError;
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("service_type_id");
+    }
+
+    /**
+     * @SWG\Get(path="/servicetypes/{service_type_id}", 
+     *   tags={"ServiceTypes"},
+     *   summary="Get ServiceType",
+     *   description="Request to get ServiceType by id",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="service_type_id",
+     *     in="path",
+     *     description="",
+     *     required=true,
+     *     type="integer"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/servicetypes")
+     *     )
+     *  )
+     */
+
+    /**
+     * get informations about servicetypes
+     */
+    function GET() {
+        require $this->sRessourcesFile;
+        $this->aFields = $this->getFields($this->aProperties['schema_vmap'], 'rt_service_type', 'service_type_id');
+    }
+}
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/ServiceTypes.class.inc b/vmap/vas/rest/ws/vmap/ServiceTypes.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..3d3752936bb7ad066c6670824b7d544e98bdfcab
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/ServiceTypes.class.inc
@@ -0,0 +1,126 @@
+<?php
+
+/**
+ * \file ServiceTypes.class.inc
+ * \class ServiceTypes
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * \brief This file contains the ServiceTypes php class
+ *
+ * This class defines Rest Api to Vmap ServiceTypes
+ * 
+ */
+require_once 'Vmap.class.inc';
+require_once 'ServiceType.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+require_once __DIR__ . '/../../class/vmlib/BdDataAccess.inc';
+
+class ServiceTypes extends Vmap {
+    /**
+     * @SWG\Definition(
+     *   definition="/servicetypes",
+     *   allOf={
+     *     @SWG\Schema(ref="#/definitions/servicetypes")
+     *   }
+     * )
+     * * @SWG\Tag(
+     *   name="ServiceTypes",
+     *   description=""
+     * )
+     */
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("service_type_id");
+    }
+
+    /**
+     * @SWG\Get(path="/servicetypes",
+     *   tags={"ServiceTypes"},
+     *   summary="Get ServiceTypes",
+     *   description="Request to get ServiceTypes",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="order_by",
+     *     in="query",
+     *     description="list of ordering fields",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="sort_order",
+     *     in="query",
+     *     description="sort order",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="limit",
+     *     in="query",
+     *     description="number of element",
+     *     required=false,
+     *     type="integer"
+     *   ),
+     * @SWG\Parameter(
+     *     name="offset",
+     *     in="query",
+     *     description="index of first element",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="attributs",
+     *     in="query",
+     *     description="list of attributs",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="filter",
+     *     in="query",
+     *     description="filter results",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="distinct",
+     *     in="query",
+     *     description="delete duplicates",
+     *     required=false,
+     *     type="boolean"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/servicetypes")
+     *     )
+     *  )
+     */
+
+    /**
+     * get ServiceTypes
+     * @return the array of objects
+     */
+    function GET() {
+        $aReturn = $this->genericGet($this->aProperties['schema_vmap'], 'rt_service_type', 'service_type_id');
+        return $aReturn['sMessage'];
+    }
+}
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/Services.class.inc b/vmap/vas/rest/ws/vmap/Services.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..7e6d3a7d6622ca795c455395a7880c82c73a06bb
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/Services.class.inc
@@ -0,0 +1,493 @@
+<?php
+
+/**
+ * \file Services.class.inc
+ * \class Services
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * \brief This file contains the Services php class
+ *
+ * This class defines Rest Api to Vmap Services
+ * 
+ */
+require_once 'Vmap.class.inc';
+require_once 'Service.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+require_once __DIR__ . '/../../class/vmlib/BdDataAccess.inc';
+
+class Services extends Vmap {
+    /**
+     * @SWG\Definition(
+     *   definition="/services",
+     *   allOf={
+     *     @SWG\Schema(ref="#/definitions/services")
+     *   }
+     * )
+     * * @SWG\Tag(
+     *   name="Services",
+     *   description=""
+     * )
+     */
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("service_id", "name", "service_type_id", "description", "url", "key", "thumbnail", "lang", "imagery", "service_type_version", "service_type_type", "service_options", "service_vm4ms", "service_login", "service_password");
+    }
+
+    /**
+     * @SWG\Get(path="/services",
+     *   tags={"Services"},
+     *   summary="Get Services",
+     *   description="Request to get Services",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="order_by",
+     *     in="query",
+     *     description="list of ordering fields",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="sort_order",
+     *     in="query",
+     *     description="sort order",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="limit",
+     *     in="query",
+     *     description="number of element",
+     *     required=false,
+     *     type="integer"
+     *   ),
+     * @SWG\Parameter(
+     *     name="offset",
+     *     in="query",
+     *     description="index of first element",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="attributs",
+     *     in="query",
+     *     description="list of attributs",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="filter",
+     *     in="query",
+     *     description="filter results",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="distinct",
+     *     in="query",
+     *     description="delete duplicates",
+     *     required=false,
+     *     type="boolean"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/services")
+     *     )
+     *  )
+     */
+
+    /**
+     * get Services
+     * @return  Services
+     */
+    function GET() {
+        $this->genericGet($this->aProperties['schema_vmap'], 'service', 'service_id', false, 'vmap_admin_map_vmap_services');
+
+        // Remplace les balises
+        for ($i = 0; $i < count($this->aObjects); $i++) {
+            if (!empty($this->aObjects[$i]->aFields['url'])) {
+                $this->aObjects[$i]->aFields['url'] = str_replace('[ms_cgi_url]', $this->aProperties['ms_cgi_url'], $this->aObjects[$i]->aFields['url']);
+            }
+        }
+
+        // Reformatte la réponse 
+        if (isset($this->aValues['sEncoding'])) {
+            $sEncoding = $this->aValues['sEncoding'];
+        } else {
+            $sEncoding = null;
+        }if (isset($this->aValues['sSourceEncoding'])) {
+            $sSourceEncoding = $this->aValues['sSourceEncoding'];
+        } else {
+            $sSourceEncoding = null;
+        }if (isset($this->aValues['output'])) {
+            $output = $this->aValues['output'];
+        } else {
+            $output = null;
+        }
+        $aXmlRacineAttribute['status'] = 1;
+        $sMessage = $this->asDocument('', 'vitis', $sEncoding, True, $aXmlRacineAttribute, $sSourceEncoding, $output);
+        $aReturn = array('sStatus' => $aXmlRacineAttribute['status'], "sMessage" => $sMessage);
+
+        return $aReturn['sMessage'];
+    }
+
+    /**
+     * @SWG\Post(path="/services",
+     *   tags={"Services"},
+     *   summary="Add service",
+     *   description="Request to add a service",
+     *   operationId="POST",
+     *   produces={"application/xml", "application/json"},
+     *   consumes= { "multipart/form-data"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="formData",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="service_type_id",
+     *     in="formData",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="name",
+     *     in="formData",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="description",
+     *     in="formData",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="url",
+     *     in="formData",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="key",
+     *     in="formData",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="service_type_version",
+     *     in="formData",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="thumbnail",
+     *     in="formData",
+     *     description="Thumbnail of the service",
+     *     required=false,
+     *     type="file"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/services")
+     *     )
+     *
+     *  )
+     * 
+     * )
+     */
+
+    /**
+     * insert service
+     * @return array containing the status and the message
+     */
+    function POST() {
+
+        // Vignette à uploader ?
+        if (!empty($_FILES['thumbnail'])) {
+            // la colonne thumbnail vaudra le nom du fichier
+            $this->aValues["thumbnail"] = $_FILES['thumbnail']["name"];
+        }
+
+        // Redimmensionnement de l'image.
+        if (!empty($this->aValues['thumbnail_width']) && !empty($this->aValues['thumbnail_height'])) {
+            // Renomme l'image en jpg
+            $aPointsArray = explode('.', $this->aValues["thumbnail"]);
+            $aPointsArray[count($aPointsArray) - 1] = 'jpg';
+            $this->aValues["thumbnail"] = join('.', $aPointsArray);
+        }
+
+        $aReturn = $this->genericPost($this->aProperties['schema_vmap'], 'service', $this->aProperties['schema_vmap'] . '.seq_common', 'service_id');
+
+        // Vignette à uploader ?
+        if (!empty($_FILES['thumbnail'])) {
+            $sImageDir = $this->aProperties['ws_data_dir'] . '/vitis/vmap_admin_map_vmap_services/documents/' . $this->aValues["my_vitis_id"] . '/thumbnail/' . $_FILES['thumbnail']["name"];
+
+            // Crée les répertoires si ils n'existent pas
+            $sDirPath = $this->createElementFilesFolder('vmap_admin_map_vmap_services', $this->aValues["my_vitis_id"]);
+            $sDirColumnPath = $sDirPath . '/thumbnail';
+            if (!is_dir($sDirColumnPath)) {
+                mkdir($sDirColumnPath, 0777, true);
+            }
+
+            $sErrorMessage = uploadFile("thumbnail", "", $sImageDir, $_FILES['thumbnail']['size'] + 1);
+
+            if ($sErrorMessage != "") {
+                writeToErrorLog($sErrorMessage);
+            } else {
+                // Redimmensionnement de l'image.
+                if (!empty($this->aValues['thumbnail_width']) && !empty($this->aValues['thumbnail_height'])) {
+                    $this->pictureResampler($sImageDir, $this->aValues['thumbnail_width'], $this->aValues['thumbnail_height']);
+                }
+            }
+        }
+
+        return $aReturn['sMessage'];
+    }
+
+    /**
+     * @SWG\Put(path="/services/{service_id}",
+     *   tags={"Services"},
+     *   summary="Update Service",
+     *   description="Request to update service",
+     *   operationId="PUT",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="service_id",
+     *     in="path",
+     *     description="",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="service_type_id",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="name",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="description",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="url",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="key",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="service_type_version",
+     *     in="query",
+     *     description="",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="thumbnail",
+     *     in="formData",
+     *     description="Thumbnail of the service",
+     *     required=false,
+     *     type="file"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/services")
+     *     ),
+     * 
+     *  )
+     */
+
+    /**
+     * modify service
+     * @return array containing the status and the message
+     */
+    function PUT() {
+        // Vignette à uploader ?
+        if (!empty($this->aValues["thumbnail_file"])) {
+
+            $sImageDir = $this->aProperties['ws_data_dir'] . '/vitis/vmap_admin_map_vmap_services/documents/' . $this->aValues["my_vitis_id"] . '/thumbnail/' . $this->aValues["thumbnail_name"];
+
+            // Crée les répertoires si ils n'existent pas
+            $sDirPath = $this->createElementFilesFolder('vmap_admin_map_vmap_services', $this->aValues["my_vitis_id"]);
+            $sDirColumnPath = $sDirPath . '/thumbnail';
+            if (!is_dir($sDirColumnPath)) {
+                mkdir($sDirColumnPath, 0777, true);
+            }
+
+            // la colonne thumbnail vaudra le nom du fichier
+            $this->aValues["thumbnail"] = $this->aValues["thumbnail_name"];
+            $fp = fopen($sImageDir, "w");
+            fwrite($fp, $this->aValues["thumbnail_file"]);
+            fclose($fp);
+
+            // Redimmensionnement de l'image.
+            if (!empty($this->aValues['thumbnail_width']) && !empty($this->aValues['thumbnail_height'])) {
+                $this->pictureResampler($sImageDir, $this->aValues['thumbnail_width'], $this->aValues['thumbnail_height']);
+                // Renomme l'image en jpg
+                $aPointsArray = explode('.', $this->aValues["thumbnail"]);
+                $aPointsArray[count($aPointsArray) - 1] = 'jpg';
+                $this->aValues["thumbnail"] = join('.', $aPointsArray);
+            }
+        }
+
+        $aReturn = $this->genericPut($this->aProperties['schema_vmap'], 'service', 'service_id');
+        return $aReturn['sMessage'];
+    }
+
+    /**
+     * @SWG\Delete(path="/services/",
+     *   tags={"Services"},
+     *   summary="delete Service",
+     *   description="Request to delete Service",
+     *   operationId="DELETE",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="service token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="idList",
+     *     in="query",
+     *     description="id of the services",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/services")
+     *     )
+     *  )
+     */
+    /**
+     * @SWG\Delete(path="/services/{service_id}",
+     *   tags={"Services"},
+     *   summary="delete Service",
+     *   description="Request to delete Service",
+     *   operationId="DELETE",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="service token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="service_id",
+     *     in="path",
+     *     description="id of the service",
+     *     required=true,
+     *     type="integer",
+     *     format = "int32"
+     *   ),
+     * @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/services")
+     *     )
+     *  )
+     */
+
+    /**
+     * delete service
+     * @return id of service deleted or error object if a service is not deleted
+     */
+    function DELETE() {
+        if (!empty($this->aValues['idList'])) {
+            $aIdList = $this->aValues['idList'];
+        }
+        if (!empty($this->aPath['2'])) {
+            $aIdList = $this->aPath['2'];
+            $this->aValues['idList'] = $this->aPath['2'];
+        }
+
+        require $this->sRessourcesFile;
+        $sSql = $aSql['getTotalServiceLayers'];
+        $aSQLParams = array(
+            'sSchemaVmap' => array('value' => $this->aProperties['schema_vmap'], 'type' => 'column_name'),
+            'idList' => array('value' => $aIdList, 'type' => 'group')
+        );
+        $resultat = $this->oConnection->oBd->executeWithParams($sSql, $aSQLParams);
+        if ($this->oConnection->oBd->enErreur()) {
+            $this->oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+            $oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } else {
+            if ($this->oConnection->oBd->objetSuivant($resultat)->nb_layers > 0) {
+                $this->oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+                $oError = new VitisError(1, 'ERROR_SERVICE_DELETE_VMAP_MAP_SERVICE');
+                $aXmlRacineAttribute['status'] = 0;
+                $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            } else {
+                $aReturn = $this->genericDelete($this->aProperties['schema_vmap'], 'service', 'service_id');
+                $sMessage = $aReturn['sMessage'];
+                // Supprime les fichiers uploadés
+                $this->deleteElementsDocuments('vmap_admin_map_vmap_services', $aIdList);
+            }
+            return $sMessage;
+        }
+    }
+
+}
+
+?>
diff --git a/vmap/vas/rest/ws/vmap/UserModule.class.inc b/vmap/vas/rest/ws/vmap/UserModule.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..673fef7f8c4169c5029ffbc206f4e6568866bf21
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/UserModule.class.inc
@@ -0,0 +1,70 @@
+<?php
+
+require_once 'Vmap.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+
+/**
+ * \file UserModule.class.inc
+ * \class UserModule
+ *
+ * \author Yoann Perollet <yoann.perollet@veremes.com>.
+ *
+ * 	\brief This file contains the UserModule php class
+ *
+ * This class defines operation for one UserModule
+ * 
+ */
+class UserModule extends Vmap {
+
+    public $oError;
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("module_id", "label", "description", "rolname", "rolname_list");
+    }
+
+    /**
+     * @SWG\Get(path="/usermodules/{module_id}", 
+     *   tags={"Modules"},
+     *   summary="Get UserModule",
+     *   description="Request to get UserModule by id",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="module_id",
+     *     in="path",
+     *     description="module id",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/usermodules")
+     *     )
+     *  )
+     */
+
+    /**
+     * get informations about usermodule
+     */
+    function GET() {
+        $this->aFields = $this->getFields($this->aProperties['schema_vmap'], 'module', 'module_id');
+    }
+}
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/UserModules.class.inc b/vmap/vas/rest/ws/vmap/UserModules.class.inc
new file mode 100644
index 0000000000000000000000000000000000000000..4e0fbdcfd7f71bdf950c8252509af5e6398cd9b4
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/UserModules.class.inc
@@ -0,0 +1,167 @@
+<?php
+
+/**
+ * \file UserModules.class.inc
+ * \class UserModules
+ *
+ * \author Yoann Perollet <yoann.perollet@veremes.com>.
+ *
+ * 	\brief This file contains the UserModules php class
+ *
+ * This class defines Rest Api to Gtf usermodules
+ *
+ */
+require_once 'Vmap.class.inc';
+require_once 'UserModule.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+require_once(__DIR__ . '/../../class/vmlib/BdDataAccess.inc');
+
+class UserModules extends Vmap {
+    /**
+     * @SWG\Definition(
+     *   definition="/usermodules",
+     *   allOf={
+     *     @SWG\Schema(ref="#/definitions/usermodules")
+     *   }
+     * )
+     */
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("module_id", "label", "description", "rolname", "rolname_list");
+    }
+
+    /**
+     * @SWG\Get(path="/usermodules",
+     *   tags={"Modules"},
+     *   summary="Get User UserModules",
+     *   description="Request to get UserModules",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="order_by",
+     *     in="query",
+     *     description="list of ordering fields",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="limit",
+     *     in="query",
+     *     description="number of element",
+     *     required=false,
+     *     type="integer"
+     *   ),
+     * @SWG\Parameter(
+     *     name="offset",
+     *     in="query",
+     *     description="index of first element",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="attributs",
+     *     in="query",
+     *     description="list of attributs",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="filter",
+     *     in="query",
+     *     description="filter results",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="distinct",
+     *     in="query",
+     *     description="delete duplicates",
+     *     required=false,
+     *     type="boolean"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/usermodules")
+     *     )
+     *  )
+     */
+
+    /**
+     * get UserModules
+     * @return  UserModules
+     */
+    function GET() {
+        require $this->sRessourcesFile;
+        // Structure json des modules et leurs paramètres.
+        $aReturn = $this->genericGet($this->aProperties['schema_vmap'], 'module', 'module_id');
+        if ($aReturn['sStatus'] == 1) {
+
+            $oUserModules = new stdClass();
+            $oUserModules->usermodules = array();
+
+            if (empty($this->aValues['my_vitis_id'])) {
+                // Nombre d'enregistrements total
+                $oUserModules->total_row_number = $this->aFields['total_row_number'];
+            }
+
+            $iListCount = 0;
+            $oUserModules->status = $aReturn['sStatus'];
+            $aUserModulesIds = [];
+            foreach ($this->aObjects as $oModule) {
+                if (!empty($oModule->aFields['rolname_list'])) {
+                    $aRoleNames = explode('|', $oModule->aFields['rolname_list']);
+                } else {
+                    // Rétrocompatibilité
+                    $aRoleNames = array($oModule->aFields['rolname']);
+                }
+
+                for ($i = 0; $i < count($aRoleNames); $i++) {
+                    if (in_array($aRoleNames[$i], $this->oConnection->aPrivileges)) {
+                        $iListCount++;
+                        $oUserModule = new stdClass();
+                        $oUserModule->infos = new stdClass();
+                        $sModuleId = $oModule->aFields['module_id'];
+                        if (!in_array($sModuleId, $aUserModulesIds)) {
+                            $oUserModule->infos->icon = 'icon-' . $sModuleId;
+                            $oUserModule->infos->image = '';
+                            $oUserModule->infos->tooltip = $oModule->aFields['label'];
+                            $oUserModules->usermodules[] = $oUserModule;
+                            $oUserModule->$sModuleId = new stdClass();
+                            $aUserModulesIds[] = $sModuleId;
+                        }
+                    }
+                }
+            }
+
+            // Nombre d'enregistrements affichés
+            $oUserModules->list_count = $iListCount;
+
+            $this->aFields = $oUserModules;
+
+            $aXmlRacineAttribute['status'] = 1;
+            $sMessage = $this->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+        } else
+            $sMessage = $aReturn['sMessage'];
+        return $sMessage;
+    }
+
+}
+
+?>
diff --git a/vmap/vas/rest/ws/vmap/UserPrintStyle.class.inc b/vmap/vas/rest/ws/vmap/UserPrintStyle.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..d60ac04ab97bd672113098cadafdd77542b3d9e3
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/UserPrintStyle.class.inc
@@ -0,0 +1,72 @@
+<?php
+
+require_once 'Vmap.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+
+/**
+ * \file UserPrintStyle.class.inc
+ * \class UserPrintStyle
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * \brief This file contains the UserPrintStyle php class
+ *
+ * This class defines operation for one UserPrintStyle
+ * 
+ */
+class UserPrintStyle extends Vmap {
+
+    public $oError;
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("printstyle_id", "name", "definition");
+    }
+
+    /**
+     * @SWG\Get(path="/userprintstyles/{printstyle_id}", 
+     *   tags={"PrintStyles"},
+     *   summary="Get UserPrintStyle",
+     *   description="Request to get UserPrintStyle by id",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="printstyle_id",
+     *     in="path",
+     *     description="printstyle id",
+     *     required=true,
+     *     type="integer"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/userprintstyles")
+     *     )
+     *  )
+     */
+
+    /**
+     * get informations about UserPrintStyle
+     */
+    function GET() {
+        $this->aFields = $this->getFields($this->aProperties['schema_vmap'], 'v_user_printstyle', 'printstyle_id');
+        $this->aFields['definition'] = str_replace(array("\r", "\n", "\t"), '', $this->aFields['definition']);
+    }
+}
+
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/UserPrintStyles.class.inc b/vmap/vas/rest/ws/vmap/UserPrintStyles.class.inc
new file mode 100644
index 0000000000000000000000000000000000000000..d24bea2b81848189bbddb6bd3d0a4d4d1ad6aa37
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/UserPrintStyles.class.inc
@@ -0,0 +1,155 @@
+<?php
+
+/**
+ * \file UserPrintStyles.class.inc
+ * \class UserPrintStyles
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * \brief This file contains the UserPrintStyles php class
+ *
+ * This class defines Rest Api to Vmap UserPrintStyles
+ *
+ */
+require_once 'Vmap.class.inc';
+require_once 'UserPrintStyle.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+require_once __DIR__ . '/../../class/vmlib/BdDataAccess.inc';
+
+class UserPrintStyles extends Vmap {
+    /**
+     * @SWG\Definition(
+     *   definition="/userprintstyles",
+     *   allOf={
+     *     @SWG\Schema(ref="#/definitions/printstyles")
+     *   }
+     * )
+     * * @SWG\Tag(
+     *   name="UserPrintStyles",
+     *   description=""
+     * )
+     */
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("printstyle_id", "name", "definition");
+    }
+
+    /**
+     * @SWG\Get(path="/userprintstyles",
+     *   tags={"PrintStyles"},
+     *   summary="Get UserPrintStyles",
+     *   description="Request to get UserPrintStyles",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="order_by",
+     *     in="query",
+     *     description="list of ordering fields",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="sort_order",
+     *     in="query",
+     *     description="sort order",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="limit",
+     *     in="query",
+     *     description="number of element",
+     *     required=false,
+     *     type="integer"
+     *   ),
+     * @SWG\Parameter(
+     *     name="offset",
+     *     in="query",
+     *     description="index of first element",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="attributs",
+     *     in="query",
+     *     description="list of attributs",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="filter",
+     *     in="query",
+     *     description="filter results",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="distinct",
+     *     in="query",
+     *     description="delete duplicates",
+     *     required=false,
+     *     type="boolean"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/userprintstyles")
+     *     )
+     *  )
+     */
+
+    /**
+     * get UserPrintStyles
+     * @return  UserPrintStyles
+     */
+    function GET() {
+        $aReturn = $this->genericGet($this->aProperties['schema_vmap'], 'v_user_printstyle', 'printstyle_id');
+
+        if ($aReturn['sStatus'] == 1) {
+            $oUserPrintStyles = new stdClass();
+            $oUserPrintStyles->userprintstyles = array();
+            if (empty($this->aValues['my_vitis_id'])) {
+                $oUserPrintStyles->list_count = $this->aFields['list_count'];
+                $oUserPrintStyles->total_row_number = $this->aFields['total_row_number'];
+            }
+            $oUserPrintStyles->status = $aReturn['sStatus'];
+            foreach ($this->aObjects as $oPrintStyle) {
+                $oUserPrintStyle = new stdClass();
+                if (!empty($oPrintStyle->aFields['printstyle_id'])) {
+                    $oUserPrintStyle->printstyle_id = $oPrintStyle->aFields['printstyle_id'];
+                }
+                if (!empty($oPrintStyle->aFields['name'])) {
+                    $oUserPrintStyle->name = $oPrintStyle->aFields['name'];
+                }
+                if (!empty($oPrintStyle->aFields['definition'])) {
+                    $oUserPrintStyle->definition = $oPrintStyle->aFields['definition'];
+                }
+                $oUserPrintStyles->userprintstyles[] = $oUserPrintStyle;
+            }
+            $this->aFields = $oUserPrintStyles;
+            $aXmlRacineAttribute['status'] = 1;
+            $sMessage = $this->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+        }
+
+        return $sMessage;
+    }
+
+}
+
+?>
diff --git a/vmap/vas/rest/ws/vmap/UserPrintTemplate.class.inc b/vmap/vas/rest/ws/vmap/UserPrintTemplate.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..c82564036d02868cf14a12d4c79fc37ff85f8486
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/UserPrintTemplate.class.inc
@@ -0,0 +1,117 @@
+<?php
+
+require_once 'Vmap.class.inc';
+require_once 'UserPrintTemplates.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+
+/**
+ * \file UserPrintTemplate.class.inc
+ * \class UserPrintTemplate
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * 	\brief This file contains the UserPrintTemplate php class
+ *
+ * This class defines operation for one UserPrintTemplate
+ * 
+ */
+class UserPrintTemplate extends Vmap {
+
+    public $oError;
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("printtemplate_id", "name", "rt_format_id", "rt_orientation_id", "definition", "outputformats_id", "sql", "ressource_id", "business_object_id", "printstyles");
+    }
+
+    /**
+     * @SWG\Get(path="/userprinttemplates/{printtemplate_id}", 
+     *   tags={"PrintTemplates"},
+     *   summary="Get UserPrintTemplate",
+     *   description="Request to get UserPrintTemplate by id",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="printtemplate_id",
+     *     in="path",
+     *     description="printtemplate id",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/userprinttemplates")
+     *     )
+     *  )
+     */
+
+    /**
+     * get informations about userprinttemplate
+     */
+    function GET() {
+        $this->aFields = $this->getFields($this->aProperties['schema_vmap'], 'v_template', 'printtemplate_id');
+//        $this->aFields['definition'] = $this->getPrintTemplateWithStyles();
+        
+        $this->aFields['printstyles'] = $this->getPrintStylesFromUser();
+    }
+
+    /**
+     * Get the printstyles associated to current user
+     * @return array
+     */
+//    function getPrintTemplateWithStyles() {
+//        $aPrintStyles = $this->getPrintStylesFromUser();        
+//        $sPrintStyle = $this->concatPrintStyles($aPrintStyles);        
+//        $sTemplateDefinition = $sPrintStyle . $this->aFields['definition'];
+//        
+//        return $sTemplateDefinition;
+//    }
+
+    /**
+     * Get the printstyles associated to current user
+     * @return array
+     */
+    function getPrintStylesFromUser() {
+        $oUserPrintStyles = new UserPrintStyles($this->aPath, $this->aValues, $this->aProperties);
+        $oUserPrintStyles->aValues['my_vitis_id'] = null;
+        $oUserPrintStyles->aValues['filter'] = '';
+        $oUserPrintStyles->GET();
+
+        $aPrintStyles = $oUserPrintStyles->aFields->userprintstyles;
+
+        return $aPrintStyles;
+    }
+
+    /**
+     * Concat the definitions of the given print styles
+     * @param array $aPrintStyles
+     * @return string
+     */
+//    function concatPrintStyles($aPrintStyles) {
+//        $sPrintStyle = "";
+//        for ($i = 0; $i < count($aPrintStyles); $i++) {
+//            $sPrintStyle .= $aPrintStyles[$i]->definition;
+//        }
+//
+//        return $sPrintStyle;
+//    }
+
+}
+
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/UserPrintTemplates.class.inc b/vmap/vas/rest/ws/vmap/UserPrintTemplates.class.inc
new file mode 100644
index 0000000000000000000000000000000000000000..98e4337fc46d95fa3bf4ef411a9d87825ac4d084
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/UserPrintTemplates.class.inc
@@ -0,0 +1,237 @@
+<?php
+
+/**
+ * \file UserPrintTemplates.class.inc
+ * \class UserPrintTemplates
+ *
+ * \author Yoann Perollet <yoann.perollet@veremes.com>.
+ *
+ * 	\brief This file contains the UserPrintTemplates php class
+ *
+ * This class defines Rest Api to Gtf userprinttemplates
+ *
+ */
+require_once 'Vmap.class.inc';
+require_once 'UserPrintTemplate.class.inc';
+require_once 'UserPrintStyles.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+require_once(__DIR__ . '/../../class/vmlib/BdDataAccess.inc');
+require_once(__DIR__ . '/../../class/vmlib/phpUtil.inc');
+
+class UserPrintTemplates extends Vmap {
+    /**
+     * @SWG\Definition(
+     *   definition="/userprinttemplates",
+     *   allOf={
+     *     @SWG\Schema(ref="#/definitions/userprinttemplates")
+     *   }
+     * )
+     */
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aValues['getGroup'] = true;
+        $this->oConnection = new Connection($this->aValues, $this->aProperties);
+        $this->aSelectedFields = Array("printtemplate_id", "name", "rt_format_id", "rt_orientation_id", "definition", "outputformats_id", "printstyles");
+    }
+
+    /**
+     * @SWG\Get(path="/userprinttemplates",
+     *   tags={"PrintTemplates"},
+     *   summary="Get User UserPrintTemplates",
+     *   description="Request to get UserPrintTemplates",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="order_by",
+     *     in="query",
+     *     description="list of ordering fields",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="limit",
+     *     in="query",
+     *     description="number of element",
+     *     required=false,
+     *     type="integer"
+     *   ),
+     * @SWG\Parameter(
+     *     name="offset",
+     *     in="query",
+     *     description="index of first element",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="attributs",
+     *     in="query",
+     *     description="list of attributs",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="filter",
+     *     in="query",
+     *     description="filter results",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * @SWG\Parameter(
+     *     name="distinct",
+     *     in="query",
+     *     description="delete duplicates",
+     *     required=false,
+     *     type="boolean"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/userprinttemplates")
+     *     )
+     *  )
+     */
+
+    /**
+     * get UserPrintTemplates
+     * @return  UserPrintTemplates
+     */
+    function GET() {
+        require $this->sRessourcesFile;
+        // Structure json des modèles d'impression et leurs paramètres.
+        $aSesGroup = explode(',', $this->oConnection->sesGroup);
+        for ($i = 0; $i < count($aSesGroup); $i++) {
+            $aSesGroup[$i] = floatval($aSesGroup[$i]);
+        }
+        if (isset($this->aValues['filter']) && !empty($this->aValues['filter'])) {
+            $old_filter = $this->aValues['filter'];
+        } else {
+            $old_filter = '';
+        }
+        $aFilter = array(
+            'relation' => 'AND',
+            'operators' => array(
+                array('column' => 'group_id', 'compare_operator' => 'IN', 'value' => $aSesGroup)
+            )
+        );
+        if (isset($this->aValues['filter']) && $this->aValues['filter'] != "") {
+            array_push($aFilter['operators'], json_decode($this->aValues['filter']));
+        }
+        $this->aValues['filter'] = json_encode($aFilter);
+
+        $aReturn = $this->genericGet($this->aProperties['schema_vmap'], 'v_user_template', 'printtemplate_id');
+        $this->aValues['filter'] = $old_filter;
+
+        if ($aReturn['sStatus'] == 1) {
+
+            // Styles d'impression liés à l'utilisateur
+            $aPrintStyles = $this->getPrintStylesFromUser();
+
+            // Enrichi les objets
+            foreach ($this->aObjects as $key => $oPrintTemplate) {
+
+                if (!empty($oPrintTemplate->aFields['rt_format_id'])) {
+                    $oPrintTemplate->aFields['format'] = $oPrintTemplate->aFields['rt_format_id'];
+                }
+                if (!empty($oPrintTemplate->aFields['rt_orientation_id'])) {
+                    $oPrintTemplate->aFields['orientation'] = $oPrintTemplate->aFields['rt_orientation_id'];
+                }
+                $oPrintTemplate->aFields['printstyles'] = $aPrintStyles;
+                $oPrintTemplate->aFields['variables'] = $this->getPrintTemplateParameters($oPrintTemplate->aFields['printtemplate_id']);
+
+                // Nettoyage
+                if (isset($oPrintTemplate->aFields['rt_format_id'])) {
+                    unset($oPrintTemplate->aFields['rt_format_id']);
+                }
+                if (isset($oPrintTemplate->aFields['rt_orientation_id'])) {
+                    unset($oPrintTemplate->aFields['rt_orientation_id']);
+                }
+            }
+            $aXmlRacineAttribute['status'] = 1;
+            $aReturn['sMessage'] = $this->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+        }
+
+
+        return $aReturn['sMessage'];
+    }
+
+    /**
+     * Get the printstyles associated to current user
+     * @return array
+     */
+    function getPrintStylesFromUser() {
+        $oUserPrintStyles = new UserPrintStyles($this->aPath, $this->aValues, $this->aProperties);
+        $oUserPrintStyles->aValues['my_vitis_id'] = null;
+        $oUserPrintStyles->aValues['filter'] = '';
+        $oUserPrintStyles->GET();
+
+        $aPrintStyles = $oUserPrintStyles->aFields->userprintstyles;
+
+        return $aPrintStyles;
+    }
+
+    /**
+     * Get the print parameters associated to the print template
+     * @return array
+     */
+    function getPrintTemplateParameters($sPrintTemplateId) {
+        require $this->sRessourcesFile;
+
+        $aVariables = array();
+
+        // Paramètres du modèle d'impression.
+        $sSql = $aSql['getPrintTemplateParameters'];
+        $aSQLParams = array(
+            'sSchemaVmap' => array('value' => $this->aProperties['schema_vmap'], 'type' => 'column_name'),
+            'printtemplate_id' => array('value' => $sPrintTemplateId, 'type' => 'number')
+        );
+        $resultat = $this->oConnection->oBd->executeWithParams($sSql, $aSQLParams);
+        if (!$this->oConnection->oBd->enErreur()) {
+            while ($aPrintParameter = $this->oConnection->oBd->ligneSuivante($resultat)) {
+                $oPrintParameter = new stdClass();
+                $oPrintParameter->printtemplate_id = $aPrintParameter['printtemplate_id'];
+                $oPrintParameter->name = $aPrintParameter['name'];
+                $oPrintParameter->editable = $aPrintParameter['editable'];
+                $oPrintParameter->label = $aPrintParameter['label'];
+                $oPrintParameter->description = $aPrintParameter['placeholder'];
+                $oPrintParameter->value = $aPrintParameter['defaultvalue'];
+                $aVariables[] = $oPrintParameter;
+            }
+        }
+
+        return $aVariables;
+    }
+
+    /**
+     * Concat the definitions of the given print styles
+     * @param array $aPrintStyles
+     * @return string
+     */
+//    function concatPrintStyles($aPrintStyles) {
+//
+//        $sPrintStyle = "";
+//        for ($i = 0; $i < count($aPrintStyles); $i++) {
+//            $sPrintStyle .= $aPrintStyles[$i]->definition;
+//        }
+//
+//        return $sPrintStyle;
+//    }
+
+}
+
+?>
diff --git a/vmap/vas/rest/ws/vmap/Versions.class.inc b/vmap/vas/rest/ws/vmap/Versions.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..0db8644feefb322a38799677697375dab8d83a48
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/Versions.class.inc
@@ -0,0 +1,77 @@
+<?php
+
+require_once 'Vmap.class.inc';
+/**
+* \file versions.class.inc
+* \class Versions
+*
+* \author Yoann Perollet <yoann.perollet@veremes.com>.
+*
+*	\brief This file contains the Versions php class
+*
+* This class defines the rest api for versions
+* 
+*/
+class Versions  extends Vmap{
+    
+    /**
+     * @SWG\Definition(
+     *   definition="/Versions",
+     *   allOf={
+     *     @SWG\Schema(ref="#/definitions/Versions")
+     *   }
+     * )
+     * @SWG\Tag(
+     *   name="Versions",
+     *   description="Operations about versions"
+     * )
+     */
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $versions ptroperties
+     */
+    function __construct($aPath, $aValues, $properties){
+        $this->aValues = $aValues;
+        $this->aPath = $aPath;
+        $this->aProperties = $properties;
+    }
+    
+    /**
+     * @SWG\Get(path="/Versions",
+     *   tags={"Versions"},
+     *   summary="Get versions",
+     *   description="Request to get versions",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *  @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/Versions")
+     *     )
+     *  )
+     */
+    /**
+     * 
+     * @return versions
+     */
+    function GET(){
+		$this->getVersion("vmap");
+        //$this->aFields = $this->aVersions;
+       
+        //
+        $aXmlRacineAttribute['status']=1;
+        $sMessage = $this->asDocument('','vitis',$this->aValues['sEncoding'],True,$aXmlRacineAttribute,$this->aValues['sSourceEncoding'],$this->aValues['output']);
+        return $sMessage;
+    }
+}
+ 
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/Vex.class.inc b/vmap/vas/rest/ws/vmap/Vex.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..023f077d134c062c6f8d2ab5db72a9ff1efd0466
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/Vex.class.inc
@@ -0,0 +1,513 @@
+<?php
+
+/**
+ * \file Vex.class.inc
+ * \class Vex
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * 	\brief This file contains the Vex php class
+ *
+ * This class defines Rest Api to Vitis vex
+ * 
+ */
+require_once 'Vmap.class.inc';
+require_once 'VexExport.class.inc';
+require_once 'VexImport.class.inc';
+require_once 'VexGetter.class.inc';
+require_once 'VexParser.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Form.class.inc';
+require_once __DIR__ . '/../../class/vmlib/BdDataAccess.inc';
+require_once 'vmlib/logUtil.inc';
+
+class Vex extends Vmap {
+    /**
+     * @SWG\Definition(
+     *   definition="/vex",
+     *   allOf={
+     *     @SWG\Schema(ref="#/definitions/vex")
+     *   }
+     * )
+     * * @SWG\Tag(
+     *   name="Vex",
+     *   description=""
+     * )
+     */
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+    }
+
+    /**
+     * @SWG\Get(path="/vex",
+     *   tags={"Vex"},
+     *   summary="",
+     *   description="",
+     *   operationId="GET",
+     *   produces={"application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="vex url",
+     *         @SWG\Schema(ref="#/definitions/vex")
+     *     )
+     *  )
+     */
+    /**
+     * @SWG\Get(path="/vex/vmap_objects",
+     *   tags={"Vex"},
+     *   summary="Get vMap objects list",
+     *   description="Return the list of maps, calques, business objects and layers",
+     *   operationId="GET",
+     *   produces={"application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Web services list",
+     *         @SWG\Schema(ref="#/vex/web_services")
+     *     )
+     *  )
+     */
+    /**
+     * @SWG\Get(path="/vex/web_services",
+     *   tags={"Vex"},
+     *   summary="Get web services list",
+     *   description="Return the list of the web services of one or many business objects",
+     *   operationId="GET",
+     *   produces={"application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="business_objects",
+     *     in="query",
+     *     description="business objects list",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Web services list",
+     *         @SWG\Schema(ref="#/vex/web_services")
+     *     )
+     *  )
+     */
+    /**
+     * @SWG\Get(path="/vex/sql_objects",
+     *   tags={"Vex"},
+     *   summary="Get avaliable sql objects list",
+     *   description="Return the list of the schemas, tables, views avaliable to dump",
+     *   operationId="GET",
+     *   produces={"application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="database",
+     *     in="query",
+     *     description="Database to search in",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Web services list",
+     *         @SWG\Schema(ref="#/vex/web_services")
+     *     )
+     *  )
+     */
+    /**
+     * @SWG\Get(path="/vex/existing_vmap_objects",
+     *   tags={"Vex"},
+     *   summary="Get existing vMap objects",
+     *   description="Return the list of the existing vMap objects with the same names than those paseed in parametters",
+     *   operationId="GET",
+     *   produces={"application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="maps",
+     *     in="query",
+     *     description="Map names separed by pipes",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="services",
+     *     in="query",
+     *     description="Service names separed by pipes",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="calques",
+     *     in="query",
+     *     description="Calque names separed by pipes",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="vm4ms_layers",
+     *     in="query",
+     *     description="Vm4ms Layer names separed by pipes",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="business_objects",
+     *     in="query",
+     *     description="Business object names separed by pipes",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="events",
+     *     in="query",
+     *     description="Event names separed by pipes",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="repports",
+     *     in="query",
+     *     description="Report names separed by pipes",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Web services list",
+     *         @SWG\Schema(ref="#/vex/web_services")
+     *     )
+     *  )
+     */
+
+    /**
+     * @SWG\Get(path="/vex/existing_web_services",
+     *   tags={"Vex"},
+     *   summary="Get existing web services",
+     *   description="Return the list of the existing web services with the same names than those paseed in parametters",
+     *   operationId="GET",
+     *   produces={"application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Parameter(
+     *     name="web_services",
+     *     in="query",
+     *     description="Web services names separed by pipes",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Web services list",
+     *         @SWG\Schema(ref="#/vex/web_services")
+     *     )
+     *  )
+     */
+    function GET() {
+        if ($this->aPath[2] === 'vmap_objects') {
+            $oVexGetter = new VexGetter($this->aPath, $this->aValues, $this->aProperties);
+            return $oVexGetter->getVMapObjectsList();
+        }
+        if ($this->aPath[2] === 'web_services') {
+            $oVexGetter = new VexGetter($this->aPath, $this->aValues, $this->aProperties);
+            return $oVexGetter->getWebServicesList();
+        }
+        if ($this->aPath[2] === 'sql_objects') {
+            $oVexGetter = new VexGetter($this->aPath, $this->aValues, $this->aProperties);
+            return $oVexGetter->getSqlObjects();
+        }
+        if ($this->aPath[2] === 'existing_vmap_objects') {
+            $oVexGetter = new VexGetter($this->aPath, $this->aValues, $this->aProperties);
+            return $oVexGetter->getExistingVMapObjectsList();
+        }
+        if ($this->aPath[2] === 'existing_web_services') {
+            $oVexGetter = new VexGetter($this->aPath, $this->aValues, $this->aProperties);
+            return $oVexGetter->getExistingWebServicesList();
+        }
+    }
+
+    // POST
+
+    /**
+     * @SWG\Post(path="/vex/parse_vex",
+     *   tags={"Vex"},
+     *   summary="Get Vex file contents",
+     *   description="Request to parse the given vex file and get his contents",
+     *   operationId="POST",
+     *   produces={"application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="vex_file",
+     *     in="formData",
+     *     description="vex file",
+     *     required=true,
+     *     type="file"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Generated VEX URL",
+     *         @SWG\Schema(ref="#/vex/export_vex")
+     *     )
+     *  )
+     * )
+     */
+    /**
+     * @SWG\Post(path="/vex/export_vex",
+     *   tags={"Vex"},
+     *   summary="Get Vex file",
+     *   description="Request to generate and get a .vex file",
+     *   operationId="POST",
+     *   produces={"application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="vmap_objects",
+     *     in="formData",
+     *     description="Maps, calques, business objects in JSON",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="web_services",
+     *     in="formData",
+     *     description="Web services folders names",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="sql_objects",
+     *     in="formData",
+     *     description="Database, schemas, tables, to export in JSON",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Generated VEX URL",
+     *         @SWG\Schema(ref="#/vex/export_vex")
+     *     )
+     *  )
+     * )
+     */
+
+    /**
+     * @SWG\Post(path="/vex/import/vmap_objects",
+     *   tags={"Vex"},
+     *   summary="Import vMap objects",
+     *   description="Request to import .vex vMap object",
+     *   operationId="POST",
+     *   produces={"application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="vmap_objects",
+     *     in="formData",
+     *     description="Maps, services, calques, vm4ms_layers, business_objects, business_objects_forms, events, reports definitions in JSON",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="database",
+     *     in="formData",
+     *     description="database",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="schema",
+     *     in="formData",
+     *     description="schema",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="srid",
+     *     in="formData",
+     *     description="srid",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="",
+     *         @SWG\Schema(ref="#/vex/import/vmap_objects")
+     *     )
+     *  )
+     * )
+    /**
+     * @SWG\Post(path="/vex/import/web_services",
+     *   tags={"Vex"},
+     *   summary="Import web services",
+     *   description="Request to import .vex web services",
+     *   operationId="POST",
+     *   produces={"application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="web_services",
+     *     in="formData",
+     *     description="Web services content",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="",
+     *         @SWG\Schema(ref="#/vex/import/vmap_objects")
+     *     )
+     *  )
+     * )
+     */
+    /**
+     * @SWG\Post(path="/vex/import/sql",
+     *   tags={"Vex"},
+     *   summary="Import sql",
+     *   description="Request to import .vex SQL",
+     *   operationId="POST",
+     *   produces={"application/json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="sql_model",
+     *     in="formData",
+     *     description="SQL model",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="sql_data",
+     *     in="formData",
+     *     description="SQL data",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="database",
+     *     in="formData",
+     *     description="Database",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="schema",
+     *     in="formData",
+     *     description="Schema",
+     *     required=true,
+     *     type="string"
+     *   ),
+     *  @SWG\Parameter(
+     *     name="srid",
+     *     in="formData",
+     *     description="SRID",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="",
+     *         @SWG\Schema(ref="#/vex/import/vmap_objects")
+     *     )
+     *  )
+     * )
+     */
+    function POST() {
+        if ($this->aPath[2] === 'parse_vex') {
+            $oVexParser = new VexParser($this->aPath, $this->aValues, $this->aProperties);
+            return $oVexParser->parseVex();
+        }
+        if ($this->aPath[2] === 'export_vex') {
+            $oVexExport = new VexExport($this->aPath, $this->aValues, $this->aProperties);
+            return $oVexExport->exportVex();
+        }
+        if ($this->aPath[2] === 'import') {
+            $oVexImport = new VexImport($this->aPath, $this->aValues, $this->aProperties);
+            if ($this->aPath[3] === 'vmap_objects') {
+                return $oVexImport->importVMapObjects();
+            }
+            if ($this->aPath[3] === 'web_services') {
+                return $oVexImport->importWebServices();
+            }
+            if ($this->aPath[3] === 'sql') {
+                return $oVexImport->importSQL();
+            }
+        }
+    }
+
+    function PUT() {
+        
+    }
+
+    function DELETE() {
+        
+    }
+
+}
+
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/Vex.class.sql.inc b/vmap/vas/rest/ws/vmap/Vex.class.sql.inc
new file mode 100755
index 0000000000000000000000000000000000000000..9ca1e46fecc28754224c1b7c6c71733c4e1575f7
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/Vex.class.sql.inc
@@ -0,0 +1,15 @@
+<?php
+
+$aSql['getAvaliableSRID'] = "SELECT srid from spatial_ref_sys";
+$aSql['getLayers'] = "SELECT * FROM s_vmap.v_layer";
+$aSql['getLayersById'] = "SELECT * FROM s_vmap.v_layer WHERE layer_id IN ([idList])";
+$aSql['getLayersByName'] = "SELECT * FROM s_vmap.v_layer WHERE name IN ([namesList])";
+$aSql['getBusinessObjects'] = "SELECT \"business_object_id\", \"database\", \"schema\", \"table\", \"id_field\" FROM s_vmap.business_object";
+$aSql['getBusinessObjectByIds'] = "SELECT * FROM s_vmap.business_object WHERE business_object_id IN ([idList])";
+$aSql['getGeometryColumns'] = 'SELECT f_geometry_column FROM public.geometry_columns WHERE f_table_schema = \'[sSchemaFramework]\' AND f_table_name = \'[sTable]\'';
+$aSql['updateTableColumnSRID'] = 'SELECT UpdateAndTransformGeometrySRID([sSchema], [sTable], [sColumn], [iSRID]);';
+$aSql['getTables'] = "SELECT tablename, schemaname FROM pg_catalog.pg_tables WHERE schemaname = [sSchema]";
+$aSql['getViews'] = "SELECT viewname, schemaname FROM pg_catalog.pg_views  WHERE schemaname = [sSchema]";
+$aSql['getSequences'] = "SELECT sequence_name FROM information_schema.sequences WHERE sequence_schema = [sSchema]";
+
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/VexExport.class.inc b/vmap/vas/rest/ws/vmap/VexExport.class.inc
new file mode 100644
index 0000000000000000000000000000000000000000..5a964bae90e7669f11e8e77c8450bb10fff290d3
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/VexExport.class.inc
@@ -0,0 +1,1675 @@
+<?php
+
+/**
+ * \file VexExport.class.inc
+ * \class VexExport
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * 	\brief This file contains the VexExport php class
+ *
+ * This class defines php functions to export VEX files
+ *
+ */
+require_once 'Vex.class.inc';
+require_once 'VexGetter.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Form.class.inc';
+require_once __DIR__ . '/../../class/vmlib/BdDataAccess.inc';
+require_once 'vmlib/logUtil.inc';
+
+/**
+ * Permet l'export de fichiers VEX en utilisant les paramètres
+ * vmap_objects, web_services, sql_objects passés dans $this->aValues
+ */
+class VexExport extends Vmap {
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+    }
+
+    /**
+     * Generate a VEX file
+     */
+    function exportVex() {
+
+        if (!in_array('vitis_admin', $this->oConnection->aPrivileges) ||
+                !in_array('vmap_admin', $this->oConnection->aPrivileges) ||
+                !in_array('vm4ms_admin', $this->oConnection->aPrivileges)) {
+            $oError = new VitisError(0, 'insufficient privileges (needs to be vitis_admin, vmap_admin and vm4ms_admin)');
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        }
+
+        // OS sur lequel tourne php
+        if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
+            $this->sOSType = 'windows';
+        } else {
+            echo 'Le serveur ne tourne pas sous Windows !';
+            $this->sOSType = 'linux';
+        }
+
+        // Nom du fichier temporaire
+        $this->sTmpName = $this->UniqFileName();
+
+        // Crée un dossier temporaire de travail
+        $this->sTmpPath = $this->createTmpFolder($this->sTmpName);
+
+        // SQL
+        if (!isset($this->oError) && !isset($this->oConnection->oError) && !$this->oConnection->oBd->enErreur()) {
+            $this->exportSQL();
+        }
+
+        // Objets vMap
+        if (!isset($this->oError) && !isset($this->oConnection->oError) && !$this->oConnection->oBd->enErreur()) {
+            $this->exportVMapObjects();
+        }
+
+        // Services WEB
+        if (!isset($this->oError) && !isset($this->oConnection->oError) && !$this->oConnection->oBd->enErreur()) {
+            $this->exportWebServices();
+        }
+
+        // Crée le fichier VEX
+        if (!isset($this->oError) && !isset($this->oConnection->oError) && !$this->oConnection->oBd->enErreur()) {
+            $this->sVexPath = $this->createVexFile();
+        }
+
+        // Supprime le dossier temporaire de travail
+        $this->deleteTmpFolder($this->sTmpPath);
+
+        if (isset($this->oError)) {
+            $oError = new VitisError(1, $this->oError->getMessage());
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } elseif (isset($this->oConnection->oError)) {
+            $oError = $this->oConnection->oError;
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } elseif ($this->oConnection->oBd->enErreur()) {
+            $oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } elseif (is_file($this->sVexPath)) {
+            $handle = fopen($this->sVexPath, "r");
+            $contents = fread($handle, filesize($this->sVexPath));
+            fclose($handle);
+
+            // Supprime le dossier vex
+            $this->deleteVexFile($this->sVexPath);
+
+            return $contents;
+        } else {
+            $oError = new VitisError(1, 'Impossoble de générer le fichier VEX');
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        }
+    }
+
+    /**
+     * Crée un répertoire temporaire
+     * @param string $sName
+     * @return string
+     */
+    function createTmpFolder($sName) {
+        $sTmpPath = $this->aProperties['vas_home'] . '/tmp/' . $sName;
+        if (is_dir($sTmpPath)) {
+            clearDir($sTmpPath);
+        }
+        mkdir($sTmpPath, 0777, true);
+        return $sTmpPath;
+    }
+
+    /**
+     * Supprime le répertoire temporaire
+     * @param string $sTmpPath
+     */
+    function deleteTmpFolder($sTmpPath) {
+        if (is_dir($sTmpPath)) {
+            clearDir($sTmpPath);
+        }
+    }
+
+    /**
+     * Crée le fichier VEX
+     */
+    function createVexFile() {
+        $sVexPath = $this->sTmpPath . '.vex';
+        createZip($this->sTmpPath, $sVexPath);
+        return $sVexPath;
+    }
+
+    /**
+     * Supprime le fichier vex
+     * @param string $sVexPath
+     */
+    function deleteVexFile($sVexPath) {
+        if (is_file($sVexPath)) {
+            @unlink($sVexPath);
+        }
+    }
+
+    // Export SQL
+
+    /**
+     * Exporte le SQL
+     */
+    function exportSQL() {
+
+        if (empty($this->aValues['sql_objects'])) {
+            return false;
+        }
+
+        $aSQLObjects = json_decode($this->aValues['sql_objects'], true);
+
+        if (empty($aSQLObjects)) {
+            return false;
+        }
+        if (empty($aSQLObjects['schemas'])) {
+            return false;
+        }
+
+        /**
+         * Objet VexGetter permettant de recueillir des informations essentielles
+         */
+        $this->oVexGetter = new VexGetter($this->aPath, $this->aValues, $this->aProperties);
+
+        // Dossier sql
+        mkdir($this->sTmpPath . '/sql', 0777, true);
+
+        // Liste des schémas utilisés
+        $this->aSchemas = [];
+
+        // Fichier SQl contenant le modèle de données SQL
+        $this->sSqlFileModelPath = $this->sTmpPath . '/sql/export_model_sql.sql';
+        $this->sSqlLogModelPath = $this->sTmpPath . '/sql/export_model_sql.log';
+
+        // Fichier SQl contenant les données SQL
+        $this->sSqlFileDataPath = $this->sTmpPath . '/sql/export_data_sql.sql';
+        $this->sSqlLogDataPath = $this->sTmpPath . '/sql/export_data_sql.log';
+
+        if (!isset($this->oError)) {
+            $this->dumpSqlTables($aSQLObjects);
+        }
+        if (is_file($this->sSqlFileModelPath)) {
+            if (!isset($this->oError)) {
+                $this->makeSQLFileReplacements($this->sSqlFileModelPath, true, true, true);
+            }
+        }
+        if (is_file($this->sSqlFileDataPath)) {
+            if (!isset($this->oError)) {
+                $this->makeSQLFileReplacements($this->sSqlFileDataPath, true);
+            }
+        }
+    }
+
+    /**
+     * Fait un dump des tables demandées
+     *
+     * @param array $aSQLObjects tables à exporter au format suivant:
+     * {
+     *  "type":"database",
+     *  "name":"[database]",
+     *  "schemas":[{
+     *      "type":"schema",
+     *      "name":"[schema1]",
+     *      "tables":["[table1]","[table2]"]
+     *      }]
+     *  }
+     *
+     * @return boolean
+     */
+    function dumpSqlTables($aSQLObjects) {
+
+        $this->dumpSqlTablesModel($aSQLObjects);
+        $this->dumpSqlTablesData($aSQLObjects);
+
+        // Vérifie si le fichier sql a été généré, sinon renvoie false
+        if (!is_file($this->sSqlFileModelPath)) {
+            $sErrorMessage = 'Impossible de récupérer les données SQL';
+
+            if (is_file($this->sSqlLogModelPath)) {
+                $aLogs = file($this->sSqlLogModelPath);
+                $sErrorMessage .= ':<br>';
+                for ($i = 0; $i < count($aLogs); $i++) {
+                    $sErrorMessage .= '<br>' . $aLogs[$i];
+                }
+            }
+
+            $this->oError = new Error($sErrorMessage);
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    /**
+     * Exporte le modèle de données (sans les données) au format sql
+     * @param array $aSQLObjects
+     */
+    function dumpSqlTablesModel($aSQLObjects) {
+
+        $sLogin = $this->aProperties['owner_login'];
+        $sPassword = $this->aProperties['owner_pass'];
+
+        // Cas particuliers dans les mots de passe
+        $sPassword = str_replace('!', '\!', $sPassword);
+
+        $sDatabase = $this->getDatabaseFromSqlObjects($aSQLObjects);
+        $aTables = $this->getTablesFromSqlObjects($aSQLObjects);
+        $aViews = $this->getViewsFromSqlObjects($aSQLObjects);
+        $aSequences = $this->getSequencesFromSqlObjects($aSQLObjects);
+
+        // Si la base de données ou la liste des tables est vide pas de dump
+        if (empty($sDatabase) || (empty($aTables) && empty($aViews))) {
+            return true;
+        }
+
+        if ($this->sOSType === 'windows') {
+            $sPgDumpCommand = 'set PGPASSWORD="' . $sPassword . '" && ';
+        } else {
+            $sPgDumpCommand = 'export PGPASSWORD="' . $sPassword . '"; ';
+        }
+        $sPgDumpCommand .= $this->aProperties['pg_utils_root_path'] . '/pg_dump';
+        $sPgDumpCommand .= ' --host ' . $this->aProperties['server'];
+        $sPgDumpCommand .= ' --port ' . $this->aProperties['port'];
+        $sPgDumpCommand .= ' --username "' . $sLogin . '"';
+        $sPgDumpCommand .= ' --format plain';
+        $sPgDumpCommand .= ' --section pre-data';
+        $sPgDumpCommand .= ' --section post-data';
+        $sPgDumpCommand .= ' --inserts';
+        $sPgDumpCommand .= ' --column-inserts';
+        $sPgDumpCommand .= ' --verbose';
+        $sPgDumpCommand .= ' --no-owner';
+        $sPgDumpCommand .= ' --no-privileges';
+        $sPgDumpCommand .= ' --file "' . $this->sSqlFileModelPath . '"';
+        for ($i = 0; $i < count($aTables); $i++) {
+            $sPgDumpCommand .= ' --table "' . $aTables[$i] . '"';
+        }
+        for ($i = 0; $i < count($aViews); $i++) {
+            $sPgDumpCommand .= ' --table "' . $aViews[$i] . '"';
+        }
+        for ($i = 0; $i < count($aSequences); $i++) {
+            $sPgDumpCommand .= ' --table "' . $aSequences[$i] . '"';
+        }
+        $sPgDumpCommand .= ' "' . $sDatabase . '"';
+        $sPgDumpCommand .= ' 2> "' . $this->sSqlLogModelPath . '"';
+
+        exec($sPgDumpCommand);
+    }
+
+    /**
+     * Exporte les données uniquement au format sql
+     * @param array $aSQLObjects
+     */
+    function dumpSqlTablesData($aSQLObjects) {
+
+        $sLogin = $this->aProperties['owner_login'];
+        $sPassword = $this->aProperties['owner_pass'];
+
+        // Cas particuliers dans les mots de passe
+        $sPassword = str_replace('!', '\!', $sPassword);
+
+        $sDatabase = $this->getDatabaseFromSqlObjects($aSQLObjects);
+        $aTables = $this->getTablesFromSqlObjects($aSQLObjects, true);
+
+        // Si la base de données ou la liste des tables est vide pas de dump
+        if (empty($sDatabase) || empty($aTables)) {
+            return true;
+        }
+
+        if ($this->sOSType === 'windows') {
+            $sPgDumpCommand = 'set PGPASSWORD="' . $sPassword . '" && ';
+        } else {
+            $sPgDumpCommand = 'export PGPASSWORD="' . $sPassword . '"; ';
+        }
+        $sPgDumpCommand .= $this->aProperties['pg_utils_root_path'] . '/pg_dump';
+        $sPgDumpCommand .= ' --host ' . $this->aProperties['server'];
+        $sPgDumpCommand .= ' --port ' . $this->aProperties['port'];
+        $sPgDumpCommand .= ' --username "' . $sLogin . '"';
+        $sPgDumpCommand .= ' --format plain';
+        $sPgDumpCommand .= ' --data-only';
+        $sPgDumpCommand .= ' --column-inserts';
+        $sPgDumpCommand .= ' --verbose';
+        $sPgDumpCommand .= ' --no-owner';
+        $sPgDumpCommand .= ' --no-privileges';
+        $sPgDumpCommand .= ' --file "' . $this->sSqlFileDataPath . '"';
+        for ($i = 0; $i < count($aTables); $i++) {
+            $sPgDumpCommand .= ' --table "' . $aTables[$i] . '"';
+        }
+        $sPgDumpCommand .= ' "' . $sDatabase . '"';
+        $sPgDumpCommand .= ' 2> "' . $this->sSqlLogDataPath . '"';
+
+        exec($sPgDumpCommand);
+    }
+
+    /**
+     * Récupère le seul nom de base de donnés présent dans $aSQLObjects
+     * @param array $aSQLObjects
+     * @return type
+     */
+    function getDatabaseFromSqlObjects($aSQLObjects) {
+        if ($aSQLObjects['type'] === 'database') {
+            if (!empty($aSQLObjects['name'])) {
+                return $aSQLObjects['name'];
+            }
+        }
+    }
+
+    /**
+     * Récupère les table définies dans $aSQLObjects,
+     * Si $bOnlyData = true alors récupère uniquement celles qui ont de la donnée
+     * @param array $aSQLObjects
+     * @return type
+     */
+    function getTablesFromSqlObjects($aSQLObjects, $bOnlyData = false) {
+        $aTables = [];
+
+        if (is_array($aSQLObjects['schemas'])) {
+            for ($i = 0; $i < count($aSQLObjects['schemas']); $i++) {
+                if ($aSQLObjects['schemas'][$i]['type'] === 'schema') {
+                    if (is_array($aSQLObjects['schemas'][$i]['tables'])) {
+                        for ($ii = 0; $ii < count($aSQLObjects['schemas'][$i]['tables']); $ii++) {
+                            if (!$bOnlyData) {
+                                array_push($aTables, $aSQLObjects['schemas'][$i]['name'] . '.' . $aSQLObjects['schemas'][$i]['tables'][$ii]['name']);
+                            } else {
+                                if ($aSQLObjects['schemas'][$i]['tables'][$ii]['data']) {
+                                    array_push($aTables, $aSQLObjects['schemas'][$i]['name'] . '.' . $aSQLObjects['schemas'][$i]['tables'][$ii]['name']);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return $aTables;
+    }
+
+    /**
+     * Récupère les vues définies dans $aSQLObjects
+     * @param array $aSQLObjects
+     * @return type
+     */
+    function getViewsFromSqlObjects($aSQLObjects) {
+        $aViews = [];
+
+        if (is_array($aSQLObjects['schemas'])) {
+            for ($i = 0; $i < count($aSQLObjects['schemas']); $i++) {
+                if ($aSQLObjects['schemas'][$i]['type'] === 'schema') {
+                    if (is_array($aSQLObjects['schemas'][$i]['views'])) {
+                        for ($ii = 0; $ii < count($aSQLObjects['schemas'][$i]['views']); $ii++) {
+                            array_push($aViews, $aSQLObjects['schemas'][$i]['name'] . '.' . $aSQLObjects['schemas'][$i]['views'][$ii]['name']);
+                        }
+                    }
+                }
+            }
+        }
+
+        return $aViews;
+    }
+
+    /**
+     * Récupère le seul nom de base de donnés présent dans $aSQLObjects
+     * @param array $aSQLObjects
+     * @return type
+     */
+    function getSequencesFromSqlObjects($aSQLObjects) {
+        $aSequences = [];
+
+        if (is_array($aSQLObjects['schemas'])) {
+            for ($i = 0; $i < count($aSQLObjects['schemas']); $i++) {
+                if ($aSQLObjects['schemas'][$i]['type'] === 'schema') {
+                    if (is_array($aSQLObjects['schemas'][$i]['sequences'])) {
+                        for ($ii = 0; $ii < count($aSQLObjects['schemas'][$i]['sequences']); $ii++) {
+                            array_push($aSequences, $aSQLObjects['schemas'][$i]['name'] . '.' . $aSQLObjects['schemas'][$i]['sequences'][$ii]['name']);
+                        }
+                    }
+                }
+            }
+        }
+
+        return $aSequences;
+    }
+
+    /**
+     * Fait les remplacements necessaires au fichier SQL
+     * @param string $sSqlFilePath
+     */
+    function makeSQLFileReplacements($sSqlFilePath, $bReplaceSchema = false, $bReplaceSRID = false, $bAddGrants = false) {
+
+        $aLines = file($sSqlFilePath);
+
+        // Commente la ligne row_security car elle ne fonctionne pas sous pg-9.3
+        for ($i = 0; $i < count($aLines); $i++) {
+            $aLines[$i] = preg_replace("/SET row_security/", "-- SET row_security", $aLines[$i]);
+        }
+
+        // Remplace les différents schémas par [SCHEMA_NAME]
+        if ($bReplaceSchema) {
+            $aLines = $this->replaceSchemasOnLines($aLines);
+        }
+
+        // Ajoute les GRANT [ROLE_USER] et [ROLE_ADMIN]
+        if ($bAddGrants) {
+            $aLines = $this->addGrantsOnLines($aLines);
+        }
+
+        file_put_contents($sSqlFilePath, $aLines);
+    }
+
+    /**
+     * Remplace les différents schémas par [SCHEMA_NAME]
+     * @param array $aLines
+     * @return array
+     */
+    function replaceSchemasOnLines($aLines) {
+
+        $this->aSchemas = array_merge($this->aSchemas, $this->oVexGetter->getSchemasFromLines($aLines));
+
+        for ($i = 0; $i < count($aLines); $i++) {
+            for ($ii = 0; $ii < count($this->aSchemas); $ii++) {
+                if (preg_match("/\b" . $this->aSchemas[$ii] . "\b/", $aLines[$i])) {
+                    $aLines[$i] = preg_replace("/\b" . $this->aSchemas[$ii] . "\b/", "[SCHEMA_NAME]", $aLines[$i]);
+                }
+            }
+        }
+
+        return $aLines;
+    }
+
+    /**
+     * Récupère la liste des SRID évoqués sur les lignes
+     * @param array $aLines
+     * @param array $aAvaliableSRIDs
+     * @return array
+     */
+    function getSRIDsFromLines($aLines, $aAvaliableSRIDs) {
+
+        // Expressions régulières geometry permettant de savoir que le SRID se situe sur la ligne
+        $aGeomRegexps = array(
+            "/\bgeometry\(\b/i",
+            "/\bst_srid\(\b/i",
+        );
+
+        // Liste des SRID
+        $aSRIDs = [];
+
+        // Récupère l'unique SRID utilisé
+        for ($i = 0; $i < count($aLines); $i++) {
+
+            // Vérifie si un des mots clés geometry est renseigné
+            for ($ii = 0; $ii < count($aGeomRegexps); $ii++) {
+                if (preg_match($aGeomRegexps[$ii], $aLines[$i])) {
+
+                    // Vérifie si un des SRID disponibles est sur la ligne
+                    for ($iii = 0; $iii < count($aAvaliableSRIDs); $iii++) {
+                        if (preg_match("/" . $aAvaliableSRIDs[$iii] . "/", $aLines[$i])) {
+
+                            // Ajoute dans la liste des SRID
+                            if (!in_array($aAvaliableSRIDs[$iii], $aSRIDs)) {
+                                array_push($aSRIDs, $aAvaliableSRIDs[$iii]);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return $aSRIDs;
+    }
+
+    /**
+     * Add the grand commands to $aLines
+     * @param array $aLines
+     * @return array
+     */
+    function addGrantsOnLines($aLines) {
+
+        $aGrants = $this->getGrantsForSQLComponent(null, 'SCHEMA');
+        for ($i = 0; $i < count($aGrants); $i++) {
+            array_push($aLines, $aGrants[$i]);
+        }
+
+        $aSQLComponents = $this->oVexGetter->getSQLGrantableObjectsFromLines($aLines);
+
+        for ($i = 0; $i < count($aSQLComponents); $i++) {
+            if (!empty($aSQLComponents[$i]['name']) && !empty($aSQLComponents[$i]['type'])) {
+                $aGrants = $this->getGrantsForSQLComponent($aSQLComponents[$i]['name'], $aSQLComponents[$i]['type']);
+
+                for ($ii = 0; $ii < count($aGrants); $ii++) {
+                    array_push($aLines, $aGrants[$ii]);
+                }
+            }
+        }
+
+        return $aLines;
+    }
+
+    /**
+     * Get a list with the grant commands for the given component
+     * @param string $sName
+     * @param string $sType
+     * @return array
+     */
+    function getGrantsForSQLComponent($sName, $sType) {
+
+        $aGrants = [];
+
+        switch ($sType) {
+            case 'TABLE':
+            case 'VIEW':
+
+                array_push($aGrants, '');
+                array_push($aGrants, '--');
+                array_push($aGrants, '-- GENERATED BY VMAP');
+                array_push($aGrants, '-- Rights on table ' . $sName . '');
+                array_push($aGrants, '--');
+                array_push($aGrants, '');
+                array_push($aGrants, 'ALTER TABLE [SCHEMA_NAME].' . $sName . ' OWNER TO u_vitis;');
+                array_push($aGrants, 'REVOKE ALL ON TABLE [SCHEMA_NAME].' . $sName . ' FROM PUBLIC;');
+                array_push($aGrants, 'REVOKE ALL ON TABLE [SCHEMA_NAME].' . $sName . ' FROM u_vitis;');
+                array_push($aGrants, 'GRANT ALL ON TABLE [SCHEMA_NAME].' . $sName . ' TO u_vitis;');
+                array_push($aGrants, 'GRANT SELECT ON TABLE [SCHEMA_NAME].' . $sName . ' TO [ROLE_USER];');
+                array_push($aGrants, 'GRANT ALL ON TABLE [SCHEMA_NAME].' . $sName . ' TO [ROLE_ADMIN];');
+                array_push($aGrants, '');
+
+                break;
+            case 'SEQUENCE':
+
+                array_push($aGrants, '');
+                array_push($aGrants, '--');
+                array_push($aGrants, '-- GENERATED BY VMAP');
+                array_push($aGrants, '-- Rights on sequence ' . $sName . '');
+                array_push($aGrants, '--');
+                array_push($aGrants, '');
+                array_push($aGrants, 'ALTER SEQUENCE [SCHEMA_NAME].' . $sName . ' OWNER TO u_vitis;');
+                array_push($aGrants, 'REVOKE ALL ON SEQUENCE [SCHEMA_NAME].' . $sName . ' FROM PUBLIC;');
+                array_push($aGrants, 'REVOKE ALL ON SEQUENCE [SCHEMA_NAME].' . $sName . ' FROM u_vitis;');
+                array_push($aGrants, 'GRANT ALL ON SEQUENCE [SCHEMA_NAME].' . $sName . ' TO u_vitis;');
+                array_push($aGrants, 'GRANT SELECT ON SEQUENCE [SCHEMA_NAME].' . $sName . ' TO [ROLE_USER];');
+                array_push($aGrants, 'GRANT ALL ON SEQUENCE [SCHEMA_NAME].' . $sName . ' TO [ROLE_ADMIN];');
+                array_push($aGrants, '');
+
+                break;
+            case 'SCHEMA':
+
+                array_push($aGrants, '');
+                array_push($aGrants, '--');
+                array_push($aGrants, '-- GENERATED BY VMAP');
+                array_push($aGrants, '-- Rights on schema [SCHEMA_NAME]');
+                array_push($aGrants, '--');
+                array_push($aGrants, '');
+                array_push($aGrants, 'ALTER SCHEMA [SCHEMA_NAME] OWNER TO u_vitis;');
+                array_push($aGrants, 'REVOKE ALL ON SCHEMA [SCHEMA_NAME] FROM PUBLIC;');
+                array_push($aGrants, 'REVOKE ALL ON SCHEMA [SCHEMA_NAME] FROM u_vitis;');
+                array_push($aGrants, 'GRANT ALL ON SCHEMA [SCHEMA_NAME] TO u_vitis;');
+                array_push($aGrants, 'GRANT USAGE ON SCHEMA [SCHEMA_NAME] TO [ROLE_USER];');
+                array_push($aGrants, 'GRANT ALL ON SCHEMA [SCHEMA_NAME] TO [ROLE_ADMIN];');
+                array_push($aGrants, '');
+
+                break;
+            default:
+                break;
+        }
+
+        for ($i = 0; $i < count($aGrants); $i++) {
+            $aGrants[$i] .= PHP_EOL;
+        }
+
+        return $aGrants;
+    }
+
+    // Objets vMap
+
+    /**
+     * Exporte les objets vMap (cartes, calques, objets métiers, couches)
+     * ainsi que leur dépendances (services, layertheme, evenements, rapports, map_layer)
+     */
+    function exportVMapObjects() {
+
+        // Dossier vmap_objects
+        mkdir($this->sTmpPath . '/vmap_objects', 0777, true);
+
+        $aVMapObjects = json_decode($this->aValues['vmap_objects'], true);
+
+        $this->aOidCounter = 0;
+        $this->aOids = [];
+
+        // Cartes
+        if (!empty($aVMapObjects['maps'])) {
+            $this->exportVMapMaps($aVMapObjects['maps']);
+        }
+
+        // Calques
+        if (!empty($aVMapObjects['calques'])) {
+            $this->exportVMapCalques($aVMapObjects['calques']);
+        }
+
+        // Couches mapserver
+        if (!empty($aVMapObjects['vm4ms_layers'])) {
+            $this->exportVMapVm4msLayers($aVMapObjects['vm4ms_layers']);
+        }
+
+        // Objet métier
+        if (!empty($aVMapObjects['business_objects'])) {
+            $this->exportVMapBusinessObjects($aVMapObjects['business_objects']);
+        }
+
+        // Services
+        if (!empty($this->aExportedCalques)) {
+            $this->exportVMapServices();
+        }
+
+        // Themes de calques
+        if (!empty($this->aExportedCalques)) {
+            $this->exportVMapCalqueThemes();
+        }
+
+        // Événements objets métier
+        if (!empty($this->aExportedBusinessObjects)) {
+            $this->exportVMapEvents();
+        }
+
+        // Rapports objets métier
+        if (!empty($this->aExportedBusinessObjects)) {
+            $this->exportVMapReports();
+        }
+
+        // Relations calques / cartes
+        if (!empty($this->aExportedCalques) && !empty($this->aExportedMaps)) {
+            $this->exportVMapCalqueMapRelations();
+        }
+
+        // Remplace les identifiants par les OID
+        $this->manageVMapObjectDependencies();
+
+        // Écrit les définitions dans les fichiers JSON
+        $this->generateDefinitionFiles();
+    }
+
+    /**
+     * Gen an oid from a type and an id
+     * @param string $sType maps, calque, vm4ms_layer etc..
+     * @param string $sId
+     * @return string
+     */
+    function generateOid($sType, $sId) {
+        $sOid = 'vex_export_oid_' . $this->aOidCounter;
+        $this->aOids[$sType][$sOid] = $sId;
+        $this->aOidCounter++;
+        return $sOid;
+    }
+
+    /**
+     * Exporte les définitions des cartes dans le fichier JSON correspondant
+     * @param array $aMapIds
+     */
+    function exportVMapMaps($aMapIds) {
+        $this->aExportedMaps = $this->getVMapMapsDefByIds($aMapIds);
+    }
+
+    /**
+     * Récupère les définitions des cartes en fonction des identifiants passés
+     * @param array $aMapIds
+     * @return array
+     */
+    function getVMapMapsDefByIds($aMapIds) {
+        require_once 'Maps.class.inc';
+
+        if (empty($aMapIds)) {
+            return array();
+        }
+
+        $aFilter = array(
+            'column' => 'map_id',
+            'compare_operator' => 'IN',
+            'value' => $aMapIds,
+        );
+
+        // Valeurs à ne pas importer
+        $aUnusedValues = [
+            'crs_name',
+            'catalog_index',
+            'thumbnail',
+            'theme_name',
+            'theme_description',
+            'maptheme_id'
+        ];
+
+        $aPath = ['vmap', 'maps'];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet'],
+            'filter' => json_encode($aFilter),
+            'module' => 'vmap'
+        );
+
+        $oMaps = new Maps($aPath, $aValues, $this->aProperties);
+        $oMaps->GET();
+
+        $aMaps = array();
+        if (!empty($oMaps->aObjects)) {
+            for ($i = 0; $i < count($oMaps->aObjects); $i++) {
+                if (!empty($oMaps->aObjects[$i]->aFields)) {
+                    array_push($aMaps, $oMaps->aObjects[$i]->aFields);
+                }
+            }
+        }
+
+        // Drop unsused values
+        for ($i = 0; $i < count($aMaps); $i++) {
+            foreach ($aMaps[$i] as $key => $value) {
+                if (in_array($key, $aUnusedValues)) {
+                    unset($aMaps[$i][$key]);
+                }
+            }
+        }
+
+        // oids
+        for ($i = 0; $i < count($aMaps); $i++) {
+            $aMaps[$i]['map_id'] = $this->generateOid('map', $aMaps[$i]['map_id']);
+        }
+
+        return $aMaps;
+    }
+
+    /**
+     * Exporte les définitions des calques dans le fichier JSON correspondant
+     * @param array $aCalqueIds
+     */
+    function exportVMapCalques($aCalqueIds) {
+        $this->aExportedCalques = $this->getVMapCalquesDefByIds($aCalqueIds);
+    }
+
+    /**
+     * Récupère les définitions des calques en fonction des identifiants passés
+     * @param array $aCalqueIds
+     * @return array
+     */
+    function getVMapCalquesDefByIds($aCalqueIds) {
+        require 'Vex.class.sql.inc';
+
+        if (empty($aCalqueIds)) {
+            return array();
+        }
+
+        // Valeurs à ne pas importer
+        $aUnusedValues = [
+            'theme_name',
+            'service_name',
+            'service_type_id',
+            'service_url',
+            'service_key',
+            'service_type_version',
+            'service_thumbnail',
+            'service_lang',
+            'service_imagery',
+            'service_type_type',
+            'service_options',
+            'service_login',
+            'service_password',
+        ];
+
+        $aCalques = array();
+        $aParams = array();
+        $aParams['idList'] = array('value' => implode('|', $aCalqueIds), 'type' => 'group');
+        $oPDOresult = $this->oConnection->oBd->executeWithParams($aSql['getLayersById'], $aParams);
+        if (!$this->oConnection->oBd->enErreur()) {
+            $aCalques = $this->oConnection->oBd->getResultTableAssoc($oPDOresult);
+        }
+
+        // Drop unsused values
+        for ($i = 0; $i < count($aCalques); $i++) {
+            foreach ($aCalques[$i] as $key => $value) {
+                if (in_array($key, $aUnusedValues)) {
+                    unset($aCalques[$i][$key]);
+                }
+            }
+        }
+
+        for ($i = 0; $i < count($aCalques); $i++) {
+
+            // Oid
+            $sOid = $this->generateOid('calque', $aCalques[$i]['layer_id']);
+
+            // Formulaires
+            if ($aCalques[$i]['is_bo_filtered']) {
+                if (!is_dir($this->sTmpPath . '/vmap_objects/calques_forms')) {
+                    mkdir($this->sTmpPath . '/vmap_objects/calques_forms', 0777, true);
+                }
+                mkdir($this->sTmpPath . '/vmap_objects/calques_forms/' . $sOid, 0777, true);
+                $sFormsDir = $this->aProperties['ws_data_dir'] . '/vmap/layer/' . $aCalques[$i]['layer_id'] . '/forms';
+                if (is_dir($sFormsDir)) {
+                    copyDirectory($sFormsDir, $this->sTmpPath . '/vmap_objects/calques_forms/' . $sOid);
+                }
+            }
+
+            $aCalques[$i]['layer_id'] = $sOid;
+        }
+
+        return $aCalques;
+    }
+
+    /**
+     * Exporte les définitions des couches mapserver dans le fichier JSON correspondant
+     * @param array $aVm4msLayerIds
+     */
+    function exportVMapVm4msLayers($aVm4msLayerIds) {
+        $this->aExportedVm4msLayers = $this->getVMapVm4msLayersDefByIds($aVm4msLayerIds);
+    }
+
+    /**
+     * Récupère les définitions des couches mapserver en fonction des identifiants passés
+     * @param array $aVm4msLayerIds
+     * @return array
+     */
+    function getVMapVm4msLayersDefByIds($aVm4msLayerIds) {
+        require_once __DIR__ . '/../vm4ms/Layers.class.inc';
+
+        if (empty($aVm4msLayerIds)) {
+            return array();
+        }
+
+        $aFilter = array(
+            'column' => 'name',
+            'compare_operator' => 'IN',
+            'value' => $aVm4msLayerIds,
+        );
+
+        // Valeurs à ne pas importer
+        $aUnusedValues = [
+            'coordsys_label',
+            'source_id',
+            'private_connection',
+            'connection_label',
+            'source_label',
+            'definitiontmp',
+            'metadata_id',
+            'definition_structure_valid'
+        ];
+
+        $aPath = ['vmap', 'layers'];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet'],
+            'filter' => json_encode($aFilter),
+            'module' => 'vmap'
+        );
+
+        $oVm4msLayers = new Layers($aPath, $aValues, $this->aProperties);
+        $oVm4msLayers->GET();
+
+        $aVm4msLayers = array();
+        if (!empty($oVm4msLayers->aObjects)) {
+            for ($i = 0; $i < count($oVm4msLayers->aObjects); $i++) {
+                if (!empty($oVm4msLayers->aObjects[$i]->aFields)) {
+                    array_push($aVm4msLayers, $oVm4msLayers->aObjects[$i]->aFields);
+                }
+            }
+        }
+
+        for ($i = 0; $i < count($aVm4msLayers); $i++) {
+
+            // Set private connection and schema name
+            $aVm4msLayers[$i]['connection_id'] = '[PRIVATE_CONNECTION]';
+            $aVm4msLayers[$i]['tableschema'] = '[SCHEMA_NAME]';
+            $aVm4msLayers[$i]['coordsys_id'] = '[SRID]';
+
+            // Put the metadata in the definition (metadata is not exported)
+            if (!empty($aVm4msLayers[$i]['metadata_id'])) {
+                $aMetadata = $this->getVMapVm4msMetadataDefById($aVm4msLayers[$i]['metadata_id']);
+                if (!empty($aMetadata['definition'])) {
+                    $aVm4msLayers[$i]['definition'] = str_replace("{METADATA}", $aMetadata['definition'], $aVm4msLayers[$i]['definition']);
+                }
+            }
+
+            // Drop unsused values
+            foreach ($aVm4msLayers[$i] as $key => $value) {
+                if (in_array($key, $aUnusedValues)) {
+                    unset($aVm4msLayers[$i][$key]);
+                }
+            }
+        }
+
+        // oids
+        for ($i = 0; $i < count($aVm4msLayers); $i++) {
+            $aVm4msLayers[$i]['ms_layer_id'] = $this->generateOid('vm4ms_layer', $aVm4msLayers[$i]['ms_layer_id']);
+        }
+
+        return $aVm4msLayers;
+    }
+
+    /**
+     * Get the Vm4ms Metadata definition from his ID
+     * @param string $sMetadataId
+     * @return array
+     */
+    function getVMapVm4msMetadataDefById($sMetadataId) {
+        require_once __DIR__ . '/../vm4ms/Metadata.class.inc';
+
+        $aPath = ['vmap', 'metadata', $sMetadataId];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet'],
+            'my_vitis_id' => $sMetadataId
+        );
+
+        $oVm4msMetadata = new Metadata($aPath, $aValues, $this->aProperties);
+        $oVm4msMetadata->GET();
+
+        return $oVm4msMetadata->aFields;
+    }
+
+    /**
+     * Exporte les définitions des objets métiers dans le fichier JSON correspondant
+     * @param array $aBusinessObjectIds
+     */
+    function exportVMapBusinessObjects($aBusinessObjectIds) {
+
+        // Définitions
+        $this->aExportedBusinessObjects = $this->getVMapBusinessObjectDefById($aBusinessObjectIds);
+
+        // Formulaires
+        if (count($this->aExportedBusinessObjects) > 0) {
+            $this->exportVMapBusinessObjectsForms($this->aExportedBusinessObjects);
+        }
+
+        // Remplacements balises
+        for ($i = 0; $i < count($this->aExportedBusinessObjects); $i++) {
+            $this->aExportedBusinessObjects[$i] = $this->makeVMapBusinessObjectReplacements($this->aExportedBusinessObjects[$i]);
+        }
+    }
+
+    /**
+     * Exporte les formulaires des objets métiers
+     * @param array $aBusinessObjects
+     */
+    function exportVMapBusinessObjectsForms($aBusinessObjects) {
+
+        mkdir($this->sTmpPath . '/vmap_objects/business_objects_forms', 0777, true);
+        for ($i = 0; $i < count($aBusinessObjects); $i++) {
+            mkdir($this->sTmpPath . '/vmap_objects/business_objects_forms/' . $aBusinessObjects[$i]['business_object_id'], 0777, true);
+            $sFormsDir = $this->aProperties['ws_data_dir'] . '/vmap/business_object/' . $aBusinessObjects[$i]['business_object_id'] . '/forms';
+            if (is_dir($sFormsDir)) {
+                copyDirectory($sFormsDir, $this->sTmpPath . '/vmap_objects/business_objects_forms/' . $aBusinessObjects[$i]['business_object_id']);
+            }
+        }
+    }
+
+    /**
+     * Récupère la définition d'un objet métier par son id
+     * @param string $sBusinessObjectIds
+     * @return array
+     */
+    function getVMapBusinessObjectDefById($sBusinessObjectIds) {
+        require 'Vex.class.sql.inc';
+
+        $aBusinessObjects = false;
+        $aParams = array();
+        $aParams['idList'] = array('value' => implode('|', $sBusinessObjectIds), 'type' => 'group');
+        $oPDOresult = $this->oConnection->oBd->executeWithParams($aSql['getBusinessObjectByIds'], $aParams);
+        if (!$this->oConnection->oBd->enErreur()) {
+            $aBusinessObjects = $this->oConnection->oBd->getResultTableAssoc($oPDOresult);
+        }
+
+        return $aBusinessObjects;
+    }
+
+    /**
+     * Effectue les remplacements de schema et base de données dans la définition ainsi que dans les formulaires
+     * @param array $aBusinessObject
+     * @return array
+     */
+    function makeVMapBusinessObjectReplacements($aBusinessObject) {
+
+        $sOriginalDatabase = $aBusinessObject['database'];
+        $sOriginalSchema = $aBusinessObject['schema'];
+
+        // Effectue les remplacements dans les fichiers
+        $aFileNames = ['custom', 'default', 'published'];
+        if (is_dir($this->sTmpPath . '/vmap_objects/business_objects_forms/' . $aBusinessObject['business_object_id'])) {
+            for ($i = 0; $i < count($aFileNames); $i++) {
+                $sFormPath = $this->sTmpPath . '/vmap_objects/business_objects_forms/' . $aBusinessObject['business_object_id'] . '/' . $aFileNames[$i] . '.json';
+                if (is_file($sFormPath)) {
+                    $aFileContents = file($sFormPath);
+
+                    for ($ii = 0; $ii < count($aFileContents); $ii++) {
+                        $aPatterns = [
+                            '/"database": "' . $sOriginalDatabase . '"/',
+                            '/"database":"' . $sOriginalDatabase . '"/',
+                            '/"schema": "' . $sOriginalSchema . '"/',
+                            '/"schema":"' . $sOriginalSchema . '"/'
+                        ];
+                        $aReplacements = [
+                            '"database": "[DATABASE_NAME]"',
+                            '"database":"[DATABASE_NAME]"',
+                            '"schema": "[SCHEMA_NAME]"',
+                            '"schema":"[SCHEMA_NAME]"'
+                        ];
+                        $aFileContents[$ii] = preg_replace($aPatterns, $aReplacements, $aFileContents[$ii]);
+                    }
+
+                    file_put_contents($sFormPath, $aFileContents);
+                }
+            }
+        }
+
+        // Remplacements sur la définition
+        $aBusinessObject['database'] = '[DATABASE_NAME]';
+        $aBusinessObject['schema'] = '[SCHEMA_NAME]';
+        $aBusinessObject['sql_summary'] = preg_replace('/\b'.$sOriginalSchema.'\b/', '[SCHEMA_NAME]', $aBusinessObject['sql_summary']);
+        $aBusinessObject['sql_list'] = preg_replace('/\b'.$sOriginalSchema.'\b/', '[SCHEMA_NAME]', $aBusinessObject['sql_list']);
+
+        return $aBusinessObject;
+    }
+
+    /**
+     * Exporte les définitions des services associés aux calques dans le fichier JSON correspondant
+     * @param array $aMapIds
+     */
+    function exportVMapServices() {
+        if (!is_array($this->aExportedCalques)) {
+            return false;
+        }
+        if (!count($this->aExportedCalques) > 0) {
+            return false;
+        }
+
+        $aServicesIds = [];
+        for ($i = 0; $i < count($this->aExportedCalques); $i++) {
+            if (!empty($this->aExportedCalques[$i]['service_id'])) {
+                array_push($aServicesIds, $this->aExportedCalques[$i]['service_id']);
+            }
+        }
+
+        $this->aExportedServices = $this->getVMapServicesByIds($aServicesIds);
+    }
+
+    /**
+     * Récupère les définitions des services en fonction des identifiants
+     * @param array $aServiceIds
+     * @return array
+     */
+    function getVMapServicesByIds($aServiceIds) {
+        require_once 'Services.class.inc';
+
+        if (empty($aServiceIds)) {
+            return array();
+        }
+
+        $aFilter = array(
+            'column' => 'service_id',
+            'compare_operator' => 'IN',
+            'value' => $aServiceIds,
+        );
+
+        // Valeurs à ne pas importer
+        $aUnusedValues = [
+            'thumbnail'
+        ];
+
+        $aPath = ['vmap', 'services'];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet'],
+            'filter' => json_encode($aFilter),
+            'module' => 'vmap'
+        );
+
+        $oServices = new Services($aPath, $aValues, $this->aProperties);
+        $oServices->GET();
+
+        $aServices = array();
+        if (!empty($oServices->aObjects)) {
+            for ($i = 0; $i < count($oServices->aObjects); $i++) {
+                if (!empty($oServices->aObjects[$i]->aFields)) {
+                    if ($oServices->aObjects[$i]->aFields['service_vm4ms'] !== true) {
+                        array_push($aServices, $oServices->aObjects[$i]->aFields);
+                    }
+                }
+            }
+        }
+
+        // Drop unsused values
+        for ($i = 0; $i < count($aServices); $i++) {
+            foreach ($aServices[$i] as $key => $value) {
+                if (in_array($key, $aUnusedValues)) {
+                    unset($aServices[$i][$key]);
+                }
+            }
+        }
+
+        // oids
+        for ($i = 0; $i < count($aServices); $i++) {
+            $aServices[$i]['service_id'] = $this->generateOid('service', $aServices[$i]['service_id']);
+        }
+
+        return $aServices;
+    }
+
+    /**
+     * Exporte les définitions des themes associés aux calques dans le fichier JSON correspondant
+     * @param array $aMapIds
+     */
+    function exportVMapCalqueThemes() {
+        if (!is_array($this->aExportedCalques)) {
+            return false;
+        }
+        if (!count($this->aExportedCalques) > 0) {
+            return false;
+        }
+        $aLayerThemeIds = [];
+        for ($i = 0; $i < count($this->aExportedCalques); $i++) {
+            if (!empty($this->aExportedCalques[$i]['layertheme_id'])) {
+                array_push($aLayerThemeIds, $this->aExportedCalques[$i]['layertheme_id']);
+            }
+        }
+
+        $this->aExportedCalqueThemes = $this->getVMapCalqueThemesByIds($aLayerThemeIds);
+    }
+
+    /**
+     * Récupère les définitions des themes de calques en fonction des identifiants
+     * @param array $aLayerThemeIds
+     * @return array
+     */
+    function getVMapCalqueThemesByIds($aLayerThemeIds) {
+        require_once 'LayerThemes.class.inc';
+
+        if (empty($aLayerThemeIds)) {
+            return array();
+        }
+
+        $aFilter = array(
+            'column' => 'layertheme_id',
+            'compare_operator' => 'IN',
+            'value' => $aLayerThemeIds,
+        );
+
+        $aPath = ['vmap', 'layerthemes'];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet'],
+            'filter' => json_encode($aFilter),
+            'module' => 'vmap'
+        );
+
+        $oLayerThemes = new LayerThemes($aPath, $aValues, $this->aProperties);
+        $oLayerThemes->GET();
+
+        $aLayerThemes = array();
+        if (!empty($oLayerThemes->aObjects)) {
+            for ($i = 0; $i < count($oLayerThemes->aObjects); $i++) {
+                if (!empty($oLayerThemes->aObjects[$i]->aFields)) {
+                    array_push($aLayerThemes, $oLayerThemes->aObjects[$i]->aFields);
+                }
+            }
+        }
+
+        // oids
+        for ($i = 0; $i < count($aLayerThemes); $i++) {
+            $aLayerThemes[$i]['layertheme_id'] = $this->generateOid('layertheme', $aLayerThemes[$i]['layertheme_id']);
+        }
+
+        return $aLayerThemes;
+    }
+
+    /**
+     * Exporte les définitions des événements associés aux objets métier dans le fichier JSON correspondant
+     * @param array $aMapIds
+     */
+    function exportVMapEvents() {
+        if (!is_array($this->aExportedBusinessObjects)) {
+            return false;
+        }
+        if (!count($this->aExportedBusinessObjects) > 0) {
+            return false;
+        }
+        $aEventIds = [];
+        for ($i = 0; $i < count($this->aExportedBusinessObjects); $i++) {
+            if (!empty($this->aExportedBusinessObjects[$i]['event_id'])) {
+                array_push($aEventIds, $this->aExportedBusinessObjects[$i]['event_id']);
+            }
+        }
+
+        $this->aExportedEvents = $this->getVMapEventsByIds($aEventIds);
+    }
+
+    /**
+     * Récupère les définitions des événements en fonction des identifiants
+     * @param array $aEventIds
+     * @return array
+     */
+    function getVMapEventsByIds($aEventIds) {
+        require_once 'BusinessObjectEvents.class.inc';
+
+        if (empty($aEventIds)) {
+            return array();
+        }
+
+        $aFilter = array(
+            'column' => 'event_id',
+            'compare_operator' => 'IN',
+            'value' => $aEventIds,
+        );
+
+        $aPath = ['vmap', 'businessobjectevents'];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet'],
+            'filter' => json_encode($aFilter),
+            'module' => 'vmap'
+        );
+
+        $oEvents = new BusinessObjectEvents($aPath, $aValues, $this->aProperties);
+        $oEvents->GET();
+
+        $aEvents = array();
+        if (!empty($oEvents->aObjects)) {
+            for ($i = 0; $i < count($oEvents->aObjects); $i++) {
+                if (!empty($oEvents->aObjects[$i]->aFields)) {
+                    array_push($aEvents, $oEvents->aObjects[$i]->aFields);
+                }
+            }
+        }
+
+        return $aEvents;
+    }
+
+    /**
+     * Exporte les définitions des événements associés aux objets métier dans le fichier JSON correspondant
+     * @param array $aMapIds
+     */
+    function exportVMapReports() {
+        if (!is_array($this->aExportedBusinessObjects)) {
+            return false;
+        }
+        if (!count($this->aExportedBusinessObjects) > 0) {
+            return false;
+        }
+
+        $aBoIds = [];
+        for ($i = 0; $i < count($this->aExportedBusinessObjects); $i++) {
+            array_push($aBoIds, $this->aExportedBusinessObjects[$i]['business_object_id']);
+        }
+        $this->aExportedReports = $this->getVMapReportsByBusinessObjectsIds($aBoIds);
+    }
+
+    /**
+     * Récupère les définitions des événements en fonction des bo_id
+     * @param array $aEventIds
+     * @return array
+     */
+    function getVMapReportsByBusinessObjectsIds($aBoIds) {
+        require_once 'PrintReports.class.inc';
+
+        if (empty($aBoIds)) {
+            return array();
+        }
+
+        $aFilter = array(
+            'column' => 'business_object_id',
+            'compare_operator' => 'IN',
+            'value' => $aBoIds,
+        );
+
+        // Valeurs à ne pas importer
+        $aUnusedValues = [
+            'business_object_title',
+            'business_object_id_field',
+            'business_object_database',
+            'business_object_schema',
+            'business_object_table',
+            'business_object_geom_column'
+        ];
+
+        $aPath = ['vmap', 'printreports'];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet'],
+            'filter' => json_encode($aFilter),
+            'module' => 'vmap'
+        );
+
+        $oReports = new PrintReports($aPath, $aValues, $this->aProperties);
+        $oReports->GET();
+
+        $aReports = array();
+        if (!empty($oReports->aObjects)) {
+            for ($i = 0; $i < count($oReports->aObjects); $i++) {
+                if (!empty($oReports->aObjects[$i]->aFields)) {
+                    array_push($aReports, $oReports->aObjects[$i]->aFields);
+                }
+            }
+        }
+
+        // Drop unsused values
+        for ($i = 0; $i < count($aReports); $i++) {
+            foreach ($aReports[$i] as $key => $value) {
+                if (in_array($key, $aUnusedValues)) {
+                    unset($aReports[$i][$key]);
+                }
+            }
+        }
+
+        // oids
+        for ($i = 0; $i < count($aReports); $i++) {
+            $aReports[$i]['printreport_id'] = $this->generateOid('printreport', $aReports[$i]['printreport_id']);
+        }
+
+        return $aReports;
+    }
+
+    /**
+     * Exporte les définitions des relations calque / map
+     * associés aux cartes et calques dans le fichier JSON correspondant
+     * @param array $aMapIds
+     */
+    function exportVMapCalqueMapRelations() {
+
+        if (!is_array($this->aExportedCalques)) {
+            return false;
+        }
+        if (!count($this->aExportedCalques) > 0) {
+            return false;
+        }
+        if (!is_array($this->aExportedMaps)) {
+            return false;
+        }
+        if (!count($this->aExportedMaps) > 0) {
+            return false;
+        }
+
+        $aMapIds = [];
+        for ($i = 0; $i < count($this->aExportedMaps); $i++) {
+            if (!empty($this->aExportedMaps[$i]['map_id'])) {
+                if (!empty($this->aOids['map'][$this->aExportedMaps[$i]['map_id']])) {
+                    array_push($aMapIds, $this->aOids['map'][$this->aExportedMaps[$i]['map_id']]);
+                }
+            }
+        }
+
+        $aCalqueIds = [];
+        for ($i = 0; $i < count($this->aExportedCalques); $i++) {
+            if (!empty($this->aExportedCalques[$i]['layer_id'])) {
+                if (!empty($this->aOids['calque'][$this->aExportedCalques[$i]['layer_id']])) {
+                    array_push($aCalqueIds, $this->aOids['calque'][$this->aExportedCalques[$i]['layer_id']]);
+                }
+            }
+        }
+
+        if (!empty($aMapIds) && !empty($aCalqueIds)) {
+            $this->aExportedMapCalqueRelations = $this->getVMapCalqueMapRelationsFromIds($aMapIds, $aCalqueIds);
+        }
+    }
+
+    /**
+     * Récupère les définitions des relations calque / map  en fonction des map_id et layer_id
+     * @param array $aMapIds
+     * @param array $aCalqueIds
+     * @return array
+     */
+    function getVMapCalqueMapRelationsFromIds($aMapIds, $aCalqueIds) {
+        require_once 'MapLayers.class.inc';
+
+        if (empty($aMapIds) || empty($aCalqueIds)) {
+            return array();
+        }
+
+        $aFilter = array(
+            'relation' => 'and',
+            'operators' => array(array(
+                    'column' => 'map_id',
+                    'compare_operator' => 'IN',
+                    'value' => $aMapIds,
+                ), array(
+                    'column' => 'layer_id',
+                    'compare_operator' => 'IN',
+                    'value' => $aCalqueIds,
+                ))
+        );
+
+        $aPath = ['vmap', 'maplayers'];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet'],
+            'filter' => json_encode($aFilter),
+            'order_by' => 'layer_index',
+            'module' => 'vmap'
+        );
+
+        $oMapCalques = new MapLayers($aPath, $aValues, $this->aProperties);
+        $oMapCalques->GET();
+
+        $aMapCalques = array();
+        if (!empty($oMapCalques->aObjects)) {
+            for ($i = 0; $i < count($oMapCalques->aObjects); $i++) {
+                if (!empty($oMapCalques->aObjects[$i]->aFields)) {
+                    array_push($aMapCalques, $oMapCalques->aObjects[$i]->aFields);
+                }
+            }
+        }
+
+        return $aMapCalques;
+    }
+
+    /**
+     * Remplace les identifinants des dépendances entre les objets vMap par leurs Oid respectifs
+     */
+    function manageVMapObjectDependencies() {
+
+        // Calques
+        for ($i = 0; $i < count($this->aExportedCalques); $i++) {
+            // Services
+            if (!empty($this->aOids['service'])) {
+                if ($this->aExportedCalques[$i]['service_vm4ms']) {
+                    $this->aExportedCalques[$i]['service_id'] = '[PRIVATE_SERVICE]';
+                } else {
+                    $sOid = array_search($this->aExportedCalques[$i]['service_id'], $this->aOids['service']);
+                    if ($sOid !== false) {
+                        $this->aExportedCalques[$i]['service_id'] = $sOid;
+                    }
+                }
+            }
+            // Themes
+            if (!empty($this->aOids['layertheme'])) {
+                $sOid = array_search($this->aExportedCalques[$i]['layertheme_id'], $this->aOids['layertheme']);
+                if ($sOid !== false) {
+                    $this->aExportedCalques[$i]['layertheme_id'] = $sOid;
+                }
+            }
+            // Vérification de l'existance des Couches MS
+            if (!empty($this->aExportedCalques[$i]['layer_list'])) {
+                $aLayerList = explode(',', $this->aExportedCalques[$i]['layer_list']);
+                $aVm4msLayerNames = [];
+                if (!empty($this->aExportedVm4msLayers)){
+                  for ($ii = 0; $ii < count($this->aExportedVm4msLayers); $ii++) {
+                      array_push($aVm4msLayerNames, $this->aExportedVm4msLayers[$ii]['name']);
+                  }
+                }
+                for ($ii = count($aLayerList) - 1; $ii >= 0; $ii--) {
+                    if (!in_array($aLayerList[$ii], $aVm4msLayerNames)) {
+                        unset($aLayerList[$ii]);
+                    }
+                }
+                $this->aExportedCalques[$i]['layer_list'] = implode(',', $aLayerList);
+            }
+
+            // Vérification de l'existance des Objets métier
+            if (!empty($this->aExportedCalques[$i]['bo_id_list'])) {
+                $aBoList = explode('|', $this->aExportedCalques[$i]['bo_id_list']);
+                $aBoNames = [];
+                for ($ii = 0; $ii < count($this->aExportedBusinessObjects); $ii++) {
+                    array_push($aBoNames, $this->aExportedBusinessObjects[$ii]['business_object_id']);
+                }
+                for ($ii = count($aBoList) - 1; $ii >= 0; $ii--) {
+                    if (!in_array($aBoList[$ii], $aBoNames)) {
+                        unset($aBoList[$ii]);
+                    }
+                }
+                $this->aExportedCalques[$i]['bo_id_list'] = implode('|', $aBoList);
+            }
+        }
+
+        // Relation calque carte
+        for ($i = 0; $i < count($this->aExportedMapCalqueRelations); $i++) {
+            if (!empty($this->aOids['calque'])) {
+                $sOid = array_search($this->aExportedMapCalqueRelations[$i]['layer_id'], $this->aOids['calque']);
+                if ($sOid !== false) {
+                    $this->aExportedMapCalqueRelations[$i]['layer_id'] = $sOid;
+                }
+            }
+            if (!empty($this->aOids['map'])) {
+                $sOid = array_search($this->aExportedMapCalqueRelations[$i]['map_id'], $this->aOids['map']);
+                if ($sOid !== false) {
+                    $this->aExportedMapCalqueRelations[$i]['map_id'] = $sOid;
+                }
+            }
+        }
+    }
+
+    /**
+     * Écrit les dépendances dans des fichiers JSON correspondants
+     */
+    function generateDefinitionFiles() {
+
+        if (!empty($this->aExportedMaps)) {
+            if (count($this->aExportedMaps) > 0) {
+                $this->aExportedMaps = $this->replaceBooleans($this->aExportedMaps);
+                file_put_contents($this->sTmpPath . '/vmap_objects/maps.json', json_encode($this->aExportedMaps));
+            }
+        }
+        if (!empty($this->aExportedCalques)) {
+            if (count($this->aExportedCalques) > 0) {
+                $this->aExportedCalques = $this->replaceBooleans($this->aExportedCalques);
+                file_put_contents($this->sTmpPath . '/vmap_objects/calques.json', json_encode($this->aExportedCalques));
+            }
+        }
+        if (!empty($this->aExportedVm4msLayers)) {
+            if (count($this->aExportedVm4msLayers) > 0) {
+                $this->aExportedVm4msLayers = $this->replaceBooleans($this->aExportedVm4msLayers);
+                file_put_contents($this->sTmpPath . '/vmap_objects/vm4ms_layers.json', json_encode($this->aExportedVm4msLayers));
+            }
+        }
+        if (!empty($this->aExportedServices)) {
+            if (count($this->aExportedServices) > 0) {
+                $this->aExportedServices = $this->replaceBooleans($this->aExportedServices);
+                file_put_contents($this->sTmpPath . '/vmap_objects/services.json', json_encode($this->aExportedServices));
+            }
+        }
+        if (!empty($this->aExportedBusinessObjects)) {
+            if (count($this->aExportedBusinessObjects) > 0) {
+                $this->aExportedBusinessObjects = $this->replaceBooleans($this->aExportedBusinessObjects);
+                file_put_contents($this->sTmpPath . '/vmap_objects/business_objects.json', json_encode($this->aExportedBusinessObjects));
+            }
+        }
+        if (!empty($this->aExportedCalqueThemes)) {
+            if (count($this->aExportedCalqueThemes) > 0) {
+                $this->aExportedCalqueThemes = $this->replaceBooleans($this->aExportedCalqueThemes);
+                file_put_contents($this->sTmpPath . '/vmap_objects/layerthemes.json', json_encode($this->aExportedCalqueThemes));
+            }
+        }
+        if (!empty($this->aExportedEvents)) {
+            if (count($this->aExportedEvents) > 0) {
+                $this->aExportedEvents = $this->replaceBooleans($this->aExportedEvents);
+                file_put_contents($this->sTmpPath . '/vmap_objects/events.json', json_encode($this->aExportedEvents));
+            }
+        }
+        if (!empty($this->aExportedReports)) {
+            if (count($this->aExportedReports) > 0) {
+                $this->aExportedReports = $this->replaceBooleans($this->aExportedReports);
+                file_put_contents($this->sTmpPath . '/vmap_objects/reports.json', json_encode($this->aExportedReports));
+            }
+        }
+        if (!empty($this->aExportedMapCalqueRelations)) {
+            if (count($this->aExportedMapCalqueRelations) > 0) {
+                $this->aExportedMapCalqueRelations = $this->replaceBooleans($this->aExportedMapCalqueRelations);
+                file_put_contents($this->sTmpPath . '/vmap_objects/map_layer.json', json_encode($this->aExportedMapCalqueRelations));
+            }
+        }
+    }
+
+    /**
+     * Remplace les booléens par "true" et "false"
+     * @param array $aVMapObjects
+     * @return array
+     */
+    function replaceBooleans($aVMapObjects) {
+        for ($i = 0; $i < count($aVMapObjects); $i++) {
+            foreach ($aVMapObjects[$i] as $key => $value) {
+                if ($aVMapObjects[$i][$key] === true) {
+                    $aVMapObjects[$i][$key] = 'true';
+                }
+                if ($aVMapObjects[$i][$key] === false) {
+                    $aVMapObjects[$i][$key] = 'false';
+                }
+            }
+        }
+
+        return $aVMapObjects;
+    }
+
+    // Services web
+
+    /**
+     * Exporte les services web
+     */
+    function exportWebServices() {
+
+        $aWebServices = $this->aValues['web_services'];
+
+        if (count($aWebServices) > 0) {
+
+            // Dossier web_services
+            mkdir($this->sTmpPath . '/web_services', 0777, true);
+
+            for ($i = 0; $i < count($aWebServices); $i++) {
+                if (strpos($aWebServices[$i], '../') === false) {
+                    if (is_dir($this->aProperties['vas_home'] . '/rest/ws/' . $aWebServices[$i])) {
+                        copyDirectory($this->aProperties['vas_home'] . '/rest/ws/' . $aWebServices[$i], $this->sTmpPath . '/web_services/' . $aWebServices[$i]);
+                    }
+                }
+            }
+        }
+    }
+
+}
+
+?>
diff --git a/vmap/vas/rest/ws/vmap/VexGetter.class.inc b/vmap/vas/rest/ws/vmap/VexGetter.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..d7515118d07d62b6d950da943fdcc8946e67dcf4
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/VexGetter.class.inc
@@ -0,0 +1,1399 @@
+<?php
+
+/**
+ * \file VexGetter.class.inc
+ * \class VexGetter
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * 	\brief This file contains the VexGetter php class
+ *
+ * This class defines php functions to export VEX files
+ *
+ */
+require_once 'Vex.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Form.class.inc';
+require_once __DIR__ . '/../../class/vmlib/BdDataAccess.inc';
+require_once 'vmlib/logUtil.inc';
+
+/**
+ * Classe contenant les fonctions permettant de récupérer
+ * les informations sur les différents objets à exporter
+ */
+class VexGetter extends Vmap {
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        require 'Vex.class.sql.inc';
+        $this->aSQL = $aSql;
+    }
+
+    // Get vMap objects
+
+    /**
+     * Retourne la liste des objets vMap au format suivant
+     *
+     * [{
+     *     type: map
+     *     name: [map_name]
+     *     map_id: [map_id]
+     *     calques: [{
+     *         type: calque
+     *         name: [layer_name]
+     *         layer_id: [layer_id]
+     *         business_objects: [{
+     *               type: business_object
+     *               name: [bo_name]
+     *         }],
+     *         vm4ms_layers: [{
+     *               type: vm4ms_layer
+     *               name: [layer_name]
+     *         }]
+     *     }]
+     * }]
+     *
+     * @return string
+     */
+    function getVMapObjectsList() {
+
+        $this->aReturn = Array();
+
+        $aVMapObjects = array();
+
+        // Liste des cartes
+        $this->aMaps = $aMaps = $this->getVMapMaps();
+
+        // Liste des calques
+        $this->aCalques = $aCalques = $this->getVMapCalques();
+
+        // Relations cartes / calques
+        $this->aMapCalques = $aMapCalques = $this->getVMapMapCalques();
+
+        // Liste des couches mapserver
+        $this->aVm4msLayers = $aVm4msLayers = $this->getVMapVm4msLayers();
+
+        // Liste des connexions mapserver
+        $this->aVm4msConnections = $aVm4msConnections = $this->getVMapVm4msConnections();
+
+        // Objets métier
+        $this->aBusinessObjects = $aBusinessObjects = $this->getVMapBusinessObjects();
+
+        // Arbre contenant ces données
+        $aVMapObjects = $this->getTreeOrderedMaps($aMaps, $aCalques, $aMapCalques);
+
+        if (isset($this->oError)) {
+            $oError = new VitisError(1, $this->oError->getMessage());
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } elseif (isset($this->oConnection->oError)) {
+            $oError = $this->oConnection->oError;
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } elseif ($this->oConnection->oBd->enErreur()) {
+            $oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } else {
+            $this->aReturn['status'] = 1;
+            $this->aReturn['vmap_objects'] = $aVMapObjects;
+            return json_encode($this->aReturn);
+        }
+    }
+
+    /**
+     * Récupère la liste des cartes
+     * @param string $sNames names filter
+     * @return array
+     */
+    function getVMapMaps($sNames = null) {
+        require_once 'Maps.class.inc';
+
+        $aPath = ['vmap', 'maps'];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet'],
+            'attributs' => 'map_id|name',
+            'module' => 'vmap',
+            'order_by' => 'name'
+        );
+
+        // Ajout filtre sur le nom
+        if (!empty($sNames)) {
+            $aNames = explode('|', $sNames);
+            if (!empty($aNames)) {
+                $aFilter = array(
+                    'column' => 'name',
+                    'compare_operator' => 'IN',
+                    'value' => $aNames
+                );
+                $aValues['filter'] = json_encode($aFilter);
+            }
+        }
+
+        $oMaps = new Maps($aPath, $aValues, $this->aProperties);
+        $oMaps->GET();
+
+        $aMaps = array();
+        if (!empty($oMaps->aObjects)) {
+            for ($i = 0; $i < count($oMaps->aObjects); $i++) {
+                if (!empty($oMaps->aObjects[$i]->aFields)) {
+                    if (!empty($oMaps->aObjects[$i]->aFields['map_id']) &&
+                            !empty($oMaps->aObjects[$i]->aFields['name'])) {
+                        array_push($aMaps, array(
+                            'name' => $oMaps->aObjects[$i]->aFields['name'],
+                            'map_id' => $oMaps->aObjects[$i]->aFields['map_id']
+                        ));
+                    }
+                }
+            }
+        }
+
+        return $aMaps;
+    }
+
+    /**
+     * Récupère la liste des services
+     * @param string $sNames names filter
+     * @param array $aAttributs attributs to request
+     * @return array
+     */
+    function getVMapServices($sNames = null, $aAttributs = ['service_id', 'name']) {
+        require_once 'Services.class.inc';
+
+        $aPath = ['vmap', 'services'];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet'],
+            'module' => 'vmap',
+            'order_by' => 'name'
+        );
+
+        if (is_array($aAttributs)) {
+            $aValues['attributs'] = implode('|', $aAttributs);
+        }
+
+        // Ajout filtre sur le nom
+        if (!empty($sNames)) {
+            $aNames = explode('|', $sNames);
+            if (!empty($aNames)) {
+                $aFilter = array(
+                    'column' => 'name',
+                    'compare_operator' => 'IN',
+                    'value' => $aNames
+                );
+                $aValues['filter'] = json_encode($aFilter);
+            }
+        }
+
+        $oServices = new Services($aPath, $aValues, $this->aProperties);
+        $oServices->GET();
+
+        $aServices = array();
+        if (!empty($oServices->aObjects)) {
+            for ($i = 0; $i < count($oServices->aObjects); $i++) {
+                if (!empty($oServices->aObjects[$i]->aFields)) {
+                    array_push($aServices, $oServices->aObjects[$i]->aFields);
+                }
+            }
+        }
+
+        return $aServices;
+    }
+
+    /**
+     * Récupère la liste des événements
+     * @param string $sNames names filter
+     * @return array
+     */
+    function getVMapEvents($sNames = null) {
+        require_once 'BusinessObjectEvents.class.inc';
+
+        $aPath = ['vmap', 'businessobjectevents'];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet'],
+            'attributs' => 'event_id|description',
+            'module' => 'vmap',
+            'order_by' => 'event_id'
+        );
+
+        // Ajout filtre sur event_id
+        if (!empty($sNames)) {
+            $aNames = explode('|', $sNames);
+            if (!empty($aNames)) {
+                $aFilter = array(
+                    'column' => 'event_id',
+                    'compare_operator' => 'IN',
+                    'value' => $aNames
+                );
+                $aValues['filter'] = json_encode($aFilter);
+            }
+        }
+
+        $oEvents = new BusinessObjectEvents($aPath, $aValues, $this->aProperties);
+        $oEvents->GET();
+
+        $aEvents = array();
+        if (!empty($oEvents->aObjects)) {
+            for ($i = 0; $i < count($oEvents->aObjects); $i++) {
+                if (!empty($oEvents->aObjects[$i]->aFields)) {
+                    if (!empty($oEvents->aObjects[$i]->aFields['event_id']) &&
+                            !empty($oEvents->aObjects[$i]->aFields['description'])) {
+                        array_push($aEvents, array(
+                            'description' => $oEvents->aObjects[$i]->aFields['description'],
+                            'event_id' => $oEvents->aObjects[$i]->aFields['event_id']
+                        ));
+                    }
+                }
+            }
+        }
+
+        return $aEvents;
+    }
+
+    /**
+     * Récupère la liste des rapports
+     * @param string $sNames names filter
+     * @return array
+     */
+    function getVMapReports($sNames = null) {
+        require_once 'PrintReports.class.inc';
+
+        $aPath = ['vmap', 'printreports'];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet'],
+            'attributs' => 'printreport_id|name',
+            'module' => 'vmap',
+            'order_by' => 'name'
+        );
+
+        // Ajout filtre sur le nom
+        if (!empty($sNames)) {
+            $aNames = explode('|', $sNames);
+            if (!empty($aNames)) {
+                $aFilter = array(
+                    'column' => 'name',
+                    'compare_operator' => 'IN',
+                    'value' => $aNames
+                );
+                $aValues['filter'] = json_encode($aFilter);
+            }
+        }
+
+        $oPrintReports = new PrintReports($aPath, $aValues, $this->aProperties);
+        $oPrintReports->GET();
+
+        $aReports = array();
+        if (!empty($oPrintReports->aObjects)) {
+            for ($i = 0; $i < count($oPrintReports->aObjects); $i++) {
+                if (!empty($oPrintReports->aObjects[$i]->aFields)) {
+                    if (!empty($oPrintReports->aObjects[$i]->aFields['printreport_id']) &&
+                            !empty($oPrintReports->aObjects[$i]->aFields['name'])) {
+                        array_push($aReports, array(
+                            'name' => $oPrintReports->aObjects[$i]->aFields['name'],
+                            'printreport_id' => $oPrintReports->aObjects[$i]->aFields['printreport_id']
+                        ));
+                    }
+                }
+            }
+        }
+
+        return $aReports;
+    }
+
+    /**
+     * Récupère la liste des calques
+     * @param string $sNames names filter
+     * @return array
+     */
+    function getVMapCalques($sNames = null) {
+
+        $aCalques = array();
+        $aParams = array();
+        $sSql = $this->aSQL['getLayers'];
+
+        if (!empty($sNames)) {
+            $aNames = explode('|', $sNames);
+            if (!empty($aNames)) {
+                $aParams['namesList'] = array('value' => implode('|', $aNames), 'type' => 'group');
+                $sSql = $this->aSQL['getLayersByName'];
+            }
+        }
+
+        $oPDOresult = $this->oConnection->oBd->executeWithParams($sSql, $aParams);
+        if (!$this->oConnection->oBd->enErreur()) {
+            $aCalques = $this->oConnection->oBd->getResultTableAssoc($oPDOresult);
+        }
+
+        return $aCalques;
+    }
+
+    /**
+     * Récupère les relations cartes/calques
+     * @return array
+     */
+    function getVMapMapCalques($sMapId = null, $sLayerId = null) {
+        require_once 'MapLayers.class.inc';
+
+        $aPath = ['vmap', 'maplayers'];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet'],
+            'attributs' => 'layer_id|name|map_id|layer_index',
+            'module' => 'vmap',
+            'order_by' => 'layer_index'
+        );
+
+        $aFilter = [
+            'relation' => 'AND',
+            'operators' => []
+        ];
+        if (!empty($sMapId)) {
+            array_push($aFilter['operators'], array(
+                'column' => 'map_id',
+                'compare_operator' => '=',
+                'value' => $sMapId
+            ));
+        }
+        if (!empty($sLayerId)) {
+            array_push($aFilter['operators'], array(
+                'column' => 'layer_id',
+                'compare_operator' => '=',
+                'value' => $sLayerId
+            ));
+        }
+        if (count($aFilter['operators']) > 0) {
+            $aValues['filter'] = json_encode($aFilter);
+        }
+
+        $oMapLayers = new MapLayers($aPath, $aValues, $this->aProperties);
+        $oMapLayers->GET();
+
+        $aMapCalques = array();
+        if (!empty($oMapLayers->aObjects)) {
+            for ($i = 0; $i < count($oMapLayers->aObjects); $i++) {
+                if (!empty($oMapLayers->aObjects[$i]->aFields)) {
+                    if (!empty($oMapLayers->aObjects[$i]->aFields['map_id']) &&
+                            !empty($oMapLayers->aObjects[$i]->aFields['name'])) {
+                        array_push($aMapCalques, array(
+                            'layer_index' => $oMapLayers->aObjects[$i]->aFields['layer_index'],
+                            'layer_id' => $oMapLayers->aObjects[$i]->aFields['layer_id'],
+                            'map_id' => $oMapLayers->aObjects[$i]->aFields['map_id']
+                        ));
+                    }
+                }
+            }
+        }
+
+        return $aMapCalques;
+    }
+
+    /**
+     * Récupère la liste des themes des calques
+     * @param string $sNames names filter
+     * @return array
+     */
+    function getVMapCalqueThemes($sNames = null) {
+        require_once 'LayerThemes.class.inc';
+
+        $aPath = ['vmap', 'layerthemes'];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet'],
+            'module' => 'vmap'
+        );
+
+        // Ajout filtre sur le nom
+        if (!empty($sNames)) {
+            $aNames = explode('|', $sNames);
+            if (!empty($aNames)) {
+                $aFilter = array(
+                    'column' => 'name',
+                    'compare_operator' => 'IN',
+                    'value' => $aNames
+                );
+                $aValues['filter'] = json_encode($aFilter);
+            }
+        }
+
+        $oLayerThemes = new LayerThemes($aPath, $aValues, $this->aProperties);
+        $oLayerThemes->GET();
+
+        $aLayerThemes = array();
+        if (!empty($oLayerThemes->aObjects)) {
+            for ($i = 0; $i < count($oLayerThemes->aObjects); $i++) {
+                if (!empty($oLayerThemes->aObjects[$i]->aFields)) {
+                    array_push($aLayerThemes, $oLayerThemes->aObjects[$i]->aFields);
+                }
+            }
+        }
+
+        return $aLayerThemes;
+    }
+
+    /**
+     * Récupère la liste des couches Mapserver
+     * @param string $sNames names filter
+     * @return array
+     */
+    function getVMapVm4msLayers($sNames = null, $aAttributs = ['name', 'tableschema', 'tablename', 'connection_id']) {
+        require_once __DIR__ . '/../vm4ms/Layers.class.inc';
+
+        $aPath = ['vm4ms', 'layers'];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet'],
+            'module' => 'vm4ms',
+            'order_by' => 'name'
+        );
+
+        if (is_array($aAttributs)) {
+            $aValues['attributs'] = implode('|', $aAttributs);
+        }
+
+        // Ajout filtre sur le nom
+        if (!empty($sNames)) {
+            $aNames = explode('|', $sNames);
+            if (!empty($aNames)) {
+                $aFilter = array(
+                    'column' => 'name',
+                    'compare_operator' => 'IN',
+                    'value' => $aNames
+                );
+                $aValues['filter'] = json_encode($aFilter);
+            }
+        }
+
+        $oLayers = new Layers($aPath, $aValues, $this->aProperties);
+        $oLayers->GET();
+
+        $aVm4msLayers = array();
+        if (!empty($oLayers->aObjects)) {
+            for ($i = 0; $i < count($oLayers->aObjects); $i++) {
+                if (!empty($oLayers->aObjects[$i]->aFields)) {
+                    array_push($aVm4msLayers, $oLayers->aObjects[$i]->aFields);
+                }
+            }
+        }
+
+        return $aVm4msLayers;
+    }
+
+    /**
+     * Récupère la liste des couches Mapserver
+     * @param string $bPrivate True pour avoir uniquement les connexions privées
+     * @return array
+     */
+    function getVMapVm4msConnections($bPrivate = false) {
+        require_once __DIR__ . '/../vm4ms/LayerConnections.class.inc';
+
+        $aPath = ['vm4ms', 'layerconnecitons'];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet'],
+            'module' => 'vm4ms',
+            'order_by' => 'connection_id'
+        );
+
+        if ($bPrivate) {
+            $aFilter = array(
+                'column' => 'private',
+                'compare_operator' => '=',
+                'value' => 'true'
+            );
+            $aValues['filter'] = json_encode($aFilter);
+        }
+
+        $oLayerConnections = new LayerConnections($aPath, $aValues, $this->aProperties);
+        $oLayerConnections->GET();
+
+        $aVm4msLayerConnections = array();
+        if (!empty($oLayerConnections->aObjects)) {
+            for ($i = 0; $i < count($oLayerConnections->aObjects); $i++) {
+                if (!empty($oLayerConnections->aObjects[$i]->aFields)) {
+                    if (!empty($oLayerConnections->aObjects[$i]->aFields['name'])) {
+                        array_push($aVm4msLayerConnections, array(
+                            'connection_id' => $oLayerConnections->aObjects[$i]->aFields['connection_id'],
+                            'name' => $oLayerConnections->aObjects[$i]->aFields['name'],
+                            'private' => $oLayerConnections->aObjects[$i]->aFields['private'],
+                            'server' => $oLayerConnections->aObjects[$i]->aFields['server'],
+                            'port' => $oLayerConnections->aObjects[$i]->aFields['port'],
+                            'database' => $oLayerConnections->aObjects[$i]->aFields['database'],
+                            'user' => $oLayerConnections->aObjects[$i]->aFields['user'],
+                            'password' => $oLayerConnections->aObjects[$i]->aFields['password']
+                        ));
+                    }
+                }
+            }
+        }
+
+        return $aVm4msLayerConnections;
+    }
+
+    /**
+     * Récupère la liste des objets métier
+     * @param string $sNames names filter
+     * @return array
+     */
+    function getVMapBusinessObjects($sNames = null) {
+
+        $aBusinessObjects = array();
+        $aParams = array();
+        $sSql = $this->aSQL['getBusinessObjects'];
+
+        if (!empty($sNames)) {
+            $aNames = explode('|', $sNames);
+            if (!empty($aNames)) {
+                $aParams['idList'] = array('value' => implode('|', $aNames), 'type' => 'group');
+                $sSql = $this->aSQL['getBusinessObjectByIds'];
+            }
+        }
+
+        $oPDOresult = $this->oConnection->oBd->executeWithParams($sSql, $aParams);
+        if (!$this->oConnection->oBd->enErreur()) {
+            $aBusinessObjects = $this->oConnection->oBd->getResultTableAssoc($oPDOresult);
+        }
+
+        for ($i = 0; $i < count($aBusinessObjects); $i++) {
+            if (empty($aBusinessObjects[$i]['database'])) {
+                $aBusinessObjects[$i]['database'] = $this->aProperties['database'];
+            }
+        }
+
+        return $aBusinessObjects;
+    }
+
+    /**
+     * Ordonne les cartes, calques, objets métiers, couches vm4ms sous forme d'arbre
+     * @param array $aMaps
+     * @param array $aCalques
+     * @param array $aMapCalques
+     * @return array
+     */
+    function getTreeOrderedMaps($aMaps, $aCalques, $aMapCalques) {
+
+        for ($i = 0; $i < count($aMaps); $i++) {
+
+            $aMaps[$i]['type'] = 'map';
+            $aMaps[$i]['calques'] = [];
+
+            // Pour chaque calque dans $aMapCalques
+            for ($ii = 0; $ii < count($aMapCalques); $ii++) {
+                if ($aMaps[$i]['map_id'] === $aMapCalques[$ii]['map_id']) {
+
+                    // Trouve le calque correspondant dans $aCalques
+                    for ($iii = 0; $iii < count($aCalques); $iii++) {
+                        if ($aMapCalques[$ii]['layer_id'] === $aCalques[$iii]['layer_id']) {
+
+                            // Ajoute le calque ordonné sous forma d'arbre
+                            array_push($aMaps[$i]['calques'], $this->getTreeOrderedCalque($aCalques[$iii]));
+                        }
+                    }
+                }
+            }
+        }
+
+        return $aMaps;
+    }
+
+    /**
+     * Retourne le calque sous forme d'arbre
+     * @param array $oCalque
+     * @return array
+     */
+    function getTreeOrderedCalque($oCalque) {
+
+        $oTmpCalque = array(
+            'type' => 'calque',
+            'name' => $oCalque['name'],
+            'layer_id' => $oCalque['layer_id']
+        );
+
+        // Liste des couches vm4ms
+        if (!empty($oCalque['layer_list'])) {
+            $oTmpCalque['vm4ms_layers'] = $this->getTreeOrderedVm4msLayers($oCalque);
+        }
+
+        // Liste des objets métiers
+        if (!empty($oCalque['bo_id_list'])) {
+            $oTmpCalque['business_objects'] = $this->getTreeOrderedBOs($oCalque);
+        }
+
+        return $oTmpCalque;
+    }
+
+    /**
+     * Retourne sous forme d'arbre la couche vm4ms
+     * @param array $oCalque
+     * @return array
+     */
+    function getTreeOrderedVm4msLayers($oCalque) {
+        $aVm4msLayers = [];
+
+        if ($oCalque['service_vm4ms']) {
+            if (!empty($oCalque['layer_list'])) {
+                $aVm4msLayerList = explode(',', $oCalque['layer_list']);
+                for ($i = 0; $i < count($aVm4msLayerList); $i++) {
+                    $oLayerConnection = $this->getVm4msLayerConnecitonFromName($aVm4msLayerList[$i]);
+                    if ($oLayerConnection !== false) {
+                        array_push($aVm4msLayers, array(
+                            'type' => 'vm4ms_layer',
+                            'name' => $aVm4msLayerList[$i],
+                            'server' => $oLayerConnection['server'],
+                            'port' => $oLayerConnection['port'],
+                            'database' => $oLayerConnection['database'],
+                            'schema' => $oLayerConnection['schema'],
+                            'table' => $oLayerConnection['table']
+                        ));
+                    }
+                }
+            }
+        }
+
+        return $aVm4msLayers;
+    }
+
+    /**
+     * Retourne sous forme d'arbre l'objet métier
+     * @param array $oCalque
+     * @return array
+     */
+    function getTreeOrderedBOs($oCalque) {
+        $aBOs = [];
+
+        if (!empty($oCalque['bo_id_list'])) {
+            $aBOList = explode('|', $oCalque['bo_id_list']);
+            for ($i = 0; $i < count($aBOList); $i++) {
+
+                $oBo = $this->getOBFromName($aBOList[$i]);
+                if ($oBo !== false) {
+                    array_push($aBOs, array(
+                        'type' => 'business_object',
+                        'name' => $oBo['business_object_id'],
+                        'database' => $oBo['database'],
+                        'schema' => $oBo['schema'],
+                        'table' => $oBo['table'],
+                        'id_field' => $oBo['id_field']
+                    ));
+                }
+            }
+        }
+
+        return $aBOs;
+    }
+
+    /**
+     * Récupère server, port, database, schema, table depuis le num d'une couche vm4ms
+     * @param string $sLayerName
+     * @return array
+     */
+    function getVm4msLayerConnecitonFromName($sLayerName) {
+        $oLayerConnection = false;
+        for ($i = 0; $i < count($this->aVm4msLayers); $i++) {
+            if ($this->aVm4msLayers[$i]['name'] === $sLayerName) {
+                $oConnection = $this->getVm4msConnexionFromId($this->aVm4msLayers[$i]['connection_id']);
+                if ($oConnection !== false) {
+                    if (empty($oConnection['server'])) {
+                        $oConnection['server'] = $this->aProperties['server'];
+                    }
+                    if (empty($oConnection['port'])) {
+                        $oConnection['port'] = $this->aProperties['port'];
+                    }
+                    if (empty($oConnection['database'])) {
+                        $oConnection['database'] = $this->aProperties['database'];
+                    }
+                    if ($oConnection['server'] === $this->aProperties['server'] &&
+                            $oConnection['port'] === $this->aProperties['port']) {
+
+                        $oLayerConnection = array(
+                            'server' => $oConnection['server'],
+                            'port' => $oConnection['port'],
+                            'database' => $oConnection['database'],
+                            'schema' => $this->aVm4msLayers[$i]['tableschema'],
+                            'table' => $this->aVm4msLayers[$i]['tablename']
+                        );
+                    }
+                }
+            }
+        }
+        return $oLayerConnection;
+    }
+
+    /**
+     * Récupère la connexion depuis un identifiant
+     * @param string $sConnectionId
+     * @return array
+     */
+    function getVm4msConnexionFromId($sConnectionId) {
+        $oConnection = false;
+        for ($i = 0; $i < count($this->aVm4msConnections); $i++) {
+            if ($this->aVm4msConnections[$i]['connection_id'] === $sConnectionId) {
+                $oConnection = $this->aVm4msConnections[$i];
+            }
+        }
+        return $oConnection;
+    }
+
+    /**
+     * Récupère l'objet métier en fonction de son nom
+     * @param string $sBOId
+     * @return boolean|array
+     */
+    function getOBFromName($sBOId) {
+        $oBO = false;
+
+        for ($i = 0; $i < count($this->aBusinessObjects); $i++) {
+            if ($this->aBusinessObjects[$i]['business_object_id'] === $sBOId) {
+                return $this->aBusinessObjects[$i];
+            }
+        }
+
+        return $oBO;
+    }
+
+    // Get Web services
+
+    /**
+     * Get the web services of the given business objects
+     * @return string
+     */
+    function getWebServicesList() {
+        $this->aReturn = Array();
+
+        if (empty($this->aValues['business_objects'])) {
+            $oError = new VitisError(2, 'business_objects parameter required');
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        }
+
+        // Liste des répertoires contennus dans ws
+        $aDirs = $this->getWsDirectoriesList();
+
+        // Récupère les nos des organismes celons la règle de nommage des objets métier
+        $aOrganismes = $this->getOrganismeNames();
+
+        // Récupère les répertoires dont les nom correspondend aux organismes
+        $aWebServices = $this->getOrganismesWebServices($aDirs, $aOrganismes);
+
+        if (isset($this->oError)) {
+            $oError = new VitisError(1, $this->oError->getMessage());
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } elseif (isset($this->oConnection->oError)) {
+            $oError = $this->oConnection->oError;
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } elseif ($this->oConnection->oBd->enErreur()) {
+            $oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } else {
+            $this->aReturn['status'] = 1;
+            $this->aReturn['web_services'] = $aWebServices;
+            return json_encode($this->aReturn);
+        }
+    }
+
+    /**
+     * Get the list of the WS directories
+     * @return array
+     */
+    function getWsDirectoriesList() {
+        chdir($this->aProperties['vas_home'] . '/rest/ws');
+        $aDirs = glob('*', GLOB_ONLYDIR);
+        return $aDirs;
+    }
+
+    /**
+     * Get the list of the organismes founded in aValues.business_objects
+     * @return array
+     */
+    function getOrganismeNames() {
+
+        // Liste des objets métier
+        $aBOs = explode('|', $this->aValues['business_objects']);
+
+        // Récupère les nos des organismes celons la règle de nommage des objets métier
+        $aOrganismes = array();
+        for ($i = 0; $i < count($aBOs); $i++) {
+            if (strpos($aBOs[$i], '_') !== false) {
+                array_push($aOrganismes, explode('_', $aBOs[$i])[0]);
+            }
+        }
+
+        return $aOrganismes;
+    }
+
+    /**
+     * Get the directories matching with the organismes
+     * @param array $aDirs
+     * @param array $aOrganismes
+     * @return array
+     */
+    function getOrganismesWebServices($aDirs, $aOrganismes) {
+        $aWebServices = array();
+        for ($i = 0; $i < count($aDirs); $i++) {
+            if (strpos($aDirs[$i], '_') !== false) {
+                if (in_array(explode('_', $aDirs[$i])[0], $aOrganismes)) {
+                    array_push($aWebServices, array(
+                        'name' => $aDirs[$i]
+                    ));
+                }
+            }
+        }
+
+        // Ajoute les infos sur les fichiers contenus au sein de chaque web service
+        $aWebServices = $this->completeWebServicesInfos($aWebServices);
+
+        return $aWebServices;
+    }
+
+    /**
+     * Complete the web service introducing contained files
+     * @param array $aWebServices
+     * @return array
+     */
+    function completeWebServicesInfos($aWebServices) {
+        for ($i = 0; $i < count($aWebServices); $i++) {
+            chdir($this->aProperties['vas_home'] . '/rest/ws/' . $aWebServices[$i]['name']);
+            $aWebServices[$i]['files'] = glob('*');
+        }
+        return $aWebServices;
+    }
+
+    // Get SQL objects
+
+    /**
+     * Récupère la liste des objets SQL exportables
+     * @return string
+     */
+    function getSqlObjects() {
+        require_once __DIR__ . '/../vitis/GenericQuerys.class.inc';
+        $this->aReturn = Array();
+
+        if (empty($this->aValues['database'])) {
+            $oError = new VitisError(2, 'database parameter required');
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        }
+
+        $aSqlObjects = array();
+
+        // Liste des schémas
+        $aSqlObjects = $this->completeSqlObjectsWithSchemas($aSqlObjects);
+
+        // Liste des tables
+        $aSqlObjects = $this->completeSqlObjectsWithTablesAndViews($aSqlObjects);
+
+        // Liste des sequences
+        $aSqlObjects = $this->completeSqlObjectsWithSequences($aSqlObjects);
+
+        if (isset($this->oError)) {
+            $oError = new VitisError(1, $this->oError->getMessage());
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } elseif (isset($this->oConnection->oError)) {
+            $oError = $this->oConnection->oError;
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } elseif ($this->oConnection->oBd->enErreur()) {
+            $oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } else {
+            $this->aReturn['status'] = 1;
+            $this->aReturn['sql_objects'] = $aSqlObjects;
+            return json_encode($this->aReturn);
+        }
+    }
+
+    /**
+     * Ajoute à $aSqlObjects les schémas disponibles
+     * @param array $aSqlObjects
+     * @return array
+     */
+    function completeSqlObjectsWithSchemas($aSqlObjects) {
+
+        $aSchemas = $this->getSchemas($this->aValues['database']);
+        for ($i = 0; $i < count($aSchemas); $i++) {
+            array_push($aSqlObjects, array(
+                'type' => 'schema',
+                'name' => $aSchemas[$i],
+                'tables' => array()
+            ));
+        }
+
+        return $aSqlObjects;
+    }
+
+    /**
+     * Ajoute à $aSqlObjects les tables et les vues disponibles
+     * @param array $aSqlObjects
+     * @return array
+     */
+    function completeSqlObjectsWithTablesAndViews($aSqlObjects) {
+
+        for ($i = 0; $i < count($aSqlObjects); $i++) {
+            if ($aSqlObjects[$i]['type'] === 'schema') {
+                $aSqlObjects[$i]['tables'] = $this->getTables($this->aValues['database'], $aSqlObjects[$i]['name']);
+                $aSqlObjects[$i]['views'] = $this->getViews($this->aValues['database'], $aSqlObjects[$i]['name']);
+            }
+        }
+
+        return $aSqlObjects;
+    }
+
+    /**
+     * Ajoute à $aSqlObjects les sequences disponibles
+     * @param array $aSqlObjects
+     * @return array
+     */
+    function completeSqlObjectsWithSequences($aSqlObjects) {
+
+        for ($i = 0; $i < count($aSqlObjects); $i++) {
+            if ($aSqlObjects[$i]['type'] === 'schema') {
+                $aSqlObjects[$i]['sequences'] = $this->getSequences($this->aValues['database'], $aSqlObjects[$i]['name']);
+            }
+        }
+
+        return $aSqlObjects;
+    }
+
+    /**
+     * Récupère la liste des schemas exportables
+     * @param string $sDatabase
+     * @return array
+     */
+    function getSchemas($sDatabase) {
+
+        $aPath = ['vitis', 'genericquerys', $sDatabase, 'schemas'];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet'],
+            'my_vitis_id' => $sDatabase,
+            'module' => 'vitis',
+            'order_by' => 'schema_name'
+        );
+
+        $oGenericQuerys = new GenericQuerys($aPath, $aValues, $this->aProperties);
+        $oGenericQuerys->GET();
+
+        $aSchemas = array();
+        $aUnExportableSchemas = ['information_schema', 'pg_catalog'];
+        if (!empty($oGenericQuerys->aObjects)) {
+            for ($i = 0; $i < count($oGenericQuerys->aObjects); $i++) {
+                if (!empty($oGenericQuerys->aObjects[$i]->aFields)) {
+                    if (!empty($oGenericQuerys->aObjects[$i]->aFields['schema_name'])) {
+                        if (!in_array($oGenericQuerys->aObjects[$i]->aFields['schema_name'], $aUnExportableSchemas)) {
+                            array_push($aSchemas, $oGenericQuerys->aObjects[$i]->aFields['schema_name']);
+                        }
+                    }
+                }
+            }
+        }
+
+        return $aSchemas;
+    }
+
+    /**
+     * Récupère la liste des tables exportables
+     * @param string $sDatabase
+     * @param string $sSchema
+     */
+    function getTables($sDatabase, $sSchema) {
+
+        $aTables = [];
+        if ($sDatabase != $this->oConnection->oBd->base) {
+            $this->oBd = new BD($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);
+        }
+
+        $sSQL = $this->aSQL['getTables'];
+        $aSQLParams = array(
+            'sSchema' => array('value' => $sSchema, 'type' => 'quoted_string')
+        );
+        $oResult = $this->oConnection->oBd->executeWithParams($sSQL, $aSQLParams);
+        if (!$this->oConnection->oBd->enErreur()) {
+            $aResult = $this->oConnection->oBd->getResultTableAssoc($oResult);
+            for ($i = 0; $i < count($aResult); $i++) {
+                if (!empty($aResult[$i]['tablename'])) {
+                    array_push($aTables, $aResult[$i]['tablename']);
+                }
+            }
+        }
+
+        return $aTables;
+    }
+
+    /**
+     * Récupère la liste des vues exportables
+     * @param string $sDatabase
+     * @param string $sSchema
+     */
+    function getViews($sDatabase, $sSchema) {
+
+        $aViews = [];
+        if ($sDatabase != $this->oConnection->oBd->base) {
+            $this->oBd = new BD($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);
+        }
+
+        $sSQL = $this->aSQL['getViews'];
+        $aSQLParams = array(
+            'sSchema' => array('value' => $sSchema, 'type' => 'quoted_string')
+        );
+        $oResult = $this->oConnection->oBd->executeWithParams($sSQL, $aSQLParams);
+        if (!$this->oConnection->oBd->enErreur()) {
+            $aResult = $this->oConnection->oBd->getResultTableAssoc($oResult);
+            for ($i = 0; $i < count($aResult); $i++) {
+                if (!empty($aResult[$i]['viewname'])) {
+                    array_push($aViews, $aResult[$i]['viewname']);
+                }
+            }
+        }
+
+        return $aViews;
+    }
+
+    /**
+     * Récupère la liste des sequences exportables
+     * @param string $sDatabase
+     * @param string $sSchema
+     */
+    function getSequences($sDatabase, $sSchema) {
+
+        $aSequences = [];
+        if ($sDatabase != $this->oConnection->oBd->base) {
+            $this->oBd = new BD($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);
+        }
+
+        $sSQL = $this->aSQL['getSequences'];
+        $aSQLParams = array(
+            'sSchema' => array('value' => $sSchema, 'type' => 'quoted_string')
+        );
+        $oResult = $this->oConnection->oBd->executeWithParams($sSQL, $aSQLParams);
+        if (!$this->oConnection->oBd->enErreur()) {
+            $aResult = $this->oConnection->oBd->getResultTableAssoc($oResult);
+            for ($i = 0; $i < count($aResult); $i++) {
+                if (!empty($aResult[$i]['sequence_name'])) {
+                    array_push($aSequences, $aResult[$i]['sequence_name']);
+                }
+            }
+        }
+
+        return $aSequences;
+    }
+
+    /**
+     * Get the list of the grantable objects
+     * @param array $aLines
+     * @return array
+     */
+    function getSQLGrantableObjectsFromLines($aLines) {
+
+        $aSQLComponents = [];
+        $aAvaliableTypes = array(
+            'TABLE',
+            'VIEW',
+            'SEQUENCE'
+        );
+
+        for ($i = 0; $i < count($aLines); $i++) {
+
+            $sName = $this->getCommentLineName($aLines[$i]);
+            $sType = $this->getCommentLineType($aLines[$i]);
+
+            if ($sName !== false && $sType !== false) {
+                if (in_array($sType, $aAvaliableTypes)) {
+                    array_push($aSQLComponents, array(
+                        'name' => $sName,
+                        'type' => $sType
+                    ));
+                }
+            }
+        }
+        return $aSQLComponents;
+    }
+
+    /**
+     * Récupère les noms des différents schémas
+     * @param array $aLines
+     * @return array
+     */
+    function getSchemasFromLines($aLines) {
+        $sSchemaTag = 'Schema: ';
+        $aSchemas = [];
+
+        for ($i = 0; $i < count($aLines); $i++) {
+            $sSchema = null;
+
+            // Récupère le nom du schema dans les commentaires
+            $sSchema = $this->getCommentLineSchema($aLines[$i]);
+            if ($sSchema !== false) {
+                if (!in_array($sSchema, $aSchemas)) {
+                    array_push($aSchemas, $sSchema);
+                }
+            }
+        }
+        return $aSchemas;
+    }
+
+    /**
+     * Cherche dans un commentaire la valeur de balise Name
+     * @param string $sLine
+     * @return string
+     */
+    function getCommentLineName($sLine) {
+        $sName = false;
+        if (substr($sLine, 0, 9) === '-- Name: ') {
+            $iStartPos = 9;
+            $iEndPos = strpos($sLine, ';', $iStartPos);
+            if ($iEndPos !== false) {
+                $sName = substr($sLine, $iStartPos, $iEndPos - $iStartPos);
+            }
+        }
+        return $sName;
+    }
+
+    /**
+     * Cherche dans un commentaire la valeur de balise Type
+     * @param string $sLine
+     * @return string
+     */
+    function getCommentLineType($sLine) {
+        $sType = false;
+        $sTag = 'Type: ';
+
+        if (substr($sLine, 0, 7) === '-- Name') {
+            $iStartPos = strpos($sLine, $sTag, 7);
+            if ($iStartPos !== false) {
+                $iStartPos = $iStartPos + strlen($sTag);
+                $iEndPos = strpos($sLine, ';', $iStartPos);
+                if ($iEndPos !== false) {
+                    $sType = substr($sLine, $iStartPos, $iEndPos - $iStartPos);
+                }
+            }
+        }
+
+        return $sType;
+    }
+
+    /**
+     * Cherche dans un commentaire la valeur de balise Schema
+     * @param string $sLine
+     * @return string
+     */
+    function getCommentLineSchema($sLine) {
+        $sSchema = false;
+        $sTag = 'Schema: ';
+
+        if (substr($sLine, 0, 7) === '-- Name') {
+            $iStartPos = strpos($sLine, $sTag, 7);
+            if ($iStartPos !== false) {
+                $iStartPos = $iStartPos + strlen($sTag);
+                $iEndPos = strpos($sLine, ';', $iStartPos);
+                if ($iEndPos !== false) {
+                    $sSchema = substr($sLine, $iStartPos, $iEndPos - $iStartPos);
+                }
+            }
+        }
+
+        return $sSchema;
+    }
+
+    // Get Existing vMap Objects
+
+    /**
+     * Récupère les objets vMap qui matchent avec les noms passés en paramètre
+     * @return string
+     */
+    function getExistingVMapObjectsList() {
+
+        $this->aReturn = Array();
+
+        $aVMapObjects = array();
+
+        // Liste des cartes
+        if (!empty($this->aValues['maps'])) {
+            $aMaps = $this->getVMapMaps($this->aValues['maps']);
+            if (!empty($aMaps)) {
+                $aVMapObjects['maps'] = $aMaps;
+            }
+        }
+
+        // Liste des services
+        if (!empty($this->aValues['services'])) {
+            $aServices = $this->getVMapServices($this->aValues['services']);
+            if (!empty($aServices)) {
+                $aVMapObjects['services'] = $aServices;
+            }
+        }
+
+        // Liste des calques
+        if (!empty($this->aValues['calques'])) {
+            $aCalques = $this->getVMapCalques($this->aValues['calques']);
+            if (!empty($aCalques)) {
+                $aVMapObjects['calques'] = $aCalques;
+            }
+        }
+
+        // Liste des thèmes des calques
+        if (!empty($this->aValues['calque_themes'])) {
+            $aCalqueThemes = $this->getVMapCalqueThemes($this->aValues['calque_themes']);
+            if (!empty($aCalqueThemes)) {
+                $aVMapObjects['calque_themes'] = $aCalqueThemes;
+            }
+        }
+
+        // Liste des couches mapserver
+        if (!empty($this->aValues['vm4ms_layers'])) {
+            $aVm4msLayers = $this->getVMapVm4msLayers($this->aValues['vm4ms_layers']);
+            if (!empty($aVm4msLayers)) {
+                $aVMapObjects['vm4ms_layers'] = $aVm4msLayers;
+            }
+        }
+
+        // Liste des objets métier
+        if (!empty($this->aValues['business_objects'])) {
+            $aBusinessObjects = $this->getVMapBusinessObjects($this->aValues['business_objects']);
+            if (!empty($aBusinessObjects)) {
+                $aVMapObjects['business_objects'] = $aBusinessObjects;
+            }
+        }
+
+        // Liste des événements
+        if (!empty($this->aValues['events'])) {
+            $aEvents = $this->getVMapEvents($this->aValues['events']);
+            if (!empty($aEvents)) {
+                $aVMapObjects['events'] = $aEvents;
+            }
+        }
+
+        // Liste des rapports
+        if (!empty($this->aValues['reports'])) {
+            $aReports = $this->getVMapReports($this->aValues['reports']);
+            if (!empty($aReports)) {
+                $aVMapObjects['reports'] = $aReports;
+            }
+        }
+
+        if (isset($this->oError)) {
+            $oError = new VitisError(1, $this->oError->getMessage());
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } elseif (isset($this->oConnection->oError)) {
+            $oError = $this->oConnection->oError;
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } elseif ($this->oConnection->oBd->enErreur()) {
+            $oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } else {
+            $this->aReturn['status'] = 1;
+            $this->aReturn['vmap_objects'] = $aVMapObjects;
+            return json_encode($this->aReturn);
+        }
+    }
+
+    // Get Existing Web services
+
+    /**
+     * Récupère les web services qui matchent avec les noms passés en paramètre
+     * @return string
+     */
+    function getExistingWebServicesList() {
+
+        $this->aReturn = [];
+        $aWebServicesReturned = [];
+
+        // Liste des web services déjà présents
+        if (!empty($this->aValues['web_services'])) {
+
+            // Liste des répertoires contennus dans ws
+            $aDirs = $this->getWsDirectoriesList();
+
+            // Liste des web services demandés
+            $aWebServices = explode('|', $this->aValues['web_services']);
+
+            for ($i = 0; $i < count($aDirs); $i++) {
+                if (in_array($aDirs[$i], $aWebServices)) {
+                    array_push($aWebServicesReturned, $aDirs[$i]);
+                }
+            }
+        }
+
+        if (isset($this->oError)) {
+            $oError = new VitisError(1, $this->oError->getMessage());
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } elseif (isset($this->oConnection->oError)) {
+            $oError = $this->oConnection->oError;
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } elseif ($this->oConnection->oBd->enErreur()) {
+            $oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } else {
+            $this->aReturn['status'] = 1;
+            $this->aReturn['web_services'] = $aWebServicesReturned;
+            return json_encode($this->aReturn);
+        }
+    }
+
+}
+
+?>
diff --git a/vmap/vas/rest/ws/vmap/VexImport.class.inc b/vmap/vas/rest/ws/vmap/VexImport.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..f68bf2674af079ba1fda2cdc8ca60fe87f109343
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/VexImport.class.inc
@@ -0,0 +1,1886 @@
+<?php
+
+/**
+ * \file VexImport.class.inc
+ * \class VexImport
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * 	\brief This file contains the VexImport php class
+ *
+ * This class defines php functions to import VEX files
+ *
+ */
+require_once 'Vex.class.inc';
+require_once 'VexGetter.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Form.class.inc';
+require_once __DIR__ . '/../../class/vmlib/BdDataAccess.inc';
+require_once 'vmlib/logUtil.inc';
+
+/**
+ * Permet l'import de fichiers VEX en utilisant les paramètres
+ * vmap_objects, web_services, sql_objects passés dans $this->aValues
+ */
+class VexImport extends Vmap {
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+    }
+
+    // Import d'objets vMap
+
+    /**
+     * Permet d'importer les objets vMap
+     */
+    function importVMapObjects() {
+
+        $this->aReturn = Array();
+
+        if (!in_array('vitis_admin', $this->oConnection->aPrivileges) ||
+                !in_array('vmap_admin', $this->oConnection->aPrivileges) ||
+                !in_array('vm4ms_admin', $this->oConnection->aPrivileges)) {
+            $oError = new VitisError(0, 'insufficient privileges (needs to be vitis_admin, vmap_admin and vm4ms_admin)');
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        }
+
+        if (!isset($this->aValues['vmap_objects']) || !isset($this->aValues['database']) || !isset($this->aValues['schema']) || !isset($this->aValues['srid'])) {
+            $oError = new VitisError(0, 'Parameters vmap_objects, database, schema, srid required');
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        }
+
+        /**
+         * Objets vMap à importer
+         */
+        $this->aVmapObjects = json_decode($this->aValues['vmap_objects'], true);
+
+        /**
+         * Objet VexGetter permettant de recueillir des informations essentielles
+         */
+        $this->oVexGetter = new VexGetter($this->aPath, $this->aValues, $this->aProperties);
+
+        /**
+         * Connexion privée
+         */
+        $this->oPrivateConnection = $this->getPrivateConnection();
+        if ($this->oPrivateConnection === false) {
+            $oError = new VitisError(0, 'Impossible de récupérer la connexion privée');
+        }
+
+        /**
+         * Service privé
+         */
+        $this->oPrivateService = $this->getPrivateService();
+        if ($this->oPrivateService === false) {
+            $oError = new VitisError(0, 'Impossible de récupérer le service privé');
+        }
+
+        /**
+         * Gestion erreur contenu
+         */
+        if (!is_array($this->aVmapObjects)) {
+            $oError = new VitisError(0, 'vmap_objects non valide');
+        }
+
+        if (!isset($oError)) {
+
+            // Remplace la balise [DATABASE_NAME]
+            $this->replaceOccurences('[DATABASE_NAME]', $this->aValues['database']);
+
+            // Remplace la balise [SCHEMA_NAME]
+            $this->replaceOccurences('[SCHEMA_NAME]', $this->aValues['schema']);
+
+            // Remplace la balise [SRID]
+            $this->replaceOccurences('[SRID]', $this->aValues['srid']);
+
+            // Remplace la balise [PRIVATE_SERVICE]
+            $this->replaceOccurences('[PRIVATE_SERVICE]', $this->oPrivateService['service_id']);
+
+            // Remplace la balise [PRIVATE_CONNECTION]
+            $this->replaceOccurences('[PRIVATE_CONNECTION]', $this->oPrivateConnection['connection_id']);
+
+            // Import des cartes
+            if (!empty($this->aVmapObjects['maps'])) {
+                $this->aReturn['maps'] = $this->importVMapMaps($this->aVmapObjects['maps']);
+            }
+
+            // Import des services
+            if (!empty($this->aVmapObjects['services'])) {
+                $this->aReturn['services'] = $this->importVMapServices($this->aVmapObjects['services']);
+            }
+
+            // Import themes des calques
+            if (!empty($this->aVmapObjects['calque_themes'])) {
+                $this->aReturn['calque_themes'] = $this->importVMapCalqueThemes($this->aVmapObjects['calque_themes']);
+            }
+
+            // Import événements
+            if (!empty($this->aVmapObjects['events'])) {
+                $this->aReturn['events'] = $this->importVMapEvents($this->aVmapObjects['events']);
+            }
+
+            // Import objets métiers
+            if (!empty($this->aVmapObjects['business_objects'])) {
+                $this->aReturn['business_objects'] = $this->importVMapBusinessObjects($this->aVmapObjects['business_objects']);
+            }
+
+            // Import rapports
+            if (!empty($this->aVmapObjects['reports'])) {
+                $this->aReturn['reports'] = $this->importVMapReports($this->aVmapObjects['reports']);
+            }
+
+            // Import couches Mapserver
+            if (!empty($this->aVmapObjects['vm4ms_layers'])) {
+                $this->aReturn['vm4ms_layers'] = $this->importVMapVm4msLayers($this->aVmapObjects['vm4ms_layers']);
+            }
+
+            // Import des calques
+            if (!empty($this->aVmapObjects['calques'])) {
+                $this->aReturn['calques'] = $this->importVMapCalques($this->aVmapObjects['calques']);
+            }
+
+            // Import relation map layer
+            if (!empty($this->aVmapObjects['map_layer'])) {
+                $this->aReturn['map_layer'] = $this->importVMapMapCalquesRelation($this->aVmapObjects['map_layer']);
+            }
+        }
+
+        if (isset($oError)) {
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } elseif (isset($this->oError)) {
+            $oError = new VitisError(1, $this->oError->getMessage());
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } elseif (isset($this->oConnection->oError)) {
+            $oError = $this->oConnection->oError;
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } elseif ($this->oConnection->oBd->enErreur()) {
+            $oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } else {
+            $this->aReturn = array(
+                'vmap_objects' => $this->aReturn,
+                'status' => 1
+            );
+            return json_encode($this->aReturn);
+        }
+    }
+
+    /**
+     * Remplace les occurences dans les objet vMap par la valeur passée en paramètre
+     * Utilisée pour remplacer les balises et les oid par exemple
+     * @param string $sOccurence
+     * @param string $sNewValue
+     */
+    function replaceOccurences($sOccurence, $sNewValue) {
+        if (!empty($sNewValue)) {
+            foreach ($this->aVmapObjects as $key => $value) {
+                switch ($key) {
+                    case 'business_objects':
+                    case 'calques':
+                    case 'calque_themes':
+                    case 'events':
+                    case 'map_layer':
+                    case 'maps':
+                    case 'reports':
+                    case 'services':
+                    case 'vm4ms_layers':
+                        for ($i = 0; $i < count($this->aVmapObjects[$key]); $i++) {
+                            foreach ($this->aVmapObjects[$key][$i] as $key2 => $value2) {
+                                if ($value2 === $sOccurence) {
+                                    $this->aVmapObjects[$key][$i][$key2] = $sNewValue;
+                                }
+                            }
+                        }
+                        break;
+                    default:
+                        break;
+                }
+            }
+        }
+    }
+
+    /**
+     * Récupère la définition de la connexion privée
+     * @return array
+     */
+    function getPrivateConnection() {
+
+        $aVm4msPrivateConnections = $this->oVexGetter->getVMapVm4msConnections(true);
+
+        $iPrivateConnection = false;
+        if (!empty($aVm4msPrivateConnections[0])) {
+            if (!empty($aVm4msPrivateConnections[0]['connection_id'])) {
+                $iPrivateConnection = $aVm4msPrivateConnections[0];
+            }
+        }
+
+        return $iPrivateConnection;
+    }
+
+    /**
+     * Récupère la définition du service privé
+     * @return array
+     */
+    function getPrivateService() {
+
+        $aServices = $this->oVexGetter->getVMapServices(null, ['service_id', 'name', 'url', 'service_vm4ms']);
+
+        $iPrivateService = false;
+
+        // Tente avec l'url
+        for ($i = 0; $i < count($aServices); $i++) {
+            if ($aServices[$i]['service_vm4ms']) {
+                if ($aServices[$i]['url'] = $this->aProperties["ms_cgi_url"] . '/private/[token]') {
+                    $iPrivateService = $aServices[$i];
+                }
+            }
+        }
+
+        // Re-tente avec la balise [token]
+        if ($iPrivateService === false) {
+            for ($i = 0; $i < count($aServices); $i++) {
+                if ($aServices[$i]['service_vm4ms']) {
+                    if (strpos($aServices[$i]['url'], '[token]') !== false) {
+                        $iPrivateService = $aServices[$i];
+                    }
+                }
+            }
+        }
+
+        // Re-tente avec le nom
+        if ($iPrivateService === false) {
+            for ($i = 0; $i < count($aServices); $i++) {
+                if ($aServices[$i]['service_vm4ms']) {
+                    if ($aServices[$i]['name'] === 'vm4ms_private') {
+                        $iPrivateService = $aServices[$i];
+                    }
+                }
+            }
+        }
+
+        return $iPrivateService;
+    }
+
+    // Import Cartes
+
+    /**
+     * Import des cartes vMap
+     * @param array $aMaps
+     */
+    function importVMapMaps($aMaps) {
+        $aReturn = [];
+        for ($i = 0; $i < count($aMaps); $i++) {
+            if (!empty($aMaps[$i]['name'])) {
+                $aExistingMaps = $this->getSameNameMaps($aMaps[$i]);
+                if (count($aExistingMaps) > 0) {
+                    for ($ii = 0; $ii < count($aExistingMaps); $ii++) {
+                        if (!empty($aExistingMaps[$ii]['map_id'])) {
+                            $sNewId = $this->updateVMapMap($aMaps[$i], $aExistingMaps[$ii]['map_id']);
+                            $this->replaceOccurences($aMaps[$i]['map_id'], $sNewId);
+                            array_push($aReturn, $sNewId);
+                        }
+                    }
+                } else {
+                    $sNewId = $this->addVMapMap($aMaps[$i]);
+                    $this->replaceOccurences($aMaps[$i]['map_id'], $sNewId);
+                    array_push($aReturn, $sNewId);
+                }
+            }
+        }
+        return $aReturn;
+    }
+
+    /**
+     * Récupère les cartes ayant le même nom
+     * @param array $aMap
+     * @return array
+     */
+    function getSameNameMaps($aMap) {
+        $aExistingMaps = $this->oVexGetter->getVMapMaps($aMap['name']);
+        return $aExistingMaps;
+    }
+
+    /**
+     * Crée une nouvelle carte
+     * @param array $aMap
+     */
+    function addVMapMap($aMap) {
+        require_once 'Maps.class.inc';
+
+        // Attributs à ne pas envoyer
+        $aUnusedValues = ['map_id', 'thumbnail', 'theme_name', 'theme_description', 'maptheme_id', 'crs_name', 'catalog_index'];
+
+        // Options à passer
+        $aPath = ['vmap', 'maps'];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet']
+        );
+        foreach ($aMap as $key => $value) {
+            if (!in_array($key, $aUnusedValues)) {
+                $aValues[$key] = $value;
+            }
+        }
+
+        $oVitisObject = new Maps($aPath, $aValues, $this->aProperties);
+        $oVitisObject->POST();
+
+        $sReturnedId = false;
+        if (!empty($oVitisObject->aFields)) {
+            if (!empty($oVitisObject->aFields['map_id'])) {
+                $sReturnedId = $oVitisObject->aFields['map_id'];
+            }
+        }
+        return $sReturnedId;
+    }
+
+    /**
+     * Met à jour une carte existante
+     * @param array $aMap
+     * @param string $sMapId identifiant de la carte à mettre à jour
+     */
+    function updateVMapMap($aMap, $sMapId) {
+        require_once 'Maps.class.inc';
+
+        // Attributs à ne pas envoyer
+        $aUnusedValues = ['map_id', 'thumbnail', 'theme_name', 'theme_description', 'maptheme_id', 'crs_name', 'catalog_index'];
+
+        // Options à passer
+        $aPath = ['vmap', 'maps', $sMapId];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet'],
+            'my_vitis_id' => $sMapId
+        );
+        foreach ($aMap as $key => $value) {
+            if (!in_array($key, $aUnusedValues)) {
+                $aValues[$key] = $value;
+            }
+        }
+
+        $oVitisObject = new Maps($aPath, $aValues, $this->aProperties);
+        $oVitisObject->PUT();
+
+        $sReturnedId = false;
+        if (!empty($oVitisObject->aFields)) {
+            if (!empty($oVitisObject->aFields['map_id'])) {
+                $sReturnedId = $oVitisObject->aFields['map_id'];
+            }
+        }
+        return $sReturnedId;
+    }
+
+    // Import Services
+
+    /**
+     * Import des services vMap
+     * @param array $aServices
+     */
+    function importVMapServices($aServices) {
+        $aReturn = [];
+        for ($i = 0; $i < count($aServices); $i++) {
+            if (!empty($aServices[$i]['name'])) {
+                $aExistingServices = $this->getSameNameServices($aServices[$i]);
+                if (count($aExistingServices) > 0) {
+                    for ($ii = 0; $ii < count($aExistingServices); $ii++) {
+                        if (!empty($aExistingServices[$ii]['service_id'])) {
+                            $sNewId = $this->updateVMapService($aServices[$i], $aExistingServices[$ii]['service_id']);
+                            $this->replaceOccurences($aServices[$i]['service_id'], $sNewId);
+                            array_push($aReturn, $sNewId);
+                        }
+                    }
+                } else {
+                    $sNewId = $this->addVMapService($aServices[$i]);
+                    $this->replaceOccurences($aServices[$i]['service_id'], $sNewId);
+                    array_push($aReturn, $sNewId);
+                }
+            }
+        }
+        return $aReturn;
+    }
+
+    /**
+     * Récupère les services ayant le même nom
+     * @param array $aService
+     * @return array
+     */
+    function getSameNameServices($aService) {
+        $aExistingServices = $this->oVexGetter->getVMapServices($aService['name']);
+        return $aExistingServices;
+    }
+
+    /**
+     * Crée un nouveau service
+     * @param array $aService
+     */
+    function addVMapService($aService) {
+        require_once 'Services.class.inc';
+
+        // Attributs à ne pas envoyer
+        $aUnusedValues = ['service_id', 'thumbnail'];
+
+        // Options à passer
+        $aPath = ['vmap', 'services'];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet']
+        );
+        foreach ($aService as $key => $value) {
+            if (!in_array($key, $aUnusedValues)) {
+                $aValues[$key] = $value;
+            }
+        }
+
+        $oVitisObject = new Services($aPath, $aValues, $this->aProperties);
+        $oVitisObject->POST();
+
+        $sReturnedId = false;
+        if (!empty($oVitisObject->aFields)) {
+            if (!empty($oVitisObject->aFields['service_id'])) {
+                $sReturnedId = $oVitisObject->aFields['service_id'];
+            }
+        }
+        return $sReturnedId;
+    }
+
+    /**
+     * Met à jour un service existant
+     * @param array $aService
+     * @param string $sServiceId identifiant de la service à mettre à jour
+     */
+    function updateVMapService($aService, $sServiceId) {
+        require_once 'Services.class.inc';
+
+        // Attributs à ne pas envoyer
+        $aUnusedValues = ['service_id', 'thumbnail'];
+
+        // Options à passer
+        $aPath = ['vmap', 'services', $sServiceId];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet'],
+            'my_vitis_id' => $sServiceId
+        );
+        foreach ($aService as $key => $value) {
+            if (!in_array($key, $aUnusedValues)) {
+                $aValues[$key] = $value;
+            }
+        }
+
+        $oVitisObject = new Services($aPath, $aValues, $this->aProperties);
+        $oVitisObject->PUT();
+
+        $sReturnedId = false;
+        if (!empty($oVitisObject->aFields)) {
+            if (!empty($oVitisObject->aFields['service_id'])) {
+                $sReturnedId = $oVitisObject->aFields['service_id'];
+            }
+        }
+        return $sReturnedId;
+    }
+
+    // Import Calques
+
+    /**
+     * Import les calques vMap
+     * @param array $aCalques
+     */
+    function importVMapCalques($aCalques) {
+        $aReturn = [];
+        for ($i = 0; $i < count($aCalques); $i++) {
+            if (!empty($aCalques[$i]['name'])) {
+                $aExistingCalques = $this->getSameNameCalques($aCalques[$i]);
+                if (count($aExistingCalques) > 0) {
+                    for ($ii = 0; $ii < count($aExistingCalques); $ii++) {
+                        if (!empty($aExistingCalques[$ii]['layer_id'])) {
+                            $sNewId = $this->updateVMapCalque($aCalques[$i], $aExistingCalques[$ii]['layer_id']);
+                            $this->importVMapCalquesForms($aCalques[$i]['layer_id'], $sNewId);
+                            $this->replaceOccurences($aCalques[$i]['layer_id'], $sNewId);
+                            array_push($aReturn, $sNewId);
+                        }
+                    }
+                } else {
+                    $sNewId = $this->addVMapCalque($aCalques[$i]);
+                    $this->importVMapCalquesForms($aCalques[$i]['layer_id'], $sNewId);
+                    $this->replaceOccurences($aCalques[$i]['layer_id'], $sNewId);
+                    array_push($aReturn, $sNewId);
+                }
+            }
+        }
+        return $aReturn;
+    }
+
+    /**
+     * Récupère les calques ayant le même nom
+     * @param array $aCalque
+     * @return array
+     */
+    function getSameNameCalques($aCalque) {
+        $aExistingCalques = $this->oVexGetter->getVMapCalques($aCalque['name']);
+        return $aExistingCalques;
+    }
+
+    /**
+     * Crée un nouveau calque
+     * @param array $aCalque
+     */
+    function addVMapCalque($aCalque) {
+        require_once 'Layers.class.inc';
+
+        // Attributs à ne pas envoyer
+        $aUnusedValues = [
+            'layer_id',
+            'theme_name',
+            'service_name',
+            'service_type_id',
+            'service_url',
+            'service_key',
+            'service_type_version',
+            'service_thumbnail',
+            'service_lang',
+            'service_imagery',
+            'service_type_type',
+            'service_options',
+            'service_login'];
+
+        // Options à passer
+        $aPath = ['vmap', 'layers'];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet']
+        );
+        foreach ($aCalque as $key => $value) {
+            if (!in_array($key, $aUnusedValues)) {
+                $aValues[$key] = $value;
+            }
+        }
+
+        $oVitisObject = new Layers($aPath, $aValues, $this->aProperties);
+        $oVitisObject->POST();
+
+        $sReturnedId = false;
+        if (!empty($oVitisObject->aFields)) {
+            if (!empty($oVitisObject->aFields['layer_id'])) {
+                $sReturnedId = $oVitisObject->aFields['layer_id'];
+            }
+        }
+        return $sReturnedId;
+    }
+
+    /**
+     * Met à jour un calque existant
+     * @param array $aCalque
+     * @param string $sCalqueId identifiant de la calque à mettre à jour
+     */
+    function updateVMapCalque($aCalque, $sCalqueId) {
+        require_once 'Layers.class.inc';
+
+        // Attributs à ne pas envoyer
+        $aUnusedValues = [
+            'layer_id',
+            'theme_name',
+            'service_name',
+            'service_type_id',
+            'service_url',
+            'service_key',
+            'service_type_version',
+            'service_thumbnail',
+            'service_lang',
+            'service_imagery',
+            'service_type_type',
+            'service_options',
+            'service_login'];
+
+        // Options à passer
+        $aPath = ['vmap', 'layers', $sCalqueId];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet'],
+            'my_vitis_id' => $sCalqueId
+        );
+        foreach ($aCalque as $key => $value) {
+            if (!in_array($key, $aUnusedValues)) {
+                $aValues[$key] = $value;
+            }
+        }
+
+        $oVitisObject = new Layers($aPath, $aValues, $this->aProperties);
+        $oVitisObject->PUT();
+
+        $sReturnedId = false;
+        if (!empty($oVitisObject->aFields)) {
+            if (!empty($oVitisObject->aFields['layer_id'])) {
+                $sReturnedId = $oVitisObject->aFields['layer_id'];
+            }
+        }
+        return $sReturnedId;
+    }
+
+    /**
+     * Importe les forumaires du calque
+     * @param string $sOid
+     * @param string $sCalqueId
+     */
+    function importVMapCalquesForms($sOid, $sCalqueId) {
+        if (!empty($sCalqueId)) {
+            if (!empty($this->aVmapObjects['calques_forms'])) {
+                if (!empty($this->aVmapObjects['calques_forms'][$sOid])) {
+
+                    $sFormsDir = $this->aProperties['ws_data_dir'] . '/vmap/layer/' . $sCalqueId;
+                    if (!is_dir($sFormsDir)) {
+                        mkdir($sFormsDir, 0777, true);
+                    }
+                    if (!is_dir($sFormsDir . '/forms')) {
+                        mkdir($sFormsDir . '/forms', 0777, true);
+                    }
+                    if (!is_dir($sFormsDir . '/forms/ressources')) {
+                        mkdir($sFormsDir . '/forms/ressources', 0777, true);
+                    }
+
+                    // Formulaires JSON
+                    $aFormNames = ['default', 'custom', 'published'];
+                    for ($i = 0; $i < count($aFormNames); $i++) {
+                        if (!empty($this->aVmapObjects['calques_forms'][$sOid][$aFormNames[$i]])) {
+                            $pFile = fopen($sFormsDir . '/forms/' . $aFormNames[$i] . '.json', 'w');
+                            if (fwrite($pFile, json_encode($this->aVmapObjects['calques_forms'][$sOid][$aFormNames[$i]])) == false) {
+                                writeToErrorLog('ERROR: ' . $aFormNames[$i] . '.json save failed');
+                            }
+                            fclose($pFile);
+                        }
+                    }
+                    // Ressources JS
+                    if (!empty($this->aVmapObjects['calques_forms'][$sOid]['ressources']['js'])) {
+                        $aFormNames = ['default', 'custom', 'published'];
+                        for ($i = 0; $i < count($aFormNames); $i++) {
+                            if (!empty($this->aVmapObjects['calques_forms'][$sOid]['ressources']['js'][$aFormNames[$i]])) {
+                                $pFile = fopen($sFormsDir . '/forms/ressources/' . $aFormNames[$i] . '.js', 'w');
+                                if (fwrite($pFile, $this->aVmapObjects['calques_forms'][$sOid]['ressources']['js'][$aFormNames[$i]]) == false) {
+                                    writeToErrorLog('ERROR: ' . $aFormNames[$i] . '.js save failed');
+                                }
+                                fclose($pFile);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    // Import themes des Calques
+
+    /**
+     * Import des themes de calques vMap
+     * @param array $aCalqueThemes
+     */
+    function importVMapCalqueThemes($aCalqueThemes) {
+        $aReturn = [];
+        for ($i = 0; $i < count($aCalqueThemes); $i++) {
+            if (!empty($aCalqueThemes[$i]['name'])) {
+                $aExistingCalqueThemes = $this->getSameNameCalqueThemes($aCalqueThemes[$i]);
+                if (count($aExistingCalqueThemes) > 0) {
+                    for ($ii = 0; $ii < count($aExistingCalqueThemes); $ii++) {
+                        if (!empty($aExistingCalqueThemes[$ii]['layertheme_id'])) {
+                            $sNewId = $this->updateVMapCalqueTheme($aCalqueThemes[$i], $aExistingCalqueThemes[$ii]['layertheme_id']);
+                            $this->replaceOccurences($aCalqueThemes[$i]['layertheme_id'], $sNewId);
+                            array_push($aReturn, $sNewId);
+                        }
+                    }
+                } else {
+                    $sNewId = $this->addVMapCalqueTheme($aCalqueThemes[$i]);
+                    $this->replaceOccurences($aCalqueThemes[$i]['layertheme_id'], $sNewId);
+                    array_push($aReturn, $sNewId);
+                }
+            }
+        }
+        return $aReturn;
+    }
+
+    /**
+     * Récupère les themes de calque ayant le même nom
+     * @param array $aCalqueTheme
+     * @return array
+     */
+    function getSameNameCalqueThemes($aCalqueTheme) {
+        $aExistingCalqueThemes = $this->oVexGetter->getVMapCalqueThemes($aCalqueTheme['name']);
+        return $aExistingCalqueThemes;
+    }
+
+    /**
+     * Crée un nouveau theme de calque
+     * @param array $aCalqueTheme
+     */
+    function addVMapCalqueTheme($aCalqueTheme) {
+        require_once 'LayerThemes.class.inc';
+
+        // Attributs à ne pas envoyer
+        $aUnusedValues = ['layertheme_id'];
+
+        // Options à passer
+        $aPath = ['vmap', 'layerthemes'];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet']
+        );
+        foreach ($aCalqueTheme as $key => $value) {
+            if (!in_array($key, $aUnusedValues)) {
+                $aValues[$key] = $value;
+            }
+        }
+
+        $oVitisObject = new LayerThemes($aPath, $aValues, $this->aProperties);
+        $oVitisObject->POST();
+
+        $sReturnedId = false;
+        if (!empty($oVitisObject->aFields)) {
+            if (!empty($oVitisObject->aFields['layertheme_id'])) {
+                $sReturnedId = $oVitisObject->aFields['layertheme_id'];
+            }
+        }
+        return $sReturnedId;
+    }
+
+    /**
+     * Met à jour un theme de calque existant
+     * @param array $aCalqueTheme
+     * @param string $sCalqueThemeId identifiant de la calque à mettre à jour
+     */
+    function updateVMapCalqueTheme($aCalqueTheme, $sCalqueThemeId) {
+        require_once 'LayerThemes.class.inc';
+
+        // Attributs à ne pas envoyer
+        $aUnusedValues = ['layertheme_id'];
+
+        // Options à passer
+        $aPath = ['vmap', 'layerthemes', $sCalqueThemeId];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet'],
+            'my_vitis_id' => $sCalqueThemeId
+        );
+        foreach ($aCalqueTheme as $key => $value) {
+            if (!in_array($key, $aUnusedValues)) {
+                $aValues[$key] = $value;
+            }
+        }
+
+        $oVitisObject = new LayerThemes($aPath, $aValues, $this->aProperties);
+        $oVitisObject->PUT();
+
+        $sReturnedId = false;
+        if (!empty($oVitisObject->aFields)) {
+            if (!empty($oVitisObject->aFields['layertheme_id'])) {
+                $sReturnedId = $oVitisObject->aFields['layertheme_id'];
+            }
+        }
+        return $sReturnedId;
+    }
+
+    // Import événements
+
+    /**
+     * Import les événements vMap
+     * @param array $aEvents
+     */
+    function importVMapEvents($aEvents) {
+        $aReturn = [];
+        for ($i = 0; $i < count($aEvents); $i++) {
+            if (!empty($aEvents[$i]['event_id'])) {
+                $aExistingEvents = $this->getSameNameEvents($aEvents[$i]);
+                if (count($aExistingEvents) > 0) {
+                    for ($ii = 0; $ii < count($aExistingEvents); $ii++) {
+                        if (!empty($aExistingEvents[$ii]['event_id'])) {
+                            $sNewId = $this->updateVMapEvent($aEvents[$i], $aExistingEvents[$ii]['event_id']);
+                            $this->replaceOccurences($aEvents[$i]['event_id'], $sNewId);
+                            array_push($aReturn, $sNewId);
+                        }
+                    }
+                } else {
+                    $sNewId = $this->addVMapEvent($aEvents[$i]);
+                    $this->replaceOccurences($aEvents[$i]['event_id'], $sNewId);
+                    array_push($aReturn, $sNewId);
+                }
+            }
+        }
+        return $aReturn;
+    }
+
+    /**
+     * Récupère les événements ayant le même nom
+     * @param array $aEvent
+     * @return array
+     */
+    function getSameNameEvents($aEvent) {
+        $aExistingEvents = $this->oVexGetter->getVMapEvents($aEvent['event_id']);
+        return $aExistingEvents;
+    }
+
+    /**
+     * Crée un nouvel événement
+     * @param array $aEvent
+     */
+    function addVMapEvent($aEvent) {
+        require_once 'BusinessObjectEvents.class.inc';
+
+        // Attributs à ne pas envoyer
+        $aUnusedValues = [];
+
+        // Options à passer
+        $aPath = ['vmap', 'businessobjectevents'];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet']
+        );
+        foreach ($aEvent as $key => $value) {
+            if (!in_array($key, $aUnusedValues)) {
+                $aValues[$key] = $value;
+            }
+        }
+
+        $oVitisObject = new BusinessObjectEvents($aPath, $aValues, $this->aProperties);
+        $oVitisObject->POST();
+
+        $sReturnedId = false;
+        if (!empty($oVitisObject->aFields)) {
+            if (!empty($oVitisObject->aFields['event_id'])) {
+                $sReturnedId = $oVitisObject->aFields['event_id'];
+            }
+        }
+        return $sReturnedId;
+    }
+
+    /**
+     * Met à jour un événement existant
+     * @param array $aEvent
+     * @param string $sEventId identifiant de la service à mettre à jour
+     */
+    function updateVMapEvent($aEvent, $sEventId) {
+        require_once 'BusinessObjectEvents.class.inc';
+
+        // Attributs à ne pas envoyer
+        $aUnusedValues = [];
+
+        // Options à passer
+        $aPath = ['vmap', 'businessobjectevents', $sEventId];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet'],
+            'my_vitis_id' => $sEventId
+        );
+        foreach ($aEvent as $key => $value) {
+            if (!in_array($key, $aUnusedValues)) {
+                $aValues[$key] = $value;
+            }
+        }
+
+        $oVitisObject = new BusinessObjectEvents($aPath, $aValues, $this->aProperties);
+        $oVitisObject->PUT();
+
+        $sReturnedId = false;
+        if (!empty($oVitisObject->aFields)) {
+            if (!empty($oVitisObject->aFields['event_id'])) {
+                $sReturnedId = $oVitisObject->aFields['event_id'];
+            }
+        }
+        return $sReturnedId;
+    }
+
+    // Import objets métier
+
+    /**
+     * Import les objets métier vMap
+     * @param array $aBusinessObjects
+     */
+    function importVMapBusinessObjects($aBusinessObjects) {
+        $aReturn = [];
+        for ($i = 0; $i < count($aBusinessObjects); $i++) {
+            if (!empty($aBusinessObjects[$i]['business_object_id'])) {
+
+                // Remplacement de la balise [SCHEMA_NAME] dans sql summary / list
+                $aBusinessObjects[$i]['sql_summary'] = preg_replace('/\[SCHEMA_NAME\]/', $this->aValues['schema'], $aBusinessObjects[$i]['sql_summary']);
+                $aBusinessObjects[$i]['sql_list'] = preg_replace('/\[SCHEMA_NAME\]/', $this->aValues['schema'], $aBusinessObjects[$i]['sql_list']);
+
+                $aExistingBusinessObjects = $this->getSameNameBusinessObjects($aBusinessObjects[$i]);
+                if (count($aExistingBusinessObjects) > 0) {
+                    for ($ii = 0; $ii < count($aExistingBusinessObjects); $ii++) {
+                        if (!empty($aExistingBusinessObjects[$ii]['business_object_id'])) {
+                            $sNewId = $this->updateVMapBusinessObject($aBusinessObjects[$i], $aExistingBusinessObjects[$ii]['business_object_id']);
+                            $this->importVMapBusinessObjectForms($sNewId);
+                            $this->replaceOccurences($aBusinessObjects[$i]['business_object_id'], $sNewId);
+                            array_push($aReturn, $sNewId);
+                        }
+                    }
+                } else {
+                    $sNewId = $this->addVMapBusinessObject($aBusinessObjects[$i]);
+                    $this->importVMapBusinessObjectForms($sNewId);
+                    $this->replaceOccurences($aBusinessObjects[$i]['business_object_id'], $sNewId);
+                    array_push($aReturn, $sNewId);
+                }
+            }
+        }
+        return $aReturn;
+    }
+
+    /**
+     * Récupère les objets métier ayant le même nom
+     * @param array $aBusinessObject
+     * @return array
+     */
+    function getSameNameBusinessObjects($aBusinessObject) {
+        $aExistingBusinessObjects = $this->oVexGetter->getVMapBusinessObjects($aBusinessObject['business_object_id']);
+        return $aExistingBusinessObjects;
+    }
+
+    /**
+     * Crée un nouvel objets métier
+     * @param array $aBusinessObject
+     */
+    function addVMapBusinessObject($aBusinessObject) {
+        require_once 'BusinessObjects.class.inc';
+
+        // Attributs à ne pas envoyer
+        $aUnusedValues = [];
+
+        // Options à passer
+        $aPath = ['vmap', 'businessobjects'];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet']
+        );
+        foreach ($aBusinessObject as $key => $value) {
+            if (!in_array($key, $aUnusedValues)) {
+                $aValues[$key] = $value;
+            }
+        }
+
+        $oVitisObject = new BusinessObjects($aPath, $aValues, $this->aProperties);
+        $oVitisObject->POST();
+
+        $sReturnedId = false;
+        if (!empty($oVitisObject->aFields)) {
+            if (!empty($oVitisObject->aFields['business_object_id'])) {
+                $sReturnedId = $oVitisObject->aFields['business_object_id'];
+            }
+        }
+        return $sReturnedId;
+    }
+
+    /**
+     * Met à jour un objets métier existant
+     * @param array $aBusinessObject
+     * @param string $sBusinessObjectId identifiant de la service à mettre à jour
+     */
+    function updateVMapBusinessObject($aBusinessObject, $sBusinessObjectId) {
+        require_once 'BusinessObjects.class.inc';
+
+        // Attributs à ne pas envoyer
+        $aUnusedValues = [];
+
+        // Options à passer
+        $aPath = ['vmap', 'businessobjects', $sBusinessObjectId];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet'],
+            'my_vitis_id' => $sBusinessObjectId
+        );
+        foreach ($aBusinessObject as $key => $value) {
+            if (!in_array($key, $aUnusedValues)) {
+                $aValues[$key] = $value;
+            }
+        }
+
+        $oVitisObject = new BusinessObjects($aPath, $aValues, $this->aProperties);
+        $oVitisObject->PUT();
+
+        $sReturnedId = false;
+        if (!empty($oVitisObject->aFields)) {
+            if (!empty($oVitisObject->aFields['business_object_id'])) {
+                $sReturnedId = $oVitisObject->aFields['business_object_id'];
+            }
+        }
+        return $sReturnedId;
+    }
+
+    /**
+     * Importe les formulaires de l'objet métier
+     * @param string $sBusinessObjectId
+     */
+    function importVMapBusinessObjectForms($sBusinessObjectId) {
+        if (!empty($sBusinessObjectId)) {
+            if (!empty($this->aVmapObjects['business_objects_forms'])) {
+                if (!empty($this->aVmapObjects['business_objects_forms'][$sBusinessObjectId])) {
+
+                    $sFormsDir = $this->aProperties['ws_data_dir'] . '/vmap/business_object/' . $sBusinessObjectId;
+                    if (!is_dir($sFormsDir)) {
+                        mkdir($sFormsDir, 0777, true);
+                    }
+                    if (!is_dir($sFormsDir . '/forms')) {
+                        mkdir($sFormsDir . '/forms', 0777, true);
+                    }
+                    if (!is_dir($sFormsDir . '/forms/ressources')) {
+                        mkdir($sFormsDir . '/forms/ressources', 0777, true);
+                    }
+
+                    // Formulaires JSON
+                    $aFormNames = ['default', 'custom', 'published'];
+                    for ($i = 0; $i < count($aFormNames); $i++) {
+
+                        $sFormContent = json_encode($this->aVmapObjects['business_objects_forms'][$sBusinessObjectId][$aFormNames[$i]]);
+
+                        if (!empty($sFormContent)) {
+
+                            $aPatterns = [
+                                '/\[DATABASE_NAME\]/',
+                                '/\[SCHEMA_NAME\]/'
+                            ];
+                            $aReplacements = [
+                                $this->aValues['database'],
+                                $this->aValues['schema']
+                            ];
+                            $sFormContent = preg_replace($aPatterns, $aReplacements, $sFormContent);
+
+                            $pFile = fopen($sFormsDir . '/forms/' . $aFormNames[$i] . '.json', 'w');
+                            if (fwrite($pFile, $sFormContent) == false) {
+                                writeToErrorLog('ERROR: ' . $aFormNames[$i] . '.json save failed');
+                            }
+                            fclose($pFile);
+                        }
+                    }
+                    // Ressources JS
+                    if (!empty($this->aVmapObjects['business_objects_forms'][$sBusinessObjectId]['ressources']['js'])) {
+                        $aFormNames = ['default', 'custom', 'published'];
+                        for ($i = 0; $i < count($aFormNames); $i++) {
+                            if (!empty($this->aVmapObjects['business_objects_forms'][$sBusinessObjectId]['ressources']['js'][$aFormNames[$i]])) {
+                                $pFile = fopen($sFormsDir . '/forms/ressources/' . $aFormNames[$i] . '.js', 'w');
+                                if (fwrite($pFile, $this->aVmapObjects['business_objects_forms'][$sBusinessObjectId]['ressources']['js'][$aFormNames[$i]]) == false) {
+                                    writeToErrorLog('ERROR: ' . $aFormNames[$i] . '.js save failed');
+                                }
+                                fclose($pFile);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    // Import rapports
+
+    /**
+     * Import des rapports vMap
+     * @param array $aReports
+     */
+    function importVMapReports($aReports) {
+        $aReturn = [];
+        for ($i = 0; $i < count($aReports); $i++) {
+            if (!empty($aReports[$i]['name'])) {
+                $aExistingReports = $this->getSameNameReports($aReports[$i]);
+                if (count($aExistingReports) > 0) {
+                    for ($ii = 0; $ii < count($aExistingReports); $ii++) {
+                        if (!empty($aExistingReports[$ii]['printreport_id'])) {
+                            $sNewId = $this->updateVMapReport($aReports[$i], $aExistingReports[$ii]['printreport_id']);
+                            $this->replaceOccurences($aReports[$i]['printreport_id'], $sNewId);
+                            array_push($aReturn, $sNewId);
+                        }
+                    }
+                } else {
+                    $sNewId = $this->addVMapReport($aReports[$i]);
+                    $this->replaceOccurences($aReports[$i]['printreport_id'], $sNewId);
+                    array_push($aReturn, $sNewId);
+                }
+            }
+        }
+        return $aReturn;
+    }
+
+    /**
+     * Récupère les rapports ayant le même nom
+     * @param array $aReport
+     * @return array
+     */
+    function getSameNameReports($aReport) {
+        $aExistingReports = $this->oVexGetter->getVMapReports($aReport['name']);
+        return $aExistingReports;
+    }
+
+    /**
+     * Crée un nouveau rapport
+     * @param array $aReport
+     */
+    function addVMapReport($aReport) {
+        require_once 'PrintReports.class.inc';
+
+        // Attributs à ne pas envoyer
+        $aUnusedValues = ['printreport_id'];
+
+
+        // Options à passer
+        $aPath = ['vmap', 'printreports'];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet']
+        );
+        foreach ($aReport as $key => $value) {
+            if (!in_array($key, $aUnusedValues)) {
+                $aValues[$key] = $value;
+            }
+        }
+
+        $oVitisObject = new PrintReports($aPath, $aValues, $this->aProperties);
+        $oVitisObject->POST();
+
+        $sReturnedId = false;
+        if (!empty($oVitisObject->aFields)) {
+            if (!empty($oVitisObject->aFields['printreport_id'])) {
+                $sReturnedId = $oVitisObject->aFields['printreport_id'];
+            }
+        }
+        return $sReturnedId;
+    }
+
+    /**
+     * Met à jour un rapport existant
+     * @param array $aReport
+     * @param string $sReportId identifiant de la service à mettre à jour
+     */
+    function updateVMapReport($aReport, $sReportId) {
+        require_once 'PrintReports.class.inc';
+
+        // Attributs à ne pas envoyer
+        $aUnusedValues = ['printreport_id'];
+
+
+        // Options à passer
+        $aPath = ['vmap', 'printreports', $sReportId];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet'],
+            'my_vitis_id' => $sReportId
+        );
+        foreach ($aReport as $key => $value) {
+            if (!in_array($key, $aUnusedValues)) {
+                $aValues[$key] = $value;
+            }
+        }
+
+        $oVitisObject = new PrintReports($aPath, $aValues, $this->aProperties);
+        $oVitisObject->PUT();
+
+        $sReturnedId = false;
+        if (!empty($oVitisObject->aFields)) {
+            if (!empty($oVitisObject->aFields['printreport_id'])) {
+                $sReturnedId = $oVitisObject->aFields['printreport_id'];
+            }
+        }
+        return $sReturnedId;
+    }
+
+    // Import couches Mapserver
+
+    /**
+     * Import les couches mapserver vMap
+     * @param array $aVm4msLayers
+     */
+    function importVMapVm4msLayers($aVm4msLayers) {
+        $aReturn = [];
+        for ($i = 0; $i < count($aVm4msLayers); $i++) {
+            if (!empty($aVm4msLayers[$i]['name'])) {
+                $aExistingVm4msLayers = $this->getSameNameVm4msLayers($aVm4msLayers[$i]);
+                if (count($aExistingVm4msLayers) > 0) {
+                    for ($ii = 0; $ii < count($aExistingVm4msLayers); $ii++) {
+                        if (!empty($aExistingVm4msLayers[$ii]['ms_layer_id'])) {
+                            $sNewId = $this->updateVMapVm4msLayer($aVm4msLayers[$i], $aExistingVm4msLayers[$ii]['ms_layer_id']);
+                            $this->replaceOccurences($aVm4msLayers[$i]['ms_layer_id'], $sNewId);
+                            array_push($aReturn, $sNewId);
+                        }
+                    }
+                } else {
+                    $sNewId = $this->addVMapVm4msLayer($aVm4msLayers[$i]);
+                    $this->replaceOccurences($aVm4msLayers[$i]['ms_layer_id'], $sNewId);
+                    array_push($aReturn, $sNewId);
+                }
+            }
+        }
+        return $aReturn;
+    }
+
+    /**
+     * Récupère les couches mapserver ayant le même nom
+     * @param array $aVm4msLayer
+     * @return array
+     */
+    function getSameNameVm4msLayers($aVm4msLayer) {
+        // Attributs à ne pas envoyer
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'attributs' => implode('|', ['ms_layer_id', 'name', 'tableschema', 'tablename', 'connection_id']),
+            'filter' => '{"column": "name", "compare_operator": "=", "value": "' . $aVm4msLayer['name'] . '"}'
+        );
+
+        // Ferme temporairement la session
+        session_write_close();
+
+        // Envoie une requête curl pour ajouter la couche Mapserver
+        $sUrl = $this->aProperties['web_server_name'] . '/' . $this->aProperties['services_alias'] . '/vm4ms/layers';
+        $ch = curl_init($sUrl);
+        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
+        curl_setopt($ch, CURLOPT_HTTPHEADER, array("Accept: application/json", "X-HTTP-Method-Override: GET"));
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+        curl_setopt($ch, CURLOPT_POST, 1);
+        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+        curl_setopt($ch, CURLOPT_POSTFIELDS, $aValues);
+        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
+        $sResponse = curl_exec($ch);
+        curl_close($ch);
+
+        // Ouvre à nouveau la session
+        $this->oConnection = new Connection($this->aValues, $this->aProperties);
+
+        $sReturnedId = false;
+        $aResponse = json_decode($sResponse, true);
+
+        $aExistingVm4msLayers = [];
+        if (!empty($aResponse['layers'])) {
+            $aExistingVm4msLayers = $aResponse['layers'];
+        }
+        return $aExistingVm4msLayers;
+    }
+
+    /**
+     * Crée une nouvelle couche mapverver
+     * @param array $aVm4msLayer
+     */
+    function addVMapVm4msLayer($aVm4msLayer) {
+        // Attributs à ne pas envoyer
+        $aUnusedValues = ['ms_layer_id'];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+        );
+
+        foreach ($aVm4msLayer as $key => $value) {
+            if (!in_array($key, $aUnusedValues)) {
+                $aValues[$key] = $value;
+            }
+        }
+
+        // Ferme temporairement la session
+        session_write_close();
+
+        // Envoie une requête curl pour ajouter la couche Mapserver
+        $sUrl = $this->aProperties['web_server_name'] . '/' . $this->aProperties['services_alias'] . '/vm4ms/layers';
+        $ch = curl_init($sUrl);
+        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
+        curl_setopt($ch, CURLOPT_HTTPHEADER, array("Accept: application/json"));
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+        curl_setopt($ch, CURLOPT_POST, 1);
+        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+        curl_setopt($ch, CURLOPT_POSTFIELDS, $aValues);
+        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
+        $sResponse = curl_exec($ch);
+        curl_close($ch);
+
+        // Ouvre à nouveau la session
+        $this->oConnection = new Connection($this->aValues, $this->aProperties);
+
+        $sReturnedId = false;
+        $aResponse = json_decode($sResponse, true);
+
+        if (!empty($aResponse['ms_layer_id'])) {
+            $sReturnedId = $aResponse['ms_layer_id'];
+        }
+        return $sReturnedId;
+    }
+
+    /**
+     * Met à jour une couche Mapserver
+     * @param array $aVm4msLayer
+     * @param string $sVm4msLayerId identifiant de la service à mettre à jour
+     */
+    function updateVMapVm4msLayer($aVm4msLayer, $sVm4msLayerId) {
+        // Attributs à ne pas envoyer
+        $aUnusedValues = ['ms_layer_id'];
+        $aValues = array(
+            'token' => $this->aValues['token']
+        );
+
+        foreach ($aVm4msLayer as $key => $value) {
+            if (!in_array($key, $aUnusedValues)) {
+                $aValues[$key] = $value;
+            }
+        }
+
+        // Ferme temporairement la session
+        session_write_close();
+
+        // Envoie une requête curl pour ajouter la couche Mapserver
+        $sUrl = $this->aProperties['web_server_name'] . '/' . $this->aProperties['services_alias'] . '/vm4ms/layers/' . $sVm4msLayerId;
+        $ch = curl_init($sUrl);
+        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
+        curl_setopt($ch, CURLOPT_HTTPHEADER, array("Accept: application/json"));
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
+        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+        curl_setopt($ch, CURLOPT_POSTFIELDS, $aValues);
+        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
+        $sResponse = curl_exec($ch);
+        curl_close($ch);
+
+        // Ouvre à nouveau la session
+        $this->oConnection = new Connection($this->aValues, $this->aProperties);
+
+        $sReturnedId = false;
+        $aResponse = json_decode($sResponse, true);
+
+        if (!empty($aResponse['ms_layer_id'])) {
+            $sReturnedId = $aResponse['ms_layer_id'];
+        }
+        return $sReturnedId;
+    }
+
+    // Import relation carte / calques
+
+    /**
+     * Importe les relations cartes calques
+     * @param Array $aMapCalques
+     */
+    function importVMapMapCalquesRelation($aMapCalques) {
+        // Association
+        for ($i = 0; $i < count($aMapCalques); $i++) {
+            if (!empty($aMapCalques[$i]['layer_id']) && !empty($aMapCalques[$i]['map_id'])) {
+                $this->updateVMapMapCalques($aMapCalques[$i]);
+            }
+        }
+
+        // Ordre
+        $aMaps = [];
+        for ($i = 0; $i < count($aMapCalques); $i++) {
+            if (empty($aMaps[$aMapCalques[$i]['map_id']])) {
+                $aMaps[$aMapCalques[$i]['map_id']] = [];
+            }
+            array_push($aMaps[$aMapCalques[$i]['map_id']], $aMapCalques[$i]);
+        }
+        foreach ($aMaps as $key => $value) {
+            $this->updateVMapMapCalquesSorting($aMaps[$key], $key);
+        }
+
+        return true;
+    }
+
+    /**
+     * Associe les calques à la carte
+     * @param array $aMapCalque
+     */
+    function updateVMapMapCalques($aMapCalque) {
+        require_once 'MapLayers.class.inc';
+
+        // Attributs à ne pas envoyer
+        $aUnusedValues = ['name', 'theme_name', 'layer_id'];
+
+        // Options à passer
+        $aPath = ['vmap', 'maplayers', $aMapCalque['map_id']];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet'],
+            'my_vitis_id' => $aMapCalque['map_id']
+        );
+        foreach ($aMapCalque as $key => $value) {
+            if (!in_array($key, $aUnusedValues)) {
+                $aValues[$key] = $value;
+            }
+        }
+        $aValues['map_layers'] = $aMapCalque['layer_id'];
+
+        $oVitisObject = new MapLayers($aPath, $aValues, $this->aProperties);
+        $oVitisObject->PUT();
+    }
+
+    /**
+     * Change l'ordre des calques dans la carte
+     * @param array $aMapCalques
+     * @param string $sMapId
+     */
+    function updateVMapMapCalquesSorting($aMapCalques, $sMapId) {
+        require_once 'MapLayers.class.inc';
+
+        $aLayerIds = [];
+        for ($i = 0; $i < count($aMapCalques); $i++) {
+            if (!empty($aMapCalques[$i]['layer_id'])) {
+                array_push($aLayerIds, $aMapCalques[$i]['layer_id']);
+            }
+        }
+
+        // Options à passer
+        $aPath = ['vmap', 'maplayers', $sMapId, 'sorting'];
+        $aValues = array(
+            'token' => $this->aValues['token'],
+            'output' => $this->aValues['output'],
+            'sEncoding' => $this->aValues['sEncoding'],
+            'sSourceEncoding' => $this->aValues['sSourceEncoding'],
+            'xslstylesheet' => $this->aValues['xslstylesheet'],
+            'my_vitis_id' => $sMapId
+        );
+
+        $aValues['map_id'] = $sMapId;
+        $aValues['map_layers'] = implode('|', $aLayerIds);
+
+        $oVitisObject = new MapLayers($aPath, $aValues, $this->aProperties);
+        $oVitisObject->PUT();
+    }
+
+    // Import des wervices web
+
+    /**
+     * Permet d'importer des services web
+     * @return type
+     */
+    function importWebServices() {
+        $this->aReturn = Array();
+
+        if (!in_array('vitis_admin', $this->oConnection->aPrivileges) ||
+                !in_array('vmap_admin', $this->oConnection->aPrivileges) ||
+                !in_array('vm4ms_admin', $this->oConnection->aPrivileges)) {
+            $oError = new VitisError(0, 'insufficient privileges (needs to be vitis_admin, vmap_admin and vm4ms_admin)');
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        }
+
+        if (!isset($this->aValues['web_services'])) {
+            $oError = new VitisError(0, 'Parameter web_services required');
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        }
+
+        /**
+         * Services web à importer
+         */
+        $this->aWebServices = json_decode($this->aValues['web_services'], true);
+
+        /**
+         * Gestion erreur contenu
+         */
+        if (!is_array($this->aWebServices)) {
+            $oError = new VitisError(0, 'web_services not valid');
+        }
+
+        if (!isset($oError)) {
+            $this->aReturn = $this->importWebServicesFiles($this->aWebServices);
+        }
+
+        if (isset($oError)) {
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } elseif (isset($this->oError)) {
+            $oError = new VitisError(1, $this->oError->getMessage());
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } elseif (isset($this->oConnection->oError)) {
+            $oError = $this->oConnection->oError;
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } elseif ($this->oConnection->oBd->enErreur()) {
+            $oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } else {
+            $this->aReturn = array(
+                'web_services' => $this->aReturn,
+                'status' => 1
+            );
+            return json_encode($this->aReturn);
+        }
+    }
+
+    /**
+     * Import the web service files
+     * @param array $aWebServices
+     * @return array
+     */
+    function importWebServicesFiles($aWebServices) {
+        for ($i = 0; $i < count($aWebServices); $i++) {
+            if (!empty($aWebServices[$i]['name'] && !empty($aWebServices[$i]['files']))) {
+
+                // Création du dossier
+                $sWebServicePath = $this->aProperties['vas_home'] . '/rest/ws/' . $aWebServices[$i]['name'];
+                if (!is_dir($sWebServicePath)) {
+                    mkdir($sWebServicePath, 0777, true);
+                }
+
+                // Import des fichiers
+                foreach ($aWebServices[$i]['files'] as $key => $value) {
+                    $pFile = fopen($sWebServicePath . '/' . $key, 'w');
+                    if (fwrite($pFile, $aWebServices[$i]['files'][$key]) == false) {
+                        unset($aWebServices[$i]['files'][$key]);
+                        writeToErrorLog('ERROR: ' . $key . '. save failed');
+                    }
+                    fclose($pFile);
+                }
+            }
+        }
+        return $aWebServices;
+    }
+
+    // Import SQL
+
+    /**
+     * Permet d'importer la partie SQL d'un .vex
+     */
+    function importSQL() {
+
+        $this->aReturn = Array();
+
+        if (!in_array('vitis_admin', $this->oConnection->aPrivileges) ||
+                !in_array('vmap_admin', $this->oConnection->aPrivileges) ||
+                !in_array('vm4ms_admin', $this->oConnection->aPrivileges)) {
+            $oError = new VitisError(0, 'insufficient privileges (needs to be vitis_admin, vmap_admin and vm4ms_admin)');
+        }
+
+        if (!isset($this->aValues['sql_model']) || !isset($this->aValues['database']) || !isset($this->aValues['schema'])) {
+            $oError = new VitisError(0, 'Parameter sql_model, database, schema required');
+        }
+
+        /**
+         * Objet VexGetter permettant de recueillir des informations essentielles
+         */
+        $this->oVexGetter = new VexGetter($this->aPath, $this->aValues, $this->aProperties);
+
+        /**
+         * Modèle SQL importer
+         */
+        $this->sSQLModel = $this->aValues['sql_model'];
+
+        /**
+         * Données SQL importer
+         */
+        $this->sSQLData = $this->aValues['sql_data'];
+
+        /**
+         * Gestion erreur contenu
+         */
+        if (!is_string($this->sSQLModel)) {
+            $oError = $oError = new VitisError(0, 'sql_model no valid');
+        }
+
+        if (!isset($oError)) {
+            $sStringRequests = $this->sSQLModel;
+            if (is_string($this->sSQLData)) {
+                if (!empty($this->sSQLData)) {
+                    $sStringRequests .= $this->sSQLData;
+                }
+            }
+
+            // Récupère le contenu au format d'un tableau
+            $aArrayRequests = $this->getRequestsAsArray($sStringRequests);
+
+            if ($aArrayRequests !== false) {
+
+                // Récupère la liste des tables, vues etc..
+                $aSQLComponents = $this->oVexGetter->getSQLGrantableObjectsFromLines($aArrayRequests);
+
+                // Enlève les les commentaires et lignes vides
+                $aArrayRequests = $this->cleanArrayRequests($aArrayRequests);
+
+                // Concatène les requêtes et retourne une chaine de caractère
+                $sSQLRequests = $this->concatArrayRequests($aArrayRequests);
+
+                // Éxécute les requêtes
+                $bSQLImported = $this->executeSQLRequests($sSQLRequests, $this->aValues['database']);
+
+                // Reprojette les données si besoin
+                if (!empty($this->aValues['srid'])) {
+                    $this->updateTablesSRID($aSQLComponents, $this->aValues['srid']);
+                }
+
+                $this->aReturn = $bSQLImported;
+            }
+        }
+
+        if (isset($oError)) {
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } elseif (isset($this->oError)) {
+            $oError = new VitisError(1, $this->oError->getMessage());
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } elseif (isset($this->oConnection->oError)) {
+            $oError = $this->oConnection->oError;
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } elseif ($this->oConnection->oBd->enErreur()) {
+            $oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } else {
+            $this->aReturn = array(
+                'sql' => $this->aReturn,
+                'status' => 1
+            );
+            return json_encode($this->aReturn);
+        }
+    }
+
+    /**
+     * Parse les requêtes contenant des sauts à la ligne etc.. et retourne un tableau
+     * @param string $sStringRequests
+     * @return array
+     */
+    function getRequestsAsArray($sStringRequests) {
+
+        $sTmpPath = $this->aProperties['vas_home'] . '/tmp/' . $this->UniqFileName();
+
+        $pFile = fopen($sTmpPath, 'w');
+        if (fwrite($pFile, $sStringRequests) == false) {
+            return false;
+        }
+        fclose($pFile);
+
+        $aArrayRequests = file($sTmpPath);
+
+        unlink($sTmpPath);
+        return $aArrayRequests;
+    }
+
+    /**
+     * Delete the white spaces and comments from the data-model file array vue
+     * @param array $aArrayRequests
+     * @return array
+     */
+    function cleanArrayRequests($aArrayRequests) {
+
+        for ($i = count($aArrayRequests) - 1; $i >= 0; $i--) {
+            // Supprime les espaces
+            $aArrayRequests[$i] = trim($aArrayRequests[$i]);
+            // Supprime les lignes vides
+            if ($aArrayRequests[$i] === '') {
+                unset($aArrayRequests[$i]);
+            } else {
+                // Supprime les commentaires
+                if (substr($aArrayRequests[$i], 0, 2) === '--') {
+                    unset($aArrayRequests[$i]);
+                } else {
+                    // Supprime SET idle_in_transaction_session_timeout = 0;
+                    if (substr($aArrayRequests[$i], 0, 39) == 'SET idle_in_transaction_session_timeout') {
+                        unset($aArrayRequests[$i]);
+                    }
+                }
+            }
+        }
+        // Redonne les bons index
+        $aArrayRequests2 = Array();
+        foreach ($aArrayRequests as $key => $value) {
+            array_push($aArrayRequests2, $value);
+        }
+        $aArrayRequests = $aArrayRequests2;
+
+        return $aArrayRequests;
+    }
+
+    /**
+     * Concatène les requêtes présentes dans $aArrayRequests
+     * @param array $aArrayRequests
+     * @return string
+     */
+    function concatArrayRequests($aArrayRequests) {
+
+        $sStringContents = '';
+        for ($i = 0; $i < count($aArrayRequests); $i++) {
+            $sStringContents .= $aArrayRequests[$i] . ' ';
+        }
+
+        return $sStringContents;
+    }
+
+    /**
+     * Execute the data-model requests
+     * @param array $aFileRequests
+     * @return array results
+     */
+    function executeSQLRequests($sSQLRequests, $sDatabase) {
+
+        // Connexion avec uVitis
+        $oBD = new Vm($this->aProperties['owner_login'], $this->aProperties['owner_pass'], $sDatabase, $this->aProperties['server'], $this->aProperties['port'], $this->aProperties['sgbd'], $this->aProperties['page_encoding']);
+        $this->oConnection->oBd = $oBD;
+
+        $this->oConnection->oBd->demarreTransaction();
+
+        $bError = false;
+        $oPDOresult = $this->oConnection->oBd->executeBlock($sSQLRequests);
+
+        if ($this->oConnection->oBd->enErreur()) {
+            $this->oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+            $bError = true;
+        } else {
+            $aResults = $this->oConnection->oBd->getResultTableAssoc($oPDOresult);
+        }
+
+        if ($bError) {
+            $this->oConnection->oBd->annuleTransaction();
+            return false;
+        } else {
+            $this->oConnection->oBd->termineTransaction();
+            return true;
+        }
+    }
+
+    /**
+     * Update and transform the tables SRID
+     * @param array $aSQLComponents
+     * @param string $sSRID
+     */
+    function updateTablesSRID($aSQLComponents, $sSRID) {
+
+        $aTables = $this->getTablesFromSQLComponents($aSQLComponents);
+        if (is_array($aTables)) {
+            for ($i = 0; $i < count($aTables); $i++) {
+                $aGeomColumns = $this->getGeometryColumns($this->aValues['schema'], $aTables[$i]);
+                if (is_array($aGeomColumns)) {
+                    for ($ii = 0; $ii < count($aGeomColumns); $ii++) {
+                        $this->updateTableColumnSRID($this->aValues['schema'], $aTables[$i], $aGeomColumns[$ii], $sSRID);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Get a table list from $aSQLComponents
+     * @param array $aSQLComponents
+     * @return array
+     */
+    function getTablesFromSQLComponents($aSQLComponents) {
+        $aTables = [];
+        for ($i = 0; $i < count($aSQLComponents); $i++) {
+            if ($aSQLComponents[$i]['type'] === 'TABLE') {
+                if (!empty($aSQLComponents[$i]['name'])) {
+                    array_push($aTables, $aSQLComponents[$i]['name']);
+                }
+            }
+        }
+        return $aTables;
+    }
+
+    /**
+     * Get the geometry columns from a table
+     * @param string $sSchema
+     * @param string $sTable
+     * @return array
+     */
+    function getGeometryColumns($sSchema, $sTable) {
+        require 'Vex.class.sql.inc';
+        $aColumn = Array();
+        $sSql = $aSql['getGeometryColumns'];
+
+        $aSqlParams = array(
+            'sSchemaFramework' => array('value' => $sSchema, 'type' => 'column_name'),
+            'sTable' => array('value' => $sTable, 'type' => 'column_name')
+        );
+
+        $oResult = $this->oConnection->oBd->executeWithParams($sSql, $aSqlParams);
+
+        // vide si postGis n'est pas installé
+        if (!empty($oResult)) {
+            while ($aObject = $this->oConnection->oBd->ligneSuivante($oResult)) {
+                array_push($aColumn, $aObject['f_geometry_column']);
+            }
+        }
+
+        return $aColumn;
+    }
+
+    /**
+     * Update the table column srid and transform his data
+     * @param string $sSchema
+     * @param string $sTable
+     * @param string $sColumn
+     * @param string $sSRID
+     */
+    function updateTableColumnSRID($sSchema, $sTable, $sColumn, $sSRID) {
+        require 'Vex.class.sql.inc';
+
+        $oResult = $this->oConnection->oBd->executeWithParams('SET search_path TO public', []);
+
+        $aSqlParams = array(
+            'sSchema' => array('value' => $sSchema, 'type' => 'quoted_string'),
+            'sTable' => array('value' => $sTable, 'type' => 'quoted_string'),
+            'sColumn' => array('value' => $sColumn, 'type' => 'quoted_string'),
+            'iSRID' => array('value' => $sSRID, 'type' => 'number')
+        );
+        $oResult = $this->oConnection->oBd->executeWithParams($aSql['updateTableColumnSRID'], $aSqlParams);
+    }
+
+}
+
+?>
diff --git a/vmap/vas/rest/ws/vmap/VexParser.class.inc b/vmap/vas/rest/ws/vmap/VexParser.class.inc
new file mode 100644
index 0000000000000000000000000000000000000000..49a041d1e8642d88cd6e5232e813570dadec48e5
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/VexParser.class.inc
@@ -0,0 +1,334 @@
+<?php
+
+/**
+ * \file VexParser.class.inc
+ * \class VexParser
+ *
+ * \author Armand Bahi <armand.bahi@veremes.com>.
+ *
+ * 	\brief This file contains the VexParser php class
+ *
+ * This class defines php functions to export VEX files
+ *
+ */
+require_once 'Vex.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Connection.class.inc';
+require_once __DIR__ . '/../../class/vitis_lib/Form.class.inc';
+require_once __DIR__ . '/../../class/vmlib/BdDataAccess.inc';
+require_once 'vmlib/logUtil.inc';
+
+/**
+ * Classe contenant les fonctions permettant de récupérer
+ * les informations sur les différents objets à exporter
+ */
+class VexParser extends Vmap {
+
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+    }
+
+    /**
+     * Parse un vex et retourne son contenu au format JSON
+     * @return string
+     */
+    function parseVex() {
+
+        $this->aReturn = Array();
+
+        if (!in_array('vitis_admin', $this->oConnection->aPrivileges) ||
+                !in_array('vmap_admin', $this->oConnection->aPrivileges) ||
+                !in_array('vm4ms_admin', $this->oConnection->aPrivileges)) {
+            $oError = new VitisError(0, 'insufficient privileges (needs to be vitis_admin, vmap_admin and vm4ms_admin)');
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        }
+        if (!isset($_FILES['vex_file'])) {
+            $oError = new VitisError(0, 'vex_file not found');
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        }
+
+        // Nom du fichier recu
+        $this->sFileName = $_FILES['vex_file']['name'];
+
+        // Nom du dossier décompressé
+        $this->sFolderName = str_replace('.vex', '', $this->sFileName);
+
+        // Test format du package
+        if (substr($this->sFileName, -4) !== '.vex') {
+            $oError = new VitisError(0, 'Package not valid');
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        }
+
+        // Dossier temporaire
+        $this->sTmpFolder = $this->createTmpFolder();
+
+        // Dossier décompressé
+        $this->sFolderPath = $this->sTmpFolder . '/' . $this->sFolderName;
+
+        if (!is_dir($this->sFolderPath)) {
+            $oError = new VitisError(0, 'Package not valid 2');
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        }
+
+        // Contenu SQL
+        $aSqlContent = $this->getSQLFromVexContent($this->sFolderPath);
+        if (!empty($aSqlContent['export_model_sql'])) {
+            $this->aReturn['sql'] = $aSqlContent;
+        }
+
+        // Objets vMap
+        $aVMapObjectsDef = $this->getVMapObjectsDefFromVexContent($this->sFolderPath);
+        if (!empty($aVMapObjectsDef)) {
+            $this->aReturn['vmap_objects'] = $aVMapObjectsDef;
+        }
+
+        // Services Web
+        $aWebServicesNames = $this->getWebServicesNamesFromVexContent($this->sFolderPath);
+        if (!empty($aWebServicesNames)) {
+            $this->aReturn['web_services'] = $aWebServicesNames;
+        }
+
+        // Supprime le dossier temporaire
+        $this->deleteTmpFolder($this->sTmpFolder);
+
+        if (isset($this->oError)) {
+            $oError = new VitisError(1, $this->oError->getMessage());
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } elseif (isset($this->oConnection->oError)) {
+            $oError = $this->oConnection->oError;
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } elseif ($this->oConnection->oBd->enErreur()) {
+            $oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+            $aXmlRacineAttribute['status'] = 0;
+            $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+            return $sMessage;
+        } else {
+            $this->aReturn = array(
+                'vex' => $this->aReturn,
+                'status' => 1
+            );
+            return json_encode($this->aReturn);
+        }
+    }
+
+    /**
+     * Crée un répertoire temporaire de travail
+     * @return string
+     */
+    function createTmpFolder() {
+        $sTmpName = $this->UniqFileName();
+        $sTmpPath = $this->aProperties['vas_home'] . '/tmp/' . $sTmpName;
+        if (is_dir($sTmpPath)) {
+            clearDir($sTmpPath);
+        }
+        // Dézippe le contennu dans un dossier dans tmp
+        $this->postFileSave('vex_file', '../../tmp/', $sTmpName);
+        unZip($sTmpPath . '/' . $this->sFileName, $sTmpPath . '/' . $this->sFolderName);
+
+        return $sTmpPath;
+    }
+
+    /**
+     * Supprime le répertoire temporaire
+     * @param string $sTmpPath
+     */
+    function deleteTmpFolder($sTmpPath) {
+        if (is_dir($sTmpPath)) {
+            clearDir($sTmpPath);
+        }
+    }
+
+    /**
+     * Récupère le contenu SQL
+     * @param string $sFolderPath
+     * @return array
+     */
+    function getSQLFromVexContent($sFolderPath) {
+        $aReturn = [];
+        if (is_dir($sFolderPath . '/sql')) {
+            if (is_file($sFolderPath . '/sql/export_model_sql.sql')) {
+                $aReturn['export_model_sql'] = file_get_contents($sFolderPath . '/sql/export_model_sql.sql');
+                if (is_file($sFolderPath . '/sql/export_data_sql.sql')) {
+                    $aReturn['export_data_sql'] = file_get_contents($sFolderPath . '/sql/export_data_sql.sql');
+                }
+            }
+        }
+        return $aReturn;
+    }
+
+    /**
+     * Récupère les définitions des objets vMap
+     * @param string $sFolderPath
+     * @return array
+     */
+    function getVMapObjectsDefFromVexContent($sFolderPath) {
+        $aReturn = [];
+        if (is_dir($sFolderPath . '/vmap_objects')) {
+
+            // Objets métier
+            if (is_file($sFolderPath . '/vmap_objects/business_objects.json')) {
+                $aReturn['business_objects'] = json_decode(file_get_contents($sFolderPath . '/vmap_objects/business_objects.json'), true);
+                $aReturn['business_objects_forms'] = $this->getObjectForms($sFolderPath . '/vmap_objects/business_objects_forms');
+            }
+
+            // Calques
+            if (is_file($sFolderPath . '/vmap_objects/calques.json')) {
+                $aReturn['calques'] = json_decode(file_get_contents($sFolderPath . '/vmap_objects/calques.json'), true);
+                $aReturn['calques_forms'] = $this->getObjectForms($sFolderPath . '/vmap_objects/calques_forms');
+            }
+
+            // Thèmes des calques
+            if (is_file($sFolderPath . '/vmap_objects/layerthemes.json')) {
+                $aReturn['calque_themes'] = json_decode(file_get_contents($sFolderPath . '/vmap_objects/layerthemes.json'), true);
+            }
+
+            // Events
+            if (is_file($sFolderPath . '/vmap_objects/events.json')) {
+                $aReturn['events'] = json_decode(file_get_contents($sFolderPath . '/vmap_objects/events.json'), true);
+            }
+
+            // Relation carte calque
+            if (is_file($sFolderPath . '/vmap_objects/map_layer.json')) {
+                $aReturn['map_layer'] = json_decode(file_get_contents($sFolderPath . '/vmap_objects/map_layer.json'), true);
+            }
+
+            // Cartes
+            if (is_file($sFolderPath . '/vmap_objects/maps.json')) {
+                $aReturn['maps'] = json_decode(file_get_contents($sFolderPath . '/vmap_objects/maps.json'), true);
+            }
+
+            // Rapports
+            if (is_file($sFolderPath . '/vmap_objects/reports.json')) {
+                $aReturn['reports'] = json_decode(file_get_contents($sFolderPath . '/vmap_objects/reports.json'), true);
+            }
+
+            // Services
+            if (is_file($sFolderPath . '/vmap_objects/services.json')) {
+                $aReturn['services'] = json_decode(file_get_contents($sFolderPath . '/vmap_objects/services.json'), true);
+            }
+
+            // Couches Mapserver
+            if (is_file($sFolderPath . '/vmap_objects/vm4ms_layers.json')) {
+                $aReturn['vm4ms_layers'] = json_decode(file_get_contents($sFolderPath . '/vmap_objects/vm4ms_layers.json'), true);
+            }
+        }
+        return $aReturn;
+    }
+
+    /**
+     * Récupère les définitions des formulaires vMap
+     * @param string $sFolderPath
+     * @return array
+     */
+    function getObjectForms($sFolderPath) {
+        $aForms = [];
+        if (is_dir($sFolderPath)) {
+            chdir($sFolderPath);
+            $aDirs = glob('*', GLOB_ONLYDIR);
+            for ($i = 0; $i < count($aDirs); $i++) {
+                $sObjectDirPath = $sFolderPath . '/' . $aDirs[$i];
+                if (is_dir($sObjectDirPath)) {
+                    $aForms[$aDirs[$i]] = $this->getObjectFormsFromPath($sObjectDirPath);
+                }
+            }
+        }
+        return $aForms;
+    }
+
+    /**
+     * Get the forms of a vMap object
+     * @param string $sFormsPath
+     * @return array
+     */
+    function getObjectFormsFromPath($sFormsPath) {
+        $aReturn = [];
+
+        if (is_file($sFormsPath . '/custom.json')) {
+            $aReturn['custom'] = json_decode(file_get_contents($sFormsPath . '/custom.json'), true);
+        }
+        if (is_file($sFormsPath . '/default.json')) {
+            $aReturn['default'] = json_decode(file_get_contents($sFormsPath . '/default.json'), true);
+        }
+        if (is_file($sFormsPath . '/published.json')) {
+            $aReturn['published'] = json_decode(file_get_contents($sFormsPath . '/published.json'), true);
+        }
+        if (is_dir($sFormsPath . '/ressources')) {
+            $aReturn['ressources'] = array();
+            if (is_file($sFormsPath . '/ressources/custom.js')) {
+                $aReturn['ressources']['js']['custom'] = file_get_contents($sFormsPath . '/ressources/custom.js');
+            }
+            if (is_file($sFormsPath . '/ressources/default.js')) {
+                $aReturn['ressources']['js']['default'] = file_get_contents($sFormsPath . '/ressources/default.js');
+            }
+            if (is_file($sFormsPath . '/ressources/published.js')) {
+                $aReturn['ressources']['js']['published'] = file_get_contents($sFormsPath . '/ressources/published.js');
+            }
+            if (is_file($sFormsPath . '/ressources/custom.css')) {
+                $aReturn['ressources']['css']['custom'] = file_get_contents($sFormsPath . '/ressources/custom.css');
+            }
+            if (is_file($sFormsPath . '/ressources/default.css')) {
+                $aReturn['ressources']['css']['default'] = file_get_contents($sFormsPath . '/ressources/default.css');
+            }
+            if (is_file($sFormsPath . '/ressources/published.css')) {
+                $aReturn['ressources']['css']['published'] = file_get_contents($sFormsPath . '/ressources/published.css');
+            }
+        }
+
+        return $aReturn;
+    }
+
+    /**
+     * Récupère les noms des services web
+     * @param string $sFolderPath
+     * @return array
+     */
+    function getWebServicesNamesFromVexContent($sFolderPath) {
+        $aReturn = [];
+        if (is_dir($sFolderPath . '/web_services')) {
+
+            // Liste des répertoires contennus dans web_services
+            chdir($sFolderPath . '/web_services');
+            $aDirs = glob('*', GLOB_ONLYDIR);
+            for ($i = 0; $i < count($aDirs); $i++) {
+
+                // Dossier
+                $aFolder = ['name' => $aDirs[$i]];
+
+                // Fichiers
+                chdir($sFolderPath . '/web_services/' . $aDirs[$i]);
+                $aFolder['files'] = [];
+                $aFiles = glob('*');
+                for ($ii = 0; $ii < count($aFiles); $ii++) {
+                    if (is_file($sFolderPath . '/web_services/' . $aDirs[$i] . '/' . $aFiles[$ii])) {
+                        $aFolder['files'][$aFiles[$ii]] = utf8_encode(file_get_contents($sFolderPath . '/web_services/' . $aDirs[$i] . '/' . $aFiles[$ii]));
+                    }
+                }
+
+                array_push($aReturn, $aFolder);
+            }
+        }
+        return $aReturn;
+    }
+
+}
+
+?>
diff --git a/vmap/vas/rest/ws/vmap/Vmap.class.inc b/vmap/vas/rest/ws/vmap/Vmap.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..5329015c791df9f8e4e9d57de14c45e28bbb9e0c
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/Vmap.class.inc
@@ -0,0 +1,225 @@
+<?php
+
+require_once __DIR__ . "/../../class/vitis_lib/DbClass.class.inc";
+require_once __DIR__ . '/../vitis/Vitis.class.inc';
+require_once 'vmlib/logUtil.inc';
+
+class Vmap extends Vitis {
+
+    //Chemin du fichier de ressources contenant les requêtes SQL
+    var $sRessourcesFile = "ws/vmap/Vmap.class.sql.inc";
+
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+    }
+    
+    /**
+     * 
+     * @param string $sSchema
+     * @param string $sTable
+     * @param string $aAttributs
+     * @param string|array $sFilter
+     * @param array $aOptions
+     * @param array $aParams
+     */
+    function vmapGet($sSchema, $sTable, $aAttributs, $sFilter, $aOptions = array(), $aOptionalParams = array()) {
+
+        if ($this->oConnection->oError != null) {
+            $oError = $this->oConnection->oError;
+            return 0;
+        }
+
+        if (strlen($sSchema) == 0) {
+            $oError = 'vmapGet: $sSchema not defined';
+            writeToErrorLog('error: ' . $oError);
+            return 0;
+        }
+
+        if (strlen($sTable) == 0) {
+            $oError = 'vmapGet: $sTable not defined';
+            writeToErrorLog('error: ' . $oError);
+            return 0;
+        }
+
+        if (sizeof($aAttributs) == 0) {
+            $oError = 'vmapGet: $aAttributs not defined';
+            writeToErrorLog('error: ' . $oError);
+            return 0;
+        }
+
+        if (is_array($sFilter) || is_object($sFilter)) {
+            $sFilter = json_encode($sFilter, true);
+        } else if (is_string($sFilter)) {
+            $sFilter = $sFilter;
+        } else {
+            $oError = 'vmapGet: $sFilter type not supported';
+            writeToErrorLog('error: ' . $oError);
+            return 0;
+        }
+
+        // SQL Request building
+        $aSqlParams = array(
+            'sSchema' => array('value' => $sSchema, 'type' => 'column_name'),
+            'sTable' => array('value' => $sTable, 'type' => 'column_name')
+        );
+
+        $aSqlParams = array_merge($aSqlParams, $aOptionalParams);
+
+        $sSql = "SELECT ";
+
+        // Set the attributs string
+        $sAttributs = "";
+        if ($aAttributs[0] == "") {
+            $sAttributs = "*";
+        } else {
+            for ($i = 0; $i < sizeof($aAttributs); $i++) {
+                if ($i > 0) {
+                    $sAttributs .= ", ";
+                }
+                if (strpos($aAttributs[$i], "(") == FALSE && strpos($aAttributs[$i], ")") == FALSE && strpos(strtolower($aAttributs[$i]), " as ") == FALSE) {
+                    $sAttributKey = 'attribute_' . vitisUniqId();
+                    $aSqlParams[$sAttributKey] = array('value' => $aAttributs[$i], 'type' => 'column_name');
+                    $sAttributs .= "\"[" . $sAttributKey . "]\"";
+                } else {
+                    // Attention: Injection possible!
+                    $sAttributs .= $aAttributs[$i];
+                }
+            }
+        }
+        $sSql .= $sAttributs . " FROM [sSchema].[sTable]";
+
+        if (!empty($sFilter)) {
+            // filtre
+            $aDecodedFilter = $this->decodeJSONFilter($sFilter, $sSchema, $sTable);
+
+            // Ajout dans la requête
+            $sSecuredFilter = $aDecodedFilter['request'];
+            // Ajout des paramètres
+            foreach ($aDecodedFilter['params'] as $key => $value) {
+                $aSqlParams[$key] = $value;
+            }
+            // Ajout du filtre dans la requête
+            if (!empty(trim($sSecuredFilter))) {
+                if (strpos($sSql, " WHERE ") == FALSE) {
+                    $sSql .= " WHERE " . $sSecuredFilter;
+                } else {
+                    $sSql .= " AND " . $sSecuredFilter;
+                }
+            }
+        }
+
+        // Options
+        foreach ($aOptions as $key => $value) {
+            switch (strtoupper($key)) {
+                case 'LIMIT':
+                    $aSqlParams['limit'] = array('value' => $value, 'type' => 'number');
+                    $sSql .= " LIMIT [limit]";
+                    break;
+                default:
+                    break;
+            }
+        }
+
+        $oResult = $this->oConnection->oBd->executeWithParams($sSql, $aSqlParams);
+
+        if ($this->oConnection->oBd->enErreur()) {
+            $this->oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+            return $this->oError->aFields;
+        }
+
+        if (gettype($oResult) == 'object') {
+            $aRecords = Array();
+            while ($aLigne = $this->oConnection->oBd->ligneSuivante($oResult)) {
+                array_push($aRecords, $aLigne);
+            }
+        }
+
+        return $aRecords;
+    }
+
+    /**
+     * 
+     * @param string $sSchema
+     * @param string $sTable
+     * @param string $geom
+     * @param array $aAttributs
+     * @return type
+     */
+    function vmapIntersectGet($sSchema, $sTable, $geom, $aAttributs, $iTolerance = 0, $sGeomColumn = 'geom', $sGeomType = 'POLYGON') {
+
+        $sGeomKey = 'geom_key_' . vitisUniqId();
+        $aOptionalParams = array(
+            $sGeomKey => array('value' => $geom, 'type' => 'geometry'),
+            $sGeomColumn => array('value' => $sGeomColumn, 'type' => 'column_name')
+        );
+
+        if ($sGeomType === 'POLYGON' || $sGeomType === 'MULTIPOLYGON') {
+            $sIntersectPercentage = "round(";
+            $sIntersectPercentage .= "ST_Area(";
+            $sIntersectPercentage .= "ST_Intersection(";
+            $sIntersectPercentage .= "ST_Transform(";
+            $sIntersectPercentage .= "ST_GeomFromEWKT([" . $sGeomKey . "]),";
+            $sIntersectPercentage .= "ST_SRID([" . $sGeomColumn . "])";
+            $sIntersectPercentage .= "), ";
+            $sIntersectPercentage .= "[" . $sGeomColumn . "])";
+            $sIntersectPercentage .= ")/ST_Area(";
+            $sIntersectPercentage .= "ST_Transform(";
+            $sIntersectPercentage .= "ST_GeomFromEWKT([" . $sGeomKey . "]),";
+            $sIntersectPercentage .= "ST_SRID([" . $sGeomColumn . "])";
+            $sIntersectPercentage .= ")";
+            $sIntersectPercentage .= ") * 100) as intersect";
+        } else if ($sGeomType === 'LINE' || $sGeomType === 'LINESTRING' || $sGeomType === 'MULTILINESTRING') {
+            $sIntersectPercentage = "round(";
+            $sIntersectPercentage .= "ST_Length(";
+            $sIntersectPercentage .= "ST_Intersection(";
+            $sIntersectPercentage .= "ST_Transform(";
+            $sIntersectPercentage .= "ST_GeomFromEWKT([" . $sGeomKey . "]),";
+            $sIntersectPercentage .= "ST_SRID([" . $sGeomColumn . "])";
+            $sIntersectPercentage .= "), ";
+            $sIntersectPercentage .= "[" . $sGeomColumn . "])";
+            $sIntersectPercentage .= ")) as intersect";
+        } else {
+            $sIntersectPercentage = "100 as intersect";
+        }
+
+        array_push($aAttributs, $sIntersectPercentage);
+        $sFilter = '{"column":"' . $sGeomColumn . '","compare_operator":"intersect","value":"' . $geom . '"}';
+
+        $aRecords = $this->vmapGet($sSchema, $sTable, $aAttributs, $sFilter, array(), $aOptionalParams);
+        $aTolerancedRecords = array();
+
+        for ($i = 0; $i < count($aRecords); $i++) {
+            if ($aRecords[$i]['intersect'] >= $iTolerance) {
+                array_push($aTolerancedRecords, $aRecords[$i]);
+            }
+        }
+        for ($i = 0; $i < count($aTolerancedRecords); $i++) {
+            if ($sGeomType === 'POLYGON' || $sGeomType === 'MULTIPOLYGON') {
+                $aTolerancedRecords[$i]['intersect'] = $aTolerancedRecords[$i]['intersect'] . '%';
+            } else if ($sGeomType === 'LINE' || $sGeomType === 'LINESTRING' || $sGeomType === 'MULTILINESTRING') {
+                $aTolerancedRecords[$i]['intersect'] = $aTolerancedRecords[$i]['intersect'] . 'm';
+            } else {
+                $aTolerancedRecords[$i]['intersect'] = true;
+            }
+        }
+
+        return $aTolerancedRecords;
+    }
+
+    /**
+     * Ajoute la chaîne de caractère au fichier des log vMap.
+     * \param $sString Chaîne de caractères.
+     */
+    function writeMapToVMapLog($sMapId, $sMapName) {
+        $sMapName = "\"" . $sMapName . "\"";
+        $sLog = $sMapId . $this->aProperties["log_delim"] . $sMapName;
+        if (isSet($this->aProperties["log_mode"])) {
+            if ($this->aProperties["log_mode"] == true) {
+                writeToLog($sLog, $this->aProperties["vmap_map_log_file"]);
+            }
+        }
+    }
+
+}
+
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/Vmap.class.sql.inc b/vmap/vas/rest/ws/vmap/Vmap.class.sql.inc
new file mode 100755
index 0000000000000000000000000000000000000000..cf54181a5398368ea642685ca3d390afdb6f49e2
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/Vmap.class.sql.inc
@@ -0,0 +1,45 @@
+<?php
+//Définition des requêtes de l'api Vitis
+$aSql['checkIP'] = "SELECT user_id, ip_constraint FROM [sSchemaFramework].v_user WHERE login ='[sLogin]'";
+$aSql['getGroups'] = "SELECT group_id FROM [sSchemaFramework].v_user_group_by_rights WHERE user_id = [user_id]";
+$aSql['loginUnique'] = 'SELECT UPPER("login") FROM [sSchemaFramework]."v_user" WHERE UPPER("login")=UPPER(\'sLoginUser\')';
+$aSql['getLoginbyId'] = 'SELECT "login" FROM [sSchemaFramework]."v_user" WHERE user_id=[user_id]';
+$aSql['getTableColumn'] = 'SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = \'[sSchemaFramework]\' and table_name= \'[sTable]\'';
+$aSql['getUserPrivileges'] = 'SELECT groname FROM pg_user s LEFT OUTER JOIN pg_group g on (s.usesysid = any(g.grolist) )inner join [sSchemaFramework].v_user on "v_user".login = usename WHERE user_id = [user_id]';
+$aSql['listDomain'] = 'SELECT distinct domain, alias FROM [sSchemaFramework].domain WHERE "type" = \'AD\'';
+$aSql['createRolname'] = 'CREATE ROLE "vitis_[sDomain]" NOSUPERUSER INHERIT NOCREATEDB CREATEROLE;';
+$aSql['getInfoRolname'] = 'SELECT * FROM pg_catalog.pg_roles WHERE rolname = \'vitis_[sDomain]\'';
+// Maps
+$aSql['getMapGroups'] = "SELECT map_group.group_id, \"group\".name FROM [sSchemaVmap].map_group LEFT JOIN [sSchemaFramework].\"group\" ON \"group\".group_id = map_group.group_id WHERE map_group.map_id = [map_id]";
+$aSql['insertMapGroups'] = "INSERT INTO [sSchemaVmap].map_group(group_id, map_id) VALUES([group_id], [map_id])";
+$aSql['getMapLayers'] = "SELECT v_layer.layer_id,name,theme_name,layer_visible FROM [sSchemaVmap].v_layer,[sSchemaVmap].map_layer WHERE v_layer.layer_id=map_layer.layer_id";
+// VmapGroups
+$aSql['getGroupMaps'] = "SELECT map_group.map_id, map.name FROM [sSchemaVmap].map_group LEFT JOIN [sSchemaVmap].map ON map.map_id = map_group.map_id WHERE map_group.group_id = [group_id]";
+$aSql['insertGroupMaps'] = "INSERT INTO [sSchemaVmap].map_group(group_id, map_id) VALUES([group_id], [map_id])";
+$aSql['getGroupPrintTemplates'] = "SELECT printtemplate_group.printtemplate_id, printtemplate.name FROM [sSchemaVmap].printtemplate_group LEFT JOIN [sSchemaVmap].printtemplate ON printtemplate.printtemplate_id = printtemplate_group.printtemplate_id WHERE printtemplate_group.group_id = [group_id]";
+$aSql['insertGroupPrintTemplates'] = "INSERT INTO [sSchemaVmap].printtemplate_group(group_id, printtemplate_id) VALUES([group_id], [printtemplate_id])";
+// MapLayers
+$aSql['updateMapLayersVisibility'] = "UPDATE [sSchemaVmap].map_layer SET layer_visible=[visibility] WHERE map_id=[map_id] AND layer_id IN ([map_layers])";
+$aSql['insertMapLayers'] = "INSERT INTO [sSchemaVmap].map_layer(layer_id, map_id) VALUES([layer_id], [map_id])";
+$aSql['deleteMapLayers'] = "DELETE FROM [sSchemaVmap].map_layer WHERE map_id=[map_id] AND layer_id IN ([idList])";
+$aSql['updateMapLayerIndex'] = "UPDATE [sSchemaVmap].map_layer SET layer_index=[index] WHERE map_id=[map_id] AND layer_id=[layer_id]";
+$aSql['updateMapLayerOpacity'] = "UPDATE [sSchemaVmap].map_layer SET layer_opacity=[layer_opacity] WHERE map_id=[map_id] AND layer_id=[layer_id]";
+// VmapUsers
+$aSql['getUserPrintStyles'] = "SELECT user_printstyle.printstyle_id,printstyle.name FROM [sSchemaVmap].user_printstyle LEFT JOIN [sSchemaVmap].printstyle ON user_printstyle.printstyle_id = printstyle.printstyle_id WHERE user_printstyle.user_id = [user_id]";
+$aSql['insertUserPrintStyles'] = "INSERT INTO [sSchemaVmap].user_printstyle(user_id, printstyle_id) VALUES([user_id], [printstyle_id])";
+// PrintTemplates
+$aSql['getPrintTemplateParameters'] = "SELECT * FROM [sSchemaVmap].v_print_parameter WHERE printtemplate_id=[printtemplate_id]";
+$aSql['insertPrintTemplateGroups'] = "INSERT INTO [sSchemaVmap].printtemplate_group(group_id, printtemplate_id) VALUES([group_id], [printtemplate_id])";
+$aSql['getPrintTemplateGroups'] = "SELECT printtemplate_group.group_id, \"group\".name FROM [sSchemaVmap].printtemplate_group LEFT JOIN [sSchemaFramework].\"group\" ON \"group\".group_id = printtemplate_group.group_id WHERE printtemplate_group.printtemplate_id = [printtemplate_id]";
+$aSql['getUserPrintTemplateIds'] = "SELECT printtemplate_id FROM [sSchemaVmap].printtemplate_group WHERE group_id IN (SELECT group_id FROM [sSchemaFramework].v_user_group_by_rights WHERE user_id = (SELECT user_id FROM [sSchemaFramework].v_user WHERE login ='[sLogin]')) GROUP BY printtemplate_id";
+// Services
+$aSql['getTotalServiceLayers'] = "SELECT COUNT(*) AS nb_layers FROM [sSchemaVmap].layer WHERE service_id IN([idList])";
+// PrintStyles
+$aSql['getPrintStyleUsers'] = "SELECT user_printstyle.user_id, \"v_user\".login FROM [sSchemaVmap].user_printstyle LEFT JOIN [sSchemaFramework].\"v_user\" ON user_printstyle.user_id = \"v_user\".user_id WHERE user_printstyle.printstyle_id = [printstyle_id]";
+$aSql['insertPrintStyleUsers'] = "INSERT INTO [sSchemaVmap].user_printstyle(user_id, printstyle_id) VALUES([user_id], [printstyle_id])";
+// Layers
+$aSql['setLayerBoId'] = "UPDATE [sSchemaVmap].layer SET bo_id = NULL WHERE layer_id = [layer_id]";
+$aSql['deleteAssociatedBos'] = "DELETE FROM [sSchemaVmap].layer_businessobject WHERE layer_id = [layer_id]";
+$aSql['deleteAssociatedLayers'] = "DELETE FROM [sSchemaVmap].layer_businessobject WHERE business_object_id = [business_object_id]";
+$aSql['addAssociatedBos'] = "INSERT INTO [sSchemaVmap].layer_businessobject(layer_id, business_object_id) VALUES ([layer_id], [business_object_id]);";
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/VmapGroup.class.inc b/vmap/vas/rest/ws/vmap/VmapGroup.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..3c3ddfe577d5db417d88cdeddc2d172fd116e6a1
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/VmapGroup.class.inc
@@ -0,0 +1,125 @@
+<?php
+require_once 'Vmap.class.inc';
+require_once __DIR__.'/../../class/vitis_lib/Connection.class.inc';
+/**
+* \file VmapGroup.class.inc
+* \class VmapGroup
+*
+* \author Armand Bahi <armand.bahi@veremes.com>.
+*
+*	\brief This file contains the VmapGroup php class
+*
+* This class defines operation for one Group
+* 
+*/
+class VmapGroup  extends Vmap {
+    
+    public $oError;
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("group_id", "name", "nb_members", "maps", "print_templates");
+    }
+      /**
+     * @SWG\Get(path="/vmapgroups/{group_id}", 
+     *   tags={"Groups"},
+     *   summary="Get Group",
+     *   description="Request to get Group by id",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+       *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+       * @SWG\Parameter(
+     *     name="group_id",
+     *     in="path",
+     *     description="group id",
+     *     required=true,
+     *     type="integer"
+     *   ),
+       * @SWG\Parameter(
+     *     name="attributs",
+     *     in="query",
+     *     description="list of attributs",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/groups")
+     *     )
+     *  )
+     */
+    /**
+     * get informations about mode
+     */
+    function GET(){
+        require $this->sRessourcesFile;
+        $this->aFields = $this->getFields($this->aProperties['schema_framework'], "v_group", "group_id");
+        $this->getMaps();
+        $this->getPrintTemplates();
+    }
+    
+    /**
+     *  get maps of group
+     */
+    function getMaps(){
+        require $this->sRessourcesFile;
+        if (in_array("maps", $this->aSelectedFields)){
+                $aParams['sSchemaVmap'] = array('value' => $this->aProperties['schema_vmap'], 'type' => 'schema_name');
+                $aParams['group_id'] = array('value' => $this->aValues['my_vitis_id'], 'type' => 'number');
+                $oPDOresult = $this->oConnection->oBd->executeWithParams($aSql['getGroupMaps'], $aParams);
+		$sListMapId = "";
+		$aListMapName = array();
+		while($aLigne=$this->oConnection->oBd->ligneSuivante ($oPDOresult)) {
+			if ($sListMapId == ""){
+				$sListMapId = $aLigne["map_id"];
+			}else{
+				$sListMapId .= "|".$aLigne["map_id"];
+			}
+                        $aListMapName[] = $aLigne["name"];
+		}
+		$oPDOresult=$this->oConnection->oBd->fermeResultat();
+                $this->aFields['maps'] = $sListMapId;
+                $this->aFields['maps_label'] = implode(',', $aListMapName);
+        }
+    }
+    
+    /**
+     *  get print templates of group
+     */
+    function getPrintTemplates(){
+        require $this->sRessourcesFile;
+        if (in_array("print_templates", $this->aSelectedFields)){
+                $aParams['sSchemaVmap'] = array('value' => $this->aProperties['schema_vmap'], 'type' => 'schema_name');
+                $aParams['group_id'] = array('value' => $this->aValues['my_vitis_id'], 'type' => 'number');
+                $oPDOresult = $this->oConnection->oBd->executeWithParams($aSql['getGroupPrintTemplates'], $aParams);
+		$sListPrintTemplateId = "";
+		$aListPrintTemplateName = array();
+		while($aLigne=$this->oConnection->oBd->ligneSuivante ($oPDOresult)) {
+			if ($sListPrintTemplateId == ""){
+				$sListPrintTemplateId = $aLigne["printtemplate_id"];
+			}else{
+				$sListPrintTemplateId .= "|".$aLigne["printtemplate_id"];
+			}
+                        $aListPrintTemplateName[] = $aLigne["name"];
+		}
+		$oPDOresult=$this->oConnection->oBd->fermeResultat();
+                $this->aFields['print_templates'] = $sListPrintTemplateId;
+                $this->aFields['print_templates_label'] = implode(',', $aListPrintTemplateName);
+        }
+    }
+}
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/VmapGroups.class.inc b/vmap/vas/rest/ws/vmap/VmapGroups.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..3b7ee9267ec6403c8374b631266d9b34860b6d6e
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/VmapGroups.class.inc
@@ -0,0 +1,152 @@
+<?php
+
+/**
+* \file VmapGroups.class.inc
+* \class VmapGroups
+*
+* \author Yoann Perollet <yoann.perollet@veremes.com>.
+*
+*	\brief This file contains the Modes php class
+*
+* This class defines Rest Api to Vmap Groups
+* 
+*/
+require_once 'Vmap.class.inc';
+require_once __DIR__.'/../../class/vitis_lib/Connection.class.inc';
+require_once 'VmapGroup.class.inc';
+require_once(__DIR__.'/../../class/vmlib/BdDataAccess.inc');
+
+class VmapGroups extends Vmap {
+    
+     /**
+     * @SWG\Definition(
+     *   definition="/vmapgroups",
+     *   allOf={
+     *     @SWG\Schema(ref="#/definitions/vmapgroups")
+     *   }
+     * )
+     * * @SWG\Tag(
+     *   name="VmapGroups",
+     *   description="Operations about Groups"
+     * )
+     */
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("group_id", "name", "nb_members", "maps", "print_templates");
+    }
+    
+    /**
+     * get Groups
+     * @return  Groups
+     */
+    function GET() {
+        $aReturn = $this->genericGet( $this->aProperties['schema_framework'], "v_group", "group_id");
+        return $aReturn['sMessage'];
+    }
+    
+    /**
+     * @SWG\Put(path="/vmapgroups/{group_id}",
+     *   tags={"Groups"},
+     *   summary="Update Group",
+     *   description="Request to update Group",
+     *   operationId="PUT",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="group token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="group_id",
+     *     in="path",
+     *     description="id of the group",
+     *     required=true,
+     *     type="integer",
+     *     format = "int32"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="maps",
+     *     in="query",
+     *     description="Maps of the group",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="print_templates",
+     *     in="query",
+     *     description="Print templates of the group",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Properties Response",
+     *         @SWG\Schema(ref="#/definitions/groups")
+     *     )
+     *  )
+     */
+
+    /**
+     * update group
+     * @return id of the group if ok error object if ko
+     */
+    function PUT() {
+        require $this->sRessourcesFile;
+        $aXmlRacineAttribute['status'] = 1;
+        $sMessage = $this->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+        // Supprime les cartes rattachés au groupe.
+        $this->oConnection->oBd->delete($this->aProperties['schema_vmap'], 'map_group', 'group_id', $this->aValues["my_vitis_id"]);
+        // Cartes à rattacher au groupe ?
+        if (!empty($this->aValues['maps'])) {
+            $aMaps = explode('|', $this->aValues['maps']);
+            foreach ($aMaps as $iMapId) {
+                $sSql = $aSql['insertGroupMaps'];
+                $aSQLParams = array(
+                    'sSchemaVmap' => array('value' => $this->aProperties['schema_vmap'], 'type' => 'column_name'),
+                    'group_id' => array('value' => $this->aValues["my_vitis_id"], 'type' => 'number'),
+                    'map_id' => array('value' => $iMapId, 'type' => 'number')
+                );
+                $resultat = $this->oConnection->oBd->executeWithParams($sSql, $aSQLParams);
+                if ($this->oConnection->oBd->enErreur()) {
+                    $this->oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+                    $oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+                    $aXmlRacineAttribute['status'] = 0;
+                    $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+                }
+            }
+        }
+        // Supprime les modèles d'impression rattachés au groupe.
+        $this->oConnection->oBd->delete($this->aProperties['schema_vmap'], 'printtemplate_group', 'group_id', $this->aValues["my_vitis_id"]);
+        // Modèles d'impression à rattacher au groupe ?
+        if (!empty($this->aValues['print_templates'])) {
+            $aPrintTemplates = explode('|', $this->aValues['print_templates']);
+            foreach ($aPrintTemplates as $iPrintTemplateId) {                
+                $sSql = $aSql['insertGroupPrintTemplates'];
+                $aSQLParams = array(
+                    'sSchemaVmap' => array('value' => $this->aProperties['schema_vmap'], 'type' => 'column_name'),
+                    'group_id' => array('value' => $this->aValues["my_vitis_id"], 'type' => 'number'),
+                    'printtemplate_id' => array('value' => $iPrintTemplateId, 'type' => 'number')
+                );
+                $resultat = $this->oConnection->oBd->executeWithParams($sSql, $aSQLParams);
+                if ($this->oConnection->oBd->enErreur()) {
+                    $this->oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+                    $oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+                    $aXmlRacineAttribute['status'] = 0;
+                    $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+                }
+            }
+        }
+        return $sMessage;
+    }
+}
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/VmapUser.class.inc b/vmap/vas/rest/ws/vmap/VmapUser.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..aa45fa79725046b61f68b8d9570e58902f563421
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/VmapUser.class.inc
@@ -0,0 +1,99 @@
+<?php
+require_once 'Vmap.class.inc';
+require_once __DIR__.'/../../class/vitis_lib/Connection.class.inc';
+/**
+* \file VmapUser.class.inc
+* \class VmapUser
+*
+* \author Yoann Perollet <yoann.perollet@veremes.com>.
+*
+*	\brief This file contains the VmapUser php class
+*
+* This class defines operation for one User
+* 
+*/
+class VmapUser  extends Vmap {
+    
+    public $oError;
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("user_id", "login", "print_styles");
+    }
+      /**
+     * @SWG\Get(path="/vmapusers/{user_id}", 
+     *   tags={"Users"},
+     *   summary="Get User",
+     *   description="Request to get user by id",
+     *   operationId="GET",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+       *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+       * @SWG\Parameter(
+     *     name="user_id",
+     *     in="path",
+     *     description="user id",
+     *     required=true,
+     *     type="integer"
+     *   ),
+       * @SWG\Parameter(
+     *     name="attributs",
+     *     in="query",
+     *     description="list of attributs",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Poprerties Response",
+     *         @SWG\Schema(ref="#/definitions/users")
+     *     )
+     *  )
+     */
+    /**
+     * get informations about mode
+     */
+    function GET(){
+        require $this->sRessourcesFile;
+        $this->aFields = $this->getFields($this->aProperties['schema_framework'], "v_user", "user_id");
+        $this->getPrintStyles();
+    }
+    
+    /**
+     *  get print styles of user
+     */
+    function getPrintStyles(){
+        require $this->sRessourcesFile;
+        if (in_array("print_styles", $this->aSelectedFields)){
+                $aParams['sSchemaVmap'] = array('value' => $this->aProperties['schema_vmap'], 'type' => 'schema_name');
+                $aParams['user_id'] = array('value' => $this->aValues['my_vitis_id'], 'type' => 'number');
+                $oPDOresult = $this->oConnection->oBd->executeWithParams($aSql['getUserPrintStyles'], $aParams);
+		$sListPrintStyleId = "";
+                $aListPrintStyleId = array();
+		while($aLigne=$this->oConnection->oBd->ligneSuivante ($oPDOresult)) {
+			if ($sListPrintStyleId == ""){
+				$sListPrintStyleId = $aLigne["printstyle_id"];
+			}else{
+				$sListPrintStyleId .= "|".$aLigne["printstyle_id"];
+			}
+                        $aListPrintStyleId[] = $aLigne["name"];
+		}
+		$oPDOresult=$this->oConnection->oBd->fermeResultat();
+                $this->aFields['print_styles'] = $sListPrintStyleId;
+                $this->aFields['print_styles_label'] = implode(',', $aListPrintStyleId);
+        }
+    }
+}
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/VmapUsers.class.inc b/vmap/vas/rest/ws/vmap/VmapUsers.class.inc
new file mode 100755
index 0000000000000000000000000000000000000000..8ec4e204d7e71094dc4d2e97bc6726cd552f7468
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/VmapUsers.class.inc
@@ -0,0 +1,131 @@
+<?php
+
+/**
+* \file VmapUsers.class.inc
+* \class VmapUsers
+*
+* \author Yoann Perollet <yoann.perollet@veremes.com>.
+*
+*	\brief This file contains the Modes php class
+*
+* This class defines Rest Api to Vmap Users
+* 
+*/
+require_once 'Vmap.class.inc';
+require_once __DIR__.'/../../class/vitis_lib/Connection.class.inc';
+require_once 'VmapUser.class.inc';
+require_once(__DIR__.'/../../class/vmlib/BdDataAccess.inc');
+
+class VmapUsers extends Vmap {
+    
+     /**
+     * @SWG\Definition(
+     *   definition="/vmapusers",
+     *   allOf={
+     *     @SWG\Schema(ref="#/definitions/vmapusers")
+     *   }
+     * )
+     * * @SWG\Tag(
+     *   name="VmapUsers",
+     *   description="Operations about Users"
+     * )
+     */
+    /**
+     * construct
+     * @param type $aPath url of the request
+     * @param type $aValues parameters of the request
+     * @param type $properties properties
+     * @param type $bShortcut false to reinit variables
+     * @param type $oConnection connection object
+     */
+    function __construct($aPath, $aValues, $properties, $bShortcut = false, $oConnection = false) {
+        parent::__construct($aPath, $aValues, $properties, $bShortcut, $oConnection);
+        $this->aSelectedFields = Array("user_id", "login", "print_styles");
+    }
+    
+    /**
+     * get Users
+     * @return  Users
+     */
+    function GET() {
+        $aReturn = $this->genericGet( $this->aProperties['schema_framework'], "v_user", "user_id");
+        return $aReturn['sMessage'];
+    }
+    
+    /**
+     * @SWG\Put(path="/vmapusers/{user_id}",
+     *   tags={"Users"},
+     *   summary="Update User",
+     *   description="Request to update User",
+     *   operationId="PUT",
+     *   produces={"application/xml", "application/json", "application/x-vm-json"},
+     *   @SWG\Parameter(
+     *     name="token",
+     *     in="query",
+     *     description="user token",
+     *     required=true,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="user_id",
+     *     in="path",
+     *     description="id of the user",
+     *     required=true,
+     *     type="integer",
+     *     format = "int32"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="maps",
+     *     in="query",
+     *     description="Maps of the user",
+     *     required=false,
+     *     type="string"
+     *   ),
+     * * @SWG\Parameter(
+     *     name="print_styles",
+     *     in="query",
+     *     description="Print styles of the user",
+     *     required=false,
+     *     type="string"
+     *   ),
+     *   @SWG\Response(
+     *         response=200,
+     *         description="Properties Response",
+     *         @SWG\Schema(ref="#/definitions/users")
+     *     )
+     *  )
+     */
+
+    /**
+     * update user
+     * @return id of the user if ok error object if ko
+     */
+    function PUT() {
+        require $this->sRessourcesFile;
+        $aXmlRacineAttribute['status'] = 1;
+        $sMessage = $this->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+        // Supprime les styles d'impression rattachés à l'utilisateur.
+        $this->oConnection->oBd->delete($this->aProperties['schema_vmap'], 'user_printstyle', 'user_id', $this->aValues["my_vitis_id"]);
+        // Styles d'impression à rattacher au usere ?
+        if (!empty($this->aValues['print_styles'])) {
+            $aPrintStyles = explode('|', $this->aValues['print_styles']);
+            foreach ($aPrintStyles as $iPrintStyleId) {                
+                $sSql = $aSql['insertUserPrintStyles'];
+                $aSQLParams = array(
+                    'sSchemaVmap' => array('value' => $this->aProperties['schema_vmap'], 'type' => 'column_name'),
+                    'user_id' => array('value' => $this->aValues["my_vitis_id"], 'type' => 'number'),
+                    'printstyle_id' => array('value' => $iPrintStyleId, 'type' => 'number')
+                );
+                $resultat = $this->oConnection->oBd->executeWithParams($sSql, $aSQLParams);
+                if ($this->oConnection->oBd->enErreur()) {
+                    $this->oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+                    $oError = new VitisError(1, $this->oConnection->oBd->getBDMessage());
+                    $aXmlRacineAttribute['status'] = 0;
+                    $sMessage = $oError->asDocument('', 'vitis', $this->aValues['sEncoding'], True, $aXmlRacineAttribute, $this->aValues['sSourceEncoding'], $this->aValues['output']);
+                }
+            }
+        }
+        return $sMessage;
+    }
+}
+?>
\ No newline at end of file
diff --git a/vmap/vas/rest/ws/vmap/overview.phtml b/vmap/vas/rest/ws/vmap/overview.phtml
new file mode 100755
index 0000000000000000000000000000000000000000..953c1aba67d7feead570b2308915797249f3fdcd
--- /dev/null
+++ b/vmap/vas/rest/ws/vmap/overview.phtml
@@ -0,0 +1,24 @@
+<?php
+/**
+ * @SWG\Swagger(
+ *      basePath="/[service_alias]/vmap",
+ *     	host="[server]",
+ *    	schemes={"[protocol]"},
+ *     	produces={  
+ *          "application/json",
+  "application/xml",
+  "text/html"
+ * 		},
+ *     @SWG\Info(
+ *         version="1.0.0",
+ *         title="Vmap Test Rest",
+ *         description="All features to access server operation for vmap",
+ *     )
+ * )
+ */
+?>
+
+<h1 class="titleOverview">Service Vmap</h1>
+<p>
+    <a class="linkOverview" href="javascript:sService='vmap';LoadApi()">Vmap</a>: service which should be used when developing applications communicating with Vmap. This service allows you to administrate Vmap application.
+</p>
\ No newline at end of file