Postgis关于Point类型的一些查询操作

本文详细介绍如何使用PostGIS进行点类型的创建与查询操作,包括多种创建点的方式、坐标系设置、坐标读取及转换等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文着重介绍Point类型的查询操作,以下操作均为二维,不讨论三维数据。

  • 创建点

      点的WKT表述如POINT(116.39088 39.90763),在Postgis中创建一个点几个方式:

ST_Point、ST_MakePoint:

--用法:ST_Point(float x_lon, float y_lat);
--输出:0101000000452A8C2D04195D402A6F47382DF44340
SELECT ST_Point(116.39088,39.90763)

      上面虽然创建了点,但是SRID却是0(unknown),可以通过ST_SRID查看。下面方式设置坐标系为4326:

--用法:ST_Point(float x_lon, float y_lat);
--输出:0101000020E6100000452A8C2D04195D402A6F47382DF44340
SELECT ST_SetSRID(ST_Point(116.39088,39.90763),4326)

      坐标顺序是经度(或x)在前,纬度(或y)在后。ST_MakePoint和ST_Point一样,ST_MakePoint可以快速高效的创建一个点。

ST_GeometryFromText、ST_PointFromText:

--用法1:geometry ST_GeometryFromText(text WKT);
--用法2:geometry ST_GeometryFromText(text WKT, integer srid);
--输出:0101000020E6100000452A8C2D04195D402A6F47382DF44340
SELECT ST_GeomFromText('POINT(116.39088 39.90763)',4326);

      ST_GeometryFromText和ST_GeomFromText一样,根据WKT描述的对象返回一个具体的geometry对象,WKT可以是POLYGON、MULTIPOLYGON、LINESTRING等。在这里它是一个点。如果要指明创建一个点,可以用ST_PointFromText:

--用法1:geometry ST_PointFromText(text WKT);
--用法2:geometry ST_PointFromText(text WKT, integer srid);
--输出:0101000020E6100000452A8C2D04195D402A6F47382DF44340
SELECT ST_PointFromText('POINT(116.39088 39.90763)',4326);

      未指定srid时,创建的geomtry默认的srid是0。

ST_GeomFromGML、ST_GMLToSQL:

