banniere

Le portail francophone de la géomatique


Toujours pas inscrit ? Mot de passe oublié ?
Nom d'utilisateur    Mot de passe              Toujours pas inscrit ?   Mot de passe oublié ?

#1 Fri 21 January 2022 13:14

janyv
Participant assidu
Lieu: Montreuil, France
Date d'inscription: 8 Feb 2006
Messages: 356

python ogr - opengeodb vers postgis

Bonjour smile

Pourriez-vous m'aider à écrire un script python permettant de transférer les classes d'entités d'une géodatabase fichier d'Esri vers un schéma d'une bdd postgres/postgis ?

J'ai commencé cet petit bout de code mais je coince sur les instructions de copie :

#!/usr/bin/python3

import sys , getopt
import os
from osgeo import ogr

def main(argv):
   dbname = ''
   schemaname = ''
   wkid = ''
   try:
       opts, args = getopt.getopt(argv,"d:s:w:",["FileGeoDB=","schema=","wkid"])
   except getopt.GetoptError:
      print ('esri2postgis.py -d <FileGeoDB> -s <schema PostGIS> -w <WKID>')
      sys.exit(2)
   for opt, arg in opts:
      if opt == '-h':
         print ('esri2postgis.py -d <FileGeoDB> -s <schema PostGIS> -w <WKID>')
         sys.exit()
      elif opt in ("-d", "--FileGeoDB"):
         dbname = arg
      elif opt in ("-s", "--schema"):
         schemaname = arg
      elif opt in ("-w", "--wkid"):
         wkid = arg

   if os.path.isdir(dbname):
      driver = ogr.GetDriverByName('OpenFileGDB')
      gdb = driver.Open(dbname)
      for featsClass_idx in range(gdb.GetLayerCount()):
         featsClass = gdb.GetLayerByIndex(featsClass_idx)
         if wkid == str(featsClass.GetSpatialRef().GetAuthorityCode(None)) :
            print (featsClass.GetName())

            ogr.UseExceptions()

            inLayerName = featsClass

            inDriver = ogr.GetDriverByName('OpenFileGDB')
            inDS = inDriver.Open(dbname, 0)
            inLayer = inDS.GetLayerByName(featsClass)

            outDriver = ogr.GetDriverByName('PostgreSQL')

# MANQUE LE CODE POUR ECRIRE DANS LE SCHEMA De la bdd PostGIS !!!

   else:
      print ("le nom de FileGeoDB fourni n'est pas un répertoire.")
      sys.exit()

if __name__ == "__main__":
   main(sys.argv[1:])


##########


Merci par avance pour votre aide smile

Bien à vous


Si tu ne sais pas demande, si tu sais partage smile

Hors ligne

 

#2 Fri 28 January 2022 16:35

janyv
Participant assidu
Lieu: Montreuil, France
Date d'inscription: 8 Feb 2006
Messages: 356

Re: python ogr - opengeodb vers postgis

Bonjour,

J'ai finalement trouvé grâce à de bonnes âmes sur Internet.

Voici une proposition de solution :

###########################################################################################
# Yvan RIOU - Janvier 2022                                                                #
# esri2postgis v 1.0                                                                      #
###########################################################################################
# script python de transfert d'une géobase fichiers esri vers une base de données PostGIS #
# paramètres :                                                                            #
# - nom de la géobasefichier en entrée                                                    #
# - SRS des classes d'entités à transférer                                                #
# - nom de la bdd postgis en sortie                                                       #
# - schéma accueillannt les classes d'éntités transférées                                 #
# - nom d'hôte ou adresse ip du serveur postgres                                          #
# - port d'écoute du serveur postgres                                                     #
# - utilisateur ayant les droits sur la bdd postgis                                       #
# - mot de passe de l'utilisateur                                                         #
###########################################################################################

import sys
import os
import argparse
from osgeo import ogr

def main(argv):

   dbname = ''
   schemaname = ''
   wkid = ''
   pGdbname = ''
   hostname = ''
   port = ''
   username = ''
   password = ''

   parser = argparse.ArgumentParser()

   parser.add_argument('-d','--filegeodb',required=True,dest='dbname',type=str)
   parser.add_argument('-w','--wkid',required=True,dest='wkid',type=str)
   parser.add_argument('-g','--postgisdb',required=True,dest='pGdbname',type=str)
   parser.add_argument('-s','--schema',required=True,dest='schemaname',type=str)
   parser.add_argument('-t','--host',required=True,dest='hostname',type=str)
   parser.add_argument('-p','--port',required=True,dest='port',type=str)
   parser.add_argument('-u','--username',required=True,dest='username',type=str)
   parser.add_argument('-r','--password',required=True,dest='password',type=str)

   args = parser.parse_args()

   dbname = args.dbname
   wkid = args.wkid
   pGdbname = args.pGdbname
   schemaname = args.schemaname
   hostname = args.hostname
   port = args.port
   username = args.username
   password = args.password

   if os.path.isdir(dbname):
      driver = ogr.GetDriverByName('OpenFileGDB')

      gdb = driver.Open(dbname)

      outDriver = ogr.GetDriverByName('PostgreSQL')
      connectionString = "PG:dbname='%s' active_schema='%s' host='%s' port='%s' user='%s' password='%s'" % (pGdbname,schemaname,hostname,port,username,password)
      try:
         outDS = ogr.Open(connectionString)
         nOutLayers = outDS.GetLayerCount()
      except:
          print('Connexion à la bdd PosgGIS impossible. Vérifiez les arguments passés.')
          exit(-3)

      for featsClass_idx in range(gdb.GetLayerCount()):
         featsClass = gdb.GetLayerByIndex(featsClass_idx)

         if wkid == str(featsClass.GetSpatialRef().GetAuthorityCode(None)) :
            nomFC = featsClass.GetName()
            nomFC = nomFC.lower()
            layerDef = featsClass.GetLayerDefn()

            for outFeatsClass_idx in range(nOutLayers):
                outFeatsClass = outDS.GetLayerByIndex(outFeatsClass_idx)
                outNomFC = outFeatsClass.GetName()
                outNomFC = outNomFC.lower()
                if outNomFC == nomFC:
                    try:
                        outDS.DeleteLayer(outNomFC)
                    except:
                        print ("Erreur de suppression")
                        exit(-1)

                    break
                del outFeatsClass

            try:
                outFeatsClass = outDS.CreateLayer(nomFC,featsClass.GetSpatialRef(),ogr.wkbUnknown,[])

                for x in range(layerDef.GetFieldCount()):
                    curFieldDefn = layerDef.GetFieldDefn(x)
                    outFeatsClass.CreateField(layerDef.GetFieldDefn(x))

                outFeatsClass.StartTransaction()
                for x in range(featsClass.GetFeatureCount()):
                    newFeat = featsClass.GetNextFeature()
                    #newFeat.setFID(-1)
                    outFeatsClass.CreateFeature(newFeat)
                    #if x % 128 == 0:
                        #outFeatsClass.CommitTransaction
                        #outFeatsClass.StartTransaction()
                outFeatsClass.CommitTransaction()

                del outFeatsClass

            except:
                print ('Erreur de création de la CE PostGIS ' + nomFC)
                exit(-2)
         del featsClass
      del outDS
      del gdb

   else:
      print ("le nom de FileGeoDB fourni n'est pas un répertoire.")
      sys.exit()

if __name__ == "__main__":
   main(sys.argv[1:])


Si tu ne sais pas demande, si tu sais partage smile

Hors ligne

 

Pied de page des forums

Powered by FluxBB