IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

shapely : union de polygones


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé Avatar de awalter1
    Inscrit en
    Août 2004
    Messages
    994
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 994
    Par défaut shapely : union de polygones
    Bonjour,
    Dans mon application python 2.1.1, j'utilise la lib shapely 1.2.13.
    Je fais l'union de polygones, et j'ai une erreur. Si je fais cette union dans un autre ordre je n'ai pas d'erreur. Voici l'extrait de mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    		l_polygon = self.d_polygons.keys()
    		print "d_polygons[ l_polygon[0]]=",self.d_polygons[ l_polygon[0] ]
    		envelop = self.d_polygons[ l_polygon[0] ]
    		i = 1
    		for p in reversed(l_polygon[1:]):
    			points = self.d_polygons[ p ]
    			print "i=%d  l_polygon[i]=%s" % (i,l_polygon[i])
    			i += 1
    			envelop = envelop.union(points)
    Le résultat est ici OK
    si je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    		l_polygon = self.d_polygons.keys()
    		print "d_polygons[ l_polygon[0]]=",self.d_polygons[ l_polygon[0] ]
    		envelop = self.d_polygons[ l_polygon[0] ]
    		i = 1
    		for p in l_polygon[1:]:
    			points = self.d_polygons[ p ]
    			print "i=%d  l_polygon[i]=%s" % (i,l_polygon[i])
    			i += 1
    			envelop = envelop.union(points)
    j'ai l'erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    >linux awalter 48>: python ./HMI/holes_and_overlaps.py -u awalter -p ipas0 -s ACE2011B -d ALLSIMUL -a FCBALDB -m Y
    IPAS_ENV file used : </ipas2/opeint/IPAS/ACE2011B/IPAS/tmp/IPAS_ENV_NESU.data>
    d_polygons[ l_polygon[0]]= POLYGON ((186581.0000000000000000 23067.0000000000000000, 186621.0000000000000000 22995.0000000000000000, 186709.0000000000000000 23005.0000000000000000, 186725.0000000000000000 23003.0000000000000000, 186716.0000000000000000 23158.0000000000000000, 186727.0000000000000000 23412.0000000000000000, 186819.0000000000000000 23716.0000000000000000, 186840.0000000000000000 23805.0000000000000000, 186877.0000000000000000 23973.0000000000000000, 186920.0000000000000000 24402.0000000000000000, 186961.0000000000000000 24447.0000000000000000, 186879.0000000000000000 24756.0000000000000000, 186679.0000000000000000 25123.0000000000000000, 186177.0000000000000000 23879.0000000000000000, 186581.0000000000000000 23067.0000000000000000))
    i=1  l_polygon[i]=A039
    i=2  l_polygon[i]=A032
    ...
    i=123  l_polygon[i]=A072
    i=124  l_polygon[i]=A049B
    Traceback (most recent call last):
      File "./HMI/holes_and_overlaps.py", line 2270, in <module>
        hole_overlap = Application__(options.user, options.password, options.simulation, options.database, options.airspace, options.watch_dog, options.mmi)
      File "./HMI/holes_and_overlaps.py", line 134, in __init__
        self.I_main = Main__(self)
      File "./HMI/holes_and_overlaps.py", line 943, in __init__
        envelop = envelop.union(points)
      File "/opt/IPASTEST/lib/python2.7/site-packages/shapely/geometry/base.py", line 343, in union
        return geom_factory(self.impl['union'](self, other))
      File "/opt/IPASTEST/lib/python2.7/site-packages/shapely/topology.py", line 53, in __call__
        "This operation produced a null geometry. Reason: unknown")
    shapely.geos.TopologicalError: This operation produced a null geometry. Reason: unknown
    >
    Je n'ai pas trop d'idée pour m'en sortir si ce n'est pas déterministe.
    Merci

  2. #2
    Membre éprouvé Avatar de awalter1
    Inscrit en
    Août 2004
    Messages
    994
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 994
    Par défaut
    J'utilise la version 3.3.0 de geos.

  3. #3
    Membre Expert Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    Janvier 2009
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 792
    Par défaut
    Bonjour awalter1

    Citation Envoyé par awalter1
    si ce n'est pas déterministe.
    Dans shapely/Geos, l'union de polygones est censée être indépendante de l'ordre dans lequel on traite les polygones.

    Mais, la topologie et les opérations d'union, d'intersection, etc... est, pour ce que je connais, le domaine où on peut le plus trainer un bug pendant très longtemps et qu'il vous "pête" à la figure des mois après. La complexité des données traitées fait le reste.

    Je suis preneur des polygones qui posent problème (format shapefile / wkt / wkb / autre ...) pour y jeter un oeil

  4. #4
    Membre éprouvé Avatar de awalter1
    Inscrit en
    Août 2004
    Messages
    994
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 994
    Par défaut
    Bonjour plxpy, content de vous retrouver sur le forum.
    Dans la boucle qui fusionne mes polygones un à un, j'ai localisé le volume qui introduit le pb (à mon avis), j'ai imprimé l'enveloppe de départ et la valeur de ce polygone :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    l_polygon = self.d_polygons.keys()
    envelop = self.d_polygons[ l_polygon[0] ]
    for p in l_polygon[1:]:
    			# add the current polygon 
    			points = self.d_polygons[ p ]
    			print "envelop=",envelop
    			print "polygon = ",p
    			print points
    			try:
    				envelop = envelop.union(points)
    			except TopologicalError, err:	
    				print "err=",err
    Le résultat est le suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    envelop= MULTIPOLYGON (((186177.0000000000000000 23879.0000000000000000, 186679.0000000000000000 25123.0000000000000000, 187108.0000000000000000 25611.0000000000000000, 187443.0000000000000000 25800.0000000000000000, 187799.0000000000000000 25998.0000000000000000, 187850.0000000000000000 26030.0000000000000000, 188098.0000000000000000 26164.0000000000000000, 188060.0000000000000000 25420.0000000000000000, 187750.0000000000000000 24635.0000000000000000, 187707.0000000000000000 24769.0000000000000000, 187698.0000000000000000 24751.0000000000000000, 187627.0000000000000000 24529.0000000000000000, 187285.0000000000000000 24351.0000000000000000, 186961.0000000000000000 24447.0000000000000000, 186920.0000000000000000 24402.0000000000000000, 186877.0000000000000000 23973.0000000000000000, 186840.0000000000000000 23805.0000000000000000, 186819.0000000000000000 23716.0000000000000000, 186727.0000000000000000 23412.0000000000000000, 186716.0000000000000000 23158.0000000000000000, 186725.0000000000000000 23003.0000000000000000, 186709.0000000000000000 23005.0000000000000000, 186621.0000000000000000 22995.0000000000000000, 186581.0000000000000000 23067.0000000000000000, 186140.0000000000000000 21764.0000000000000000, 185860.0000000000000000 21973.0000000000000000, 185861.0000000000000000 22876.0000000000000000, 185906.0000000000000000 23297.0000000000000000, 186177.0000000000000000 23879.0000000000000000)), ((193200.0000000000000000 23400.0000000000000000, 198001.0000000000000000 23400.0000000000000000, 198000.0000000000000000 23115.0000000000000000, 198000.0000000000000000 22860.0000000000000000, 198000.0000000000000000 21746.0000000000000000, 198000.0000000000000000 21122.0000000000000000, 193078.0000000000000000 19813.0000000000000000, 192546.0000000000000000 19678.0000000000000000, 192600.0000000000000000 20040.0000000000000000, 192623.0000000000000000 20162.0000000000000000, 193200.0000000000000000 23400.0000000000000000)), ((190098.0000000000000000 17306.0000000000000000, 189907.0000000000000000 17336.0000000000000000, 189949.0000000000000000 17780.0000000000000000, 189997.0000000000000000 18164.0000000000000000, 190027.0000000000000000 18480.0000000000000000, 190082.0000000000000000 19023.0000000000000000, 190158.0000000000000000 19017.0000000000000000, 192535.0000000000000000 19616.0000000000000000, 192390.0000000000000000 18630.0000000000000000, 192380.0000000000000000 18580.0000000000000000, 192180.0000000000000000 17640.0000000000000000, 192120.0000000000000000 17400.0000000000000000, 192060.0000000000000000 17280.0000000000000000, 191940.0000000000000000 17160.0000000000000000, 191820.0000000000000000 17040.0000000000000000, 191790.0000000000000000 17035.0000000000000000, 191700.0000000000000000 17018.0000000000000000, 191399.0000000000000000 17098.0000000000000000, 190098.0000000000000000 17306.0000000000000000)), ((192900.0000000000000000 23701.0000000000000000, 192818.0000000000000000 23784.0000000000000000, 192682.0000000000000000 24020.0000000000000000, 192616.0000000000000000 24270.0000000000000000, 192277.0000000000000000 23790.0000000000000000, 191545.0000000000000000 22173.0000000000000000, 190084.0000000000000000 19031.0000000000000000, 190100.0000000000000000 19200.0000000000000000, 189120.0000000000000000 20040.0000000000000000, 189120.0000000000000000 22800.0000000000000000, 188734.0000000000000000 22800.0000000000000000, 188650.0000000000000000 22947.0000000000000000, 189006.0000000000000000 23789.0000000000000000, 189121.0000000000000000 24060.0000000000000000, 189143.0000000000000000 25345.0000000000000000, 189566.0000000000000000 25410.0000000000000000, 189785.0000000000000000 25430.0000000000000000, 190070.0000000000000000 25455.0000000000000000, 189950.0000000000000000 22800.0000000000000000, 190500.0000000000000000 23395.0000000000000000, 191919.0000000000000000 25494.0000000000000000, 191940.0000000000000000 25290.0000000000000000, 192011.0000000000000000 25177.0000000000000000, 192236.0000000000000000 25018.0000000000000000, 192508.0000000000000000 24709.0000000000000000, 192585.0000000000000000 24539.0000000000000000, 192599.0000000000000000 24415.0000000000000000, 192914.0000000000000000 24970.0000000000000000, 192900.0000000000000000 23701.0000000000000000)))
    polygon =  A020A
    POLYGON ((190048.0000000000000000 22906.0000000000000000, 190070.0000000000000000 25455.0000000000000000, 189950.0000000000000000 22800.0000000000000000, 190048.0000000000000000 22906.0000000000000000))
     
    envelop= MULTIPOLYGON (((186177.0000000000000000 23879.0000000000000000, 186679.0000000000000000 25123.0000000000000000, 187108.0000000000000000 25611.0000000000000000, 187443.0000000000000000 25800.0000000000000000, 187799.0000000000000000 25998.0000000000000000, 187850.0000000000000000 26030.0000000000000000, 188098.0000000000000000 26164.0000000000000000, 188060.0000000000000000 25420.0000000000000000, 187750.0000000000000000 24635.0000000000000000, 187707.0000000000000000 24769.0000000000000000, 187698.0000000000000000 24751.0000000000000000, 187627.0000000000000000 24529.0000000000000000, 187285.0000000000000000 24351.0000000000000000, 186961.0000000000000000 24447.0000000000000000, 186920.0000000000000000 24402.0000000000000000, 186877.0000000000000000 23973.0000000000000000, 186840.0000000000000000 23805.0000000000000000, 186819.0000000000000000 23716.0000000000000000, 186727.0000000000000000 23412.0000000000000000, 186716.0000000000000000 23158.0000000000000000, 186725.0000000000000000 23003.0000000000000000, 186709.0000000000000000 23005.0000000000000000, 186621.0000000000000000 22995.0000000000000000, 186581.0000000000000000 23067.0000000000000000, 186140.0000000000000000 21764.0000000000000000, 185860.0000000000000000 21973.0000000000000000, 185861.0000000000000000 22876.0000000000000000, 185906.0000000000000000 23297.0000000000000000, 186177.0000000000000000 23879.0000000000000000)), ((193200.0000000000000000 23400.0000000000000000, 198001.0000000000000000 23400.0000000000000000, 198000.0000000000000000 23115.0000000000000000, 198000.0000000000000000 22860.0000000000000000, 198000.0000000000000000 21746.0000000000000000, 198000.0000000000000000 21122.0000000000000000, 193078.0000000000000000 19813.0000000000000000, 192546.0000000000000000 19678.0000000000000000, 192600.0000000000000000 20040.0000000000000000, 192623.0000000000000000 20162.0000000000000000, 193200.0000000000000000 23400.0000000000000000)), ((190098.0000000000000000 17306.0000000000000000, 189907.0000000000000000 17336.0000000000000000, 189949.0000000000000000 17780.0000000000000000, 189997.0000000000000000 18164.0000000000000000, 190027.0000000000000000 18480.0000000000000000, 190082.0000000000000000 19023.0000000000000000, 190158.0000000000000000 19017.0000000000000000, 192535.0000000000000000 19616.0000000000000000, 192390.0000000000000000 18630.0000000000000000, 192380.0000000000000000 18580.0000000000000000, 192180.0000000000000000 17640.0000000000000000, 192120.0000000000000000 17400.0000000000000000, 192060.0000000000000000 17280.0000000000000000, 191940.0000000000000000 17160.0000000000000000, 191820.0000000000000000 17040.0000000000000000, 191790.0000000000000000 17035.0000000000000000, 191700.0000000000000000 17018.0000000000000000, 191399.0000000000000000 17098.0000000000000000, 190098.0000000000000000 17306.0000000000000000)), ((192900.0000000000000000 23701.0000000000000000, 192818.0000000000000000 23784.0000000000000000, 192682.0000000000000000 24020.0000000000000000, 192616.0000000000000000 24270.0000000000000000, 192277.0000000000000000 23790.0000000000000000, 191545.0000000000000000 22173.0000000000000000, 190084.0000000000000000 19031.0000000000000000, 190100.0000000000000000 19200.0000000000000000, 189120.0000000000000000 20040.0000000000000000, 189120.0000000000000000 22800.0000000000000000, 188734.0000000000000000 22800.0000000000000000, 188650.0000000000000000 22947.0000000000000000, 189006.0000000000000000 23789.0000000000000000, 189121.0000000000000000 24060.0000000000000000, 189143.0000000000000000 25345.0000000000000000, 189566.0000000000000000 25410.0000000000000000, 189785.0000000000000000 25430.0000000000000000, 190070.0000000000000000 25455.0000000000000000, 190048.0001584033016115 22906.0183531817456242, 190500.0000000000000000 23395.0000000000000000, 191919.0000000000000000 25494.0000000000000000, 191940.0000000000000000 25290.0000000000000000, 192011.0000000000000000 25177.0000000000000000, 192236.0000000000000000 25018.0000000000000000, 192508.0000000000000000 24709.0000000000000000, 192585.0000000000000000 24539.0000000000000000, 192599.0000000000000000 24415.0000000000000000, 192914.0000000000000000 24970.0000000000000000, 192900.0000000000000000 23701.0000000000000000)))
    Le polygone A02A est simple et "propre" (pas de chiffres après la virgule) et pourtant le résultat de cette union introduit des valeurs après la virgule. J'ai du mal à comprendre.
    Je ne sais pas si cela vous permets de tester. Sous quelle forme puis je vous soumettre mes données vous (moi je les lis à partir d'une database) ?
    Merci

  5. #5
    Membre Expert Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    Janvier 2009
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 792
    Par défaut
    Je ne pense pas qu'il y ait d'erreur sur les exemples que tu me fournis.

    4 images à la suite, dans l'ordre :

    1. l'enveloppe avant (vert) et le polygone (rouge)
    2. petit zoom sur la partie "intéressante"
    3. très fort zoom sur cette même partie
    4. même endroit dans l'enveloppe résultat







    Les coordonnées non entières que tu récupères sont celles du point d'intersection d'un segment de l'enveloppe (vert) et d'un segment du polygone (rouge) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    from shapely.geometry import LineString
    >>> segment_enveloppe = LineString(((189950.,22800.),(190500.,23395.))) 
    >>> 
    >>> segment_polygone = LineString(((190070.,25455.),(190048.,22906)))
    >>> 
    >>> segment_enveloppe.intersection(segment_polygone).wkt
    'POINT (190048.0001584033016115 22906.0183531817456242)'
    Tu retrouves les coordonnées non entières de l'enveloppe résultat.

    Si, par contre, lors des unions successives, et selon l'ordre, une exception est levée, c'est un autre problème. Pour y jeter un coup d'oeil, il me faudrait tous les polygones (le format utilisé me convient)

  6. #6
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 062
    Par défaut
    chapeau!!!

Discussions similaires

  1. Union de polygones concaves
    Par regliss76 dans le forum Algorithmes et structures de données
    Réponses: 3
    Dernier message: 05/07/2010, 13h50
  2. Intersection Line2D et Shape (voire Polygon..)
    Par GrassEh dans le forum 2D
    Réponses: 1
    Dernier message: 26/01/2010, 14h18
  3. classe héritée de system.windows.shapes.polygon
    Par eldrad95 dans le forum Windows Forms
    Réponses: 7
    Dernier message: 18/01/2010, 14h34
  4. Union de deux polygones
    Par aidos dans le forum Algorithmes et structures de données
    Réponses: 11
    Dernier message: 02/01/2007, 10h39
  5. Union de deux polygones
    Par aidos dans le forum C++
    Réponses: 4
    Dernier message: 21/12/2006, 03h15

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo