Go语言和Python使用Spatialite配置(Linux和Windows)

关于Windows的解决方案,仅在Python语言中测试通过 GO语言在Windows下加载Spatialite仍然未通过。

全网唯一的一篇如何在WindowsPython编程配置Spatialite的教程,非常详细,建议大家看一看

  1. 下载Spatialite的库文件,完整的库文化由多个.dll相互依赖的DLL组成,一个不能少;
  2. Spatialite的库文件的存放目录添加到环境变量Path中;
  3. 下载sqlite3最新版的库文件sqlite3.dll,也放在系统环境变量Path路径中,如C:\Windows\system32等;

为什么要使用最新版:从此文得知,要使用Spatialite扩展,需要sqlite3支持R-tree,是否支持的测试方法,sqlite中执行以下sql语句不报错:CREATE VIRTUAL TABLE testrtree USING rtree(id,minX,maxX,minY,maxY);

Python编程语言在使用sqlite3包及后续加载Spatialite扩展时会自动到Path环境变量中搜索相应DLL,如果没有找到,就会报错; 下载方法:

访问:https://www.gaia-gis.it/gaia-sins/ 找到MS Windows binaries -> current stable version 截止到成文时的最新版下载地址

虽然GO语言有现成的加载Spatialite的实现:https://github.com/shaxbee/go-spatialite 但是其仅适用于Linux类环境,经测试Windows下加载Spatialite仍然未通过,原因未知。

2023年12月25日17时测试发现:将本文Go语言使用Spatialite章节中的代码放在Spatialite库文件目录中,可正常运行了,也就是说,Go语言在Windows下加载Spatialite,编译程序需要直接在当前目录查找mod-spatialite库文件,而不会在Path中搜索mod-spatialite库文件。 整体目录结果如下:

1
2
3
4
5
6
7
    main.go
    go.mod
    go.sum
    mod_spatialite.dll
    libcrypto-3-x64.dll
    libcurl-4.dll
    ....

2023年12月25日20时再次测试发现:

直接在SQLiteDriver中指定mod-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
package main

import (
	"database/sql"
	"fmt"
	"log"

	"github.com/mattn/go-sqlite3"
)

func main() {
	sql.Register("sqlite3_with_spatialite",
		&sqlite3.SQLiteDriver{
			Extensions: []string{"C:/spatialite/mod_spatialite.dll"},
		})

	db, err := sql.Open("sqlite3_with_spatialite", ":memory:")
	if err != nil {
		log.Panic(err)
	}
	defer db.Close()
	// 要使用地理数据库,必须执行以下sql来初始化 spatialite,多次执行无害处,也无益处
	q := "SELECT InitSpatialMetaData();"
	db.Query(q)

	var r interface{}
	q = "SELECT spatialite_version();"
	db.QueryRow(q).Scan(&r)
	fmt.Println(r)
}
  1. 使用脚本将所有数据汇集到一个GEOJSON文件中; 2 .使用Spatialite GUI成文时的官方下载地址)导入GEOJSON文件;
  2. 保存到Spatialite数据库。 使用Spatialite GUI加载https://www.geojson.io生成的GEOJSON文件,结果报错load GeoJSON error:GeoJSON parser: invalid Geometry (fid=1)

官方文档关于Spatialite GUI加载GEOJSON文件的描述也没有解决方法。 故,还是只能走编程事先的路。

见:https://coloraven.github.io/2023/12/geopandas读取geojson文件并写入Spatialite数据库/

  1. 直接使用apt安装,如apt-get install libsqlite3-mod-spatialiteUbuntu测试通过)
  2. http://www.gaia-gis.it下载最新的Linux版本的Spatialite库文件,然后自行编译(不推荐)
1
2
3
4
5
6
wget https://www.gaia-gis.it/gaia-sins/libspatialite-sources/libspatialite-xxxxxxx.tar.gz
tar xaf libspatialite-xxxxxxx.tar.gz
cd libspatialite-xxxxxxx
./configure
make
sudo make install

