Aller au contenu

Detection de polygones dans polygones


lecrabe

Messages recommandés

 

Hello

 

SVP je desire une routine qui permette la selection de polylignes 2D closes (+ MPOLYGON de MAP si possible) par rapport a d'autres polylignes 2D closes (+ MPOLYGON si possible) !

 

Sous entendu par exemple : je selectionne un ensemble de polylignes 2D closes (+ MPOLYGON de MAP si possible) provenant du calque PARCELLE, que je desire croiser avec les polylignes 2D closes (+ MPOLYGON de MAP si possible) du calque BATIMENT !

 

Resultat un simple selection en sortie, ainsi je pourrais trouver ou compter facilement ou transferer sur un autre calque, les PARCELLEs qui contiennent AU MOINS UN Batiment !

ou celle qui ne contiennent PAS de BATIMENT

 

Donc une petite question au depart pour la selection resultante : polygones "vides" (Parcelles SANS Batiment) ou polygones "remplis" (Parcelles AVEC au moins un Batiment).

 

Ceci est possible sous MAP (ou CIVIL) avec les fonctions topologiques mais c "tres complique" et en plus il faut decomposer (sous entendu perdre) les polylignes closes ou MPolygons pour generer des topologies de type polygones puis croiser subtilement les topologies et jouer avec les donnees d'objets + requetes, etc. EN resume = la galere !

 

Merci d'avance de votre aide, Le Decapode

 

Autodesk Expert Elite Team

Lien vers le commentaire
Partager sur d’autres sites

 

Hello Fab

 

En effet c des fonctions assurées par tout bon logiciel de SIG (Croisement de couches polygonales) mais MAP (ou CIVIL) ne sait pas du tout réaliser ceci "simplement" !

 

Sélection d'objets de type Polylignes 2D closes, Cercles (j'avais oublié ! :o )

et aussi si possible des fameux Mpolygons de MAP (ou CIVIL)

 

pour obtenir en sortie une nouvelle sélection donnant tous ces objets "englobants" qui contiennent ou PAS d'autres objets de même type voire même pourquoi pas aussi de blocs/symboles !! :)

 

Pour des raisons de simplicité, on supposera qu'il n'y a PAS d'imbrication des Polygones, Cercles, Mpolygons

 

Le Decapode

 

Autodesk Expert Elite Team

Lien vers le commentaire
Partager sur d’autres sites

Salut,

 

Voilà une ébauche, on peut certainement faire plus élaboré (boite dialogue, choix des objets à rechercher, contenu des mpolygons ...) mais ça demanderait beaucoup plus de temps et de courage que je n'en ai actuellement.

 

Le LISP sélectionne les polylignes closes sur le calque "contenant" qui contiennent des objets (polylignes closes, cercles, mpolygons) sur le calque "contenu".

 

(defun c:toto (/ lay1 lay2 ss n pl elst ang inc cen rad)
 (vl-load-com)
 (or *acdoc*
     (setq *acdoc* (vla-get-ActiveDocument (vlax-get-acad-object)))
 )
 (if
   (and
     (setq lay1
     (car
       (entsel
	 "\nSélectionnez un objet sur le calque \"contenant\": "
       )
     )
     )
     (setq lay1 (assoc 8 (entget lay1)))
     (setq lay2
     (car (entsel
	    "\nSélectionnez un objet sur le calque \"contenu\": "
	  )
     )
     )
     (setq lay2 (assoc 8 (entget lay2)))
     (setq ss
     (ssget "_X"
	    (list
	      '(-4 . "[b]		      '(0 . "CIRCLE")
	      '(-4 . "[b]		      '(0 . "LWPOLYLINE")
	      '(-4 . "&")
	      '(70 . 1)
	      '(-4 . "AND>")
	      '(-4 . "OR>")
	      lay1
	    )
     )
     )
     (setq n 0)
     (setq ss2 (ssadd))
   )
    (progn
      (vla-Zoomextents (vlax-get-acad-object))
      (while (setq pl (ssname ss n))
 (setq elst (entget pl)
       n (1+ n))
 (if (= (cdr (assoc 0 elst)) "LWPOLYLINE")
   (setq plst (mapcar 'cdr
		      (vl-remove-if-not
			'(lambda (x) (= (car x) 10))
			(entget pl)
		      )
	      )
   )
   (progn
     (setq ang 0.0
	   inc (/ pi 30)
	   cen (cdr (assoc 10 elst))
	   rad (cdr (assoc 40 elst))
	   plst nil
     )
     (repeat 60
       (setq plst
	      (cons (polar cen (setq inc (+ inc (/ pi 30))) rad)
		    plst
	      )
       )
     )
   )
 )
 (if (ssget "_WP"
	    plst
	    (list
	      '(-4 . "[b]		      '(0 . "POINT,CIRCLE,INSERT,MPOLYGON")
	      '(-4 . "[b]		      '(0 . "LWPOLYLINE")
	      '(-4 . "&")
	      '(70 . 1)
	      '(-4 . "AND>")
	      '(-4 . "OR>")
	      lay2
	    )
     )
   (ssadd pl ss2)
 )
      )
      (vla-ZoomPrevious (vlax-get-acad-object))
    )
 )
 (sssetfirst nil ss2)
 (princ)
) 

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

 

