Jump to content
Developer Wiki and Function Reference Links ×

LOC criteria not reliable?


MarcelP102

Recommended Posts

I'm using the below script to let a user draw a square, name it and delete everything outside that object using LOC criteria. Unfortunately it also deletes polygon's that are within the square but it center point is outside it. That happens a lot with unregular shaped polygon, like the polygon representing multiple connected streets. I've tried everything but I'm unable to keep all the objects within the square. 

 

Basically I want it to work the same as the 2D selection tool while holding ALT.

 

Any help? See attached file for a sample project.

 

PROCEDURE DrawToDelete;

VAR
	H1, dummyH				:HANDLE; 


BEGIN
	Locus(0,0);
	dummyH := LNewObj;
	CallTool(-203);
	h1 := NextObj (dummyH);
	SetName(h1, 'MySelectionPolygon');
	DSelectAll;
	SelectObj(INSYMBOL & INOBJECT & (LOC<>'MySelectionPolygon'));
	DeleteObjs;
	DSelectAll;
	DelObject(h1);
	DelObject(dummyH);
	ReDrawAll;
END;	

 

LOCproblem.vwx

 

Something else I've tried is to call the selection tool and use that to draw a box to delete. Only thing is that I don't know a way to script the ALT pressing, is that possible?

 

PROCEDURE DrawToDelete;

    PROCEDURE DeleteThem(h :HANDLE);
    BEGIN
        DelObject(h);
    END;

BEGIN
	DSelectAll;
	CallToolWithMode(-240,3,1);
	ForEachObject(DeleteThem, SEL=FALSE);
END;	

 

Edited by MarcelP102
Link to comment

@MarcelP102 It is not that LOC is not reliable, it is just that it does not do what you want. 😉

 

As you have discovered, LOC only returns objects that have the "insertion point" (insertion point, bounding box center, maybe a few other cases) of the object within the LOC object.

 

For your case you probably are going to have to write your own function. Similar to the Maven's idea, but I would suggest checking all four points of the bounding box and the object center as well. And even that might not be enough depending on the size of your LOC object and the complexity of the objects that an are overlapping. I can certainly see cases where the corners and center of the BB would be outside the LOC but still have lines that pass through.  I don't think there is really a good option for what you want.

 

Another possibility might be to take each object and duplicate and "explode" it and then compare each of the items from the expose to the LOC. If any one of them matches then mark the unexploded version as needing to not be deleted. Then go back and delete all of the "exploded" parts. You will need to mark the exploded versions somehow either via class or by attaching a record to allow you to find them later to delete.

 

And I can imaging edge cases where even that will not be 100% correct.

 

It is a hard problem. One that your human brain can handle easily but that is very difficult for a computer algorithm to handle.

 

Basic idea:

 

Get LOC object handle and coordinates.

Compare the bounding box of every object in the drawing to the LOC coordinates. Delete those objects that don't overlap at all with the LOC.

Use the LOC to get the objects that are known to be within the LOC. Mark them somehow so you don't have to test them again. Probably by attaching a record.

For the remaining objects in the drawing, duplicate and "explode" them. This could be a Convert to Group or possibly multiple Convert to Group. You will have to consider what is needed based on your object types. Enter the group and mark all the objects for later deleting.

Compare the bounding box and center of each object to the bounding box of LOC. PtInPoly is probably the best way. If you find s point that is inside the LOC, then stop processing the rest of those exploded objects and delete them. Add the original unexploded to the Do Not Delete List. If none of the objects are within in the LOC then delete the exploded objects and the unexploded version. Repeat with every object in the drawing.

 

Because you are going to have to do a lot of comparisons, this is likely going to be a very slow process.

 

Good Luck.

 

HTH

Link to comment

Thnx, got it working for now with the script below. Will test more later.

 

PROCEDURE DrawToDelete;

VAR
	H1, dummyH				:HANDLE; 

PROCEDURE SelectThem(h :HANDLE);

	VAR
	vertX, vertY	:REAL; 
	i		      	:INTEGER;
	BOOl 			:BOOLEAN;
	
	BEGIN
		FOR i := 1 to GetVertNum(h) DO
		BEGIN
			GetPolyPt(h, i, vertX, vertY);
			BOOL := PtInPoly(vertX, vertY, h1);
			IF BOOL = TRUE THEN 
				BEGIN
				SetSelect(h);
				END;
		END;
	END;
	
PROCEDURE DeleteThem(h :HANDLE);
    BEGIN
        DelObject(h);
    END;

BEGIN
	Locus(0,0);
	dummyH := LNewObj;
	CallTool(-203);
	h1 := NextObj (dummyH);
	SetName(h1, 'MySelectionPolygon');
	DSelectAll;
	ForEachObject(SelectThem, ALL);
	ForEachObject(DeleteThem, SEL=FALSE);
	DelObject(h1);
	DelObject(dummyH);
	DSelectAll;
END;	

Run(DrawToDelete);

 

Edited by MarcelP102
  • Like 1
Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...