GIS开源库GEOS库学习教程(二):geos中的几何图形(Geometry)

前言

  上一节我们学过了GEOS库的介绍和环境编译及示例代码,在这一节我们将了解一下geos中的各种几何图形类,它们大部分都是从Geometry类派生的。而几何图形(Geometry)是geos里面基本的操作对象,因此Geometry类就是最重要的一个类。
  几何图形中主要有三个要素:点,线,面。横纵坐标构成点,多个点构成线,环线构成面,点线面混合构成几何集合。GEOS库中对应的几个类为:

  • 坐标:Coordinate
  • 点:Point、MultiPoint
  • 线:LineString、MultiLineString(多条线)、LinearRing(环线)
  • 面:Polygon、MultiPolygon
  • 集合:GeometryCollection

  在geos中,最小的组成单位是坐标,由Coordinate类来创建,如:Coordinate(2,3),表示一个点,横坐标是2,纵坐标是3,其中所有的几何图形的创建,都是由类GeometryFactory来完成。因此,在创建几何图形前,可以先创建一个全局的GeometryFactory对象;

GeometryFactory g_factory; //全局对象,所有的图形都由此对象创建

1、坐标-Coordinate

  Coordinate类是用于存储坐标的轻量级类。它与Point不同,Point是Geometry的一个子类。
与Point类型的对象不同,Point类型的对象包含附加的诸如包络线、精度模型和空间等
参考系统信息,一个Coordinate只包含纵坐标值和访问方法。Coordinate对象是带有附加的二维点z-ordinate。
  从类的说明我们可以看出,Coordinate是比较特殊的一个类,它不从Geometry类派生的。

Coordinate(double xNew=0.0, double yNew=0.0, double zNew=DoubleNotANumber);

2、点-Point / MultiPoint

  point类比较特殊,相比于Coordinate类,Coordinate类更像我们理解的点对象。point类不能通过x,y坐标值来进行初始化,它只能通过Coordinate类来进行创建。

Point* createGeosPoint(double x, double y)
{
    
    
	Coordinate coordt(x, y);
	Point* pt = g_factory.createPoint(coordt);
	return pt;
}

MultiPoint* createGeosMultiPoint()
{
    
    
	double x, double y;
	Coordinate coordt1(x, y);
	Coordinate coordt2(x+1, y+1);

	std::vector<Coordinate> vecCoords;
	vecCoords.push_back(coordt1);
	vecCoords.push_back(coordt2);

	MultiPoint* mPt = g_factory.createMultiPoint(vecCoords);
	return mPt;
}

3、线-LineString / MultiLineString / LinearRing

  GeoJSON中MulitLineString类型与LineString类型的主要区别如下:

  • 1)一个MultiLineString要素中可以包含一条或多条互不相连的线段,这些线段被当做同一个要素,共享同一份属性信息。一个LineString类型的要素中只能包含一条线段,属性信息被这条线段所独享;

  • 2)当有多条相邻的属性信息相同的线段时,使用MultiLineString类型,只要一个要素(数据库中的一条记录)即可表示,而使用LineString类型,却需要创建多个要素。因此,不难发现MultiLineString类型更节省存储空间;

  • 3)GeoJSON文件中,LineString类要素的coordinates属性用二维数组表示,而MultiLineString类要素用三维数组表示;

  • 4)常用的shp格式的矢量文件中线要素用Polyline类型表示,并不严格区分LineString与MultiLineString。

{
    "type": "Feature",
    "geometry": {
        "type": "MultiLineString",
        "coordinates": [
            [
                [119.283461766823521,35.113845473433457],
                [119.285033114198498,35.11405167501087]
            ],
            [
                [119.186893667167482,34.88690637041627],
                [119.186947247282234,34.890273599368562]
            ]
        ]
    }
}
{ 
    "type": "Feature",
    "geometry": {
        "type": "LineString",
        "coordinates": [
            [119.207185494071,34.9298513918505],
            [119.207555586034,34.9294932576001]
        ]
    }
}
LineString* createGeosLine(double x,double y, double offset)
{
    
    
    CoordinateArraySequence *cas=new CoordinateArraySequence(); //构建点序列
    cas->add(Coordinate(x,y));
    cas->add(Coordinate(x,y+offset));
    cas->add(Coordinate(x+offset,y+offset));
    cas->add(Coordinate(x+offset,y+2*offset));
    cas->add(Coordinate(x+2*offset,y+2*offset));
    LineString *ls = g_factory.createLineString(cas);
    return ls;
}

//创建一条环线,与线的区别就是环线是闭合的。即第一个点和最后一点重合
LinearRing* createGeosRing(double x,double y,double offset)
{
    
    
    CoordinateArraySequence *cas=new CoordinateArraySequence(); //构建点序列
    cas->add(Coordinate(x,y));
    cas->add(Coordinate(x,y+offset));
    cas->add(Coordinate(x+offset,y+offset));
    cas->add(Coordinate(x+offset,y+2*offset));
    cas->add(Coordinate(x+2*offset,y+2*offset));
    cas->add(Coordinate(x+2*offset,y));
    cas->add(Coordinate(x,y)); //与第一个点相等
    LinearRing *lr = g_factory.createLinearRing(cas);
    return lr;
}

4、面-Polygon / MultiPolygon

//创建一个多边形,如果多边形内部没有孔洞实际上与环线是一样的
Polygon* createGeosPolygon(double x,double y,double offset)
{
    
    
    LinearRing *lr = createGeosRing(x,y,offset);
    Polygon *poly = g_factory.createPolygon(lr,NULL); //如果多边形中间没有孔洞,第二个参数设为NULL
    return poly;
}

猜你喜欢

转载自blog.csdn.net/m0_37251750/article/details/129773252