{"_id":"postgis","_rev":"9-d8e179c874311fc920fa210ba4e4d606","name":"postgis","dist-tags":{"latest":"1.2.0"},"versions":{"1.0.1":{"name":"postgis","version":"1.0.1","keywords":["postgis","postgresql","geospatial","nodejs","database","geojson","geobuf","mvt"],"author":{"name":"Suyog Dinesh Jadhav"},"license":"ISC","_id":"postgis@1.0.1","maintainers":[{"name":"jsuyog2","email":"jsuyog2@gmail.com"}],"homepage":"https://github.com/jsuyog2/postgis#readme","bugs":{"url":"https://github.com/jsuyog2/postgis/issues"},"dist":{"shasum":"ef176d7aed20a021dd3e3ff0becc371278352187","tarball":"https://registry.npmjs.org/postgis/-/postgis-1.0.1.tgz","fileCount":18,"integrity":"sha512-bmjzM2H+dRthuuLVdcY4ToUOrVJTJlVKBmr5Wj4pDtzMjnodau69BxqHuFRj6CzWxX7a85tilQaIK0+HNiSHKg==","signatures":[{"sig":"MEUCIDYdmudoX+MHmPuMsHihiYHCgMJO/92+T/jNRUmknuWeAiEAgGlvYfwRYWosePHSyWHf1D2SVkKyLl+f5vwICS+zoP4=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":41877},"main":"index.js","gitHead":"365bf1e0a361b601b74cfbe424dd379f14d4631b","scripts":{"lint":"eslint .","test":"jest --detectOpenHandles --coverage"},"_npmUser":{"name":"jsuyog2","email":"jsuyog2@gmail.com"},"repository":{"url":"git+https://github.com/jsuyog2/postgis.git","type":"git"},"_npmVersion":"10.8.1","description":"A Node.js class for interacting with PostGIS-enabled PostgreSQL databases.","directories":{},"_nodeVersion":"22.3.0","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.0","globals":"^15.9.0","prettier":"^2.8.4","@eslint/js":"^9.9.1"},"_npmOperationalInternal":{"tmp":"tmp/postgis_1.0.1_1724808068001_0.1941316847434289","host":"s3://npm-registry-packages"}},"1.0.2":{"name":"postgis","version":"1.0.2","keywords":["postgis","postgresql","geospatial","nodejs","database","geojson","geobuf","mvt"],"author":{"name":"Suyog Dinesh Jadhav"},"license":"ISC","_id":"postgis@1.0.2","maintainers":[{"name":"jsuyog2","email":"jsuyog2@gmail.com"}],"homepage":"https://github.com/jsuyog2/postgis#readme","bugs":{"url":"https://github.com/jsuyog2/postgis/issues"},"dist":{"shasum":"8411a79d2e505da8d44a1f78242a4ed622fa6139","tarball":"https://registry.npmjs.org/postgis/-/postgis-1.0.2.tgz","fileCount":20,"integrity":"sha512-SPt76gR4msGup6RnhgAViBiKOn23Xgc2uiRjXR9/aaqV4AAJXY5YTULkeUsrWpmMN9qsCFmyfoD1cBc6w0Imhg==","signatures":[{"sig":"MEUCIHwn/3F+MvnY5nHyB/I2MU40UeMlAhPzaFgyStvmOwfpAiEAzSYxNuih+bNvVDdzMqou1Xs5hZfgB/BJleQEjleUyPk=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":74210},"main":"index.js","gitHead":"67d338f8e7bd18361e06365618ecd7c4ff7bcd59","scripts":{"lint":"eslint .","test":"jest --detectOpenHandles --coverage --reporters=jest-junit"},"_npmUser":{"name":"jsuyog2","email":"jsuyog2@gmail.com"},"repository":{"url":"git+https://github.com/jsuyog2/postgis.git","type":"git"},"_npmVersion":"10.8.2","description":"A Node.js class for interacting with PostGIS-enabled PostgreSQL databases.","directories":{},"_nodeVersion":"20.17.0","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.0","globals":"^15.9.0","prettier":"^2.8.4","@eslint/js":"^9.9.1","jest-junit":"^16.0.0"},"_npmOperationalInternal":{"tmp":"tmp/postgis_1.0.2_1725022629765_0.9773653331062968","host":"s3://npm-registry-packages"}},"1.0.3":{"name":"postgis","version":"1.0.3","keywords":["postgis","postgresql","geospatial","nodejs","database","geojson","geobuf","mvt"],"author":{"name":"Suyog Dinesh Jadhav"},"license":"ISC","_id":"postgis@1.0.3","maintainers":[{"name":"jsuyog2","email":"jsuyog2@gmail.com"}],"homepage":"https://github.com/jsuyog2/postgis#readme","bugs":{"url":"https://github.com/jsuyog2/postgis/issues"},"dist":{"shasum":"a7c273c68508c3b52b8df8632dd066f63cb9a74b","tarball":"https://registry.npmjs.org/postgis/-/postgis-1.0.3.tgz","fileCount":20,"integrity":"sha512-/0NIRi8xVzU4nf1/qhgg37H2Arfr9PCY8kxA93YeENninT8EvA7k8sygPb17n2JcTBjiIrlnwG498ICsj69tlQ==","signatures":[{"sig":"MEUCIBHLOhH/KANXvndFIRNpx28IB4HDB7lJ9L07/5aiXgmzAiEAh9tkIiv21KMhNCXwGA6L1BD7zK4coScT/1jggR9f6RI=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":74238},"main":"index.js","gitHead":"de8e055892b3bb288725296851cecc599249b85e","scripts":{"lint":"eslint .","test":"jest --detectOpenHandles --coverage --reporters=jest-junit"},"_npmUser":{"name":"jsuyog2","email":"jsuyog2@gmail.com"},"repository":{"url":"git+https://github.com/jsuyog2/postgis.git","type":"git"},"_npmVersion":"10.8.2","description":"A Node.js class for interacting with PostGIS-enabled PostgreSQL databases.","directories":{},"_nodeVersion":"20.17.0","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.0","globals":"^15.9.0","prettier":"^2.8.4","@eslint/js":"^9.9.1","jest-junit":"^16.0.0"},"_npmOperationalInternal":{"tmp":"tmp/postgis_1.0.3_1725024574059_0.8411260192294119","host":"s3://npm-registry-packages"}},"1.0.4":{"name":"postgis","version":"1.0.4","keywords":["postgis","postgresql","geospatial","nodejs","database","geojson","geobuf","mvt"],"author":{"name":"Suyog Dinesh Jadhav"},"license":"ISC","_id":"postgis@1.0.4","maintainers":[{"name":"jsuyog2","email":"jsuyog2@gmail.com"}],"homepage":"https://github.com/jsuyog2/postgis#readme","bugs":{"url":"https://github.com/jsuyog2/postgis/issues"},"dist":{"shasum":"fa6bdcc4ecfa20f4ac50ff81fbbdafe9118919ae","tarball":"https://registry.npmjs.org/postgis/-/postgis-1.0.4.tgz","fileCount":20,"integrity":"sha512-q94+pRs1xW6tzxvUqTIC5dQmmg2w7sK9vALK3uz5Uy0NAmCMMF91PZaKByx7pYzyxkSWKud+yqufkQmymdPCJw==","signatures":[{"sig":"MEUCIQCi7yJ0PE0FK3rwTcbFMeNqmFDUannD4f0aDoa1dSFydwIgGPGVZJdZd/cEw6bTQEirgIWTI6tgCNd+/In/NmdUU/o=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":74329},"main":"index.js","gitHead":"25ef6b9c91568e4bd7c5c2ac879fa6f607cf3a0e","scripts":{"lint":"eslint .","test":"jest --detectOpenHandles --coverage --reporters=jest-junit"},"_npmUser":{"name":"jsuyog2","email":"jsuyog2@gmail.com"},"repository":{"url":"git+https://github.com/jsuyog2/postgis.git","type":"git"},"_npmVersion":"10.8.2","description":"A Node.js class for interacting with PostGIS-enabled PostgreSQL databases.","directories":{},"_nodeVersion":"20.17.0","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.0","globals":"^15.9.0","prettier":"^2.8.4","@eslint/js":"^9.9.1","jest-junit":"^16.0.0"},"_npmOperationalInternal":{"tmp":"tmp/postgis_1.0.4_1725047345914_0.5593500740321316","host":"s3://npm-registry-packages"}},"1.0.5":{"name":"postgis","version":"1.0.5","keywords":["postgis","postgresql","geospatial","nodejs","database","geojson","geobuf","mvt"],"author":{"name":"Suyog Dinesh Jadhav"},"license":"ISC","_id":"postgis@1.0.5","maintainers":[{"name":"jsuyog2","email":"jsuyog2@gmail.com"}],"homepage":"https://github.com/jsuyog2/postgis#readme","bugs":{"url":"https://github.com/jsuyog2/postgis/issues"},"dist":{"shasum":"23a6d99fe45fe81afa45b7a0ceb18783dcca3b57","tarball":"https://registry.npmjs.org/postgis/-/postgis-1.0.5.tgz","fileCount":20,"integrity":"sha512-P4d8CQ6vYh2LqidsrfLvLDYs7urWH7bgmqOC/3xMrvlk/Z2eprKe5DzpGRLjsiRohXEkc28F8f8FbgwSjeUUTg==","signatures":[{"sig":"MEUCIQC7J2WBjN4ntBtRhVguFlr9gloOutB6G1Qe+uTirH5l0gIgCFX8C5vi88FcFpgS50EzqtRXj1ynkD1huOlNp9eUJAc=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":74780},"main":"index.js","gitHead":"c2677549130268a89f9a38aeea1f8ded3d73be2c","scripts":{"lint":"eslint .","test":"jest --detectOpenHandles --coverage --reporters=jest-junit"},"_npmUser":{"name":"jsuyog2","email":"jsuyog2@gmail.com"},"repository":{"url":"git+https://github.com/jsuyog2/postgis.git","type":"git"},"_npmVersion":"10.8.2","description":"A Node.js class for interacting with PostGIS-enabled PostgreSQL databases.","directories":{},"_nodeVersion":"20.17.0","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.0","globals":"^15.9.0","prettier":"^2.8.4","@eslint/js":"^9.9.1","jest-junit":"^16.0.0"},"_npmOperationalInternal":{"tmp":"tmp/postgis_1.0.5_1725567131288_0.06335817747009753","host":"s3://npm-registry-packages"}},"1.0.6":{"name":"postgis","version":"1.0.6","keywords":["postgis","postgresql","geospatial","nodejs","database","geojson","geobuf","mvt"],"author":{"name":"Suyog Dinesh Jadhav"},"license":"ISC","_id":"postgis@1.0.6","maintainers":[{"name":"jsuyog2","email":"jsuyog2@gmail.com"}],"homepage":"https://github.com/jsuyog2/postgis#readme","bugs":{"url":"https://github.com/jsuyog2/postgis/issues"},"dist":{"shasum":"8d0ff24f16d5c719854f978b738b0fe8d680ef47","tarball":"https://registry.npmjs.org/postgis/-/postgis-1.0.6.tgz","fileCount":20,"integrity":"sha512-xYeRPekZfFW34nJOitzVCzPXpk4M++27y3MH9XzJIQcrMMB2xxSCRm+cHnvk1TAKrbY1W+9XB3h2fgJqIS4Lag==","signatures":[{"sig":"MEQCICEPFh/ZmsHAqa7Nw/ylYTyHsWJeUmf7ayezFtsjwUiaAiBF7VwVTzf0OuRv0HHsLg+5YO7JIZn0LMtYEEwsBVNHBg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":74797},"main":"index.js","gitHead":"430509d949dd08162ec27599111d7461cd5ef1d6","scripts":{"lint":"eslint .","test":"jest --detectOpenHandles --coverage --reporters=jest-junit"},"_npmUser":{"name":"jsuyog2","email":"jsuyog2@gmail.com"},"repository":{"url":"git+https://github.com/jsuyog2/postgis.git","type":"git"},"_npmVersion":"10.8.2","description":"A Node.js class for interacting with PostGIS-enabled PostgreSQL databases.","directories":{},"_nodeVersion":"20.19.4","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","eslint":"^8.57.0","globals":"^15.9.0","prettier":"^2.8.4","@eslint/js":"^9.9.1","jest-junit":"^16.0.0"},"_npmOperationalInternal":{"tmp":"tmp/postgis_1.0.6_1753685527574_0.8413088239088551","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"postgis","version":"1.2.0","description":"A lightweight, type-safe Node.js library for interacting with PostGIS-enabled PostgreSQL databases. Supports GeoJSON, Geobuf, MVT tiles, spatial queries, and more.","author":{"name":"Suyog Dinesh Jadhav"},"license":"MIT","homepage":"https://jsuyog2.github.io/postgis","repository":{"type":"git","url":"git+https://github.com/jsuyog2/postgis.git"},"bugs":{"url":"https://github.com/jsuyog2/postgis/issues"},"sideEffects":false,"main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"engines":{"node":">=18"},"keywords":["postgis","postgresql","postgres","geospatial","gis","spatial","nodejs","database","geojson","geobuf","mvt","vector-tiles","mapbox","pg","node-postgres","typescript","wgs84","srid","bounding-box","nearest-neighbor"],"scripts":{"build":"tsup","dev":"tsup --watch","test":"vitest run --coverage","test:watch":"vitest","lint":"eslint src __tests__","format":"prettier --write .","format:check":"prettier --check .","docs:dev":"vitepress dev docs","docs:build":"vitepress build docs","docs:preview":"vitepress preview docs","prepublishOnly":"npm run lint && npm run test && npm run build"},"devDependencies":{"@eslint/js":"^9.9.1","@types/node":"^25.4.0","@typescript-eslint/eslint-plugin":"^8.0.0","@typescript-eslint/parser":"^8.0.0","@vitest/coverage-v8":"^3.0.0","eslint":"^9.0.0","globals":"^15.9.0","prettier":"^3.0.0","tsup":"^8.0.0","typescript":"^5.5.0","typescript-eslint":"^8.0.0","vitepress":"^1.6.4","vitest":"^3.0.0"},"funding":{"type":"github","url":"https://github.com/sponsors/jsuyog2"},"_id":"postgis@1.2.0","gitHead":"10699acff91a6fc7ccc13095bfe4c5f86df5ad3b","_nodeVersion":"20.20.0","_npmVersion":"10.8.2","dist":{"integrity":"sha512-Zyo+7za+b3+k29z87eUoefAzgq5Nm0yVi5iwuDjtGZ+tfCSevJ7ZucxF3Bfb+Vgza1LqRnkBLszJQHtszxsKWw==","shasum":"044427aababd6185c1757eaa33ad9c0f50cbded7","tarball":"https://registry.npmjs.org/postgis/-/postgis-1.2.0.tgz","fileCount":10,"unpackedSize":156328,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDvIJM4zV2IpE+xQyDaA/5IvcREzmw3oIwggmif5HSvrwIgQHLyxfxv4G6ENJh+nhatXEUopivu/S798thH+bH9jsQ="}]},"_npmUser":{"name":"jsuyog2","email":"jsuyog2@gmail.com"},"directories":{},"maintainers":[{"name":"jsuyog2","email":"jsuyog2@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/postgis_1.2.0_1773125641584_0.23036147232272453"},"_hasShrinkwrap":false}},"time":{"created":"2024-08-30T12:57:09.764Z","modified":"2026-03-10T06:54:01.833Z","1.0.0":"2022-05-13T04:39:47.140Z","1.0.1":"2024-08-28T01:21:08.172Z","1.0.2":"2024-08-30T12:57:09.938Z","1.0.3":"2024-08-30T13:29:34.229Z","1.0.4":"2024-08-30T19:49:06.087Z","1.0.5":"2024-09-05T20:12:11.491Z","1.0.6":"2025-07-28T06:52:07.767Z","1.2.0":"2026-03-10T06:54:01.724Z"},"bugs":{"url":"https://github.com/jsuyog2/postgis/issues"},"author":{"name":"Suyog Dinesh Jadhav"},"license":"MIT","homepage":"https://jsuyog2.github.io/postgis","keywords":["postgis","postgresql","postgres","geospatial","gis","spatial","nodejs","database","geojson","geobuf","mvt","vector-tiles","mapbox","pg","node-postgres","typescript","wgs84","srid","bounding-box","nearest-neighbor"],"repository":{"type":"git","url":"git+https://github.com/jsuyog2/postgis.git"},"description":"A lightweight, type-safe Node.js library for interacting with PostGIS-enabled PostgreSQL databases. Supports GeoJSON, Geobuf, MVT tiles, spatial queries, and more.","maintainers":[{"name":"jsuyog2","email":"jsuyog2@gmail.com"}],"readme":"# postgis\n\n[![npm version](https://img.shields.io/npm/v/postgis.svg?style=flat-square)](https://www.npmjs.com/package/postgis)\n[![npm downloads](https://img.shields.io/npm/dm/postgis.svg?style=flat-square)](https://www.npmjs.com/package/postgis)\n[![Build Status](https://github.com/jsuyog2/postgis/actions/workflows/ci.yml/badge.svg)](https://github.com/jsuyog2/postgis/actions/workflows/ci.yml)\n[![Coverage](https://codecov.io/gh/jsuyog2/postgis/branch/main/graph/badge.svg)](https://codecov.io/gh/jsuyog2/postgis)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](https://opensource.org/licenses/MIT)\n[![TypeScript](https://img.shields.io/badge/TypeScript-5.x-blue?style=flat-square&logo=typescript)](https://www.typescriptlang.org/)\n\n> A **lightweight, type-safe** Node.js library for interacting with PostGIS-enabled PostgreSQL databases. Export GeoJSON, serve MVT vector tiles, run spatial queries, and more — with zero runtime dependencies.\n\n📖 **[Full Documentation →](https://jsuyog2.github.io/postgis)**\n\n---\n\n## Features\n\n| Feature | Details |\n|---|---|\n| 🔷 **TypeScript First** | Full type definitions, IntelliSense, and compile-time safety |\n| 📦 **Dual ESM + CJS** | Tree-shakable ESM + CommonJS fallback — works everywhere |\n| ⚡ **Zero Runtime Deps** | Bring your own `pg` client, nothing else required |\n| 🗺️ **Spatial Queries** | bbox, centroid, intersections, nearest, coordinate transforms |\n| 📄 **GeoJSON Export** | Full `FeatureCollection` with bounds, ID, and precision control |\n| 🗜️ **Geobuf Export** | Binary-compact protobuf encoding via `ST_AsGeobuf` |\n| 🧱 **MVT Tiles** | Server-side Mapbox Vector Tiles via `ST_AsMVT` |\n| 🧪 **Fully Tested** | 50+ unit tests with mocked `pg.Client` — no database needed |\n\n---\n\n## Installation\n\n```bash\nnpm install postgis pg\n```\n\n```bash\nyarn add postgis pg\n```\n\n```bash\npnpm add postgis pg\n```\n\n**Requirements:** Node.js ≥ 18, PostgreSQL ≥ 12, PostGIS ≥ 3.0\n\n---\n\n## Quick Start\n\n```typescript\nimport { Client } from 'pg';\nimport Postgis from 'postgis';\n\nconst client = new Client({ connectionString: process.env.DATABASE_URL });\nawait client.connect();\n\nconst postgis = new Postgis(client);\n\n// List spatial tables\nconst tables = await postgis.list_tables();\n\n// Export as GeoJSON\nconst fc = await postgis.geojson('parcels', { precision: 6, columns: 'name, area' });\nconsole.log(fc.type); // \"FeatureCollection\"\n\n// Find 5 nearest hospitals\nconst nearby = await postgis.nearest('hospitals', '73.5,14.9,4326', { limit: 5 });\n\nawait client.end();\n```\n\n**CommonJS:**\n\n```javascript\nconst Postgis = require('postgis');\nconst postgis = new Postgis(client);\n```\n\n---\n\n## API Documentation\n\n### Constructor\n\n```typescript\nnew Postgis(client: PostgisClient)\n```\n\nAccepts any `pg.Client`, `pg.Pool` client, or any object with a `query(sql)` method.\n\n---\n\n### `list_tables(options?)`\n\nLists all user-accessible tables with PostGIS geometry metadata.\n\n```typescript\nconst tables = await postgis.list_tables({ filter: \"table_type = 'BASE TABLE'\" });\n```\n\n---\n\n### `list_columns(table)`\n\nLists all columns of a table using PostgreSQL system catalogs.\n\n```typescript\nconst cols = await postgis.list_columns('parcels');\n// [{ field_name: 'geom', field_type: 'geometry' }, ...]\n```\n\n---\n\n### `query_table(table, options?)`\n\nFlexible SELECT with filter, group, sort, and limit.\n\n```typescript\nconst rows = await postgis.query_table('parcels', {\n  columns: 'id, name',\n  filter: \"status = 'active'\",\n  sort: 'name ASC',\n  limit: 50,\n});\n```\n\n---\n\n### `bbox(table, options?)`\n\nReturns the spatial bounding box (`ST_Extent`) of all geometries.\n\n```typescript\nconst [{ bbox }] = await postgis.bbox('parcels', { srid: 4326 });\n```\n\n---\n\n### `centroid(table, options?)`\n\nReturns the centroid `(x, y)` of each geometry.\n\n```typescript\nconst pts = await postgis.centroid('parcels', { force_on_surface: true });\n```\n\n---\n\n### `intersect_feature(table_from, table_to, options?)`\n\nCross-table spatial intersection using `ST_DWithin`.\n\n```typescript\nconst hits = await postgis.intersect_feature('roads', 'parcels', { distance: '50' });\n```\n\n---\n\n### `intersect_point(table, point, options?)`\n\nFeatures within `distance` of a point.\n\n```typescript\n// point format: \"longitude,latitude,SRID\"\nconst nearby = await postgis.intersect_point('shops', '73.5,14.9,4326', {\n  distance: '500',\n  limit: 20,\n});\n```\n\n---\n\n### `geojson(table, options?)`\n\nExports a GeoJSON `FeatureCollection`.\n\n```typescript\nconst fc = await postgis.geojson('parcels', {\n  bounds: '72.8,18.9,73.2,19.2',  // xmin,ymin,xmax,ymax\n  precision: 6,\n  columns: 'name, area',\n});\n// { type: 'FeatureCollection', features: [...] }\n```\n\n---\n\n### `geobuf(table, options?)`\n\nExports features as a Geobuf binary `Buffer`.\n\n```typescript\nconst buf = await postgis.geobuf('parcels');\nres.setHeader('Content-Type', 'application/x-protobuf');\nres.send(buf);\n```\n\n---\n\n### `mvt(table, x, y, z, options?)`\n\nGenerates a Mapbox Vector Tile for tile coordinate `z/x/y`.\n\n```typescript\nconst [{ mvt }] = await postgis.mvt('parcels', 0, 0, 0);\nres.setHeader('Content-Type', 'application/vnd.mapbox-vector-tile');\nres.send(mvt);\n```\n\n---\n\n### `nearest(table, point, options?)`\n\nKNN nearest-neighbor search ordered by `<->` distance operator.\n\n```typescript\nconst closest = await postgis.nearest('hospitals', '73.5,14.9,4326', { limit: 5 });\n// Each row includes a `distance` column\n```\n\n---\n\n### `transform_point(point, options?)`\n\nTransforms a point between coordinate systems.\n\n```typescript\nconst [{ x, y }] = await postgis.transform_point('73.5,14.9,4326', { srid: 3857 });\n```\n\n---\n\n## Configuration\n\n### Environment Variables\n\n| Variable | Description |\n|---|---|\n| `DATABASE_URL` | PostgreSQL connection string |\n| `POSTGIS_DEBUG` | Set to `'true'` to log all SQL queries to stderr |\n\n### Point Format\n\nMethods accepting a `point` argument use `\"x,y,srid\"` format:\n\n```\n73.70534,14.94202,4326  →  longitude,latitude,EPSG:4326\n```\n\n---\n\n## Advanced Usage\n\n### MVT Tile Server (Express)\n\n```typescript\napp.get('/tiles/:z/:x/:y.mvt', async (req, res) => {\n  const client = await pool.connect();\n  try {\n    const postgis = new Postgis(client);\n    const [row] = await postgis.mvt('parcels', +req.params.x, +req.params.y, +req.params.z);\n    if (!row?.mvt) return res.status(204).end();\n    res\n      .setHeader('Content-Type', 'application/vnd.mapbox-vector-tile')\n      .setHeader('Cache-Control', 'public, max-age=3600')\n      .send(row.mvt);\n  } finally {\n    client.release();\n  }\n});\n```\n\n### Using with pg.Pool\n\n```typescript\nconst client = await pool.connect();\nconst postgis = new Postgis(client);\ntry {\n  return await postgis.geojson('my_layer');\n} finally {\n  client.release();\n}\n```\n\n---\n\n## Performance Notes\n\n- **Spatial indexes** are essential for large tables. Add a GiST index:\n  ```sql\n  CREATE INDEX ON my_layer USING GIST(geom);\n  ```\n- **MVT queries** internally call `ST_TileEnvelope` — PostGIS 3.0+ required.\n- **Bounds filtering** avoids full-table scans when a `bounds` argument is provided.\n- **`nearest()`** uses the index-accelerated `<->` KNN operator — much faster than `ORDER BY ST_Distance`.\n\n---\n\n## Security\n\n> [!WARNING]\n> SQL values (table names, column names, filters) are interpolated directly into SQL strings — **not parameterized**. Never pass raw user input as `table`, `filter`, or `columns` arguments.\n\nSee [SECURITY.md](SECURITY.md) for the full security policy and reporting process.\n\n---\n\n## Examples\n\nSee the [`examples/`](examples/) directory:\n\n| File | Description |\n|---|---|\n| [`basic-usage.js`](examples/basic-usage.js) | List tables, columns, query, bbox |\n| [`geojson-export.js`](examples/geojson-export.js) | Export GeoJSON and Geobuf to files |\n| [`mvt-server.js`](examples/mvt-server.js) | Express MVT tile server with Mapbox GL JS viewer |\n\n---\n\n## FAQ\n\n**Does it work with pg.Pool?**\nYes — acquire a client from the pool, pass it to `new Postgis(client)`, and release it after.\n\n**CommonJS or ESM?**\nBoth. Import with `import Postgis from 'postgis'` (ESM) or `const Postgis = require('postgis')` (CJS).\n\n**Any runtime dependencies?**\nNone. `pg` is a peer dependency — you install and manage it yourself.\n\nFull FAQ: [jsuyog2.github.io/postgis/guide/faq](https://jsuyog2.github.io/postgis/guide/faq)\n\n---\n\n## Contributing\n\nWe welcome contributions! Please read [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines on:\n\n- Setting up the dev environment\n- Running tests (`npm test`)\n- Submitting pull requests\n\n## Changelog\n\nSee [CHANGELOG.md](CHANGELOG.md) for version history.\n\n## License\n\n[MIT](LICENSE) © [Suyog Dinesh Jadhav](https://github.com/jsuyog2)","readmeFilename":"README.md"}