Skip to content

Commit

Permalink
Merge pull request #97 from mdouchin/publipostage
Browse files Browse the repository at this point in the history
Ajout d'un outil de sélection spatiale et d'export pour publipostage pour les parcelles
  • Loading branch information
mdouchin authored Dec 18, 2023
2 parents 071a7d7 + cb69116 commit d504245
Show file tree
Hide file tree
Showing 16 changed files with 1,092 additions and 57 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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
18 changes: 17 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
9 changes: 8 additions & 1 deletion cadastre/classes/cadastre.listener.php
Original file line number Diff line number Diff line change
Expand Up @@ -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')),
);
Expand Down
44 changes: 44 additions & 0 deletions cadastre/classes/cadastreDockable.listener.php
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
182 changes: 182 additions & 0 deletions cadastre/classes/cadastreExtraInfos.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down Expand Up @@ -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);
}
}
Loading

0 comments on commit d504245

Please sign in to comment.