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 @@ ]]> + + + + + + + + + + + + _selectClause; + if (!empty($spatialLayerField)) { + $sql .= ' , i."' . trim($spatialLayerField, " '\n\r\t\v\x00") . '"'; + } + + $sql .= $this->_fromClause; + $sql .= ' JOIN "' . $spatialLayerSchema . '"."' . $spatialLayerTable . '" AS i'; + $sql .= ' ON ST_DWithin(i.geom, "parcelle_info".geom, ' . $this->_prepareValue($spatialLayerBuffer,'string') .')'; + + if (count($spatialLayerSelectedIds) > 0) { + $sql .= ' AND i."' . trim($spatialLayerPk, " '\n\r\t\v\x00") . '" IN ('; + $virg = ''; + foreach($spatialLayerSelectedIds as $v) { + $sql .= $virg . $this->_prepareValue(trim($v), 'string'); + $virg = ', '; + } + $sql .= ' ) '; + } + + $sql .= $this->_whereClause; + + if ($layerConditions || $searchConditions->hasConditions()) { + $sql.= ($this->_whereClause == ''?' WHERE ':' AND '); + } + + if ($layerConditions) { + $sql.= '('. $layerConditions .')'; + } + + if ($searchConditions->hasConditions()) { + if ($layerConditions) { + $sql.= ' AND '; + } + $sql.= '('. $this->_createConditionsClause($searchConditions) .')'; + } + + $sql.= $this->_createOrderClause($searchConditions); + + $rs = $this->_conn->query($sql); + $rs->setFetchMode(8,$this->_DaoRecordClassName); + return $rs; + ]]> + + diff --git a/cadastre/forms/search.form.xml b/cadastre/forms/search.form.xml index 8cf6960..9e31cef 100644 --- a/cadastre/forms/search.form.xml +++ b/cadastre/forms/search.form.xml @@ -56,6 +56,44 @@ + + + + + + + + + + + + + + + + + + +