我的GIS/CS学习笔记:https://github.com/yunwei37/ZJU-CS-GIS-ClassNotes
<一个浙江大学本科生的计算机、地理信息科学知识库 >
SQL (stands for Structured Query Language)
Current standard is SQL-2016
内容:
特点:综合统一、高度非过程化、面向集合的操作方式、以同一种语法结构提供两种使用方式、语言简捷,易学易用
定义功能包括:
定义基本表
CREATE TABLE <表名>
(<列名> <数据类型>[ <列级完整性约束条件> ]
[,<列名> <数据类型>[ <列级完整性约束条件>] ] …
[,<表级完整性约束条件> ] );
创建Students\Enrolled关系
CREATE TABLE Students (
sid CHAR(10) PRIMARY KEY,
name VARCHAR(20) NOT NULL,
age INT CHECK(age > 0));
CREATE TABLE Enrolled (
student_id CHAR(10) REFERENCES Students(sid),
cid CHAR(20),
grade INT,
PRIMARY KEY(student_id, cid));
修改和删除表
ALTER TABLE <表名>
[ ADD <新列名> <数据类型> [ 完整性约束 ] ]
[ DROP <完整性约束名> ]
[ MODIFY <列名> <数据类型> ]
DROP TABLE <表名>
举例:
ALTER TABLE Students ADD Scome DATE;
ALTER TABLE Students ALTER COLUMN Scome type timestamp;
ALTER TABLE Students DROP Scome;
ALTER TABLE Enrolled ADD CONSTRAINT grade_check
ALTER TABLE Enrolled DROP CONSTRAINT pk_En;
DROP TABLE Students;
数据插入
INSERT
INTO <表名> [(<属性列1>[,<属性列2 >] … )]
VALUES (<常量1> [,<常量2>] … )
将新元组插入指定表中:
Insert into Students Values(‘200011’, ‘张三’, 19);
Insert into Students(sid, age, name)
Values(‘200012’, 20, ‘李四’);
Insert into Students(sid, name)
Values(‘200013’, ‘王五’);
数据修改
UPDATE <表名>
SET <列名>=<表达式>[,<列名>=<表达式>]…
[WHERE <条件>]
修改指定表中满足WHERE子句条件的元组:
Update Students Set age = 20 Where sid = ‘200011’
Update Students Set age = 21 Where name = ‘王五’
Update Students Set age = age + 1;
Update Students Set sid = ‘200012’ Where sid = ‘200011’;
数据删除
DELETE
FROM <表名>
[WHERE <条件>];
删除指定表中满足WHERE子句条件的元组
Delete From Students Where sid = ‘200011’;
Delete From Students Where sid = ‘200000’;
Delete From Students
SELECT
SELECT A1, A2, …, An #3: what to return
FROM R1, R2, …, Rn #1: relations to query
WHERE condition #2: combine, filter relations
GROUP BY Ai, Aj, …, Ak
HAVING condition
ORDER BY <列名1> [ASC|DESC]
Max/Min value problem:
▬ Solution 0
SELECT sID FROM Student ORDER BY GPA DESC LIMIT 1;
▬ Solution 1 (all/any?)
SELECT sID FROM Student
WHERE GPA >= all (SELECT GPA FROM Student);
▬ Solution 2
SELECT sID FROM Student
WHERE GPA = (SELECT max(GPA) FROM Student)
(Left | Right | Full) Outer Join:
If join condition don’t match for certain tuples, include those tuples in the result, but pad with NULL values
Write a SQL query that returns the number ofcolleges applied to by each student, including 0 for those who applied nowhere
SELECT Student.sID, count(distinct cName)
FROM Student, Apply
WHERE Student.sID = Apply.sID
GROUP BY Student.sID
union
SELECT sID, 0
FROM Student
WHERE sID NOT IN (SELECT sID FROM Apply);
查询每个城市最受欢迎的站点:
select station.city,station_name,max as visit_count from
(select city,max(count)
from
(select s1.id as id, s1.count+s2.count as count from
(select start_station_id as id, count(*)
from trip group by start_station_id) as s1,
(select end_station_id as id, count(*)
from trip group by end_station_id) as s2
where s1.id = s2.id) as counts, station
where counts.id =station_id
group by city
) as maxCity,station,
(select s1.id as id, s1.count+s2.count as count from
(select start_station_id as id, count(*)
from trip group by start_station_id) as s1,
(select end_station_id as id, count(*)
from trip group by end_station_id) as s2
where s1.id = s2.id
) as counts
where counts.id = station_id and counts.count = max and maxCity.city = station.city
order by station.city;
在PostgreSQL中,可使用extract函数从timestamp类型变量中提取年月日信息,如:extract(year from date)
绘制日均租车量-时间变化直方图(在sql中仅需输出month与number):
select extract(month from date) as month ,avg(count) as number from (
select extract(doy from start_time),count(*) from trip
where start_station_id in (select station_id from station where zip_code = '94107')
and extract(year from start_time) = 2014
group by extract(doy from start_time)
) as days, weather where extract(doy from date) = date_part
group by extract(month from date) order by month;
NULL values
Text comparison
天气关系数据weather导入,未给出的数据默认为NULL
copy weather from ‘E://weather.txt’ delimiter ‘,’ NULL ‘’;
空间数据模型:
GIS中常见的两大数据模型:栅格模型、矢量模型
矢量模型的优点:
栅格模型的优缺点:
矢量模型:
地理要素(feature):
几何对象模型利用对象关系型数据库中的扩展数据类型实现.
几何对象模型的核心:
空间参考系(Spatial Reference System)
和测量参考系(Measure Reference System)
的几何(Geometry)类
点(Point)
、线(Curve)
、面(Surface)
、多点(MultiPoint)
、多线(MultiCurve)
、多面(MultiPolygon)
等类型模型层次关系 (数据):
坐标维数和几何维数的区别:
任何几何模型都有其边界(boundary)、内部(interior)和外部(exterior):
几何对象模型的坐标维数为3,但目前仅能描述二维几何对象。 z值仅用于记录点在坐标空间中第3个坐标轴的测量值。
M值:点类除了x, y, z坐标外,还有一个M坐标
由于体表面违反了“多边形元素只能相交在有限数量的点上”的规则,所以体表面不是多多边形
几何对象的方法 (函数):
九交模型:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nlJYaLUq-1598684054065)(pictures\Nine-Intersection.png)]
空间拓扑关系: 前面加上 st_ 就是对应函数
FF*FF****
TFFFTFFFT
T*T***T**
T*F**F***
FT*******
F**T*****
F***T****
T*T******
线性参考系查询方法
基于概念模型,OGC提出了基于预定义数据类型和基于扩展几何类型的两种逻辑模型实现方法:
几何对象物理模型:
举例:
POINT(0 0)
LINESTRING(0 0, 1 1, 1 2)
POLYGON((0 0, 4 0, 4 4, 0 4, 0 0))
POLYGON((0 0, 4 0, 4 4, 0 4, 0 0), (1 1, 2 1, 2 2, 1 2, 1 1))
MULTIPOINT((0 0), (1 2))
MULTILINESTRING((0 0, 1 1, 1 2), (2 3, 3 2, 5 4))
MULTIPOLYGON(((0 0, 4 0, 4 4, 0 4, 0 0), (1 1, 2 1, 2 2, 1 2, 1 1)), ((-1 -1, -1 -2, -2 -2, -2 -1, -1 -1)))
GEOMETRYCOLLECTION(POINT(2 3), LINESTRING(2 3,3 4))
PostGIS中常用数据类型:
表的定义:
create table landuse (
landuse_id integer NOT NULL,
name varchar(20),
the_geom geometry,
area double precision,
perimeter double precision,
constraint landuse_key primary key (landuse_id));
数据插入:
insert into landuse
values(12, ‘Timber-forest’,
‘01010000001DDB93F460BB4241A84E5AC86F455441’,
47806700, 34246.2);
insert into landuse
values(12, ‘Timber-forest’,
ST_GeomFromText(‘Polygon((10 10, 10 20, 20 20, 20 10, 10 10))’, 4326),
47806700, 34246.2);
AddGeometryColumn 增加几何属性:
select AddGeometryColumn('testgeom', 'geom', 4326, 'MULTILINESTRING', 2);
Dimension()
ST_Dimension('GEOMETRYCOLLECTION(LINESTRING(1 1,0 0), POINT(0 0))');
SRID() : Integer 用于获取几何类型的空间参考系
SELECT ST_SRID(ST_GeomFromText('POINT(-71.1043 42.315)',4326));
空间参考系更改为4326
select UpdateGeometrySRID('ushighways', 'geom', 4326);
Envelope() : Geometry 用于获取Geometry的最小边界矩形
SELECT ST_AsText(ST_Envelope('POINT(1 3)'::geometry));
Boundary() : Geometry 获取几何类型的边界
SELECT ST_AsText(ST_Boundary(ST_GeomFromText('LINESTRING(1 1,0 0, -1 1)')));
Distance(another: Geometry) : Distance 求本Geometry与另一个Geometry间的距离
SELECT ST_Distance(
ST_GeomFromText('POINT(-72.1235 42.3521)',4326),
ST_GeomFromText('LINESTRING(-72.1260 42.45, -72.123 42.1546)', 4326)
);
比较~=(操作符)、=(操作符)、ST_Equals和ST_OrderingEquals四个函数的异同
boolean =( geometry A , geometry B ):仅将在所有方面完全相同,坐标相同,顺序相同的几何视为相等。
boolean ~=( geometry A , geometry B );将边界框相同的几何要素视为相等。(PostGIS 1.5前测试实际相等性)
boolean ST_Equals(geometry A, geometry B);几何在空间上相等则返回true,不考虑点的顺序。即 ST_Within(A,B)= true 且 ST_Within(B,A)= true 。
boolean ST_OrderingEquals(geometry A, geometry B);如果几何相等且坐标顺序相同,则返回TRUE。
可以将MultiXXX转换XXX,如MultiPolygon转换获得多个Polygon
select ST_Dump(ST_GeomFromText('MULTILINESTRING((0 0,1 1,1 2),(2 3,3 2,5 4))'))
查询点的数目:
select gid, 'Lake Superior''s number of point' as name, ST_NPoints(geom) as number
from uslakes
where name like '%Superior%';
ConvexHull() : Geometry 求本Geometry的凸包
ST_AsText(ST_ConvexHull(
ST_Collect(
ST_GeomFromText('MULTILINESTRING((100 190,10 8),(150 10, 20 30))'),
ST_GeomFromText('MULTIPOINT(50 5, 150 30, 50 10, 10 10)')
)) );
查询距离ST_CASE = 10012交通事故最近的城市
select uc.name || ' in ' || uc.state as name from uscities uc, usaccidents ua where st_case = 10012
and ST_Distance(uc.geom,ua.geom) = ( select min(ST_Distance(uc.geom,ua.geom))
from uscities uc, usaccidents ua where st_case = 10012);
查询哪条高速公路上的交通事故最多:该高速公路上的交通事故
select ua.gid, hw1.name,ua.geom from
(select hw.gid, hw.full_name as name, hw.geom, count(*) c
from (select * from usaccidents where month = 8 or month = 9) ua, ushighways hw
where ST_DWithin(hw.geom::geography, ua.geom::geography,500)
group by hw.gid order by c desc limit 1) hw1, (select * from usaccidents where month = 8 or month = 9) ua
where ST_DWithin(hw1.geom::geography, ua.geom::geography,500);
空间网格关联查询:
select x || '0' || y as gid, x || ' ' || y as name, grid1.geom ,count(*) as value
from usaccidents ua,
(WITH
usext AS (
SELECT
ST_SetSRID(CAST(ST_Extent(geom) AS geometry),
4326) AS geom_ext, 50 AS x_gridcnt, 46 AS y_gridcnt
FROM cal
),
grid_dim AS (
SELECT
(
ST_XMax(geom_ext)-ST_XMin(geom_ext)
) / x_gridcnt AS g_width,
ST_XMin(geom_ext) AS xmin, ST_xmax(geom_ext) AS xmax,
(
ST_YMax(geom_ext)-ST_YMin(geom_ext)
) / y_gridcnt AS g_height,
ST_YMin(geom_ext) AS ymin, ST_YMax(geom_ext) AS ymax
FROM usext
),
grid AS (
SELECT
x, y,
ST_MakeEnvelope(
xmin + (x - 1) * g_width, ymin + (y - 1) * g_height,
xmin + x * g_width, ymin + y * g_height,
4326
) AS grid_geom
FROM
(SELECT generate_series(1,x_gridcnt) FROM usext) AS x(x)
CROSS JOIN
(SELECT generate_series(1,y_gridcnt) FROM usext) AS y(y)
CROSS JOIN
grid_dim
)
SELECT
g.x x, g.y y,
ST_Intersection(s.geom, grid_geom) AS geom
FROM cal AS s INNER JOIN grid AS g
ON ST_Intersects(s.geom,g.grid_geom)) grid1
where ST_Within(ua.geom,grid1.geom)
group by grid1.x,grid1.y,grid1.geom;
查询在加州范围内的交通事故,通过heatMap进行可视化
select gid, tway_id as name, geom from usaccidents where ST_Within(geom, (select geom from cal ));