Hello Gilles

 

1er test sous MAP 2008 avec seulement des polylignes closes de parcelles et batiments :

(chacunes sur leurs propres calques et AUCUNE imbrication)

 

Cela semble OK mais la selection des polylignes "contenantes" ne concerne que le rectangle de l'ecran graphique et non pas tous les objets réellement concernés ! :o

 

SI je zoome aux limites alors cela semble presque OK car il manque qq polylignes de parcelles avec batiments !

 

C curieux la qualité du résultat semble dépendre du niveau de zoom !

 

Le Decapode "qui continue à tester"

 

 

Autodesk Expert Elite Team

Lien vers le commentaire
Partager sur d’autres sites

 

ReHello

 

A propos de ta routine, je la trouve très bien comme elle est actuellement dans son principe !

Inutile d'inclure des cases de dialogue sophistiquées ;)

 

Je suis impressionné par sa "petite" taille !!! :) :D

 

Qq améliorations : :P

 

- ajouter les cercles aux objets du calque "contenant"

Je comprend qu'une interprétation des MPOLYGONs serait "compliqué", donc tant pis !

 

- ajouter les Points ET les Blocs aux objets du calque "contenu"

 

Je pense que ca rendrait bien des services à beaucoup de gens dans le monde du SIG / Cadastre / Urba / VRD / etc

 

Par exemple :

- trouver les parcelles avec/sans batiments ou piscines

