diff --git a/cadastre/cadastre_common_base.py b/cadastre/cadastre_common_base.py index 89088b57..a2d5092f 100644 --- a/cadastre/cadastre_common_base.py +++ b/cadastre/cadastre_common_base.py @@ -262,8 +262,9 @@ def postgisToSpatialite(sql: str, targetSrid: str = '2154') -> str: {'in': r'alter table [^;]+drop constraint[^;]+;', 'out': ''}, # ~ {'in': r'^analyse [^;]+;', 'out': ''}, # replace - {'in': r'truncate (bati|fanr|lloc|nbat|pdll|prop)', - 'out': r'drop table \1;create table \1 (tmp text)'}, + {'in': r'truncate (bati|lloc|nbat|pdll|prop)', + 'out': r'drop table if exists \1;create table \1 (tmp text)'}, + {'in': r'truncate topo', 'out': r'delete from topo'}, {'in': r'truncate ', 'out': 'delete from '}, {'in': r'distinct on *\([a-z, ]+\)', 'out': 'distinct'}, {'in': r'serial', 'out': 'INTEGER PRIMARY KEY AUTOINCREMENT'}, @@ -276,6 +277,10 @@ def postgisToSpatialite(sql: str, targetSrid: str = '2154') -> str: 'out': r"date(substr(\2, 5, 4) || '-' || substr(\2, 3, 2) || '-' || substr(\2, 1, 2))"}, {'in': r"(to_date\()([^']+) *, *'DD/MM/YYYY' *\)", 'out': r"date(substr(\2, 7, 4) || '-' || substr(\2, 4, 2) || '-' || substr(\2, 1, 2))"}, + + {'in': r"(to_char\()(.+), 'DDD'\)", + 'out': r"strftime('%j', \2)"}, + {'in': r"(to_date\()([^']+) *, *'YYYYMMDD' *\)", 'out': r"date(substr(\2, 1, 4) || '-' || substr(\2, 5, 2) || '-' || substr(\2, 7, 2))"}, {'in': r"(to_char\()([^']+) *, *'dd/mm/YYYY' *\)", diff --git a/cadastre/cadastre_import.py b/cadastre/cadastre_import.py index 79cefef4..da7aa6e9 100644 --- a/cadastre/cadastre_import.py +++ b/cadastre/cadastre_import.py @@ -43,12 +43,12 @@ from cadastre.definitions import ( IMPORT_MEMORY_ERROR_MESSAGE, REGEX_BATI, - REGEX_FANTOIR, REGEX_LOTLOCAL, REGEX_NBATI, REGEX_PDL, REGEX_PROP, - URL_FANTOIR, + REGEX_TOPO, + URL_TOPO, ) from cadastre.dialogs.dialog_common import CadastreCommon @@ -118,9 +118,9 @@ def __init__(self, dialog): 'required': True }, { - 'key': '[FICHIER_FANTOIR]', - 'regex': s.value("cadastre/regexFantoir", REGEX_FANTOIR, type=str), - 'table': 'fanr', + 'key': '[FICHIER_TOPO]', + 'regex': s.value("cadastre/regexTopo", REGEX_TOPO, type=str), + 'table': 'topo', 'required': True }, { @@ -165,7 +165,7 @@ def __init__(self, dialog): if self.dialog.hasStructure: self.hasConstraints = True - # Remove MAJIC from tables bati|fanr|lloc|nbat|pdll|prop + # Remove MAJIC from tables bati|topo|lloc|nbat|pdll|prop self.removeMajicRawData = True self.beginImport() @@ -305,7 +305,7 @@ def importMajic(self): # dict for parameters replacement replaceDict = self.replaceDict.copy() - # mandatoryFilesKeys = ['[FICHIER_BATI]', '[FICHIER_FANTOIR]', '[FICHIER_NBATI]', '[FICHIER_PROP]'] + # mandatoryFilesKeys = ['[FICHIER_BATI]', '[FICHIER_TOPO]', '[FICHIER_NBATI]', '[FICHIER_PROP]'] # missingMajicFiles = False scriptList = [] @@ -350,6 +350,7 @@ def importMajic(self): scriptList.append(importScript) # Format data + replaceDict['DEPDIR'] = f'{self.dialog.edigeoDepartement}{self.dialog.edigeoDirection}' scriptList.append( { 'title': 'Mise en forme des données', @@ -460,9 +461,8 @@ def get_available_majic_files(self) -> tuple[dict, dict]: file_path = os.path.join(root, file_sub_path) maj_list.append(file_path) - # Store dep_dir for this file - # avoid fantoir, as now it is given for the whole country - if table == 'fanr': + # avoid topo, since direction is not used in TOPO + if table == 'topo': continue # Get dep_dir : first line with content @@ -490,17 +490,21 @@ def check_missing_majic_files(self, majic_files_found: dict) -> bool: "Des fichiers MAJIC importants sont manquants :
" " {}

" "Vérifier le chemin des fichiers MAJIC :
" - "{}
" + "{}

" "ainsi que les mots recherchés pour chaque type de fichier configurés dans les options du plugin Cadastre :
" - "{}

