判断一个面(Polygon)是不是矩形

Posted by Young Ken on 2016-03-21

判断一个面是不是矩形在GIS中很长用的功能,那么怎么判断一个面是不是矩形呢。
这里先要弄懂一些概念,面是什么,先看OGC标准的定义。

我的英文水平有限,(有翻译更好的请留言,如果翻译的准确将被采纳)大概的意思就是一个面(Polygon 后面说的面都指的是Polygon)是平面的,是由1个外边界和0或者多个内边界组成,每个内边界是一个多边形的孔。
这样还是抽象啊,上个图就清醒多了。

上面三个都是面,但是有一些特殊的情况,这里就不做深入讨论了,在不同的GIS框架中也有一点点小区别。
好了我们就判断这样的面是不是矩形。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
//首先在这里声明一下,这里不是全都得代码,你要是copy肯能不能运行这里讲的是个思想也是个基本的思路,希望大家能根据我的思路写出自己的代码
public boolean isRectangle()
{
//首先判断外外环上是不是有5个点
if(outLine.getPointNum() != 5) return false;<br>     //内环的数量只能是零
if(getNumInteriorRing() != 0) return false;
     //取这个面的外包络线
Envelope envelope = getEnvelope();
     //取出外包络线的宽和高
double envelopeHeight = envelope.getHeight();
double envelopeWidth = envelope.getWidth();     
//这里为什么循环4次,因为面的定义是闭合的,闭合要求首点和末点相等,这个是GIS的知识
//这个for循环排出了一些情况。看图一
for (int i = 0 ; i < 5; i ++)
{
Coordinate coordinate = outLine.getPoint(i);
double x = coordinate.getX();
double y = coordinate.getY();
if (!(x == envelope.getMaxX() || x == envelope.getMinX()))
{
return false;
}
if(!(y == envelope.getMaxY() || y == envelope.getMinY()))
{
return false;
}
}
     //这里是本框架的特殊定义,线有外接矩形。
if (envelopeHeight == 0 || envelopeWidth == 0)
{
return true;
}
Coordinate upCoor = outLine.getPoint(0);
Coordinate nextCoor = outLine.getPoint(1);
     //因为计算机计算乘法比开方快,就选择了用乘法去进行进行
double doubleEnvelopeHeight = envelopeHeight * envelopeHeight;
double doubleEnvelopWidth = envelopeWidth * envelopeWidth;
//除了图一难道还要其他的情况<br>     
//请看图二
for (int i = 1; i < 4; i ++)
{<br>       //a^2 + b^2 这里不进行开方计算,为了效率
double length = MathUtil.distanceTwoPointNoSquare(upCoor,nextCoor);
if (length > doubleEnvelopeHeight && length > doubleEnvelopWidth)
{
return false;
}
upCoor = outLine.getPoint(i);
nextCoor = outLine.getPoint(i+1);
}
return true;
}


图一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
for (int i = 0 ; i < 5; i ++)
{
Coordinate coordinate = outLine.getPoint(i);
double x = coordinate.getX();
double y = coordinate.getY();
if (!(x == envelope.getMaxX() || x == envelope.getMinX()))
{
return false;
}
if(!(y == envelope.getMaxY() || y == envelope.getMinY()))
{
return false;
}
}

这个for选好排出了点不在外接矩形的顶点上的情况。]

图二

1
2
3
4
5
6
7
8
9
10
11
for (int i = 1; i < 4; i ++)
{
     //a^2 + b^2 这里不进行开方计算,为了效率
double length = MathUtil.distanceTwoPointNoSquare(upCoor,nextCoor);
if (length > doubleEnvelopeHeight && length > doubleEnvelopWidth)
{
return false;
}
upCoor = outLine.getPoint(i);
nextCoor = outLine.getPoint(i+1);
}

这个for循环式排出图二那种情况,每个点都在外接矩形的点上,(这里要特别的说明一下,有的GIS框架中点不能定义重复的点如最后面的三角形中最后两个点相同,大家不要有什么争议)。