方法暂不支持Windows 来源:https://gist.github.com/ptrv/6335248

 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
package main

import (
	"database/sql"
	"fmt"
	"log"

	"github.com/mattn/go-sqlite3"
)

func main() {
	sql.Register("sqlite3_with_spatialite",
		&sqlite3.SQLiteDriver{
			Extensions: []string{"mod_spatialite"}, // Windows必须指定mod_spatialite.dll的绝对路径
		})

	db, err := sql.Open("sqlite3_with_spatialite", ":memory:")
	if err != nil {
		log.Panic(err)
	}
	defer db.Close()
	// 要使用地理数据库,必须执行以下sql来初始化 spatialite,多次执行无害处,也无益处
	q := "SELECT InitSpatialMetaData();"
	db.Query(q)

	var r interface{}
	q = "SELECT spatialite_version();"
	db.QueryRow(q).Scan(&r)
	fmt.Println(r)
}

已编译好的现成容器(基于alpine):

  1. SpatiaLite: https://github.com/Geocodio/docker-alpine-spatialite
  2. SQLite + SpatiaLite: https://github.com/wakumaku/spatialite
  3. docker hub中使用数最多的容器: https://github.com/Geocodio/docker-alpine-spatialite
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
FROM golang:alpine3.19
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories
COPY --from=geocodio/alpine-spatialite /usr/lib/ /usr/lib
COPY --from=geocodio/alpine-spatialite /usr/bin/ /usr/bin
# 解决以下报错
# # runtime/cgo
# _cgo_export.c:3:10: fatal error: stdlib.h: No such file or directory
#     3 | #include <stdlib.h>
#       |          ^~~~~~~~~~
# compilation terminated.
RUN apk add --no-cache build-base
# 创建存放目录
RUN mkdir -p /app
WORKDIR /app
# 设置 go 国内源
RUN go env -w GOPROXY=https://goproxy.cn,direct
# 开启cgo编译
RUN go env -w CGO_ENABLED=1
# COPY --from=wakumaku/spatialite /usr/local/bin/sqlite3 /usr/local/bin/sqlite3
EXPOSE 3000
  1. Ubuntu下编译Spatialite:https://github.com/Dushistov/libspatialite
  1. 各个系统下Spatialite的编译:https://github.com/Dushistov/libspatialite
  2. 修改此处代码的libspatialitemod_spatialite即可在Linux中成功运行:https://github.com/pampa0629/gogis/blob/cc934844d334c46a1dc6ef42c8488d4179edd902/src/gogis/study/spatialite-tst.go
  3. sourcegraph.com中搜索mod_spatialite lang:Go来获取Go语言的mod_spatialite加载Spatialite的实现:https://sourcegraph.com/search?q=context:global+++++mod_spatialite+lang:Go&patternType=standard&sm=1&groupBy=repo
  4. 一个专注于空间地理的Go项目:https://github.com/go-spatial/geom
  5. 关于无法加载Spatialite的讨论:https://groups.google.com/g/Golang-nuts/c/Kj0WKQaLBqY
  6. 中文作者用GO实现的GIS功能,其中有Spatialite加载及测试,项目地址:https://github.com/pampa0629/gogis
  7. GO语言的加载Spatialite的实现:https://github.com/shaxbee/go-spatialite
  8. 纯Go实现的地理关系计算:https://github.com/tidwall/geojson/geometry
  9. https://github.com/golang/geo/s2
  10. https://github.com/paulmach/orb
  11. 自带地理数据库的web服务,https://github.com/tidwall/tile38
  12. https://mp.weixin.qq.com/s/ZHVBLhd8yNuSynRCgLXQcQ
  13. geopanda 写入spatialite: https://www.giacomodebidda.com/posts/export-a-geodataframe-to-spatialite/