1
2
3
4
5
6
7
8
9
10
|
INSTALL spatial;
LOAD spatial;
CREATE TABLE world AS SELECT * FROM ST_Read('C:\Users\......\Desktop\testspatialite\world.geojson');
SELECT name_zh FROM world WHERE ST_Contains(geom,ST_Point(92.5976562500021, 42.58220940617247));
┌────────────────┐
│ name_zh │
│ varchar │
├────────────────┤
│ 中华人民共和国 │
└────────────────┘
|
具体参见:https://coloraven.github.io/2023/12/geopandas读取geojson文件并写入Spatialite数据库/
环境配置见:https://coloraven.github.io/2023/12/使用Spatialite的环境配置/
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
|
import sqlite3
import pandas as pd
import geopandas as gpd
import uuid
pd.options.display.max_rows = 10
gdf = gpd.read_file('world.geojson') # `world.geojson`(大小:`23+MB`) 生成自 `https://geojson-maps.ash.ms`,选择 `High resolution` 加 `All`。
# 为每条记录生成一个唯一的 UUID,便于后面更新时找到关联点
gdf['uuid'] = gdf.apply(lambda _: "".join(str(uuid.uuid4()).split('-')), axis=1)
DB_PATH = "test_save.db"
# 先创建普通 df
df = gdf.drop(columns=['geometry'])
with sqlite3.connect(DB_PATH) as conn:
# 在数据库中创建普通表
df.to_sql("world_geo", conn, if_exists='replace', index=False)
# 新增地理列
conn.enable_load_extension(True)
conn.load_extension("mod_spatialite")
conn.execute("SELECT InitSpatialMetaData(1);")
conn.execute(
"""
SELECT AddGeometryColumn('world_geo', 'geometry', 4326, 'GEOMETRY', 2);
"""
)
with sqlite3.connect(DB_PATH) as conn:
conn.enable_load_extension(True)
conn.load_extension("mod_spatialite")
# 所有要插入的数据的列表
data_to_update = [(row['geometry'].wkt, row['uuid']) for _, row in gdf.iterrows()]
# 使用 executemany 一次性执行所有插入
conn.executemany("UPDATE world_geo SET geometry = GeomFromText(?, 4326) WHERE uuid = ?", data_to_update)
conn.commit()
# 写入完毕创建空间索引
conn.execute("SELECT CreateSpatialIndex('your_table', 'geometry_column');")
# 如有需要删除uuid列(过程中新增的列)
conn.execute("ALTER TABLE world_geo DROP COLUMN uuid;")
conn.commit()
conn.close()
|
使用geopandas读取并导入是最便捷的。
先安装必要的依赖
1
|
pip install sqlalchemy psycopg2-binary geoalchemy2 geopandas psycopg2 -i https://pypi.tuna.tsinghua.edu.cn/simple
|
1
2
3
4
5
6
7
8
9
10
11
|
import geopandas as gpd
from sqlalchemy import create_engine
gdf = gpd.read_file('world.geojson',encoding='utf-8')
# 连接字符串
db_string = "postgresql://user:xxxxx@host........./dbname?sslmode=require"
# 创建数据库引擎
engine = create_engine(db_string)
gdf.to_postgis(name='geo_table', con=engine, if_exists='replace', index=False)
|
注意:1. public.不能省略,2. ST_SetSRID不能省略。
1
|
SELECT name_zh FROM public.geo_table WHERE ST_Contains(geometry,ST_SetSRID(ST_MakePoint(92.5976562500021, 42.58220940617247),4326));
|
windows下安装postgis的方法
先安装postgresql普通数据库,然后停止postgresql服务,下载postgis(https://download.osgeo.org/postgis/windows/pg16/),安装postgis到postgresql普通数据库所在安装目录,重新启动postgresql服务,执行CREATE EXTENSION postgis;SQL命令,再执行SELECT PostGIS_version();SQL命令