Skip to content

Commit 5362557

Browse files
committed
new doc
1 parent ab9e78f commit 5362557

File tree

4 files changed

+230
-0
lines changed

4 files changed

+230
-0
lines changed

201807/20180725_01.md

Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
## PostgreSQL 空间位置(geometry 经纬、点、线、面...)、行政地址(门牌、商圈、行政区...) 相互转换方法
2+
3+
### 作者
4+
digoal
5+
6+
### 日期
7+
2018-07-25
8+
9+
### 标签
10+
PostgreSQL , openstreetmap , 空间位置 , 点 , 线 , 面 , 行政地址 , 转换 , osm2pgsql , poi , 门牌 , 商圈 , 行政区
11+
12+
----
13+
14+
## 背景
15+
空间位置(geometry 经纬、点、线、面...)、行政地址(门牌、商圈、行政区...) 相互转换需求,如果你有这方面的素材库,在PostgreSQL里面转换,性能是非常高效的。
16+
17+
例如输入任意一个空间对象,扫描出附近的空间对象,或者包含它的对象,或者它包含的对象。(构图)
18+
19+
输入任意一个空间对象,搜索离他最近的空间对象。
20+
21+
输入任意一个空间对象,以及其他的非空间过滤条件(使用btree_gist插件),搜索出附近的空间对象,或者包含它的对象,或者它包含的对象。或离他最近的空间对象。
22+
23+
24+
## DEMO
25+
1、建表,存储空间、实体映射信息。
26+
27+
```
28+
create table tbl_loc (
29+
id int8 primary key,
30+
level int2, -- 空间对象的级别(国、省、市、区、县、街道、建筑、街道)
31+
pos geometry, -- 空间对象的位置(多边形、线段、点)
32+
loc_name text -- 空间对象的描述
33+
);
34+
```
35+
36+
2、创建空间+级别复合索引
37+
38+
```
39+
create extension btree_gist;
40+
41+
create index idx_tbl_loc_1 on tbl_loc using gist(level, pos);
42+
```
43+
44+
3、创建UDF接口函数
45+
46+
```
47+
create or replace function get_loc_name(
48+
int2, -- 级别(国、省、市、区、县、街道、建筑、街道)
49+
geometry -- 输入一个空间对象(点、线段、多边形),找在某个级别内,离他最近的空间对象,并找出它的描述
50+
) returns tbl_loc as $$
51+
select tbl_loc from tbl_loc where level=$1 order by pos <-> $2 limit 1;
52+
$$ language sql strict;
53+
```
54+
55+
4、查看UDF接口函数执行计划
56+
57+
```
58+
load 'auto_explain';
59+
set auto_explain.log_analyze =on;
60+
set auto_explain.log_buffers =on;
61+
set auto_explain.log_min_duration =0;
62+
set auto_explain.log_nested_statements =on;
63+
set auto_explain.log_timing =on;
64+
set auto_explain.log_verbose =on;
65+
set client_min_messages =log;
66+
67+
postgres=# select * from get_loc_name(1::int2,st_setsrid(st_makepoint(110+random()*10,30+random()*10),4326));
68+
LOG: duration: 0.171 ms plan:
69+
Query Text:
70+
select tbl_loc from tbl_loc where level=$1 order by pos <-> $2 limit 1;
71+
72+
Limit (cost=0.42..0.96 rows=1 width=107) (actual time=0.168..0.168 rows=1 loops=1)
73+
Output: tbl_loc.*, ((pos <-> $2))
74+
Buffers: shared hit=6
75+
-> Index Scan using idx_tbl_loc_1 on public.tbl_loc (cost=0.42..2455327.73 rows=4586107 width=107) (actual time=0.167..0.167 rows=1 loops=1)
76+
Output: tbl_loc.*, (pos <-> $2)
77+
Index Cond: (tbl_loc.level = $1)
78+
Order By: (tbl_loc.pos <-> $2)
79+
Buffers: shared hit=6
80+
LOG: duration: 0.466 ms plan:
81+
Query Text: select * from get_loc_name(1::int2,st_setsrid(st_makepoint(110+random()*10,30+random()*10),4326));
82+
Function Scan on public.get_loc_name (cost=0.27..0.28 rows=1 width=74) (actual time=0.451..0.451 rows=1 loops=1)
83+
Output: id, level, pos, loc_name
84+
Function Call: get_loc_name('1'::smallint, st_setsrid(st_makepoint(('110'::double precision + (random() * '10'::double precision)), ('30'::double precision + (random() * '10'::double precision))), 4326))
85+
Buffers: shared hit=6
86+
id | level | pos | loc_name
87+
-----------+-------+----------------------------------------------------+----------------------------------
88+
333848315 | 1 | 0101000020E610000000001C7BA1735C400000F03DF1984040 | 8cbcf713c4210ca4bbc09cd4c039c230
89+
(1 row)
90+
```
91+
92+
5、空间位置(geometry 经纬、点、线、面...)、行政地址(门牌、商圈、行政区...) 相互转换压测
93+
94+
首先写入一批随机空间对象数据(以点为例,写入约1亿个点 122536913)
95+
96+
```
97+
vi test.sql
98+
99+
\set id random(1,2000000000)
100+
\set level random(1,10)
101+
insert into tbl_loc values (:id, :level, st_setsrid(st_makepoint(110+random()*10, 30+random()*10), 4326), md5(random()::text)) on conflict(id) do nothing;
102+
103+
104+
pgbench -M prepared -n -r -P 1 -f ./test.sql -c 32 -j 32 -T 600
105+
```
106+
107+
压测
108+
109+
```
110+
vi test.sql
111+
112+
select * from get_loc_name(1::int2,st_setsrid(st_makepoint(110+random()*10, 30+random()*10),4326));
113+
114+
pgbench -M prepared -n -r -P 1 -f ./test.sql -c 56 -j 56 -T 120
115+
```
116+
117+
性能,TPS: 10.3万。
118+
119+
```
120+
transaction type: ./test.sql
121+
scaling factor: 1
122+
query mode: prepared
123+
number of clients: 56
124+
number of threads: 56
125+
duration: 120 s
126+
number of transactions actually processed: 12377402
127+
latency average = 0.543 ms
128+
latency stddev = 0.171 ms
129+
tps = 103143.196980 (including connections establishing)
130+
tps = 103153.166730 (excluding connections establishing)
131+
script statistics:
132+
- statement latencies in milliseconds:
133+
0.543 select * from get_loc_name(1::int2,st_setsrid(st_makepoint(110+random()*10, 30+random()*10),4326));
134+
```
135+
136+
使用PG的流复制,可以很容易把请求吞吐做上去,哪怕是对外提供高并发的转换类接口服务也是很轻松的。
137+
138+
## 如何得到 空间位置(geometry 经纬、点、线、面...)、行政地址(门牌、商圈、行政区...) 对应关系
139+
一种方法是通过openstreetmap得到,openstreetmap是开放的,自由的,社会人都可以维护、获取的一个开源空间素材库。
140+
141+
1、导出映射关系
142+
143+
https://www.openstreetmap.org/
144+
145+
![pic](20180725_01_pic_001.jpg)
146+
147+
https://www.openstreetmap.org/export#map=15/30.2601/120.1653
148+
149+
2、将空间位置(geometry 经纬、点、线、面...)、行政地址(门牌、商圈、行政区...) 对应关系导入到PostgreSQL
150+
151+
https://github.com/openstreetmap/osm2pgsql/releases
152+
153+
```
154+
sudo yum install -y cmake3 make gcc-c++ boost-devel expat-devel zlib-devel \
155+
bzip2-devel postgresql10-devel proj-devel proj-epsg lua-devel
156+
157+
wget wget https://github.com/openstreetmap/osm2pgsql/archive/0.96.0.tar.gz
158+
tar -zxvf 0.96.0.tar.gz
159+
cd osm2pgsql-0.96.0/
160+
161+
alias cmake=cmake3
162+
163+
mkdir build && cd build
164+
cmake .. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTS=ON
165+
make
166+
make install
167+
168+
Install the project...
169+
-- Install configuration: "Debug"
170+
-- Installing: /usr/local/bin/osm2pgsql
171+
-- Set runtime path of "/usr/local/bin/osm2pgsql" to ""
172+
-- Installing: /usr/local/share/man/man1/osm2pgsql.1
173+
-- Installing: /usr/local/share/osm2pgsql/default.style
174+
-- Installing: /usr/local/share/osm2pgsql/empty.style
175+
```
176+
177+
3、导入到数据
178+
179+
```
180+
osm2pgsql -d postgres -E 4326 ./map.osm
181+
```
182+
183+
```
184+
public | planet_osm_line | table | postgres
185+
public | planet_osm_point | table | postgres
186+
public | planet_osm_polygon | table | postgres
187+
public | planet_osm_roads | table | postgres
188+
```
189+
190+
4、查询导入的一些对象
191+
192+
```
193+
postgres=# select name,way,st_astext(way) from planet_osm_point limit 5;
194+
name | way | st_astext
195+
--------+----------------------------------------------------+-------------------------------
196+
湘湖 | 0101000020E6100000924149DCBE0E5E40F67CCD72D92A3E40 | POINT(120.2303992 30.1673805)
197+
江虹路 | 0101000020E6100000741200D26D0C5E4030B6B52A2E2F3E40 | POINT(120.1942029 30.1842982)
198+
江晖路 | 0101000020E6100000C0C469D2370D5E409862B3C81B2F3E40 | POINT(120.2065321 30.1840177)
199+
西兴 | 0101000020E6100000EB1F9FEBD60D5E40433866D993303E40 | POINT(120.2162427 30.189756)
200+
滨康路 | 0101000020E6100000E1F725D1810E5E400E034CCFAA2F3E40 | POINT(120.2266734 30.1862001)
201+
(5 rows)
202+
```
203+
204+
## 参考
205+
206+
https://www.openstreetmap.org/
207+
208+
https://github.com/openstreetmap/osm2pgsql/releases
209+
210+
http://postgis.net/
211+
212+
[《OSM(OpenStreetMap) poi、路网 数据导入 PostgreSQL》](../201801/20180118_01.md)
213+
214+
[《GIS术语 - POI、AOI、LOI、路径、轨迹》](../201712/20171204_01.md)
215+
216+
[《HTAP数据库 PostgreSQL 场景与性能测试之 47 - (OLTP) 空间应用 - 高并发空间位置更新、多属性KNN搜索并测(含空间索引)末端配送类项目》](../201711/20171107_48.md)
217+
218+
[[未完待续] HTAP数据库 PostgreSQL 场景与性能测试之 44 - (OLTP) 空间应用 - 空间包含查询(输入多边形 包含 表内空间对象)》](../201711/20171107_45.md)
219+
220+
[《HTAP数据库 PostgreSQL 场景与性能测试之 29 - (OLTP) 空间应用 - 高并发空间位置更新(含空间索引)》](../201711/20171107_30.md)
221+
222+
[《HTAP数据库 PostgreSQL 场景与性能测试之 6 - (OLTP) 空间应用 - KNN查询(搜索附近对象,由近到远排序输出)》](../201711/20171107_07.md)
223+
224+
[《HTAP数据库 PostgreSQL 场景与性能测试之 5 - (OLTP) 空间应用 - 空间包含查询(表内多边形 包含 输入空间对象)》](../201711/20171107_06.md)
225+
226+
227+
<a rel="nofollow" href="http://info.flagcounter.com/h9V1" ><img src="http://s03.flagcounter.com/count/h9V1/bg_FFFFFF/txt_000000/border_CCCCCC/columns_2/maxflags_12/viewers_0/labels_0/pageviews_0/flags_0/" alt="Flag Counter" border="0" ></a>
228+