--geometry ST_GeomFromGML(text geomgml);
--geometry ST_GeomFromGML(text geomgml, integer srid);
--输出:0101000020E6100000452A8C2D04195D402A6F47382DF44340
SELECT ST_GeomFromGML('
    <gml:Point srsName="EPSG:4326">
    	<gml:coordinates>116.39088,39.90763</gml:coordinates>
    </gml:Point>
');

      属性srsName会被读取。也可以在参数中指定srid:

SELECT ST_GeomFromGML('
    <gml:Point>
	<gml:coordinates>116.39088,39.90763</gml:coordinates>
    </gml:Point>
',4326);

     ST_GeomFromGML参数geomgml只能是GML的geometry部分,不是整个GML文档。目前支持 GML 2.1.2、 3.1.1、 3.2.1等版本。ST_GMLToSQL是ST_GeomFromGML的别名,用法一样:

--输出:0101000020E6100000452A8C2D04195D402A6F47382DF44340
SELECT ST_GMLToSQL('
    <gml:Point>
	<gml:coordinates>116.39088,39.90763</gml:coordinates>
    </gml:Point>
',4326);

ST_GeomFromGeoJSON:

--geometry ST_GeomFromGeoJSON(text geomjson);
--输出:0101000020E6100000452A8C2D04195D402A6F47382DF44340
SELECT ST_SetSRID(ST_GeomFromGeoJSON('{
    "type":"Point",
    "coordinates":[116.39088,39.90763]
}'),4326);

      与ST_GeomFromGML一致,参数geomjson只能是geometry描述。ST_GeomFromGeoJSON没有srid参数,而标准GeoJSON geometry对象中不含坐标系,所以需要ST_SetSRID用设置坐标系。 

ST_GeomFromKML:

--geometry ST_GeomFromKML(text geomkml);
--输出:0101000020E6100000452A8C2D04195D402A6F47382DF44340
SELECT ST_SetSRID(ST_GeomFromKML('
    <Point>
        <coordinates>116.39088,39.90763</coordinates>
    </Point>
'),4326);

      和ST_GeomFromGeoJSON一致,参数geomkml只能是geometry描述。ST_GeomFromGeoJSON没有srid参数,所以需要ST_SetSRID用设置坐标系。

      其他还有一些二进制、EWKT的读取类似,这里不做介绍。

  • 输出

ST_X、ST_Y、ST_Z等:

--float ST_X(geometry a_point);
--输出:116.39088
SELECT ST_X(ST_GeomFromText('POINT(116.39088 39.90763)',4326));
--输出:Null
SELECT ST_Z(ST_GeomFromText('POINT(116.39088 39.90763)',4326));

      a_point是一个POINT对象,ST_X输出X坐标。

GeometryType:

--text GeometryType(geometry geomA);
--输出:POINT
SELECT GeometryType(ST_GeomFromText('POINT(116.39088 39.90763)',4326));
ST_GeometryType:
--text ST_GeometryType(geometry g1);
--输出:ST_Point
SELECT ST_GeometryType(ST_GeomFromText('POINT(116.39088 39.90763)',4326));

ST_FlipCoordinates交换X和Y坐标:

--geometry ST_FlipCoordinates(geometry geom);
--输出:POINT(39.90763 116.39088)
SELECT ST_AsText(ST_FlipCoordinates(ST_GeomFromText('POINT(116.39088 39.90763)',4326)))
--输出:POINT ZM (39.90763 116.39088 3 6)
SELECT ST_AsText(ST_FlipCoordinates(ST_GeomFromText('POINT(116.39088 39.90763 3 6)',4326)))

      除了POINT外,还支持其他的LINESTRING等。

ST_Transform坐标转换:

--4326转4490。4326与4490都是地理坐标系,坐标系差异很小,所以转出的该点差别小
--输出:POINT(116.39088 39.90763)
-- SELECT ST_AsText(ST_Transform(ST_GeomFromText('POINT(116.39088 39.90763)',4326),4490))

--4326转3857。投影
--输出:POINT(12956573.494581 4852528.38789462)
SELECT ST_AsText(ST_Transform(ST_GeomFromText('POINT(116.39088 39.90763)',4326),3857))

其他

--输出:{"type":"Point","coordinates":[116.39088,39.90763]}
SELECT ST_AsGeoJSON(ST_GeomFromText('POINT(116.39088 39.90763)',4326));

--输出:<Point><coordinates>116.39088,39.907629999999997</coordinates></Point>
SELECT ST_AsKML(ST_GeomFromText('POINT(116.39088 39.90763)',4326));

--输出:<gml:Point srsName="EPSG:4326"><gml:coordinates>116.39088,39.907629999999997</gml:coordinates></gml:Point>
SELECT ST_AsGML(ST_GeomFromText('POINT(116.39088 39.90763)',4326));

--输出:POINT(116.39088 39.90763)
SELECT ST_AsText(ST_GeomFromText('POINT(116.39088 39.90763)',4326));

--integer ST_CoordDim(geometry geomA);
--输出:2
SELECT ST_CoordDim(ST_GeomFromText('POINT(116.39088 39.90763)',4326));
以上就是一些关于POINT的WKT操作。



<think>好的,用户想了解PostGIS中的数据类型支持与用法,我需要结合之前的回答和提供的引用内容来整理一个清晰的回答。首先,用户之前的问题是关于ST_开头的函数与其他函数的对比,现在向数据类型,我需要确保覆盖主要的数据类型,比如geometry和geography,还有栅格数据。 根据引用1,geometry类型的信息存储在geometry_columns表中,遵循OGC规范,用户在创建时会自动维护这个表。应该提到这一点,说明如何查看和管理geometry类型。 引用2提到了在MyBatis中使用TypeHandler处理PostGIS数据类型,特别是如何换WKT格式。这可能和用户的实际应用相关,但用户现在的问题更偏向理论,所以可能需要简要提到如何与应用程序交互,比如通过WKT或WKB。 引用3讨论了geography类型换为geometry来使用ST_X函数,这说明两种类型的区别和使用场景,比如地理坐标系和平面坐标系的差异,以及何时需要换。 引用4提到了栅格数据,虽然引用不完整,但需要补充PostGIS的栅格支持,比如raster类型和相关函数。 接下来,我需要组织数据类型部分,可能分为几何、地理、栅格,以及复合类型如GeometryCollection。还要对比geometry和geography的不同,比如计算距离时的不同方法,以及空间函数的支持情况。 另外,用户可能想知道如何创建这些类型的字段,比如建表语句,以及如何插入数据,比如使用ST_GeomFromText等函数。引用1中的geometry_columns表需要解释,确保用户知道如何查询现有空间表的信息。 还要注意常见问题,比如选择geometry还是geography,可能的应用场景,比如地理分析使用geography,而平面地图使用geometry。同时,栅格数据的应用场景,如遥感或高程数据存储。 需要确保回答结构清晰,分点说明,并给出示例SQL语句,帮助用户理解如何实际操作。比如创建表、插入数据、查询等步骤,以及如何类型。 最后,相关问题部分要引导用户深入,比如性能优化、类型换的影响,以及空间索引的应用。这些问题可以帮助用户进一步学习,解决实际中可能遇到的问题。</think>### PostGIS数据类型详解及使用指南 --- #### 一、核心数据类型分类 PostGIS支持**几何(Geometry)**、**地理(Geography)**和**栅格(Raster)**三大类空间数据类型,满足不同的空间计算需求。 1. **几何类型(Geometry)** - **定义**:基于平面坐标系(如Web墨卡托),用于二维平面空间计算 - **适用场景**:地图可视化、工程测量、平面分析(如$ST\_Area$计算平面面积) - **子类型**: - 点(`POINT`)、线(`LINESTRING`)、面(`POLYGON`) - 集合类型(`MULTIPOINT`, `GEOMETRYCOLLECTION`等) - **元数据管理**:通过`geometry_columns`表自动记录所有几何字段的坐标系(SRID)、几何类型等信息[^1] ```sql -- 查看所有几何字段定义 SELECT * FROM geometry_columns; ``` 2. **地理类型(Geography)** - **定义**:基于地理坐标系(如WGS84),支持球面距离计算(如$ST\_Distance$返回米制单位) - **适用场景**:地球表面距离/面积计算(如计算两个城市间的实际距离) - **限制**:部分几何函数需先换为Geometry类型[^3] ```sql -- 地理类型几何后提取坐标 SELECT ST_X(geog::geometry) AS longitude FROM city; ``` 3. **栅格类型(Raster)** - **定义**:存储像元矩阵数据(如卫星影像、高程模型) - **功能支持**:波段运算、栅格代数、与矢量数据叠加分析[^4] - **典型函数**:`ST_Intersects`(栅矢叠加分析)、`ST_Clip`(按几何裁剪栅格) --- #### 二、数据类型选择对比 | 特征 | Geometry | Geography | Raster | |---------------|----------------------|----------------------|---------------------| | **坐标系** | 平面坐标系(SRID) | 地理坐标系(SRID=4326) | 任意坐标系 | | **计算方式** | 平面几何计算 | 球面地理计算 | 像元矩阵运算 | | **性能** | 高(适合局部地图) | 低(需球面计算) | 中等(依赖数据量) | | **典型函数** | `ST_Area`, `ST_Length` | `ST_Distance` | `ST_Union`, `ST_Reclass` | --- #### 三、数据类型操作实践 1. **创建空间表** ```sql -- 创建包含几何字段的表 CREATE TABLE roads ( id SERIAL PRIMARY KEY, name VARCHAR(64), geom GEOMETRY(LINESTRING, 3857) -- 指定类型和坐标系 ); ``` 2. **数据插入方法** - **WKT格式**(人类可读): ```sql INSERT INTO roads (geom) VALUES (ST_GeomFromText('LINESTRING(0 0, 10 10)', 3857)); ``` - **WKB格式**(二进制高效): ```sql INSERT INTO roads (geom) VALUES (ST_GeomFromEWKB(E'\\x0010...')); ``` 3. **类型换** - **隐式换**:部分函数自动处理类型换 ```sql SELECT ST_Distance(geom::geography, target_geog) FROM points; ``` - **显式换**:使用`::`操作符或换函数 ```sql SELECT ST_AsText(geom) FROM (SELECT geog::geometry AS geom FROM cities) t; ``` --- #### 四、应用开发集成 1. **Java类型映射** - **实体类设计**:使用`org.postgis.Geometry`类型或自定义类型处理器[^2] ```java public class Road { private PGgeometry geom; // PostGIS几何对象 // WKT格式换方法 public String getGeomAsWKT() { return geom.getGeometry().toWKT(); } } ``` 2. **空间索引** - 使用`CREATE INDEX`加速空间查询: ```sql CREATE INDEX roads_geom_gist ON roads USING GIST (geom); ``` --- #### 五、常见问题解答 **Q1: 何时选择Geometry/Geography?** - 需要球面距离计算(如GPS轨迹分析)→ Geography - 平面地图可视化或局部区域分析→ Geometry **Q2: 如何解决函数不兼容问题?** - 使用显式类型换:`geog::geometry` - 检查函数文档(如`ST_Distance`支持两种类型但计算结果不同) --- ### 流程图:数据类型选择决策 ```mermaid graph TD A[是否需要处理地球表面距离/面积?] -->|是| B[使用Geography类型] A -->|否| C{是否涉及栅格分析?} C -->|是| D[使用Raster类型] C -->|否| E[使用Geometry类型] ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值