llsheng_73 发表于 2013-4-1 00:09

多边形多重包含关系的分析

本帖最后由 llsheng_73 于 2015-8-24 16:52 编辑





在测绘类工作中,经常碰到上图所示的一些情况(当然一般没这么复杂),比如宗地内含岛宗,大片旱地中间有几块水田,水田中间有个水池,而一般情况下,搞测绘的都习惯于用闭合多线段来表示一个面,这就给很多统计分析等带来了麻烦。
当这种情况出现的时候,要求得它们的面积就比较头痛了,头痛就在于它们嵌套包含,所以发现一个多边形内部有几个小多边形的时候,计算它的面积就不能直接把内部多边形都减掉就了事。。。比如左边那个白色多边形,它里边有5个多边形,但计算它的面积只能减掉那两个红色的
对这个问题的我处理的思路其实很简单,先是把每一个多边形弄成一个表,第一个元素是图元名,第二个元素是包含它的图元名(只有一个,暂时叫做母图元吧),第三个元素是所包含的图元名(这可以有0到N个,所以又是一个表,就先叫它们为子图元吧)
每个图元如果里边有多形,那么就去把其母图元的子图元表中去掉现在这个图元所包含的图元(就是把母图元的孙子去掉),接下看这些多边形,它们的母图元是不是在选中的多边形内,如果在话,那它就不是子图元,而是孙子辈的,这一类的多边形也要去掉,最后剩下的就是真正能计算在内的子图元。。。
源码附最后:函数名(dzfx s)参数s是一个只有闭合多线段的选择集,为了以后使用方便
最后返回的是一个表((图元名,母图元名,(子图元名,子图元名...))),可以根据各种需要对图元进行各种处理比如计算面积的时候就可以直接用图元名的面积直接去减子图元表中的所有子图元的面积,因为它里边已经没有它的孙子们存在了
(defun plinexy(e / p i)
(setq i -1)
(mapcar(function(lambda(x)(list(car x)(cadr x))))(reverse(repeat(fix(1+(vlax-curve-getEndParam e)))
    (setq i(1+ i)p(cons(vlax-curve-getPointAtParam e i)p)))))
(if(equal(car p)(last p))(reverse(cdr(reverse p)))p)
)
(defun SStoES(s / m n e)
   (if s(progn
   (setq n(sslength s)m 0)
   (while(< m n)
   (setq e(if e(append e(list(ssname s m)))(list(ssname s m)))m(1+ m))))
   )e)
(defun dzfx(/ i ss e a b c d s1)
(repeat(length(setq i -1
                      ss(mapcar(function(lambda(x)(list x""nil)))
                             (vl-sort(SStoES(ssget"X"(list(cons 0 "LWPOLYLINE")(CONS -4 "&")'(70 . 1))))
                                     (function(lambda(a b)(>(vlax-curve-getarea a)(vlax-curve-getarea b))))))))
        (if(setq i(1+ i)e(nth i ss)
                  s1(SStoES(ssget"WP"(plinexy(car e))(list(cons 0 "LWPOLYLINE")(CONS -4 "&")'(70 . 1))))
                  f1(assoc(nth 1 e)ss))
          (progn
                (setq d(nth 2 f1))
                (foreach a s1(if(member a d)(setq b(assoc a ss)c(nth 1 b)
                                                  ss(subst(subst f c b)b ss)l 0)))
                (setq d(vl-remove-if(FUNCTION(LAMBDA(a)(member a s1)))d))
                (setq ss(subst(subst d(nth 2 f1)f1)f1 ss)l 0)))
        (setq d nil)
        (foreach a s1
          (setq b(assoc a ss)c(nth 1 b)d nil)
          (if(member c s1)(progn
                          (if c(setq b(assoc c ss)c(nth 2 b)
                                     ss(subst(subst(vl-remove a c)c b)b ss)l 0))
                          (setq d(if d(append d(list a))(list a))))
          (setq ss(subst(subst f c b)b ss))
          ))
        (setq s1(vl-remove-if(FUNCTION(LAMBDA(a)(member a d)))s1)
              ss(subst(subst s1(nth 2 e)e)e ss))
        )
)

yjtdkj 发表于 2021-6-23 12:48

Gu_xl 发表于 2013-4-1 13:06
判断两个多边形之间的关系,可利用面域来判断!
假设将两个多边形转成面域1和面域2,分别计算出面域1和面 ...

学习了,mark

flowerson 发表于 2019-7-17 00:34

嵌套比较多的会有错误。

Gu_xl 发表于 2013-4-1 13:06

判断两个多边形之间的关系,可利用面域来判断!
假设将两个多边形转成面域1和面域2,分别计算出面域1和面域2的面积S1和S2,
然后,用 面域1 union 面域2,得到新面域1,计算新面域1的面积S3,
当 S3 = S1,则多边形1包含多边形2
当S3 = S2, 则多边形2包含多边形1
当 S3< S1+S2,则多边形1和多边形2相交
当S3 = s1+S2,则 当多边形1和多边形2无交点时,相离,当当多边形1和多边形2有交点时,多边形1和多边形2为邻接关系!

328302216 发表于 2013-4-1 16:29

Gu_xl 版主出手 学习了之前也遇到过这个问题

328302216 发表于 2013-4-1 16:45

楼主程序的执行命令是哪个呢?还是这只是程序的一部分?

cxjzxh 发表于 2013-4-2 21:31

如果数据多的时候,面域会导致计算速度有点慢。

liujing95 发表于 2013-5-9 12:53

写得非常好,思路不错

soly2006 发表于 2013-10-14 13:13

没有人作完整的代吗?

llsheng_73 发表于 2013-10-18 12:51

328302216 发表于 2013-4-1 16:45 static/image/common/back.gif
楼主程序的执行命令是哪个呢?还是这只是程序的一部分?

这就是程序的一部分,你可以把它当成一个函数用到你程序中,先测试下返回的表是什么样子自己决定怎么用它就是了,如果有对返回表有什么建议请一定说出来

llsheng_73 发表于 2013-10-18 12:55

liujing95 发表于 2013-5-9 12:53 static/image/common/back.gif
写得非常好,思路不错

谢谢夸奖

liujing95 发表于 2014-4-4 18:42

加了 plinexy函数进去,怎么反回值是空呀,请问哪里出问题了
(cons 8 LDK)应该是 (cons 8 “ LDK”)吧,过滤LDK图层
页: [1] 2
查看完整版本: 多边形多重包含关系的分析