201807/20180725_01_pic_001.jpg

472 KB
Loading

201807/readme.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
### 文章列表
44
----
5+
##### 20180725_01.md [《PostgreSQL 空间位置(geometry 经纬、点、线、面...)、行政地址(门牌、商圈、行政区...) 相互转换方法》](20180725_01.md)
56
##### 20180724_01.md [[转载] 环境变量的继承,fork、source、exec区别差异》](20180724_01.md)
67
##### 20180721_01.md [《PostgreSQL 批量SQL before/after for each row trigger的触发时机、性能差异分析、建议 - 含9.4 , 10版本》](20180721_01.md)
78
##### 20180720_02.md [《PostgreSQL 无法kill(pg_terminate_backend, pg_cancel_backend)的情况分析 - 进程hang strace,pstack》](20180720_02.md)

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ digoal's|PostgreSQL|文章|归类
3131

3232
### 未归类文档如下
3333
----
34+
##### 201807/20180725_01.md [《PostgreSQL 空间位置(geometry 经纬、点、线、面...)、行政地址(门牌、商圈、行政区...) 相互转换方法》](201807/20180725_01.md)
3435
##### 201807/20180724_01.md [[转载] 环境变量的继承,fork、source、exec区别差异》](201807/20180724_01.md)
3536
##### 201807/20180721_01.md [《PostgreSQL 批量SQL before/after for each row trigger的触发时机、性能差异分析、建议 - 含9.4 , 10版本》](201807/20180721_01.md)
3637
##### 201807/20180720_02.md [《PostgreSQL 无法kill(pg_terminate_backend, pg_cancel_backend)的情况分析 - 进程hang strace,pstack》](201807/20180720_02.md)

0 commit comments

Comments
 (0)