diff --git a/.gitignore b/.gitignore
index c2f6e37..9e4cea3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,3 +26,9 @@ tests/lizmap/qgis-server-plugins/
tests/lizmap/cache-python
tests/lizmap/local-python
tests/sql/majic/*.sql
+
+# dev tools
+*.code-workspace
+
+# QGIS useless files
+*_attachments.zip
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2587509..08ce349 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,22 @@
## Unreleased
+
+## 2.1.0 - 2023-12-18
+
+### Added
+
+* Panneau de recherche : ajout d'un onglet "Recherche spatiale" qui permet de sélectionner
+ les parcelles par croisement avec les objets sélectionnés d'une autre couche.
+ * Choix de la couche PostgreSQL de croisement (elle doit être dans la même base que la couche des Parcelles)
+ * Choix du tampon en mètres à utiliser pour rechercher les parcelles à partir des objets
+ * Choix optionnel du champ à ajouter à l'export CSV
+* Ajout de 2 boutons qui permettent d'exporter la liste des propriétaires des parcelles sélectionnées
+
+### Fixed
+
+* Correction de l'affichage de la barre d'outil cadastre sur la popup des parcelles
+
## 2.0.5 - 2023-10-31
### Fixed
@@ -18,7 +34,7 @@
### Fixed
* Amélioration de la recherche des parcelles
-* Utilisation du cache handler de projet
+* Utilisation du cache handler de projet
* Amélioration des recherches par autocomplétion
* Amélioration de la recherche par section
* Amélioration du zoom lors de la recherche
diff --git a/Makefile b/Makefile
index 7f9984b..92a4611 100644
--- a/Makefile
+++ b/Makefile
@@ -11,4 +11,4 @@ php-cs-fixer-apply:
php-cs-fixer fix --config=.php-cs-fixer.dist.php
php-cs-fixer-apply-docker:
- docker run --rm -it -w=/app -v ${PWD}:/app oskarstark/php-cs-fixer-ga:3.12.0 --allow-risky=yes --config=.php-cs-fixer.dist.php
+ docker run --rm -it -w=/app -v ${PWD}:/app oskarstark/php-cs-fixer-ga:latest --allow-risky=yes --config=.php-cs-fixer.dist.php
diff --git a/cadastre/classes/cadastre.listener.php b/cadastre/classes/cadastre.listener.php
index 1401d4e..e12d6f1 100644
--- a/cadastre/classes/cadastre.listener.php
+++ b/cadastre/classes/cadastre.listener.php
@@ -36,7 +36,14 @@ public function ongetMapAdditions($event)
$jscode = array();
$css = array();
- if ($hasCadastreConfig) {
+ // Add the cadastre config only if at least one right is granted
+ $hasEnoughRights = (
+ jAcl2::check('cadastre.use.search.tool')
+ || jAcl2::check('cadastre.acces.donnees.proprio')
+ || jAcl2::check('cadastre.acces.donnees.proprio.simple')
+ );
+
+ if ($hasCadastreConfig && $hasEnoughRights) {
$js = array(
jUrl::get('jelix~www:getfile', array('targetmodule' => 'cadastre', 'file' => 'cadastre.js')),
);
diff --git a/cadastre/classes/cadastreDockable.listener.php b/cadastre/classes/cadastreDockable.listener.php
index 1a7748a..a04f67e 100644
--- a/cadastre/classes/cadastreDockable.listener.php
+++ b/cadastre/classes/cadastreDockable.listener.php
@@ -58,6 +58,50 @@ public function onmapDockable($event)
$hasMajic = '1';
}
$searchForm->setData('has_majic', $hasMajic);
+
+ // Add the PostgreSQL layers of the same database in the 3rd search tab "Spatial"
+ if ($hasMajic == '1') {
+ // Get the project
+ $p = lizmap::getProject($event->repository . '~' . $event->project);
+ if ($p === null) {
+ throw new Exception("Spatial search: Unknown repository/project {$event->repository}.'~'.{$event->project}");
+ }
+
+ // Get the PostgreSQL database info of the Parcelle layer
+ /** @var \qgisVectorLayer $parcelleLayer The QGIS vector layer instance */
+ $parcelleLayer = $p->getLayer($parcelleId);
+ $parcelleProfile = $parcelleLayer->getDatasourceProfile(30, false);
+
+ // Get the list of PostgreSQL layers
+ $layers = array();
+ foreach ($p->getLayers() as $layer) {
+ /** @var \qgisVectorLayer $qgisLayer The QGIS vector layer instance */
+ $qgisLayer = $p->getLayer($layer->id);
+ // Only for existing layers
+ if (!$qgisLayer) {
+ continue;
+ }
+ // Not the parcelle layer itself
+ if ($qgisLayer->getId() == $parcelleId) {
+ continue;
+ }
+ // Only PostgreSQL layers
+ if ($qgisLayer->getProvider() != 'postgres') {
+ continue;
+ }
+ // Check if the database is the same as the Parcelle layer
+ if ($qgisLayer->getDatasourceProfile(30, false) != $parcelleProfile) {
+ continue;
+ }
+ $layers[$layer->id] = $layer->name;
+ }
+
+ // Add the list of spatial layers in the combobox
+ $datasource = new \jFormsStaticDatasource();
+ $datasource->data = $layers;
+ $searchForm->getControl('spatial_layer_id')->datasource = $datasource;
+ }
+
$assign = array(
'form' => $searchForm,
'has_majic' => $hasMajic,
diff --git a/cadastre/classes/cadastreExtraInfos.class.php b/cadastre/classes/cadastreExtraInfos.class.php
index 705150b..be323db 100644
--- a/cadastre/classes/cadastreExtraInfos.class.php
+++ b/cadastre/classes/cadastreExtraInfos.class.php
@@ -156,6 +156,160 @@ protected function getLocauxAndProprioSql($parcelle_ids, $withGeom = false, $for
return $sql;
}
+ /**
+ * Get SQL request to get parcelles and proprios data for parcelle ids.
+ *
+ * @param array $parcelle_ids The ids of parcelles
+ * @param bool $withGeom With geometry data (optional)
+ * @param bool $forThirdParty Without infos for third party (optional)
+ * @param null|array $intersectionData If the query must compute list of item codes from the intersected layer
+ *
+ * @return string The SQL
+ */
+ protected function getParcellesAndProprioSql($parcelle_ids, $withGeom = false, $forThirdParty = false, $intersectionData = null)
+ {
+ $hasIntersectionData = ($intersectionData !== null && is_array($intersectionData));
+
+ $sql = "
+ --SET SEARCH_PATH TO cadastre_caen, public;
+
+ SELECT
+ -- commune
+ c.libcom AS commune,
+ -- proprio
+ pr.dnuper AS code_proprietaire,
+ trim(pr.dqualp) AS qualite,
+ trim(pr.dnomus) AS nom,
+ trim(pr.dprnus) AS prenom,
+ -- on ne garde que le nom d'usage
+ --trim(pr.dnomlp) AS nom,
+ --trim(pr.dprnlp) AS prenom,
+ trim(pr.ddenom) AS denomination,
+
+ -- adresse du propriétaire
+ ltrim(trim(coalesce(pr.dlign4, '')), '0') AS adresse,
+ trim(coalesce(pr.dlign5, '')) AS complement_adresse,
+ trim(coalesce(pr.ccopos, '')) AS code_postal,
+ replace(
+ trim(coalesce(pr.dlign6, '')),
+ trim(coalesce(pr.ccopos, '')),
+ ''
+ ) AS ville,
+ replace(
+ ltrim(trim(coalesce(pr.dlign4, ' ')), '0') || ' ' || trim(coalesce(pr.dlign5, ' ')) || ' ' || trim(coalesce(pr.dlign6, ' ')),
+ ' ',
+ ' '
+ ) AS adresse_complete,
+ ";
+
+ // Ajout des informations de naissance
+ if (!$forThirdParty) {
+ $sql .= "
+ coalesce( trim(cast(pr.jdatnss AS text) ), '-') AS date_naissance,
+ coalesce(trim(pr.dldnss), '-') AS lieu_naissance,
+ ";
+ }
+ $sql .= "
+ -- parcelles
+ string_agg(DISTINCT p.parcelle, ', ' ORDER BY p.parcelle) AS parcelles
+ ";
+
+ // Ajout de la géométrie
+ if ($withGeom) {
+ $sql .= ',
+ -- geometrie
+ ST_Centroid(geom)::geometry(point,2154) AS geom
+ ';
+ }
+
+ // Ajout des objets intersectés
+ // Ceux qui ont été sélectionnés dans l'onglet "Recherche spatiale"
+ // du panneau de recherche
+ if ($hasIntersectionData) {
+ $sql .= '
+ -- Code objet
+ ,
+ string_agg(DISTINCT z."' . $intersectionData['field'] . '"::text, \', \' ORDER BY z."' . $intersectionData['field'] . '"::text)
+ FILTER (WHERE z."' . $intersectionData['field'] . '" IS NOT NULL) AS code_objet
+ ';
+ }
+
+ $sql .= '
+ FROM parcelle p
+ INNER JOIN parcelle_info gp ON gp.geo_parcelle = p.parcelle
+ LEFT JOIN proprietaire AS pr ON pr.comptecommunal = p.comptecommunal
+ LEFT JOIN commune AS c ON c.commune = concat(pr.ccodep, pr.ccodir, pr.ccocom)
+ ';
+
+ // Ajout des objets intersectés
+ // Ceux qui ont été sélectionnés dans l'onglet "Recherche spatiale"
+ // du panneau de recherche
+ if ($hasIntersectionData) {
+ $sql .= '
+ -- Code objet
+ LEFT JOIN "' . $intersectionData['schema'] . '"."' . $intersectionData['table'] . '" AS z
+ ON z."' . $intersectionData['pk'] . '" IN (' . $intersectionData['selectedIds'] . ')
+ AND ST_DWithin(z."' . $intersectionData['geometryColumn'] . '", gp.geom, ' . $intersectionData['buffer'] . ')
+ ';
+ }
+
+ $pids = array();
+ foreach ($parcelle_ids as $pid) {
+ $pids[] = "'" . $pid . "'";
+ }
+
+ $sql .= '
+ WHERE
+ p.parcelle IN ( ' . implode(', ', $pids) . ' )
+ ';
+
+ // Questions
+ // Seulement le principal ou les usufruitiers ?
+ // Seulement les peronnes physiques ou tout le monde ?
+
+ $filterConfig = cadastreConfig::getFilterByLogin($this->repository, $this->project, $this->config->parcelle->id);
+ $layerSql = cadastreConfig::getLayerSql($this->repository, $this->project, $this->config->parcelle->id);
+ $polygonFilter = cadastreConfig::getPolygonFilter($this->repository, $this->project, $this->config->parcelle->id);
+
+ if ($filterConfig !== null) {
+ $sql .= ' AND ';
+ $sql .= $this->getFilterSql($filterConfig);
+ }
+ if ($layerSql) {
+ $sql .= ' AND (' . $layerSql . ')';
+ }
+ if ($polygonFilter) {
+ $sql .= ' AND (' . $polygonFilter . ')';
+ }
+
+ // Regroupement par propriétaire
+ $sql .= '
+ GROUP BY
+ c.libcom,
+ pr.dnuper, pr.dqualp,
+ pr.dnomus, pr.dprnus,
+ -- pr.dnomlp, pr.dprnlp,
+ pr.ddenom,
+ pr.dlign4, pr.dlign5, pr.dlign6, pr.ccopos
+ ';
+ if (!$forThirdParty) {
+ $sql .= '
+ , pr.jdatnss, pr.dldnss
+ ';
+ }
+ if ($withGeom) {
+ $sql .= ',
+ , geom
+ ';
+ }
+
+ $sql .= '
+ ORDER BY c.libcom, pr.ddenom
+ ';
+
+ return $sql;
+ }
+
/**
* Get data from database and return an array.
*
@@ -234,4 +388,32 @@ public function getLocauxAndProprioInfos($repository, $project, $parcelleLayer,
return $this->buildCsv($rows);
}
+
+ /**
+ * Build the parcelles and proprios CSV file and return its path.
+ *
+ * @param string $repository
+ * @param string $project
+ * @param mixed $parcelleLayer
+ * @param array $parcelle_ids The ids of parcelles
+ * @param bool $withGeom With geometry data (optional)
+ * @param bool $forThirdParty Without infos for third party (optional)
+ * @param null|array $intersectionData Array containing needed parameters used to get intersected layer data
+ *
+ * @return string The CSV file path
+ */
+ public function getParcellesAndProprioInfos($repository, $project, $parcelleLayer, $parcelle_ids, $withGeom = false, $forThirdParty = false, $intersectionData = null)
+ {
+ $this->repository = $repository;
+ $this->project = $project;
+ $this->config = cadastreConfig::get($repository, $project);
+ $sql = $this->getParcellesAndProprioSql($parcelle_ids, $withGeom, $forThirdParty, $intersectionData);
+
+ $profile = cadastreProfile::get($repository, $project, $parcelleLayer);
+
+ $parameters = array();
+ $rows = $this->query($sql, $parameters, $profile);
+
+ return $this->buildCsv($rows);
+ }
}
diff --git a/cadastre/classes/listParcelleSpatialDatasource.class.php b/cadastre/classes/listParcelleSpatialDatasource.class.php
new file mode 100644
index 0000000..a3623ce
--- /dev/null
+++ b/cadastre/classes/listParcelleSpatialDatasource.class.php
@@ -0,0 +1,190 @@
+getData($this->criteriaFrom[0]);
+ $project = $form->getData($this->criteriaFrom[1]);
+ $layerId = $form->getData($this->criteriaFrom[2]);
+ $spatialLayerId = $form->getData($this->criteriaFrom[3]);
+ // $spatialLayerUseSelected = $form->getData($this->criteriaFrom[4]);
+ $spatialLayerSelectedIds = $form->getData($this->criteriaFrom[4]);
+ $spatialLayerField = $form->getData($this->criteriaFrom[5]);
+ $spatialLayerBuffer = $form->getData($this->criteriaFrom[6]);
+
+ if (empty($spatialLayerId)) {
+ return array();
+ }
+ $this->profile = cadastreProfile::getWithLayerId($repository, $project, $layerId);
+
+ if ($this->dao === null) {
+ $this->dao = jDao::get($this->selector, $this->profile);
+ }
+
+ $searchConditions = jDao::createConditions();
+
+ $config = cadastreConfig::get($repository, $project);
+ $layerConditions = null;
+ $layerSql = cadastreConfig::getLayerSql($repository, $project, $config->parcelle->id);
+ $polygonFilter = cadastreConfig::getPolygonFilter($repository, $project, $config->parcelle->id);
+ $loginFilter = cadastreConfig::getLoginFilter($repository, $project, $config->parcelle->id);
+ $layerFilters = array();
+ if ($layerSql !== null) {
+ $layerFilters[] = $layerSql;
+ }
+ if ($polygonFilter !== null) {
+ $layerFilters[] = $polygonFilter;
+ }
+ if ($loginFilter !== null) {
+ $layerFilters[] = $loginFilter;
+ }
+ if (count($layerFilters) != 0) {
+ if (count($layerFilters) == 1) {
+ $layerConditions = $layerFilters[0];
+ } else {
+ $layerConditions = '(' . implode(') AND (', $layerFilters) . ')';
+ }
+ }
+
+ foreach ((array) $this->labelProperty as $property) {
+ $searchConditions->addItemOrder($property, 'asc');
+ }
+
+ // Get spatial layer name, table info, fields, etc.
+ $p = lizmap::getProject($repository . '~' . $project);
+ if ($p === null) {
+ throw new Exception("Spatial search: Unknown repository/project {$repository}.'~'.{$project}");
+ }
+
+ /** @var \qgisVectorLayer $qgisLayer The QGIS vector layer instance */
+ $qgisLayer = $p->getLayer($spatialLayerId);
+ if (!$qgisLayer) {
+ throw new Exception("Spatial search: Unknown layer {$layerId} used in spatial search");
+ }
+
+ // Get the PostgreSQL information
+ $dataSourceParameters = $qgisLayer->getDatasourceParameters();
+ $spatialLayerSchema = $dataSourceParameters->schema;
+ $spatialLayerTable = $dataSourceParameters->tablename;
+
+ // Check that the given field exists
+ $fields = $qgisLayer->getFields();
+ if (!empty($spatialLayerField) && !in_array($spatialLayerField, $fields)) {
+ throw new Exception("Spatial search: the field {$spatialLayerField} does not exist in the table ");
+ }
+
+ // Get the table primary key field
+ // Only one field supported
+ $dbFieldsInfo = $qgisLayer->getDbFieldsInfo();
+ $spatialLayerPk = null;
+ foreach ($dbFieldsInfo->primaryKeys as $key) {
+ $spatialLayerPk = $key;
+
+ break;
+ }
+
+ // Get the optional selection
+ // JS 3.6 : lizMap.config.layers["Parcelles"]['selectedFeatures']
+ // JS 3.7 : lizMap.mainLizmap.config.layers["Parcelles"]['selectedFeatures']
+ $selectedIds = array();
+ if (!empty($spatialLayerSelectedIds)) {
+ $selectedIds = explode(',', $spatialLayerSelectedIds);
+ } else {
+ $selectedIds = array('-9999999');
+ }
+
+ // Run the query by using the DAO method
+ $found = $this->dao->{$this->method}(
+ $layerConditions,
+ $searchConditions,
+ $spatialLayerSchema,
+ $spatialLayerTable,
+ $spatialLayerPk,
+ $selectedIds,
+ $spatialLayerField,
+ $spatialLayerBuffer
+ );
+
+ $result = array();
+
+ foreach ($found as $obj) {
+ $label = $this->buildLabel($obj);
+ $value = $obj->{$this->valueProperty};
+
+ $result[$value] = $label;
+ }
+
+ return $result;
+ }
+
+ public function getLabel2($key, $form)
+ {
+ if ($key === null || $key == '') {
+ return null;
+ }
+
+ $repository = $form->getData($this->criteriaFrom[0]);
+ $project = $form->getData($this->criteriaFrom[1]);
+ $layerId = $form->getData($this->criteriaFrom[2]);
+ $this->profile = cadastreProfile::getWithLayerId($repository, $project, $layerId);
+
+ if ($this->dao === null) {
+ $this->dao = jDao::get($this->selector, $this->profile);
+ }
+
+ $method = $this->labelMethod;
+
+ $rec = $this->dao->{$method}($key);
+
+ if ($rec) {
+ return $this->buildLabel($rec);
+ }
+
+ return null;
+ }
+
+ protected function buildLabel($rec)
+ {
+ $label = '';
+ foreach ((array) $this->labelProperty as $property) {
+ if ((string) $rec->{$property} !== '') {
+ $label .= $rec->{$property} . $this->labelSeparator;
+ }
+ }
+ if ($this->labelSeparator != '') {
+ $label = substr($label, 0, -strlen($this->labelSeparator));
+ }
+
+ return $label;
+ }
+
+ public function setCriteriaControls($criteriaFrom = null)
+ {
+ if (count($criteriaFrom) !== 7) {
+ throw new Exception(
+ '7 criterias needed: repository, project, parcelleLayerId, spatial_layer_id, spatial_layer_selected_ids, spatial_layer_field, spatial_layer_buffer'
+ );
+ }
+ $this->criteriaFrom = $criteriaFrom;
+ }
+}
diff --git a/cadastre/classes/listSpatialLayerFieldDatasource.class.php b/cadastre/classes/listSpatialLayerFieldDatasource.class.php
new file mode 100644
index 0000000..ac5b132
--- /dev/null
+++ b/cadastre/classes/listSpatialLayerFieldDatasource.class.php
@@ -0,0 +1,85 @@
+getData($this->criteriaFrom[0]);
+ $project = $form->getData($this->criteriaFrom[1]);
+ $spatialLayerId = $form->getData($this->criteriaFrom[2]);
+ if (empty($spatialLayerId)) {
+ return array();
+ }
+
+ // Get spatial layer name, table info, fields, etc.
+ $p = lizmap::getProject($repository . '~' . $project);
+ if ($p === null) {
+ throw new Exception("Spatial search: Unknown repository/project {$repository}.'~'.{$project}");
+ }
+
+ /** @var \qgisVectorLayer $qgisLayer The QGIS vector layer instance */
+ $qgisLayer = $p->getLayer($spatialLayerId);
+ if (!$qgisLayer) {
+ throw new Exception("Spatial search: Unknown layer {$spatialLayerId} used in spatial search");
+ }
+
+ // Get fields and aliases
+ $this->fields = $qgisLayer->getFields();
+ $this->aliases = $qgisLayer->getAliasFields();
+ $result = array();
+ foreach ($this->fields as $field) {
+ $label = $field;
+ if (array_key_exists($field, $this->aliases) && !empty($this->aliases[$field])) {
+ $label = $this->aliases[$field];
+ }
+ $result[$field] = $label;
+ }
+
+ return $result;
+ }
+
+ public function getLabel2($key, $form)
+ {
+ if ($key === null || $key == '') {
+ return null;
+ }
+ $repository = $form->getData($this->criteriaFrom[0]);
+ $project = $form->getData($this->criteriaFrom[1]);
+ $spatialLayerId = $form->getData($this->criteriaFrom[2]);
+
+ return $key;
+
+ return null;
+ }
+
+ protected function buildLabel($key)
+ {
+ return $key;
+ }
+
+ public function setCriteriaControls($criteriaFrom = null)
+ {
+ if (count($criteriaFrom) !== 3) {
+ throw new Exception(
+ '3 criterias needed: repository, project, spatial_layer_id'
+ );
+ }
+ $this->criteriaFrom = $criteriaFrom;
+ }
+}
diff --git a/cadastre/controllers/service.classic.php b/cadastre/controllers/service.classic.php
index ad22df9..732293a 100644
--- a/cadastre/controllers/service.classic.php
+++ b/cadastre/controllers/service.classic.php
@@ -466,6 +466,10 @@ public function downloadExport()
return $rep;
}
+ /**
+ * Récupération des locaux et des propriétaires
+ * pour toutes les parcelles sélectionnées.
+ */
public function locauxProprios()
{
$rep = $this->getResponse('json');
@@ -497,6 +501,7 @@ public function locauxProprios()
$forThirdParty = ($advanced !== '1');
}
+ /** @var \jResponseBinary $rep */
$rep = $this->getResponse('binary');
$rep->mimeType = 'text/csv';
@@ -515,4 +520,165 @@ public function locauxProprios()
return $rep;
}
+
+ /**
+ * Get the needed information on the given QGIS layer.
+ *
+ * @param string $layerId The ID of the QGIS layer
+ * @param mixed $repository
+ * @param mixed $project
+ * @param mixed $field
+ *
+ * @return null|array The layer characteristics
+ */
+ private function getSpatialLayerInfo($repository, $project, $layerId, $field)
+ {
+ // Get spatial layer name, table info, fields, etc.
+ $p = lizmap::getProject($repository . '~' . $project);
+ if ($p === null) {
+ return null;
+ }
+
+ /** @var \qgisVectorLayer $qgisLayer The QGIS vector layer instance */
+ $qgisLayer = $p->getLayer($layerId);
+ if (!$qgisLayer) {
+ return null;
+ }
+
+ // Get the PostgreSQL information
+ $dataSourceParameters = $qgisLayer->getDatasourceParameters();
+ $spatialLayerSchema = $dataSourceParameters->schema;
+ $spatialLayerTable = $dataSourceParameters->tablename;
+
+ // Check that the given field exists
+ $fields = $qgisLayer->getFields();
+ if (!empty($field) && !in_array($field, $fields)) {
+ return null;
+ }
+
+ // Get the table primary key field
+ // Only one field supported
+ $dbFieldsInfo = $qgisLayer->getDbFieldsInfo();
+ $spatialLayerPk = null;
+ foreach ($dbFieldsInfo->primaryKeys as $key) {
+ $spatialLayerPk = $key;
+
+ break;
+ }
+
+ return array(
+ 'schema' => $spatialLayerSchema,
+ 'table' => $spatialLayerTable,
+ 'pk' => $spatialLayerPk,
+ 'field' => $field,
+ 'geometryColumn' => $dbFieldsInfo->geometryColumn,
+ );
+ }
+
+ /**
+ * Récupération des parcelles et des propriétaires
+ * pour toutes les parcelles sélectionnées.
+ */
+ public function parcellesProprios()
+ {
+ $rep = $this->getResponse('json');
+
+ if (!jAcl2::check('cadastre.acces.donnees.proprio') && !jAcl2::check('cadastre.acces.donnees.proprio.simple')) {
+ $rep->data = array(
+ 'status' => 'error',
+ 'message' => 'Vous n\'avez pas les droits pour voir les données de propriété.',
+ );
+
+ return $rep;
+ }
+
+ $project = $this->param('project');
+ $repository = $this->param('repository');
+ $p = lizmap::getProject($repository . '~' . $project);
+ if (!$p) {
+ $rep->data = array('status' => 'error', 'message' => 'A problem occurred while loading project with Lizmap');
+
+ return $rep;
+ }
+
+ $parcelleIds = $this->param('parcelles');
+ $parcelleIds = explode(',', $parcelleIds);
+ $withGeom = false;
+ $forThirdParty = true;
+ if (jAcl2::check('cadastre.acces.donnees.proprio')) {
+ $advanced = $this->param('advanced');
+ $forThirdParty = ($advanced !== '1');
+ }
+
+ /** @var \jResponseBinary $rep */
+ $rep = $this->getResponse('binary');
+ $rep->mimeType = 'text/csv';
+
+ // Get profile
+ $parcelleLayer = $this->param('layer', 'Parcelles');
+
+ // If we need to compute the list of codes from the intersected layer for each returned line
+ $intersectionDataJson = $this->param('additionalData', null);
+ $intersectionParams = null;
+ $intersectionData = null;
+ if ($intersectionDataJson) {
+ $intersectionData = json_decode($intersectionDataJson);
+ }
+ if (!empty($intersectionData)
+ && property_exists($intersectionData, 'spatial_layer_id') && !empty($intersectionData->spatial_layer_id)
+ && property_exists($intersectionData, 'spatial_layer_field') && !empty($intersectionData->spatial_layer_field)
+ && property_exists($intersectionData, 'spatial_layer_buffer') && preg_match('/^[0-9]+$/', $intersectionData->spatial_layer_buffer)
+ && property_exists($intersectionData, 'spatial_layer_selected_ids') && !empty($intersectionData->spatial_layer_selected_ids)
+ ) {
+ // Get the QGIS layer information
+ $spatialLayerInfo = $this->getSpatialLayerInfo(
+ $repository,
+ $project,
+ $intersectionData->spatial_layer_id,
+ $intersectionData->spatial_layer_field
+ );
+ if ($spatialLayerInfo !== null) {
+ // Format & validate selected Ids
+ $ids = explode(',', $intersectionData->spatial_layer_selected_ids);
+ $selectedIds = array();
+ foreach ($ids as $id) {
+ if (preg_match('/[0-9A-Za-z_]+/', trim($id))) {
+ $selectedIds[] = trim($id);
+ }
+ }
+ if (count($selectedIds) > 0) {
+ $selectedIdsString = "'" . implode("', '", $selectedIds) . "'";
+ $intersectionParams = array(
+ 'field' => $spatialLayerInfo['field'],
+ 'schema' => $spatialLayerInfo['schema'],
+ 'table' => $spatialLayerInfo['table'],
+ 'pk' => $spatialLayerInfo['pk'],
+ 'selectedIds' => $selectedIdsString,
+ 'geometryColumn' => $spatialLayerInfo['geometryColumn'],
+ 'buffer' => (int) $intersectionData->spatial_layer_buffer,
+ );
+ }
+ }
+ }
+
+ /** @var cadastreExtraInfos $extra_infos */
+ $extra_infos = jClasses::getService('cadastre~cadastreExtraInfos');
+ $path = $extra_infos->getParcellesAndProprioInfos(
+ $repository,
+ $project,
+ $parcelleLayer,
+ $parcelleIds,
+ $withGeom,
+ $forThirdParty,
+ $intersectionParams
+ );
+
+ $rep->fileName = $path;
+ $rep->deleteFileAfterSending = true;
+
+ $rep->doDownload = true;
+ $rep->outputFileName = 'cadastre_parcelles_et_proprietaires.csv';
+
+ return $rep;
+ }
}
diff --git a/cadastre/daos/parcelle_info.dao.xml b/cadastre/daos/parcelle_info.dao.xml
index 3817165..6397bce 100644
--- a/cadastre/daos/parcelle_info.dao.xml
+++ b/cadastre/daos/parcelle_info.dao.xml
@@ -18,8 +18,8 @@
-
+ selectpattern="parcelle_info.codecommune || ' - ' || CASE WHEN substr(parcelle_info.idu,4,3) != '000' THEN substr(parcelle_info.idu,4,3) || ' - ' ELSE '' END || substr(parcelle_info.idu,7,6)"/>
+
@@ -354,5 +354,61 @@
]]>