" - "NB: Vous pouvez télécharger les fichiers FANTOIR à cette adresse :
" + "{}


" + "NB: Vous pouvez télécharger les fichiers TOPO à cette adresse :
" "{}
" ).format( - ', '.join(missing_files), + ',
'.join(missing_files), self.dialog.majicSourceDir, - ',
'.join([f"* {a['key'].strip('[]')}: {a['regex'].upper()}" for a in self.majicSourceFileNames]), - URL_FANTOIR, - URL_FANTOIR, + ',
'.join([ + f"* {a['key'].strip('[]')}: {a['regex'].upper()}" + for a in self.majicSourceFileNames + if a['table'] in missing_files + ]), + URL_TOPO, + URL_TOPO, ) missing_majic_ignore = QMessageBox.question( self.dialog, @@ -691,9 +695,12 @@ def import_majic_into_database(self) -> bool: self.totalSteps += len(majic_files_found[table]) processed_files_count += len(majic_files_found[table]) for file_path in majic_files_found[table]: + self.qc.updateLog(f'{table}') self.qc.updateLog(file_path) - - import_file = self.import_majic_file_into_database(table, file_path, dep_dir) + if table == 'topo': + import_file = self.import_file_with_ogr(file_path, 'topo') + else: + import_file = self.import_majic_file_into_database(table, file_path, dep_dir) if not import_file: continue @@ -1187,6 +1194,12 @@ def replaceParametersInScript(self, scriptPath, replaceDict): self.qc.updateLog(msg) return msg + except KeyError as e: + msg = "Erreur lors du paramétrage des scripts d'import: %s" % e + self.go = False + self.qc.updateLog(msg) + return msg + finally: QApplication.restoreOverrideCursor() @@ -1408,7 +1421,7 @@ def importAllEdigeoToDatabase(self): self.step = 0 self.totalSteps = len(thfList) for thf in thfList: - self.importEdigeoThfToDatabase(thf) + self.import_file_with_ogr(thf, 'thf') self.updateProgressBar() if not self.go: break @@ -1442,110 +1455,139 @@ def importAllEdigeoToDatabase(self): self.totalSteps = initialTotalSteps QApplication.restoreOverrideCursor() - def importEdigeoThfToDatabase(self, filename): + def import_file_with_ogr(self, file_path: str, file_type: str): """ - Import one edigeo THF files into database + Import file into the database. + + It can either be an EDIGEO THF file or a TOPO file. source : db_manager/dlg_import_vector.py """ - if self.go: - # Get options + if not self.go: + return None + + # SRID configurations + if file_type == 'thf': targetSridOption = '-t_srs' if self.sourceSridFull == self.targetSridFull: targetSridOption = '-a_srs' - # Build ogr2ogr command - conn_name = self.dialog.connectionName - settings = QSettings() - settings.beginGroup(f"/{self.db.dbplugin().connectionSettingsKey()}/{conn_name}") + # Build ogr2ogr command + conn_name = self.dialog.connectionName + settings = QSettings() + settings.beginGroup(f"/{self.db.dbplugin().connectionSettingsKey()}/{conn_name}") - # normalising file path - filename = os.path.normpath(filename) - if self.dialog.dbType == 'postgis': - if not settings.contains("database"): # non-existent entry? - raise Exception(self.tr('There is no defined database connection "%s".') % conn_name) - settingsList = ["service", "host", "port", "database", "username", "password"] - service, host, port, database, username, password = (settings.value(x) for x in settingsList) - - if service: - pg_access = 'PG:service={} active_schema={}'.format( - service, - self.dialog.schema - ) - else: - # qgis can connect to postgis DB without a specified host param connection, but ogr2ogr cannot - if not host: - host = "localhost" - - pg_access = 'PG:host={} port={} dbname={} active_schema={} user={} password={}'.format( - host, - port, - database, - self.dialog.schema, - username, - password - ) - cmdArgs = [ - '', + # normalising file path + file_path = os.path.normpath(file_path) + if self.dialog.dbType == 'postgis': + if not settings.contains("database"): # non-existent entry? + raise Exception(self.tr('There is no defined database connection "%s".') % conn_name) + settingsList = ["service", "host", "port", "database", "username", "password"] + service, host, port, database, username, password = (settings.value(x) for x in settingsList) + + if service: + pg_access = 'PG:service={} active_schema={}'.format( + service, + self.dialog.schema + ) + else: + # qgis can connect to postgis DB without a specified host param connection, but ogr2ogr cannot + if not host: + host = "localhost" + + pg_access = 'PG:host={} port={} dbname={} active_schema={} user={} password={}'.format( + host, + port, + database, + self.dialog.schema, + username, + password + ) + cmdArgs = [ + '', + ] + if file_type == 'thf': + cmdArgs += [ '-s_srs', self.sourceSridFull, targetSridOption, self.targetSridFull, - '-append', - '-f', 'PostgreSQL', - pg_access, - filename, + ] + cmdArgs += [ + '-append', + '-f', 'PostgreSQL', + pg_access, + file_path, + '-lco', 'PG_USE_COPY=YES', + '-gt', '50000', + '--config', 'PG_USE_COPY', 'YES', + ] + if file_type == 'thf': + cmdArgs += [ '-lco', 'GEOMETRY_NAME=geom', - '-lco', 'PG_USE_COPY=YES', '-nlt', 'GEOMETRY', - '-gt', '50000', '--config', 'OGR_EDIGEO_CREATE_LABEL_LAYERS', 'NO', - '--config', 'PG_USE_COPY', 'YES', ] - # -c client_encoding=latin1 + if file_type == 'topo': + cmdArgs += [ + '-nln', 'topo', + ] + # -c client_encoding=latin1 - if self.dialog.dbType == 'spatialite': - if not settings.contains("sqlitepath"): # non-existent entry? - self.go = False - raise Exception('there is no defined database connection "%s".' % conn_name) + if self.dialog.dbType == 'spatialite': + if not settings.contains("sqlitepath"): # non-existent entry? + self.go = False + raise Exception('there is no defined database connection "%s".' % conn_name) - database = settings.value("sqlitepath") + database = settings.value("sqlitepath") - cmdArgs = [ - '', + cmdArgs = [ + '', + ] + if file_type == 'thf': + cmdArgs += [ '-s_srs', self.sourceSridFull, targetSridOption, self.targetSridFull, - '-append', - '-f', 'SQLite', - database, - filename, + ] + cmdArgs += [ + '-append', + '-f', 'SQLite', + database, + file_path, + '-gt', '50000', + '--config', 'OGR_SQLITE_SYNCHRONOUS', 'OFF', + '--config', 'OGR_SQLITE_CACHE', '512' + ] + if file_type == 'thf': + cmdArgs += [ '-lco', 'GEOMETRY_NAME=geom', '-nlt', 'GEOMETRY', '-dsco', 'SPATIALITE=YES', - '-gt', '50000', '--config', 'OGR_EDIGEO_CREATE_LABEL_LAYERS', 'NO', - '--config', 'OGR_SQLITE_SYNCHRONOUS', 'OFF', - '--config', 'OGR_SQLITE_CACHE', '512' + ] + if file_type == 'topo': + cmdArgs += [ + '-nln', 'topo', ] - # self.qc.updateLog( ' '.join(cmdArgs)) - # Run only if ogr2ogr found - if self.go: - # Workaround to get ogr2ogr error messages via stdout - # as ogr2ogr.py does not return exceptions nor error messages - # but only prints the error before returning False - stdout = sys.stdout - try: - sys.stdout = file = io.StringIO() - self.go = ogr2ogr(cmdArgs) - printedString = file.getvalue() - finally: - sys.stdout = stdout + # self.qc.updateLog( ' '.join(cmdArgs)) + # Run only if ogr2ogr found + if self.go: + # Workaround to get ogr2ogr error messages via stdout + # as ogr2ogr.py does not return exceptions nor error messages + # but only prints the error before returning False + stdout = sys.stdout + try: + sys.stdout = file = io.StringIO() + self.go = ogr2ogr(cmdArgs) + printedString = file.getvalue() + finally: + sys.stdout = stdout - if not self.go: - self.qc.updateLog( - "Erreur - L'import des données via OGR2OGR a échoué:\n\n{}\n\n{}".format( - printedString, - cmdArgs - ) + if not self.go: + self.qc.updateLog( + "Erreur - L'import des données via OGR2OGR a échoué:\n\n{}\n\n{}".format( + printedString, + cmdArgs ) + ) return None diff --git a/cadastre/definitions.py b/cadastre/definitions.py index 779daca6..52c644bb 100644 --- a/cadastre/definitions.py +++ b/cadastre/definitions.py @@ -1,15 +1,15 @@ -URL_FANTOIR = ( - "https://drive.opendata.craig.fr/s/opendata?path=%2Fadresse%2Ffantoir" +URL_TOPO = ( + "https://drive.opendata.craig.fr/s/opendata?path=%2Fadresse%2Ftopo" ) URL_DOCUMENTATION = "https://docs.3liz.org/QgisCadastrePlugin/" REGEX_BATI = "BATI" -REGEX_FANTOIR = "FANTOIR|FANR" REGEX_LOTLOCAL = "LLOC|D166" REGEX_NBATI = "NBAT" REGEX_PDL = "PDL" REGEX_PROP = "PROP" +REGEX_TOPO = "TOPO" IMPORT_MEMORY_ERROR_MESSAGE = "ERREUR : Mémoire
" "Veuillez recommencer l'import en baissant la valeur du " diff --git a/cadastre/dialogs/options_dialog.py b/cadastre/dialogs/options_dialog.py index b21105d6..27bd8c84 100644 --- a/cadastre/dialogs/options_dialog.py +++ b/cadastre/dialogs/options_dialog.py @@ -14,11 +14,11 @@ from cadastre.definitions import ( REGEX_BATI, - REGEX_FANTOIR, REGEX_LOTLOCAL, REGEX_NBATI, REGEX_PDL, REGEX_PROP, + REGEX_TOPO, ) from cadastre.tools import set_window_title @@ -120,9 +120,9 @@ def getValuesFromSettings(self): regexBati = s.value("cadastre/regexBati", REGEX_BATI, type=str) if regexBati: self.inMajicBati.setText(regexBati) - regexFantoir = s.value("cadastre/regexFantoir", REGEX_FANTOIR, type=str) - if regexFantoir: - self.inMajicFantoir.setText(regexFantoir) + regexTopo = s.value("cadastre/regexTopo", REGEX_TOPO, type=str) + if regexTopo: + self.inMajicTopo.setText(regexTopo) regexLotLocal = s.value("cadastre/regexLotLocal", REGEX_LOTLOCAL, type=str) if regexLotLocal: self.inMajicLotlocal.setText(regexLotLocal) @@ -192,7 +192,7 @@ def onAccept(self): # Save Majic file names s = QgsSettings() s.setValue("cadastre/regexBati", self.inMajicBati.text().strip(' \t\n\r')) - s.setValue("cadastre/regexFantoir", self.inMajicFantoir.text().strip(' \t\n\r')) + s.setValue("cadastre/regexTopo", self.inMajicTopo.text().strip(' \t\n\r')) s.setValue("cadastre/regexLotLocal", self.inMajicLotlocal.text().strip(' \t\n\r')) s.setValue("cadastre/regexNbati", self.inMajicNbati.text().strip(' \t\n\r')) s.setValue("cadastre/regexPdl", self.inMajicPdl.text().strip(' \t\n\r')) diff --git a/cadastre/dialogs/search_dialog.py b/cadastre/dialogs/search_dialog.py index 8e1b0bc2..b37393ea 100644 --- a/cadastre/dialogs/search_dialog.py +++ b/cadastre/dialogs/search_dialog.py @@ -409,7 +409,7 @@ def checkMajicContent(self): if not self.hasMajicDataParcelle or not self.hasMajicDataVoie: self.qc.updateLog( - "Pas de données MAJIC non bâties et/ou fantoir -> désactivation de la recherche d'adresse") + "Pas de données MAJIC non bâties et/ou TOPO -> désactivation de la recherche d'adresse") if not self.hasMajicDataProp: self.qc.updateLog( "Pas de données MAJIC propriétaires -> désactivation de la recherche de propriétaires") @@ -578,7 +578,7 @@ def refreshAutocomplete(self, key): # Build SQL query hasCommuneFilter = None if key == 'adresse': - sql = ' SELECT DISTINCT v.voie, c.tex2 AS libcom, v.natvoi, v.libvoi' + sql = " SELECT DISTINCT v.voie, c.tex2 AS libcom, Coalesce(v.natvoi, '') AS natvoi, coalesce(v.libvoi, '') AS libvoi" if self.dbType == 'postgis': sql += ' FROM "{}"."voie" v'.format(connectionParams['schema']) else: @@ -602,9 +602,9 @@ def refreshAutocomplete(self, key): hasCommuneFilter = True # order - sql += ' ORDER BY c.tex2, v.natvoi, v.libvoi' + sql += ' ORDER BY c.tex2, natvoi, libvoi' - if key == 'proprietaire': + elif key == 'proprietaire': # determines if search by usage name or birth name searchByBirthName = self.cbSearchNameBirth.isChecked() @@ -625,7 +625,7 @@ def refreshAutocomplete(self, key): selectedCity = '' if selectedCity is None else selectedCity - if searchByBirthName is False: + if not searchByBirthName: # search by usage name sql = "/* search by usage name*/\r\n" sql += "WITH proprio AS (\r\n" @@ -649,7 +649,7 @@ def refreshAutocomplete(self, key): sql += "GROUP BY proprio.ccocom, comptecommunal, dnuper, nom_usage, geo_commune\r\n" sql += "ORDER BY nom_usage\r\n" - elif searchByBirthName is True: + else: # search by birth name sql = "/* search by birth name*/\r\n" sql += "WITH proprio AS (\r\n" @@ -672,8 +672,10 @@ def refreshAutocomplete(self, key): sql += " AND commune.commune LIKE %s" % self.connector.quoteString('%' + selectedCity + '%') + "\r\n" sql += "GROUP BY proprio.ccocom, comptecommunal, dnuper, dnomus, dprnus, nom_naissance, geo_commune\r\n" sql += "ORDER BY nom_naissance\r\n" + sql += ' LIMIT 50' + # self.qc.updateLog(sql) data, rowCount, ok = CadastreCommon.fetchDataFromSqlQuery(connector, sql) # Write message in log diff --git a/cadastre/forms/cadastre_option_form.ui b/cadastre/forms/cadastre_option_form.ui index 0ea530a8..04c5c2a6 100644 --- a/cadastre/forms/cadastre_option_form.ui +++ b/cadastre/forms/cadastre_option_form.ui @@ -169,16 +169,16 @@ - + - FANTOIR|FANR + TOPO - FANTOIR + TOPO @@ -310,7 +310,7 @@ inMajicPdl inMajicProp lineEdit - inMajicFantoir + inMajicTopo inComposerTemplateFile btComposerTemplateFile inTempDir diff --git a/cadastre/scripts/plugin/2024/majic3_formatage_donnees.sql b/cadastre/scripts/plugin/2024/majic3_formatage_donnees.sql index 3839c19f..27bfa1c9 100644 --- a/cadastre/scripts/plugin/2024/majic3_formatage_donnees.sql +++ b/cadastre/scripts/plugin/2024/majic3_formatage_donnees.sql @@ -966,34 +966,43 @@ FROM ${PREFIXE}lloc; -- Traitement: commune INSERT INTO ${PREFIXE}commune ( - commune, geo_commune, annee, ccodep, ccodir, ccocom, clerivili, libcom, typcom, ruract, carvoi, indpop, poprel, poppart, popfict, annul, dteannul, dtecreart, codvoi, + commune, geo_commune, annee, ccodep, ccodir, ccocom, clerivili, libcom, typcom, + ruract, carvoi, indpop, poprel, poppart, popfict, annul, dteannul, dtecreart, codvoi, typvoi, indldnbat, motclas, lot ) SELECT - REPLACE(SUBSTRING(tmp,1,6),' ', '0') AS commune, - REPLACE(SUBSTRING(tmp,1,6),' ', '0') AS geo_commune, - '${ANNEE}', - SUBSTRING(tmp,1,2) AS ccodep, - SUBSTRING(tmp,3,1) AS ccodir, - SUBSTRING(tmp,4,3) AS ccocom, - SUBSTRING(tmp,11,1) AS clerivili, - SUBSTRING(tmp,12,30) AS libcom, - CASE WHEN trim(SUBSTRING(tmp,43,1))='' THEN NULL ELSE trim(SUBSTRING(tmp,43,1)) END AS typcom, - SUBSTRING(tmp,46,1) AS ruract, - SUBSTRING(tmp,49,1) AS carvoi, - SUBSTRING(tmp,50,1) AS indpop, - CASE WHEN trim(SUBSTRING(tmp,53,7))='' THEN NULL ELSE to_number(trim(SUBSTRING(tmp,53,7)),'0000000') END AS poprel, - to_number(SUBSTRING(tmp,60,7),'9999999') AS poppart, - to_number(SUBSTRING(tmp,67,7),'0000000') AS popfict, - SUBSTRING(tmp,74,1) AS annul, - SUBSTRING(tmp,75,7) AS dteannul, - SUBSTRING(tmp,82,7) AS dtecreart, - SUBSTRING(tmp,104,5) AS codvoi, - SUBSTRING(tmp,109,1) AS typvoi, - SUBSTRING(tmp,110,1) AS indldnbat, - SUBSTRING(tmp,113,8) AS motclas, + '${DEPDIR}' || SUBSTRING("code topo", 10, 3) AS commune, + '${DEPDIR}' || SUBSTRING("code topo", 10, 3) AS geo_commune, + '${ANNEE}' AS annee, + SUBSTRING("code topo", 8, 2) AS ccodep, + SUBSTRING('${DEPDIR}', 3, 1) AS ccodir, + SUBSTRING("code topo", 10, 3) AS ccocom, + NULL AS clerivili, + trim("libelle") AS libcom, + nullif("type commune actuel (r ou n)", '') AS typcom, + nullif("rur actuel", '') AS ruract, + NULL AS carvoi, + NULL AS indpop, + NULL AS poprel, + NULL AS poppart, + NULL AS popfict, + nullif("annulation", '') AS annul, + CASE + WHEN "date annulation" != '00000000' + THEN substr("date annulation", 1, 4) || to_char(to_date("date annulation", 'YYYYMMDD'), 'DDD') + ELSE '0000000' + END AS dteannul, + CASE + WHEN "date creation de article" != '00000000' + THEN substr("date creation de article", 1, 4) || to_char(to_date("date creation de article", 'YYYYMMDD'), 'DDD') + ELSE '0000000' + END AS dtecreart, + NULL AS codvoi, + NULL AS typvoi, + NULL AS indldnbat, + NULL AS motclas, '${LOT}' as lot -FROM ${PREFIXE}fanr WHERE SUBSTRING(tmp,4,3) != ' ' AND trim(SUBSTRING(tmp,7,4))=''; +FROM ${PREFIXE}topo WHERE substr("code topo", 17, 2) = '13'; -- Traitement: voie INSERT INTO ${PREFIXE}voie @@ -1003,33 +1012,51 @@ INSERT INTO ${PREFIXE}voie commune, lot ) SELECT - REPLACE(SUBSTRING(tmp,1,6)||SUBSTRING(tmp,104,5)||SUBSTRING(tmp,7,4),' ', '0') AS voie, + REPLACE('${DEPDIR}' || SUBSTRING("code topo", 10, 3) || '00000' || SUBSTRING("code topo", 13, 4) , ' ', '0') AS voie, '${ANNEE}', - SUBSTRING(tmp,1,2) AS ccodep, - SUBSTRING(tmp,3,1) AS ccodir, - SUBSTRING(tmp,4,3) AS ccocom, - CASE WHEN trim(SUBSTRING(tmp,7,1))='' THEN NULL ELSE trim(SUBSTRING(tmp,7,1)) END AS natvoiriv, - SUBSTRING(tmp,7,4) AS ccoriv, - SUBSTRING(tmp,11,1) AS clerivili, - TRIM(SUBSTRING(tmp,12,4)) AS natvoi, - SUBSTRING(tmp,16,26) AS libvoi, - CASE WHEN trim(SUBSTRING(tmp,43,1))='' THEN NULL ELSE trim(SUBSTRING(tmp,43,1)) END AS typcom, - SUBSTRING(tmp,46,1) AS ruract, - CASE WHEN trim(SUBSTRING(tmp,49,1))='' THEN NULL ELSE trim(SUBSTRING(tmp,49,1)) END AS carvoi, - SUBSTRING(tmp,50,1) AS indpop, - SUBSTRING(tmp,53,7) AS poprel, - to_number(SUBSTRING(tmp,60,7),'0000000') AS poppart, - to_number(SUBSTRING(tmp,67,7),'0000000') AS popfict, - CASE WHEN trim(SUBSTRING(tmp,74,1))='' THEN NULL ELSE trim(SUBSTRING(tmp,74,1)) END AS annul, - SUBSTRING(tmp,75,7) AS dteannul, - SUBSTRING(tmp,82,7) AS dtecreart, - SUBSTRING(tmp,104,5) AS codvoi, - CASE WHEN trim(SUBSTRING(tmp,109,1))='' THEN NULL ELSE trim(SUBSTRING(tmp,109,1)) END AS typvoi, - CASE WHEN trim(SUBSTRING(tmp,110,1))='' THEN NULL ELSE trim(SUBSTRING(tmp,110,1)) END AS indldnbat, - SUBSTRING(tmp,113,8) AS motclas, - REPLACE(SUBSTRING(tmp,1,6),' ', '0') AS commune, + SUBSTRING("code topo", 8, 2) AS ccodep, + SUBSTRING('${DEPDIR}', 3, 1) AS ccodir, + SUBSTRING("code topo", 10, 3) AS ccocom, + SUBSTRING("code topo", 13, 1) AS natvoiriv, + SUBSTRING("code topo", 13, 4) AS ccoriv, + NULL AS clerivili, + CASE + WHEN "type voie" != '3' AND substr(libelle, 1, 4) IN (SELECT substr(natvoi || ' ', 1, 4) FROM ${PREFIXE}natvoi) + THEN substr(libelle, 1, 4) + ELSE NULL + END AS natvoi, + CASE + WHEN "type voie" != '3' AND substr(libelle, 1, 4) IN (SELECT substr(natvoi || ' ', 1, 4) FROM ${PREFIXE}natvoi) + THEN trim(substr(libelle, 5)) + ELSE trim(libelle) + END AS libvoi, + nullif("type commune actuel (r ou n)", '') AS typcom, + nullif("rur actuel", '') AS ruract, + nullif("caractere voie", '') AS carvoi, + NULL AS indpop, + NULL AS poprel, + NULL AS poppart, + NULL AS popfict, + nullif("annulation", '') AS annul, + CASE + WHEN "date annulation" != '00000000' + THEN substr("date annulation", 1, 4) || to_char(to_date("date annulation", 'YYYYMMDD'), 'DDD') + ELSE '0000000' + END AS dteannul, + CASE + WHEN "date creation de article" != '00000000' + THEN substr("date creation de article", 1, 4) || to_char(to_date("date creation de article", 'YYYYMMDD'), 'DDD') + ELSE '0000000' + END AS dtecreart, + NULL AS codvoi, + "type voie" AS typvoi, + 1 AS indldnbat, + trim("mot classant") AS motclas, + '${DEPDIR}' || SUBSTRING("code topo", 10, 3) AS commune, '${LOT}' as lot -FROM ${PREFIXE}fanr WHERE trim(SUBSTRING(tmp,4,3)) != '' AND trim(SUBSTRING(tmp,7,4)) != ''; +FROM ${PREFIXE}topo +WHERE substr("code topo", 17, 2) = '14' +; -- purge des doublons : voie CREATE INDEX idxan_voie ON voie (annee); diff --git a/cadastre/scripts/plugin/commun_create_metier.sql b/cadastre/scripts/plugin/commun_create_metier.sql index 0ba3d296..82f78b57 100644 --- a/cadastre/scripts/plugin/commun_create_metier.sql +++ b/cadastre/scripts/plugin/commun_create_metier.sql @@ -1,10 +1,26 @@ CREATE TABLE bati (tmp text); -CREATE TABLE fanr (tmp text); CREATE TABLE lloc (tmp text); CREATE TABLE nbat (tmp text); CREATE TABLE pdll (tmp text); CREATE TABLE prop (tmp text); +CREATE TABLE topo ( + ogc_fid serial, + "code topo" character varying, + libelle character varying, + "type commune actuel (r ou n)" character varying, + "type commune fip (rounfip)" character varying, + "rur actuel" character varying, + "rur fip" character varying, + "caractere voie" character varying, + annulation character varying, + "date annulation" character varying, + "date creation de article" character varying, + "type voie" character varying, + "mot classant" character varying, + "date derniere transition" character varying +); + CREATE TABLE parcelle ( parcelle text, annee text, diff --git a/cadastre/scripts/plugin/edigeo_create_table_parcelle_info_majic.sql b/cadastre/scripts/plugin/edigeo_create_table_parcelle_info_majic.sql index eb676522..11311b3e 100644 --- a/cadastre/scripts/plugin/edigeo_create_table_parcelle_info_majic.sql +++ b/cadastre/scripts/plugin/edigeo_create_table_parcelle_info_majic.sql @@ -45,7 +45,7 @@ CASE ELSE 'Non' END AS parcelle_batie, CASE - WHEN v.libvoi IS NOT NULL THEN trim(ltrim(p.dnvoiri, '0') || ' ' || trim(v.natvoi) || ' ' || v.libvoi) + WHEN v.libvoi IS NOT NULL THEN trim(ltrim(p.dnvoiri, '0') || ' ' || trim(Coalesce(v.natvoi, '')) || v.libvoi) ELSE ltrim(p.cconvo, '0') || p.dvoilib END AS adresse, CASE diff --git a/cadastre/scripts/plugin/majic3_purge_donnees_brutes.sql b/cadastre/scripts/plugin/majic3_purge_donnees_brutes.sql index ec315b33..bb41fb51 100644 --- a/cadastre/scripts/plugin/majic3_purge_donnees_brutes.sql +++ b/cadastre/scripts/plugin/majic3_purge_donnees_brutes.sql @@ -1,6 +1,6 @@ -- PURGE DES DONNEES BRUTES: DEBUT; TRUNCATE ${PREFIXE}bati; -TRUNCATE ${PREFIXE}fanr; +TRUNCATE ${PREFIXE}topo; TRUNCATE ${PREFIXE}lloc; TRUNCATE ${PREFIXE}nbat; TRUNCATE ${PREFIXE}pdll; diff --git a/cadastre/scripts/plugin/majic_recuperation_locaux_par_parcelle.sql b/cadastre/scripts/plugin/majic_recuperation_locaux_par_parcelle.sql index 9037bb6e..b8cc16d4 100644 --- a/cadastre/scripts/plugin/majic_recuperation_locaux_par_parcelle.sql +++ b/cadastre/scripts/plugin/majic_recuperation_locaux_par_parcelle.sql @@ -11,7 +11,7 @@ WITH infos AS ( -- adresse ltrim(l.dnvoiri, '0') || l.dindic AS l_numero_voirie, - CASE WHEN v.libvoi IS NOT NULL THEN v.natvoi || v.libvoi ELSE p.cconvo || p.dvoilib END AS l_adresse, + CASE WHEN v.libvoi IS NOT NULL THEN Coalesce(v.natvoi, '') || v.libvoi ELSE p.cconvo || p.dvoilib END AS l_adresse, -- proprio et acte string_agg((l10.ccodep || l10.ccocom || '-' ||l10.dnupro), '|') AS l10_compte_proprietaire, diff --git a/cadastre/templates/parcelle_info_locaux_detail.sql b/cadastre/templates/parcelle_info_locaux_detail.sql index 0c6f6622..bdeef1ff 100644 --- a/cadastre/templates/parcelle_info_locaux_detail.sql +++ b/cadastre/templates/parcelle_info_locaux_detail.sql @@ -9,7 +9,7 @@ WITH infos AS ( -- adresse ltrim(l.dnvoiri, '0') || l.dindic AS l_numero_voirie, - CASE WHEN v.libvoi IS NOT NULL THEN v.natvoi || ' ' || v.libvoi ELSE p.cconvo || ' ' || p.dvoilib END AS l_adresse, + CASE WHEN v.libvoi IS NOT NULL THEN Coalesce(v.natvoi || ' ', '') || v.libvoi ELSE p.cconvo || ' ' || p.dvoilib END AS l_adresse, -- proprio et acte string_agg((l10.ccodep || l10.ccocom || '-' ||l10.dnupro), '|') AS l10_compte_proprietaire, diff --git a/cadastre/templates/proprietes_baties_line.tpl.sql b/cadastre/templates/proprietes_baties_line.tpl.sql index af600756..e9b79ffc 100644 --- a/cadastre/templates/proprietes_baties_line.tpl.sql +++ b/cadastre/templates/proprietes_baties_line.tpl.sql @@ -1,7 +1,7 @@ SELECT l.ccosec AS section, ltrim(l.dnupla, '0') AS ndeplan, ltrim(l.dnvoiri, '0') || l.dindic AS ndevoirie, -CASE WHEN v.libvoi IS NOT NULL THEN v.natvoi || ' ' || v.libvoi ELSE p.cconvo || ' ' || p.dvoilib END AS adresse, +CASE WHEN v.libvoi IS NOT NULL THEN Coalesce(v.natvoi || ' ', '') || v.libvoi ELSE p.cconvo || ' ' || p.dvoilib END AS adresse, l.ccoriv AS coderivoli, l.dnubat AS bat, l.descr AS ent, l.dniv AS niv, l.dpor AS ndeporte, substring(l.invar, 4, length(l.invar)) || ' ' || l.cleinvar AS numeroinvar, pev.ccostb AS star, l10.ccoeva AS meval, pev.ccoaff AS af, l10.cconlc AS natloc, pev.dcapec AS cat, diff --git a/cadastre/templates/proprietes_non_baties_line.tpl.sql b/cadastre/templates/proprietes_non_baties_line.tpl.sql index 17272536..4d014e0d 100644 --- a/cadastre/templates/proprietes_non_baties_line.tpl.sql +++ b/cadastre/templates/proprietes_non_baties_line.tpl.sql @@ -1,7 +1,7 @@ SELECT p.ccosec AS section, ltrim(p.dnupla, '0') AS ndeplan, ltrim(p.dnvoiri, '0') || p.dindic AS ndevoirie, -CASE WHEN v.libvoi IS NOT NULL THEN v.natvoi || ' ' || v.libvoi ELSE p.cconvo || ' ' || p.dvoilib END AS adresse, +CASE WHEN v.libvoi IS NOT NULL THEN Coalesce(v.natvoi || ' ') || v.libvoi ELSE p.cconvo || ' ' || p.dvoilib END AS adresse, p.ccoriv AS coderivoli, p.dparpi AS nparcprim, p.gparnf AS fpdp, s.ccostn AS star, s.ccosub AS suf, s.cgrnum || '/' || s.dsgrpf AS grssgr, s.dclssf AS cl, s.cnatsp AS natcult, CASE WHEN length(Cast(s.dcntsf AS text)) > 4 THEN substring(Cast(s.dcntsf AS text), 0, length(Cast(s.dcntsf AS text))-3) ELSE '0' END AS ha_contenance, diff --git a/docs/extension-qgis/import.md b/docs/extension-qgis/import.md index 9a9930a6..b23fceff 100644 --- a/docs/extension-qgis/import.md +++ b/docs/extension-qgis/import.md @@ -66,9 +66,14 @@ Vous pouvez utiliser le téléchargeur Edigeo dans la boîte à outil **Traiteme ### FANTOIR -Si vous ne possédez pas les données FANTOIR dans votre jeu de données MAJIC, nous conseillons de les télécharger sur le -[site du CRAIG](https://drive.opendata.craig.fr/s/opendata?path=%2Fadresse%2Ffantoir) -et de configurer l'extension pour donner le bon nom au fichier FANTOIR. +Le support des fichiers FANTOIR a été abandonné début 2025 au profit du support des fichiers TOPO. + +### TOPO + +Si vous ne possédez pas les données TOPO dans votre jeu de données MAJIC, nous conseillons de les télécharger sur le +[site du CRAIG](https://drive.opendata.craig.fr/s/opendata?path=%2Fadresse%2Ftopo) +et de configurer l'extension pour vérifier que vous avez configuré le bon mot pour la recherche +des fichiers TOPO. ## Les étapes d'importation @@ -166,7 +171,7 @@ SRID. Nous avons utilisé ici `998999`, qui est le maximum possible. !!! tip Pour trouver la chaîne **WKT** décrivant la projection, à défaut de la trouver sur internet pour le moment, nous pouvons utiliser l'API PyQGIS. Dans le menu **Extensions** → **Console Python**, écrire : - + ```python QgsCoordinateReferenceSystem('IGNF:GUAD48UTM20').toWkt() ``` diff --git a/docs/extension-qgis/interface.md b/docs/extension-qgis/interface.md index 4a53f0a0..c58ca885 100644 --- a/docs/extension-qgis/interface.md +++ b/docs/extension-qgis/interface.md @@ -50,7 +50,7 @@ Ainsi qu'une zone contenant des **boutons d'action** : parcelle, zoomer sur la parcelle ou sélectionner l'objet dans la couche * Un dernier bouton pour **sélectionner dans la couche toutes les parcelles du propriétaire** -> Si vous n'avez pas importé de données FANTOIR, la commune de la parcelle ne sera pas affichée dans la +> Si vous n'avez pas importé de données TOPO, la commune de la parcelle ne sera pas affichée dans la > fenêtre et l'adresse pourra être tronquée (de même pour les relevés exportés) >Si vous n'avez pas de données MAJIC, seule les informations sur la parcelle (1er onglet) seront présentées. @@ -133,9 +133,9 @@ Le **PDF est généré et ouvert** avec le lecteur PDF par défaut du système. ### Recherche d'adresse > Pour l'instant, cet outil ne fonctionne que si des données MAJIC sont dans la base, et si les données -> FANTOIR ont été importées. Si vous ne possédez pas de données FANTOIR dans votre lot de données MAJIC, +> TOPO ont été importées. Si vous ne possédez pas de données TOPO dans votre lot de données MAJIC, > vous pouvez le télécharger pour votre département ici (et relancer l'import Majic) : -> https://drive.opendata.craig.fr/s/opendata?path=%2Fadresse%2Ffantoir +> https://drive.opendata.craig.fr/s/opendata?path=%2Fadresse%2Ftopo Pour lancer une **recherche de parcelles par adresse**, il suffit :