- trouver les parcelles avec/sans Poteaux EDF/PTT/Incendie ou Regard (Clin d'oeil à Fabcad)

- trouver les pieces d'un batiment avec/sans Extincteurs

etc

 

Même si il reste des choses à faire à la main APRES sur les cas particuliers

Les MPOLYGONS seront traités "manuellement" et "visuellement" comme avant ...

 

Le Decapode (sous la neige dans les environs de St-Etienne)

 

 

Autodesk Expert Elite Team

Lien vers le commentaire
Partager sur d’autres sites

Hello

 

; erreur: cdrs supplémentaire dans la paire pointée en entrée

 

Voile le resultat du dernier copier/coller de ta routine

 

Le Decapode

 

Oui c'est toujours ce problème avec les

 

J'ai modifé le code, les cercles peuvent être contenants. les contenus des points, blocs, cercles, polylignes, mpolygons.

Ça demande une bonne gestion des calques pour être efficace.

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

 

Hello

 

Suite de mes tests, les polylignes qui contiennent des arcs de cercles ne semblent pas "toujours" traitees correctement !

 

Ce qui me semble peut être NORMAL et donc j'utilise une autre excellente routine de notre indispensable Gilles : ARC2SEG pour polygoniser mes Arcs dans les polylignes ... :P

 

Par contre, pour être sur de ne pas louper une quelconque polyligne 2D avec Arc ou Polyligne 2D lissée, est-il possible d'avoir un simple Lisp qui détecte/sélectionne les polylignes ayant au moins un Arc dans leur Contour ou lissée ?

 

Le Decapode "bien content quand même" :cool:

 

 

Autodesk Expert Elite Team

Lien vers le commentaire
Partager sur d’autres sites

Salut,

 

Voilà une nouvelle version qui devrait fonctionner avec les polylignes avec arcs, comme au départ il était question de polygones, je pensais éviter le traitement des arcs qui devrait sensiblement ralentir le processus sur des gros fichiers.

Cette version utilise la routine SelByObj qu'on trouve dans Spécial_sélections sur cette page (et qui doit être chargée, bien sûr).

 

(defun c:toto (/ lay1 lay2 ss n pl ss2)
 (vl-load-com)
 (or *acdoc*
     (setq *acdoc* (vla-get-ActiveDocument (vlax-get-acad-object)))
 )
 (if
   (and
     (setq lay1
     (car
       (entsel
	 "\nSélectionnez un objet sur le calque \"contenant\": "
       )
     )
     )
     (setq lay1 (assoc 8 (entget lay1)))
     (setq lay2
     (car (entsel
	    "\nSélectionnez un objet sur le calque \"contenu\": "
	  )
     )
     )
     (setq lay2 (assoc 8 (entget lay2)))
     (setq ss
     (ssget "_X"
	    (list
	      '(-4 . "[b]		      '(0 . "CIRCLE")
	      '(-4 . "[b]		      '(0 . "LWPOLYLINE")
	      '(-4 . "&")
	      '(70 . 1)
	      '(-4 . "AND>")
	      '(-4 . "OR>")
	      lay1
	    )
     )
     )
     (setq n 0)
     (setq ss2 (ssadd))
   )
    (progn
      (while (setq pl (ssname ss n))
 (if (SelByObj pl
	       "WP"
	       (list
		 '(-4 . "[b]			 '(0 . "POINT,CIRCLE,INSERT,MPOLYGON")
		 '(-4 . "[b]			 '(0 . "LWPOLYLINE")
		 '(-4 . "&")
		 '(70 . 1)
		 '(-4 . "AND>")
		 '(-4 . "OR>")
		 lay2
	       )
     )
   (ssadd pl ss2)
 )
 (setq n (1+ n))
      )
    )
 )
 (sssetfirst nil ss2)
 (princ)
) 

 

Pour les polylignes 2d (lissées ou splinées) je propose le LISP 2D2LW qui les convertit en polylignes optimisées (LWPOLYLINE).

 

;; 2D2LW (gile)
;; Convertit les polylignes 2d (old style) en polylignes optimisées
;; Traite les polylignes lissées ou splinées

(defun c:2d2lw (/ f n s p)
 (and
   (setq f '((0 . "POLYLINE")
      (-4 . "[b]	      (-4 . "&")
      (70 . 120)
      (-4 . "NOT>")
     )
  n 0
   )
   (princ "\nSélectionnez les polylignes ou : ")
   (or (setq s (ssget f)) (setq s (ssget "_X" f)))
   (while (setq p (ssname s n))
     (OldStyle2LwPolyline p)
     (setq n (1+ n)
     )
   )
 )
 (princ)
)

;; OldStyle2LwPolyline
;; Remplace une polyligne 2d par une polyligne optimisée
;;
;; Argument : polyligne 2d (ename)
;; Retour : polyligne optimisée (ename)

(defun OldStyle2LwPolyline (pl / plst xdata vtx vlst elst)
 (setq	plst  (entget pl '("*"))
xdata (assoc -3 plst)
vtx   (entnext pl)
 )
 (while (= (cdr (assoc 0 (setq vlst (entget vtx)))) "VERTEX")
   (if	(zerop (logand (cdr (assoc 70 vlst)) 16))
     (setq elst (cons (vl-remove-if-not
		 (function
		   (lambda (x)
		     (member (car x) '(10 40 41 42))
		   )
		 )
		 vlst
	       )
	       elst
	 )
     )
   )
   (setq vtx (entnext vtx))
 )
 (if (setq new
     (entmakex
       (append
	 (list
	   '(0 . "LWPOLYLINE")
	   '(100 . "AcDbEntity")
	   (assoc 410 plst)
	   (assoc 8 plst)
	   (cond
	     ((assoc 39 plst))
	     (T '(39 . 0))
	   )
	   '(100 . "AcDbPolyline")
	   (cons 90 (length elst))
	   (cons 70 (logand 129 (cdr (assoc 70 plst))))
	   (cons 38 (last (caar elst)))
	   (assoc 210 plst)
	 )
	 (apply 'append (reverse elst))
	 (if xdata
	   (list xdata)
	 )
       )
     )
     )
   (entdel pl)
 )
 new
) 

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

Créer un compte ou se connecter pour commenter

Vous devez être membre afin de pouvoir déposer un commentaire

Créer un compte

Créez un compte sur notre communauté. C’est facile !

Créer un nouveau compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant
×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer. Politique de confidentialité