@developmentseed/epsg 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -0
- package/dist/all.csv.gz +0 -0
- package/dist/all.d.ts +15 -0
- package/dist/all.d.ts.map +1 -0
- package/dist/all.js +73 -0
- package/dist/all.js.map +1 -0
- package/package.json +51 -0
package/README.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# @developmentseed/epsg
|
|
2
|
+
|
|
3
|
+
The full EPSG projection database, compressed to **309kb** for the web.
|
|
4
|
+
|
|
5
|
+
[EPSG]: https://en.wikipedia.org/wiki/EPSG_Geodetic_Parameter_Dataset
|
|
6
|
+
|
|
7
|
+
Some existing EPSG amalgamations exist, but all are uncompressed, incomplete, outdated, and/or not reproducible [^1] [^2] [^3] [^4]. This package uses the [DecompressionStream] API, now [widely available in browsers][DecompressionStream_gzip], to bundle a gzip-compressed text file of WKT definitions for **all 7352 defined EPSG projection codes**.
|
|
8
|
+
|
|
9
|
+
[DecompressionStream]: https://developer.mozilla.org/en-US/docs/Web/API/DecompressionStream
|
|
10
|
+
[DecompressionStream_gzip]: https://caniuse.com/mdn-api_decompressionstream_decompressionstream_gzip
|
|
11
|
+
|
|
12
|
+
[^1]: [`epsg`](https://www.npmjs.com/package/epsg) includes only 3912 definitions, stores older, deprecated proj strings, and is uncompressed, coming to 500kb.
|
|
13
|
+
|
|
14
|
+
[^2]: [`epsg-index`](https://www.npmjs.com/package/epsg-index) stores extra parsed information for each projection and is **7.7 MB**.
|
|
15
|
+
|
|
16
|
+
[^3]: [`proj4-list`](https://www.npmjs.com/package/proj4-list) includes only 5434 definitions, stores older, deprecated proj strings, and is 759KB of uncompressed strings.
|
|
17
|
+
|
|
18
|
+
[^4]: [`@esri/proj-codes`](https://www.npmjs.com/package/@esri/proj-codes) ships a lot of redundant information, coming to nearly **15MB** of JSON.
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
Currently, the only package entrypoint is `@developmentseed/epsg/all`, which loads a `Map<number, string>`, with all EPSG definitions in OGC WKT2 format.
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
import loadEPSG from "@developmentseed/epsg/all";
|
|
26
|
+
import proj4 from "proj4";
|
|
27
|
+
|
|
28
|
+
// Load the EPSG database
|
|
29
|
+
const epsg = await loadEPSG();
|
|
30
|
+
|
|
31
|
+
// Access WKT strings by EPSG code.
|
|
32
|
+
const wkt4326 = epsg.get(4326);
|
|
33
|
+
const wkt3857 = epsg.get(3857);
|
|
34
|
+
|
|
35
|
+
// Then use proj4.js as normal
|
|
36
|
+
const converter = proj4(wkt4326, wkt3857);
|
|
37
|
+
const inputPoint = [1, 52];
|
|
38
|
+
const outputPoint = converter.forward(inputPoint);
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Generate new EPSG definitions
|
|
42
|
+
|
|
43
|
+
First, download the latest EPSG definitions in WKT format. Go to [epsg.org/download-dataset.html](https://epsg.org/download-dataset.html), create an account or log in, then download the `WKT File` version.
|
|
44
|
+
|
|
45
|
+
Then, from this directory, run
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
python scripts/generate.py
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Then the file `src/all.csv.gz` will be updated with the latest EPSG definitions.
|
|
52
|
+
|
|
53
|
+
## Publishing
|
|
54
|
+
|
|
55
|
+
The `build` script in `package.json` will automatically include `all.csv.gz` in the published NPM package.
|
|
56
|
+
|
|
57
|
+
If you get an error like
|
|
58
|
+
|
|
59
|
+
> `cp: dist/all.csv.gz: No such file or directory`
|
|
60
|
+
|
|
61
|
+
You may need to delete an errant `tsconfig.build.tsbuildinfo` and try again. I'm not sure why.
|
|
62
|
+
|
package/dist/all.csv.gz
ADDED
|
Binary file
|
package/dist/all.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Load the EPSG database into memory.
|
|
3
|
+
*
|
|
4
|
+
* The database is stored as a gzipped CSV file. This function loads and parses
|
|
5
|
+
* the file, returning a map of EPSG code to WKT string.
|
|
6
|
+
*
|
|
7
|
+
* The result is cached after the first call, so subsequent calls will return
|
|
8
|
+
* the cached result.
|
|
9
|
+
*
|
|
10
|
+
* @param url - Optional URL to the gzipped CSV file. When using a bundler like
|
|
11
|
+
* Vite, pass the asset URL directly to ensure correct resolution:
|
|
12
|
+
* `import csvUrl from "@developmentseed/epsg/all.csv.gz?url"`
|
|
13
|
+
*/
|
|
14
|
+
export default function loadEPSG(url?: string | URL): Promise<Map<number, string>>;
|
|
15
|
+
//# sourceMappingURL=all.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"all.d.ts","sourceRoot":"","sources":["../src/all.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,OAAO,UAAU,QAAQ,CAC9B,GAAG,CAAC,EAAE,MAAM,GAAG,GAAG,GACjB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAM9B"}
|
package/dist/all.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
const SEP = "|";
|
|
2
|
+
/** A cached promise for the loaded EPSG database */
|
|
3
|
+
let cachedLoad = null;
|
|
4
|
+
/**
|
|
5
|
+
* Load the EPSG database into memory.
|
|
6
|
+
*
|
|
7
|
+
* The database is stored as a gzipped CSV file. This function loads and parses
|
|
8
|
+
* the file, returning a map of EPSG code to WKT string.
|
|
9
|
+
*
|
|
10
|
+
* The result is cached after the first call, so subsequent calls will return
|
|
11
|
+
* the cached result.
|
|
12
|
+
*
|
|
13
|
+
* @param url - Optional URL to the gzipped CSV file. When using a bundler like
|
|
14
|
+
* Vite, pass the asset URL directly to ensure correct resolution:
|
|
15
|
+
* `import csvUrl from "@developmentseed/epsg/all.csv.gz?url"`
|
|
16
|
+
*/
|
|
17
|
+
export default function loadEPSG(url) {
|
|
18
|
+
if (!cachedLoad) {
|
|
19
|
+
cachedLoad = load(url ?? new URL("./all.csv.gz", import.meta.url));
|
|
20
|
+
}
|
|
21
|
+
return cachedLoad;
|
|
22
|
+
}
|
|
23
|
+
async function load(url) {
|
|
24
|
+
const response = await fetch(url);
|
|
25
|
+
if (!response.body) {
|
|
26
|
+
throw new Error("Response has no body");
|
|
27
|
+
}
|
|
28
|
+
// When the server serves the gzipped file with `Content-Encoding: gzip`, the
|
|
29
|
+
// browser automatically decompresses it, so we can just read the text
|
|
30
|
+
// directly.
|
|
31
|
+
// If the header is missing, we need to decompress it ourselves.
|
|
32
|
+
const alreadyDecompressed = response.headers.get("Content-Encoding") === "gzip";
|
|
33
|
+
const stream = !alreadyDecompressed
|
|
34
|
+
? response.body
|
|
35
|
+
.pipeThrough(new DecompressionStream("gzip"))
|
|
36
|
+
.pipeThrough(new TextDecoderStream())
|
|
37
|
+
: response.body.pipeThrough(new TextDecoderStream());
|
|
38
|
+
return parseStream(stream);
|
|
39
|
+
}
|
|
40
|
+
async function parseStream(stream) {
|
|
41
|
+
const reader = stream.getReader();
|
|
42
|
+
const map = new Map();
|
|
43
|
+
let buffer = "";
|
|
44
|
+
while (true) {
|
|
45
|
+
// Read the next chunk from the stream
|
|
46
|
+
const { value, done } = await reader.read();
|
|
47
|
+
if (done) {
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
buffer += value;
|
|
51
|
+
// The position of the newline character
|
|
52
|
+
let newlineIndex = buffer.indexOf("\n");
|
|
53
|
+
// Iterate over each line in the buffer
|
|
54
|
+
while (newlineIndex !== -1) {
|
|
55
|
+
const line = buffer.slice(0, newlineIndex);
|
|
56
|
+
// Update buffer range and search for next newline
|
|
57
|
+
buffer = buffer.slice(newlineIndex + 1);
|
|
58
|
+
newlineIndex = buffer.indexOf("\n");
|
|
59
|
+
if (!line) {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
const sep = line.indexOf(SEP);
|
|
63
|
+
if (sep === -1) {
|
|
64
|
+
throw new Error(`Invalid line, missing separator: ${line}`);
|
|
65
|
+
}
|
|
66
|
+
const code = Number.parseInt(line.slice(0, sep), 10);
|
|
67
|
+
const wkt = line.slice(sep + 1);
|
|
68
|
+
map.set(code, wkt);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return map;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=all.js.map
|
package/dist/all.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"all.js","sourceRoot":"","sources":["../src/all.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@developmentseed/epsg",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "The full EPSG projection database, compressed to 309kb for the web.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
"./all": {
|
|
8
|
+
"types": "./dist/all.d.ts",
|
|
9
|
+
"default": "./dist/all.js"
|
|
10
|
+
},
|
|
11
|
+
"./all.csv.gz": "./dist/all.csv.gz"
|
|
12
|
+
},
|
|
13
|
+
"sideEffects": false,
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc --build tsconfig.build.json && cp src/all.csv.gz dist/all.csv.gz",
|
|
19
|
+
"test": "vitest run",
|
|
20
|
+
"test:watch": "vitest",
|
|
21
|
+
"typecheck": "tsc --noEmit",
|
|
22
|
+
"prepublishOnly": "npm run build"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"proj4",
|
|
26
|
+
"geotiff",
|
|
27
|
+
"zarr",
|
|
28
|
+
"cog",
|
|
29
|
+
"cloud-optimized-geotiff",
|
|
30
|
+
"raster",
|
|
31
|
+
"visualization",
|
|
32
|
+
"webgl",
|
|
33
|
+
"gpu"
|
|
34
|
+
],
|
|
35
|
+
"author": "Development Seed",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "git+https://github.com/developmentseed/deck.gl-raster.git"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@types/node": "^25.3.3",
|
|
43
|
+
"jsdom": "^27.4.0",
|
|
44
|
+
"proj4": "^2.20.3",
|
|
45
|
+
"typescript": "^5.9.3",
|
|
46
|
+
"vitest": "^4.0.18"
|
|
47
|
+
},
|
|
48
|
+
"volta": {
|
|
49
|
+
"extends": "../../package.json"
|
|
50
|
+
}
|
|
51
|
+
}
|