catastrogps 1.2.1 → 2.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 +54 -34
- package/dist/index.d.mts +486 -186
- package/dist/index.d.ts +486 -186
- package/dist/index.js +75 -28
- package/dist/index.mjs +74 -28
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# catastrogps
|
|
2
2
|
|
|
3
|
-
Official JavaScript and TypeScript client for the [Catastro GPS API](https://www.catastrogps.es/developers): cadastral parcels from **29 European countries (
|
|
3
|
+
Official JavaScript and TypeScript client for the [Catastro GPS API](https://www.catastrogps.es/developers): cadastral parcels from **29 European countries (including the Basque Country and Navarre foral cadastres)**, with one API key: by cadastral reference in 27, by coordinates in all 29.
|
|
4
4
|
|
|
5
5
|
- Look up a parcel by its **official cadastral reference** or by **coordinates**, with the country detected for you.
|
|
6
6
|
- Turn a **postal address into parcels** in Spain and 26 more countries, ranked by confidence.
|
|
@@ -27,7 +27,7 @@ import { CatastroGPS } from 'catastrogps';
|
|
|
27
27
|
const client = new CatastroGPS({ apiKey: process.env.CATASTROGPS_API_KEY });
|
|
28
28
|
|
|
29
29
|
const parcel = await client.parcels.get('9872023VH5797S0001WX');
|
|
30
|
-
console.log(parcel.
|
|
30
|
+
console.log(parcel.municipality, parcel.parcelArea, parcel.latitude, parcel.longitude);
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
`new CatastroGPS()` with no arguments reads `CATASTROGPS_API_KEY` from the environment.
|
|
@@ -36,42 +36,46 @@ console.log(parcel.municipio, parcel.superficieParcela, parcel.latitud, parcel.l
|
|
|
36
36
|
|
|
37
37
|
| Method | Endpoint | Countries |
|
|
38
38
|
|--------|----------|-----------|
|
|
39
|
-
| `parcels.get(ref, { country })` | `GET /
|
|
40
|
-
| `parcels.
|
|
41
|
-
| `
|
|
42
|
-
| `parcels.
|
|
43
|
-
| `
|
|
44
|
-
| `parcels.
|
|
45
|
-
| `
|
|
46
|
-
| `parcels.
|
|
47
|
-
| `parcels.
|
|
48
|
-
| `parcels.
|
|
39
|
+
| `parcels.get(ref, { country, lang })` | `GET /v1/parcels/{ref}` | All references (see coverage); `subparcelCount` and `cropSummary` where there are crops |
|
|
40
|
+
| `parcels.subparcels(ref, { country, lang })` | `GET /v1/parcels/{ref}/subparcels` | ES (with Bizkaia, Álava, Navarre, Gipuzkoa), AT, EE, GR. 1 unit; 0 when there are none; `503 SUB_001` is not charged |
|
|
41
|
+
| `parcels.neighbors(ref, { country })` | `GET /v1/parcels/{ref}/neighbors` | Spain from the cadastre; elsewhere from our own copy (`supported: false`, free, when not) |
|
|
42
|
+
| `parcels.atPoint({ lat, lng, country })` | `GET /v1/search/coordinates` | All, including HR, SE and UK (Scotland) |
|
|
43
|
+
| `searchAddressCandidates(q \| { q, street, number, municipality, postcode, country, limit })` | `GET /v1/search/address/candidates` | Spain (with Basque Country and Navarre) and 26 more; not SE or HR |
|
|
44
|
+
| `parcels.findByAddress(text)` | `POST /v1/search/address/parse` | Spain, central Catastro, live (prefer the candidates search) |
|
|
45
|
+
| `getUnits(ref14, { country, previous })`, `iterUnitPages` | `GET /v1/parcels/{ref14}/units` | `ES`, `PV`, `NA` |
|
|
46
|
+
| `parcels.geometry(ref, { country })` | `GET /v1/parcels/{ref}/polygon` | All but UK |
|
|
47
|
+
| `parcels.terrain(ref, { country, lat, lng })` | `GET /v1/parcels/{ref}/terrain` | All; `lat`/`lng` required outside ES, PV, NA, PT, FR, IT, DE |
|
|
48
|
+
| `parcels.groundMotion(ref, { country, lat, lng })` | `GET /v1/parcels/{ref}/ground-motion` | Same as terrain, inside EGMS coverage |
|
|
49
|
+
| `parcels.solar`, `parcels.agriculture`, `parcels.score` | `/solar`, `/agriculture`, `/score` | ES, PV, NA, PT, FR, IT, DE |
|
|
50
|
+
| `parcels.market(ref, { country })` | `/market` | Sales in FR (DVF), IT (OMI) and DE (NRW); official province prices in `zonePrices` for ES, PV, NA; PT `available: false` |
|
|
49
51
|
| `parcels.valueHistory(ref, { country })` | `/value-history` | ES, PV, NA, PT, FR, IT, DE, AT |
|
|
50
|
-
| `parcels.compare([{ reference, country }, ...])` | `POST /
|
|
51
|
-
| `export.file(ref, 'kml' \| 'gpx'
|
|
52
|
-
| `
|
|
52
|
+
| `parcels.compare([{ reference, country }, ...])` | `POST /v1/parcels/compare` | 2 or 3 parcels in ES, PT, FR, IT, DE |
|
|
53
|
+
| `export.file(ref, 'kml' \| 'gpx', { country })` | `GET /v1/export/{format}` | Where a geometry exists |
|
|
54
|
+
| `locations.provinces()`, `locations.municipalities(region)`, `locations.streets({ region, municipality, name })` | `GET /v1/locations/...` | Spain (common territory): the names `findByAddress` expects |
|
|
55
|
+
| `cropCatalog({ lang })` | `GET /v1/reference/crops` | Free, no quota: every `cropCode` with its name in 10 languages |
|
|
56
|
+
| `resolve(text, { hint })` | `GET /v1/resolve` | Free, no quota: which country and kind a text is |
|
|
53
57
|
|
|
54
58
|
## Examples
|
|
55
59
|
|
|
56
60
|
```ts
|
|
57
61
|
const inWarsaw = await client.parcels.atPoint({ lat: 52.2297, lng: 21.0122 });
|
|
58
|
-
inWarsaw.
|
|
59
|
-
inWarsaw.
|
|
62
|
+
inWarsaw.reference;
|
|
63
|
+
inWarsaw.country;
|
|
60
64
|
|
|
61
|
-
const {
|
|
62
|
-
|
|
63
|
-
|
|
65
|
+
const { candidates } = await client.searchAddressCandidates({ q: 'Damrak 1, 1012 LG Amsterdam', country: 'NL' });
|
|
66
|
+
candidates[0].reference;
|
|
67
|
+
candidates[0].confidence;
|
|
64
68
|
|
|
65
69
|
const terrain = await client.parcels.terrain('10194A00110004');
|
|
66
70
|
terrain.relief.slope?.class;
|
|
67
|
-
terrain.
|
|
71
|
+
terrain.protectedAreas.natura2000;
|
|
68
72
|
terrain.climate?.baseline;
|
|
69
73
|
|
|
70
74
|
const brussels = await client.parcels.terrain('21004C0123/00', { country: 'BE', lat: 50.848139, lng: 4.353613 });
|
|
71
75
|
|
|
72
76
|
const motion = await client.parcels.groundMotion('0745901TG4304N0002KH');
|
|
73
77
|
motion.status;
|
|
74
|
-
motion.
|
|
78
|
+
motion.groundMotion?.vertical.meanMmYear;
|
|
75
79
|
|
|
76
80
|
const comparison = await client.parcels.compare([
|
|
77
81
|
{ reference: '9872023VH5797S0001WX', country: 'ES' },
|
|
@@ -82,35 +86,51 @@ const kml = await client.export.file('9872023VH5797S0001WX', 'kml');
|
|
|
82
86
|
|
|
83
87
|
const guess = await client.resolve('05102200100005');
|
|
84
88
|
guess.candidates;
|
|
89
|
+
|
|
90
|
+
const crops = await client.parcels.subparcels('46063A00100121', { lang: 'en' });
|
|
91
|
+
crops.subparcels[0].cropCode;
|
|
92
|
+
crops.subparcels[0].crop;
|
|
93
|
+
crops.subparcels[0].cropOriginal;
|
|
94
|
+
|
|
95
|
+
const catalog = await client.cropCatalog({ lang: 'fr' });
|
|
96
|
+
catalog.crops.find((crop) => crop.code === 'G-')?.name;
|
|
97
|
+
|
|
98
|
+
const around = await client.parcels.neighbors('9872023VH5797S');
|
|
99
|
+
around.neighbors.map((n) => n.reference);
|
|
100
|
+
|
|
101
|
+
const { provinces } = await client.locations.provinces();
|
|
102
|
+
const { streets } = await client.locations.streets({ region: 'CIUDAD REAL', municipality: 'AGUDO', name: 'GLORIA' });
|
|
85
103
|
```
|
|
86
104
|
|
|
105
|
+
Crop names come in `lang` (`es`, `ca`, `en`, `pt`, `fr`, `it`, `de`, `pl`, `nl`, `cs`; English by default); the label as the source writes it is always in `cropOriginal`, and `cropCode` is stable across languages. Since 2.1.0 the parcel no longer embeds its subparcels: it carries `subparcelCount` and a `cropSummary` (crop and share of the area), and the full list with outlines is `parcels.subparcels`.
|
|
106
|
+
|
|
87
107
|
`terrain` and `groundMotion` carry a `source.attribution` string that must be shown next to the data. A ground motion answer with `status: 'no_data'` and `reason: 'no_reflectors'` means the satellite had nothing stable to measure (fields, forest, water): there is no figure, not a zero.
|
|
88
108
|
|
|
89
|
-
Responses are the
|
|
109
|
+
Responses are the `data` object of the English v1 API (`https://api.parcelgps.com/v1`), typed: `reference`, `municipality`, `parcelArea`, `latitude`, `longitude`… Values that come from an official source (land use, addresses) stay in its language. See the [API reference](https://www.parcelgps.com/en/api/docs) and the OpenAPI spec at `https://api.parcelgps.com/v1/openapi.json`. Version 2 of this SDK talks only to `/v1`; 1.x used the deprecated Spanish-named `/api` routes.
|
|
90
110
|
|
|
91
111
|
## Import a building (comunidad de propietarios, Spain)
|
|
92
112
|
|
|
93
113
|
Address, then finca (14-character reference), then every unit with use, area, participation coefficient, stair, floor and door.
|
|
94
114
|
|
|
95
115
|
```ts
|
|
96
|
-
const {
|
|
97
|
-
const finca =
|
|
116
|
+
const { candidates } = await client.searchAddressCandidates('Avenida José Rodríguez de la Borbolla Camoyán 10, Dos Hermanas');
|
|
117
|
+
const finca = candidates[0];
|
|
98
118
|
|
|
99
|
-
const comunidad = await client.getUnits(finca.
|
|
100
|
-
comunidad.
|
|
101
|
-
for (const u of comunidad.
|
|
102
|
-
console.log(u.
|
|
119
|
+
const comunidad = await client.getUnits(finca.reference, { country: finca.country as 'ES' | 'PV' | 'NA' });
|
|
120
|
+
comunidad.propertyUnitCount;
|
|
121
|
+
for (const u of comunidad.units) {
|
|
122
|
+
console.log(u.reference, u.use, u.area, u.ownershipShare, u.staircase, u.floor, u.door);
|
|
103
123
|
}
|
|
104
124
|
comunidad.dataSource;
|
|
105
125
|
comunidad.attribution;
|
|
106
126
|
|
|
107
|
-
const refreshed = await client.getUnits(finca.
|
|
127
|
+
const refreshed = await client.getUnits(finca.reference, { previous: comunidad });
|
|
108
128
|
refreshed.changed;
|
|
109
129
|
```
|
|
110
130
|
|
|
111
131
|
- `getUnits` follows `nextCursor` for you (up to 200 units per page). `iterUnitPages(ref)` yields page by page.
|
|
112
132
|
- **Cost: one quota unit per unit served** in each page, minimum one per page; a page is cut to the quota you have left. Pass the previous result as `previous` to re-import: unchanged pages come back as `304 Not Modified`, cost nothing and are reused; `changed` tells you if anything moved.
|
|
113
|
-
- Basque Country and Navarre (`country: 'PV' | 'NA'`) are served from our copy of each foral cadastre: pass the foral reference of any unit or the finca key
|
|
133
|
+
- Basque Country and Navarre (`country: 'PV' | 'NA'`) are served from our copy of each foral cadastre: pass the foral reference of any unit or the finca key as the reference. The foral open data carry no participation coefficient.
|
|
114
134
|
- Organisations with a per-finca cap agreed by contract (Startup and Growth) pay at most that cap per finca and period: see `client.lastQuota.fincaCap` (`{ cap, used }`).
|
|
115
135
|
|
|
116
136
|
## Quota, prepaid balance and limits
|
|
@@ -163,7 +183,7 @@ try {
|
|
|
163
183
|
| `NotFoundError` | `404 NOT_FOUND` |
|
|
164
184
|
| `QuotaExceededError` | `429 KEY_AUTH_004` |
|
|
165
185
|
| `RateLimitError` | `429 KEY_RATE_002`, `RATE_LIMIT_EXCEEDED`; `retryAfterSeconds` |
|
|
166
|
-
| `ServiceUnavailableError` | `503 SERVICE_UNAVAILABLE
|
|
186
|
+
| `ServiceUnavailableError` | `503 SERVICE_UNAVAILABLE`, `503 SUB_001` (subparcels source down, not charged); `retryAfterSeconds` |
|
|
167
187
|
| `ServerError`, `TimeoutError`, `NetworkError` | `5xx`, client timeout, network failure |
|
|
168
188
|
|
|
169
189
|
Timeouts, network errors, per-minute 429s and 502/503/504 are retried up to `maxRetries` times (default 2) with exponential backoff, waiting `Retry-After` when the API sends it (up to 60 s). An exhausted monthly quota is never retried.
|
|
@@ -173,14 +193,14 @@ Timeouts, network errors, per-minute 429s and 502/503/504 are retried up to `max
|
|
|
173
193
|
| Option | Default | |
|
|
174
194
|
|--------|---------|---|
|
|
175
195
|
| `apiKey` | `process.env.CATASTROGPS_API_KEY` | Required |
|
|
176
|
-
| `baseUrl` | `https://api.
|
|
196
|
+
| `baseUrl` | `https://api.parcelgps.com` | Paths are under `/v1` |
|
|
177
197
|
| `timeoutMs` | `30000` | Official cadastres can be slow |
|
|
178
198
|
| `maxRetries` | `2` | |
|
|
179
199
|
| `fetch` | `globalThis.fetch` | Inject your own for tests or proxies |
|
|
180
200
|
|
|
181
201
|
## Coverage
|
|
182
202
|
|
|
183
|
-
Measured against production on 1 October 2026. 29 European countries,
|
|
203
|
+
Measured against production on 1 October 2026. 29 European countries, including the Basque Country and Navarre foral cadastres: by cadastral reference in 27, by coordinates in all 29; in Croatia, Sweden and the United Kingdom the source is partial, as the table shows.
|
|
184
204
|
|
|
185
205
|
| Code | Country / region | Reference | Coordinates | Address | Notes |
|
|
186
206
|
|------|------------------|:---:|:---:|:---:|-------|
|