turning a ss of Plines into a MPOLYGON - AutoLisp

turning a ss of Plines into a MPOLYGON - AutoLisp

Michiel.Valcke
Advisor Advisor
2,354 Views
12 Replies
Message 1 of 13

turning a ss of Plines into a MPOLYGON - AutoLisp

Michiel.Valcke
Advisor
Advisor

- AutoCAD MAP / CIVIL -

Excuse my inexperience in lisp, but I'm hoping one of the more wise among you might be able to help me out.

I'm working on a routine where a bunch of mpolygons with OD were imported as polylines, so that their boundaries could easily be edited and changed. 

In an other routine all those polylines are sorted in different layers based on their KEY value in the OD, from which per layer we try to turn them back into MPOLYGONS and attach the OD data from the polylines back to the MPOLYGON.

Now at a certain point in the routine we use the following code to make the MPOLYGONS

 

          (command "_mpolygon" "_S" tmpss "") ; make a mpolygon of all objects in the current ss
          (command) ; empty command to produce an ESC to quit the MPOLYGON command


The problem is that everything works well, except that if I have 3 polylines in my ss, the mpolygon command will create 3 mpolygons (with the correct 2 inner islands) instead of 1 mpolygon (with the correct 2 inner islands). And so on... depending on the number of items in my SS, that amount of mpolygons will be created, while the whole point is that only a single mpolygon is created per layer.

If you run the command manually in AutoCAD with the same items as in the ss, it works correctly and only generates a single mpolygon with the correct islands/multi-geometry.

Do you guys know of any way to avoid this, rather than trying to add a 'find and delete duplicates' to the routine. (We are talking about 2000+ mpolygons that need to be created per project)

Maybe there is an easier way to turn a ss of closed polylines into a single mpolygon with some of the vlax- commands?

I didn't find any help from the AutoLISP or ade_function catalogs.

Thank you for your time ... 

 

0 Likes
Accepted solutions (1)
2,355 Views
12 Replies
Replies (12)
Message 2 of 13

ВeekeeCZ
Consultant
Consultant

I would try to add (initcommandversion) prior to the mpolygon command. 

 

If that will not work, post something to be able to reproduce the issue. I tried but no vail. (C3D 2020)

0 Likes
Message 3 of 13

cadffm
Consultant
Consultant


Hi,


>> I'm working on a routine where a bunch of mpolygons with OD

>>except that if I have 3 polylines in my ss,
As AutoCAD-User (without the Mpolygon-Command, i have to use API programming to create Mpolygons)
i don't know (and i don't want to search for you in the forum), but i would try as first idea (test it with few import data)
Add
(command "_.ZOOM" "_object" tmpss "")
in Front of you (command "_mpolygon" .. line - just for a test.

 

 

>> (command "_mpolygon" "_S" tmpss "") ; make a mpolygon of all objects in the current ss
>> (command) ; empty command to produce an ESC to quit the MPOLYGON command

 

(command) is like [ESC], right - But why not exiting the command well (installed of cancel?).
Nothing to do with Lisp, but if you want to end the Mpolygon command,
like Line Pline and other commands too, send "nothing" - Just an <Enter> Hit
By hand [ENTER] or in Lisp (Command => ""

(command "_mpolygon" "_S" tmpss "" "") <- This works not better, but the clean way to exit the mpolygon command
and you don't need two Lisp statements.

 

Sebastian

0 Likes
Message 4 of 13

Michiel.Valcke
Advisor
Advisor

Hello,

I tried the zoom to ss, since I was not sure if the command had similarities to hatch/bpoly but alas that did not help. (Although the effect was pretty cool while running the routine on 2000+ polylines xD - I might leave it in so the user knows the computer is calculating something, instead of getting impatient if the routine takes 30+ seconds to run)

as for the exit out of the MPolygon command: I copied the line from an older different routine, where it was needed to prevent the routine from coming to a screeching halt (it used to be that the extra "" relaunched the mpolygon command instead of finishing it, or at least that is how I remember it.) I tried it again and it looks like the routine works find with the extra "" without the (command) line. Unfortunately that still creates double polygons.

0 Likes
Message 5 of 13

Michiel.Valcke
Advisor
Advisor

Hi,

Thank you for the suggestion, 

I tried the (initcommandversion) and (initcommandversion 1), but both gave a similar result. 

I have found the alternative "MAPPOLYLINETOPOLYGON" command, which works ideally when I put the items in a group. (if a group of polylines is fed to the command, the outer polyline is used as an outer boundary and the inner polylines are subtracted, creating an MPOLYGON) And because that command also automatically transfers the OD from the polylines to the mpolygons I would be able to drop a large chunk of my routine. 

Unfortunately after 2 or 3 succesful mpolygon creations the routine stops and the command bar spits out: 

"redefine it? <N>" I haven't yet been able to identify the cause.

I'll see to post my code (unfinished with a lot of commented out ideas)  and a test data set as you suggested.

I'm running the routine in MAP2021, but civil should also be able to run it.
0 Likes
Message 6 of 13

Michiel.Valcke
Advisor
Advisor

In attachment you can find my code (in progress) and a dataset I am using to test the routine.

0 Likes
Message 7 of 13

ВeekeeCZ
Consultant
Consultant

How is a KEY param related to your mpolygons? Should all plines of same key turn into 1 mpolygon?

0 Likes
Message 8 of 13

ВeekeeCZ
Consultant
Consultant

@ВeekeeCZ wrote:

How is a KEY param related to your mpolygons? Should all plines of same key turn into 1 mpolygon?


 

Ok, it seems to be the case.

The issue is definitely NOT about the mpolygon command. You can try to add (print (sslength tmpss)) prior to the command-call and you'll see how many polygons are created.

 

 

IMHO your code with multiple (ssget "X" layer)) selection is too complicated... and not correct.

I think that all you need to do is build a list like this:

'((key1 ename11 ename12 ename13 .....)

(key2 ename21 ename22)).

 

