pg_eviltransform extends PostGIS ST_Transform with BD09/GCJ02 support.
It exposes one public function name, following the same overload interface as ST_Transform:
ST_EvilTransform(geometry, to_srid integer)ST_EvilTransform(geometry, to_proj text)ST_EvilTransform(geometry, from_proj text, to_srid integer)ST_EvilTransform(geometry, from_proj text, to_proj text)
Behavior:
- If neither side uses custom coordinates, it delegates directly to
ST_Transform. - If BD09/GCJ02 is involved, it transforms via WGS84 (
4326) when needed.
Custom SRIDs:
990001: GCJ02990002: BD09
regex_eviltransform.sql defines Regex_EvilTransform(...) with the same overload interface as ST_EvilTransform(...).
Regex_EvilTransform is a SQL/PLpgSQL + regex implementation used for comparison and benchmarking against pg_eviltransform.
Patent reference for the regex-based SQL approach:
If you use the regex-based SQL approach, cite:
@patent{CN112000902B,
title = {用于地图区域绘制的方法、电子设备和存储介质},
author = {梁展钊},
number = {CN112000902B},
year = {2021},
type = {Chinese Patent},
assignee = {Shanghai Maice Data Technology Co., Ltd.; Maice (Shanghai) Intelligent Technology Co., Ltd.},
url = {https://patents.google.com/patent/CN112000902B}
}- googollee/eviltransform for the open-source coordinate transform implementation and reference formulas.
- Rust stable
cargo-pgrxfrom the pinned pgrx PG19 beta branch:cargo install --locked --git https://github.com/pgcentralfoundation/pgrx --rev 15017e6461222d1882ad0b5ba16eee9b9bccaf9c cargo-pgrx- PostgreSQL + PostGIS (PG 14-19 packages; PG19 beta is experimental until PostgreSQL 19 GA)
librttopo-dev(for the native GSERIALIZED fast path)
Packaging note:
- DEB packages have no hard runtime package dependency to keep installation lightweight.
- PostgreSQL/PostGIS are kept as suggested packages to avoid pulling a large dependency tree during
apt install. - Runtime still requires PostGIS (
CREATE EXTENSION postgis) beforeCREATE EXTENSION pg_eviltransform.
cargo pgrx init \
--pg14=/usr/lib/postgresql/14/bin/pg_config \
--pg15=/usr/lib/postgresql/15/bin/pg_config \
--pg16=/usr/lib/postgresql/16/bin/pg_config \
--pg17=/usr/lib/postgresql/17/bin/pg_config \
--pg18=/usr/lib/postgresql/18/bin/pg_config \
--pg19=/usr/lib/postgresql/19/bin/pg_config
cargo pgrx package --release --features pg18 --no-default-features --pg-config /usr/lib/postgresql/18/bin/pg_config
# Experimental PG19 beta:
cargo pgrx package --release --features pg19 --no-default-features --pg-config /usr/lib/postgresql/19/bin/pg_configcargo test
cargo pgrx test pg18 --features "pg18 pg_test"
# Experimental PG19 beta:
cargo pgrx test pg19 --features "pg19 pg_test"-- Preferred: explicit literals (no need to remember custom SRID numbers)
SELECT ST_EvilTransform(ST_SetSRID('POINT(120 30)'::geometry, 4326), 'GCJ02');
SELECT ST_EvilTransform(ST_SetSRID('POINT(120 30)'::geometry, 4326), 'BD09');
-- Equivalent numeric custom SRID form
SELECT ST_EvilTransform(ST_SetSRID('POINT(120 30)'::geometry, 4326), 990001);
-- BD09 (990002) -> Web Mercator (3857)
SELECT ST_EvilTransform(ST_SetSRID('POINT(120.011070620552 30.0038830555128)'::geometry, 990002), 3857);
-- from_proj / to_proj overload with literals
SELECT ST_EvilTransform('POINT(120 30)'::geometry, 'EPSG:4326', 'GCJ02');Use the benchmark script to compare ST_EvilTransform and Regex_EvilTransform:
# optional env: PGHOST, PGPORT, PGUSER, PGDATABASE, ROWS
scripts/benchmark_pg18.sh
# Experimental PG19 beta:
PG_MAJOR=19 scripts/benchmark_pg18.shIt will:
- Ensure
postgisandpg_eviltransformextensions exist. - Load
regex_eviltransform.sql(creatingRegex_EvilTransform). - Generate benchmark data in
public.bench_points. - Run
EXPLAIN (ANALYZE, BUFFERS)forST_EvilTransformandRegex_EvilTransform. - Write report to
benchmark_pg18_report.txt(or custom output path).
Example:
ROWS=500000 PGDATABASE=testdb scripts/benchmark_pg18.sh /tmp/bench_pg18.txtLatest run (PG18, ROWS=200000, report: benchmark_pg18_report.txt):
| Scenario | ST_EvilTransform |
Regex_EvilTransform |
Speedup (Regex / ST) |
|---|---|---|---|
4326 -> 990001 |
92.402 ms |
2832.821 ms |
30.7x |
990002 -> 3857 (via 4326) |
183.856 ms |
8393.272 ms |
45.7x |
Experimental PG19 beta run (postgres:19beta1-trixie, ROWS=200000, report: benchmark_pg19_report.txt):
| Scenario | ST_EvilTransform |
Regex_EvilTransform |
Speedup (Regex / ST) |
|---|---|---|---|
4326 -> 990001 |
68.468 ms |
2800.963 ms |
40.9x |
990002 -> 3857 (via 4326) |
188.930 ms |
7871.404 ms |
41.7x |
scripts/release_debian_trixie.shThis builds .deb artifacts under dist/:
postgresql-14-pg-eviltransform_<version>_trixie_<arch>.debpostgresql-15-pg-eviltransform_<version>_trixie_<arch>.debpostgresql-16-pg-eviltransform_<version>_trixie_<arch>.debpostgresql-17-pg-eviltransform_<version>_trixie_<arch>.debpostgresql-18-pg-eviltransform_<version>_trixie_<arch>.debpostgresql-19-pg-eviltransform_<version>_trixie_<arch>.deb
GitHub Release CI publishes both amd64 and arm64 package artifacts (.deb + .rpm).
MIT. See LICENSE.