Here is a quick example.

(defun c:Test ( / lst)

  (defun :getkey (e) (cdr (assoc 62 (entget e)))) ; get color to be simple

  (if (and (setq e (car (entsel "\nPick an object to select a layer: ")))
	   (setq lp (assoc 8 (entget e)))
	   (setq x (ssget "_X" (list '(0 . "LWPOLYLINE") lp)))
	   )
    (progn
      (repeat (setq i (sslength x))
	(setq e (ssname x (setq i (1- i))))
	(setq k (:getkey e))
	(setq lst (if (setq a (assoc k lst))
		    (subst (reverse (cons e (reverse a))) a lst)
		    (cons (cons k (list e)) lst))))
      (foreach k lst
	(setq s (ssadd))
	(foreach e (cdr k) (ssadd e s))
	;(:makelayercurrent (car k)
	(command "_.mpolygon" "s" s "" ""))))
  (princ)
  )

 

 

Message 9 of 13

Michiel.Valcke
Advisor
Advisor

That is indeed a lot more efficient approach, I will try to implement that.

But I don't think that will take away the mpolygon problem. I did a test in a drawing with just 3 polylines. If I do it manually through the command bar, the mpolygon command gives me 1 polygon with 2 islands. If I take the same polylines in a ss through lisp and feed that ss to the (command "_mpolygon" "_s" ss "" "") I again get 3 separate polygons, each with two islands. It's as if the mpolygon command through lisp processes the ss an additional time for each member it has. 

I will try to implement your suggestion tomorrow. And I will let you know how it went.

0 Likes
Message 10 of 13

ВeekeeCZ
Consultant
Consultant

If you try this simple test on your pl+2 islands.. even that will fail?

 

(defun c:test ()
  (setq s (ssget))
  (command "_.mpolygon" "s" s "" "")
  )

 

 

Also try this simple test with the other one... mappoly..to.poly command.

Message 11 of 13

cadffm
Consultant
Consultant
Accepted solution

@Michiel.Valcke  schrieb:

But I don't think that will take away the mpolygon problem.

 

If I do it manually through the command bar, the mpolygon command gives me 1 polygon with 2 islands. If I take the same polylines in a ss through lisp and feed that ss to the (command "_mpolygon" "_s" ss "" "") I


Thank you for the code (and DWG), now it's easy to see the ProblemS.

 

Your statement above is wrong. You never did that - I am sure 😉

Do exactly what you wrote and it will work the same way as manually.

 

Note: I would create the code structure very different to yours,

but this wasn't the topic and so i will show the main problem only

in my DWG "testb_samples"

 

 

testb_original.dwg - Your file with your code result, this is the same result you have on your side, right?

testb_sample.dwg - Some information about your file and results

(for usual you know that all), incl. the Point of issue and solution.

One Question, can you explain me why there are so many polylines "doubled"? - Different data(OD),

but the same shape one top of the other one.

What are these different data behind - I like to understand the background.

testb_withoutCodeBug.dwg - Your file and the result of a fixed code

 

 

OT: A mix of national and international (command calls make no sense.

(command "_mpolygon" "_S" tmpss "" "") => would work in other languages,

but the program will crash before because of the english ssget param ":S"

(setq polygonpolylines (ssget ":S" '((0 . "LWPOLY... => (setq polygonpolylines (ssget "_:S" '((0 . "LWPOLY

 

Sebastian

Message 12 of 13

Michiel.Valcke
Advisor
Advisor

actually this works xD, so you're absolutely right, the problem is not with the mpolygon

I feel like such an idiot now. 

@cadffm : I did do the test, but I realize now that using a drawing with only 3 polygons and running the test from the same routine with most lines commented out is pretty idiotic and didn't actually do squat.

0 Likes
Message 13 of 13

Michiel.Valcke
Advisor
Advisor

@cadffm 

I completely missed what happened to the newlaylist.

About the data:

the polygons represent city permits (both historical and those still in use) pertaining to one or more parcels of land. There are several types of permits (20+), each with its own OD table, but all have the "KEY" parameter as a unique identifier. The dataset I used to test the routine is a small subset of the 'sv' permits

Recently on a national level the geo-referenced projection of the parcels (and also a lot of their unique identifiers) have been updated, on top of that, some have been merged, or split up. Which makes that for a lot of cities their permit database no longer correctly reflect for which parcels a permit was issued. 

A large part of these records could be updated by using queries on a database level. Unfortunately a large part still needs to be manually inspected and if necessary updated. I'm in the process of writing a few routines to help myself and the others doing this manual inspection to accelerate the process. One part of which is importing the data into AutoCAD where it is easier to bulk update / edit the geometry of a bunch of polylines rather than trying to update a bunch of GIS features. (also you find a lot more people that can execute this on a CAD level than you find people that can execute this on a GIS level)

As you can see, I'm not a programmer. The more 'lean' ways to conceptualize this routine do not come to (yet), and sometimes actually make it harder for me to follow what the code should be doing. Writing it out step by step helps me. But I think I'm learning step by step.

@cadffm  & @ВeekeeCZ 

Thank you both taking the time out to help me. I'm sure to take the things I've learned here with me in my future Autolisp endeavours.


0 Likes