catastrogps 1.0.0 → 1.2.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 +132 -41
- package/dist/index.d.mts +293 -2
- package/dist/index.d.ts +293 -2
- package/dist/index.js +291 -56
- package/dist/index.mjs +286 -55
- package/package.json +9 -4
package/README.md
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
# catastrogps
|
|
2
2
|
|
|
3
|
-
Official JavaScript and TypeScript client for the [Catastro GPS API](https://www.catastrogps.es/developers): cadastral parcels
|
|
3
|
+
Official JavaScript and TypeScript client for the [Catastro GPS API](https://www.catastrogps.es/developers): cadastral parcels from **26 European cadastres plus the foral cadastres of the Basque Country and Navarre** with one API key.
|
|
4
4
|
|
|
5
5
|
- Look up a parcel by its **official cadastral reference** or by **coordinates**, with the country detected for you.
|
|
6
|
-
- Turn a **
|
|
6
|
+
- Turn a **postal address into parcels** in Spain and 26 more countries, ranked by confidence.
|
|
7
|
+
- Import **every unit of a Spanish building** (dwellings, shops, garages) with paging and free `304` refreshes.
|
|
7
8
|
- Get the **parcel outline** (GeoJSON or a `[lat, lng]` ring), and **KML / GPX / DXF** exports.
|
|
8
|
-
- **
|
|
9
|
+
- **Relief, Natura 2000 and climate** (Copernicus DEM, EEA, ERA5-Land) and **ground motion** (Copernicus EGMS, mm/year) for any covered country.
|
|
10
|
+
- **Solar**, **agriculture**, **market**, **score**, **value history** and **comparison** for Spain, Portugal, France, Italy and Germany.
|
|
11
|
+
- Quota, prepaid balance and per-minute limit of every response, typed errors for every API code.
|
|
9
12
|
- Zero runtime dependencies. Node.js 18+, Deno, Bun and edge runtimes with `fetch`. ESM and CommonJS, fully typed.
|
|
10
13
|
|
|
11
14
|
**Free tier: 250 calls a month, forever. Failed lookups are not charged.** Get a key at [catastrogps.es/developers](https://www.catastrogps.es/developers).
|
|
@@ -29,40 +32,106 @@ console.log(parcel.municipio, parcel.superficieParcela, parcel.latitud, parcel.l
|
|
|
29
32
|
|
|
30
33
|
`new CatastroGPS()` with no arguments reads `CATASTROGPS_API_KEY` from the environment.
|
|
31
34
|
|
|
35
|
+
## Methods
|
|
36
|
+
|
|
37
|
+
| Method | Endpoint | Countries |
|
|
38
|
+
|--------|----------|-----------|
|
|
39
|
+
| `parcels.get(ref, { country })` | `GET /api/catastro/{ref}` | All references (see coverage) |
|
|
40
|
+
| `parcels.atPoint({ lat, lng, country })` | `GET /api/search/coordinates` | All, including HR, SE and UK (Scotland) |
|
|
41
|
+
| `searchAddressCandidates(q \| { q, street, number, municipality, postcode, country, limit })` | `GET /api/search/address/candidates` | Spain (with Basque Country and Navarre) and 26 more; not SE or HR |
|
|
42
|
+
| `parcels.findByAddress(text)` | `POST /api/search/address/parse` | Spain, central Catastro, live (prefer the candidates search) |
|
|
43
|
+
| `getUnits(ref14, { country, previous })`, `iterUnitPages` | `GET /api/catastro/{ref14}/units` | `ES`, `PV`, `NA` |
|
|
44
|
+
| `parcels.geometry(ref, { country })` | `GET /api/catastro/{ref}/polygon` | All but UK |
|
|
45
|
+
| `parcels.terrain(ref, { country, lat, lng })` | `GET /api/catastro/{ref}/terrain` | All; `lat`/`lng` required outside ES, PV, NA, PT, FR, IT, DE |
|
|
46
|
+
| `parcels.groundMotion(ref, { country, lat, lng })` | `GET /api/catastro/{ref}/ground-motion` | Same as terrain, inside EGMS coverage |
|
|
47
|
+
| `parcels.solar`, `parcels.agriculture`, `parcels.score` | `/solar`, `/agro`, `/score` | ES, PV, NA, PT, FR, IT, DE |
|
|
48
|
+
| `parcels.market(ref, { country })` | `/market` | Figures in FR, IT and DE (NRW); a note without figures elsewhere |
|
|
49
|
+
| `parcels.valueHistory(ref, { country })` | `/value-history` | ES, PV, NA, PT, FR, IT, DE, AT |
|
|
50
|
+
| `parcels.compare([{ reference, country }, ...])` | `POST /api/catastro/compare` | 2 or 3 parcels in ES, PT, FR, IT, DE |
|
|
51
|
+
| `export.file(ref, 'kml' \| 'gpx' \| 'dxf', { country })` | `GET /api/export/{format}` | Where a geometry exists |
|
|
52
|
+
| `resolve(text, { hint })` | `GET /api/resolve` | Free, no quota: which country and kind a text is |
|
|
53
|
+
|
|
32
54
|
## Examples
|
|
33
55
|
|
|
34
56
|
```ts
|
|
35
|
-
const fromAddress = await client.parcels.findByAddress('Calle Mallorca 213, Barcelona');
|
|
36
|
-
fromAddress.referenciaCatastral;
|
|
37
|
-
|
|
38
57
|
const inWarsaw = await client.parcels.atPoint({ lat: 52.2297, lng: 21.0122 });
|
|
39
58
|
inWarsaw.referenciaCatastral;
|
|
40
59
|
inWarsaw.pais;
|
|
41
60
|
|
|
42
|
-
const
|
|
61
|
+
const { candidatos } = await client.searchAddressCandidates({ q: 'Damrak 1, 1012 LG Amsterdam', country: 'NL' });
|
|
62
|
+
candidatos[0].refCatastral;
|
|
63
|
+
candidatos[0].confianza;
|
|
64
|
+
|
|
65
|
+
const terrain = await client.parcels.terrain('10194A00110004');
|
|
66
|
+
terrain.relief.slope?.class;
|
|
67
|
+
terrain.protected_areas.natura2000;
|
|
68
|
+
terrain.climate?.baseline;
|
|
43
69
|
|
|
44
|
-
const
|
|
45
|
-
outline.geojson;
|
|
70
|
+
const brussels = await client.parcels.terrain('21004C0123/00', { country: 'BE', lat: 50.848139, lng: 4.353613 });
|
|
46
71
|
|
|
47
|
-
const
|
|
48
|
-
|
|
72
|
+
const motion = await client.parcels.groundMotion('0745901TG4304N0002KH');
|
|
73
|
+
motion.status;
|
|
74
|
+
motion.ground_motion?.vertical.mean_mm_year;
|
|
75
|
+
|
|
76
|
+
const comparison = await client.parcels.compare([
|
|
77
|
+
{ reference: '9872023VH5797S0001WX', country: 'ES' },
|
|
78
|
+
{ reference: '750560000AB0001', country: 'FR' },
|
|
79
|
+
]);
|
|
49
80
|
|
|
50
81
|
const kml = await client.export.file('9872023VH5797S0001WX', 'kml');
|
|
51
82
|
|
|
52
83
|
const guess = await client.resolve('05102200100005');
|
|
53
84
|
guess.candidates;
|
|
85
|
+
```
|
|
54
86
|
|
|
55
|
-
|
|
87
|
+
`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
|
+
|
|
89
|
+
Responses are the API's `data` object, with the field names the API uses (`refCatastral`, `municipio`, `superficieParcela`…). See the [API reference](https://www.catastrogps.es/developers) and the OpenAPI spec at `https://api.parcelgps.com/api/openapi.json`.
|
|
90
|
+
|
|
91
|
+
## Import a building (comunidad de propietarios, Spain)
|
|
92
|
+
|
|
93
|
+
Address, then finca (14-character reference), then every unit with use, area, participation coefficient, stair, floor and door.
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
const { candidatos } = await client.searchAddressCandidates('Avenida José Rodríguez de la Borbolla Camoyán 10, Dos Hermanas');
|
|
97
|
+
const finca = candidatos[0];
|
|
98
|
+
|
|
99
|
+
const comunidad = await client.getUnits(finca.refCatastral, { country: finca.pais as 'ES' | 'PV' | 'NA' });
|
|
100
|
+
comunidad.totalUnidadesFinca;
|
|
101
|
+
for (const u of comunidad.unidades) {
|
|
102
|
+
console.log(u.refCatastral, u.uso, u.superficie, u.participacion, u.escalera, u.planta, u.puerta);
|
|
103
|
+
}
|
|
104
|
+
comunidad.dataSource;
|
|
105
|
+
comunidad.attribution;
|
|
106
|
+
|
|
107
|
+
const refreshed = await client.getUnits(finca.refCatastral, { previous: comunidad });
|
|
108
|
+
refreshed.changed;
|
|
56
109
|
```
|
|
57
110
|
|
|
58
|
-
|
|
111
|
+
- `getUnits` follows `nextCursor` for you (up to 200 units per page). `iterUnitPages(ref)` yields page by page.
|
|
112
|
+
- **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 in `refCatastral`. The foral open data carry no participation coefficient.
|
|
114
|
+
- 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
|
+
|
|
116
|
+
## Quota, prepaid balance and limits
|
|
117
|
+
|
|
118
|
+
`client.lastQuota` is read from the headers of the last response; `conditionalRequest` also returns the `quota` of that exact response.
|
|
119
|
+
|
|
120
|
+
| Field | Header | Meaning |
|
|
121
|
+
|-------|--------|---------|
|
|
122
|
+
| `plan`, `limit`, `remaining`, `resetsAt` | `X-Quota-Tier`, `X-Quota-Limit`, `X-Quota-Remaining`, `X-Quota-Reset` | Monthly quota of your plan, after this response |
|
|
123
|
+
| `overage.balance`, `overage.unitPrice`, `overage.remainingUnits` | `X-Quota-Overage`, `X-Quota-Balance`, `X-Quota-Overage-Unit-Price`, `X-Quota-Overage-Remaining` | Prepaid pay-as-you-go balance in euros, used once the monthly quota is spent |
|
|
124
|
+
| `rateLimit.limit`, `rateLimit.remaining`, `rateLimit.resetSeconds` | `X-RateLimit-*` | Per-minute burst limit of your key (Free 10, Developer 60, Startup 120, Growth 300) |
|
|
125
|
+
| `fincaCap.cap`, `fincaCap.used` | `X-Quota-Finca-Cap`, `X-Quota-Finca-Cap-Used` | Only on `/units`, only with a contract cap |
|
|
126
|
+
|
|
127
|
+
When the monthly quota is spent and there is no prepaid balance left, the API answers `429 KEY_AUTH_004` (never `402`): the client throws `QuotaExceededError` with the `quota` of that response, and `prepaidBalanceEmpty` is true when your organisation has the prepaid overage on (top up at `https://parcelgps.com/app/developer`). Only 2xx responses spend quota; `300`, `304`, `4xx` and `5xx` are free, and so are 2xx answers without data.
|
|
59
128
|
|
|
60
129
|
## Errors
|
|
61
130
|
|
|
62
131
|
Every error is a `CatastroGPSError` with `status`, `code` and `details`. Subclasses let you branch cleanly:
|
|
63
132
|
|
|
64
133
|
```ts
|
|
65
|
-
import { AmbiguousReferenceError, CoverageError, NotFoundError, QuotaExceededError } from 'catastrogps';
|
|
134
|
+
import { AmbiguousReferenceError, CoverageError, NotFoundError, PlaceNameError, QuotaExceededError } from 'catastrogps';
|
|
66
135
|
|
|
67
136
|
try {
|
|
68
137
|
await client.parcels.get('05102200100005');
|
|
@@ -70,57 +139,79 @@ try {
|
|
|
70
139
|
if (error instanceof AmbiguousReferenceError) {
|
|
71
140
|
const [first] = error.candidates;
|
|
72
141
|
await client.parcels.get('05102200100005', { country: first.country as 'DE' });
|
|
73
|
-
} else if (error instanceof
|
|
142
|
+
} else if (error instanceof PlaceNameError) {
|
|
143
|
+
console.log('A place name, not a reference', error.location);
|
|
144
|
+
} else if (error instanceof CoverageError) {
|
|
145
|
+
console.log(error.country, error.feature, error.supportedCountries);
|
|
146
|
+
} else if (error instanceof NotFoundError) {
|
|
74
147
|
console.log(error.message);
|
|
75
148
|
} else if (error instanceof QuotaExceededError) {
|
|
76
|
-
console.log('
|
|
149
|
+
console.log('Quota spent', error.quota?.resetsAt, error.prepaidBalanceEmpty);
|
|
77
150
|
} else {
|
|
78
151
|
throw error;
|
|
79
152
|
}
|
|
80
153
|
}
|
|
81
154
|
```
|
|
82
155
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
156
|
+
| Class | API code / status |
|
|
157
|
+
|-------|-------------------|
|
|
158
|
+
| `AmbiguousReferenceError` | `300 CNV_AMBIGUOUS`: bare digits of several countries; `candidates` lists them |
|
|
159
|
+
| `CoverageError` | `422 CNV_COVERAGE`: country not covered, or an analysis outside its countries |
|
|
160
|
+
| `PlaceNameError` (a `ValidationError`) | `422 CNV_PLACE_NAME`: a place name, with the geocoded `location` when found |
|
|
161
|
+
| `ValidationError` | `400 VALIDATION_ERROR`, other `422` |
|
|
162
|
+
| `AuthenticationError` / `ForbiddenError` | `401 KEY_AUTH_001..003`, `403` |
|
|
163
|
+
| `NotFoundError` | `404 NOT_FOUND` |
|
|
164
|
+
| `QuotaExceededError` | `429 KEY_AUTH_004` |
|
|
165
|
+
| `RateLimitError` | `429 KEY_RATE_002`, `RATE_LIMIT_EXCEEDED`; `retryAfterSeconds` |
|
|
166
|
+
| `ServiceUnavailableError` | `503 SERVICE_UNAVAILABLE`; `retryAfterSeconds` |
|
|
167
|
+
| `ServerError`, `TimeoutError`, `NetworkError` | `5xx`, client timeout, network failure |
|
|
168
|
+
|
|
169
|
+
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.
|
|
86
170
|
|
|
87
171
|
## Options
|
|
88
172
|
|
|
89
173
|
| Option | Default | |
|
|
90
174
|
|--------|---------|---|
|
|
91
175
|
| `apiKey` | `process.env.CATASTROGPS_API_KEY` | Required |
|
|
92
|
-
| `baseUrl` | `https://api.catastrogps.es` | |
|
|
176
|
+
| `baseUrl` | `https://api.catastrogps.es` | `https://api.parcelgps.com` is the same API |
|
|
93
177
|
| `timeoutMs` | `30000` | Official cadastres can be slow |
|
|
94
178
|
| `maxRetries` | `2` | |
|
|
95
179
|
| `fetch` | `globalThis.fetch` | Inject your own for tests or proxies |
|
|
96
180
|
|
|
97
181
|
## Coverage
|
|
98
182
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
|
102
|
-
|
|
103
|
-
| `
|
|
104
|
-
| `
|
|
105
|
-
| `
|
|
106
|
-
| `
|
|
107
|
-
| `
|
|
108
|
-
| `
|
|
109
|
-
| `
|
|
110
|
-
| `
|
|
111
|
-
|
|
112
|
-
|
|
183
|
+
Measured against production on 1 October 2026. 26 European cadastres plus the Basque Country and Navarre; Croatia, Sweden and the United Kingdom are partial sources, listed for honesty.
|
|
184
|
+
|
|
185
|
+
| Code | Country / region | Reference | Coordinates | Address | Notes |
|
|
186
|
+
|------|------------------|:---:|:---:|:---:|-------|
|
|
187
|
+
| `ES` | Spain | Yes | Yes | Yes | Units per building |
|
|
188
|
+
| `PV` · `NA` | Basque Country · Navarre | Yes | Yes | With `country: 'ES'` | Foral cadastres; units per building |
|
|
189
|
+
| `FR` · `IT` | France · Italy | Yes | Yes | Yes | |
|
|
190
|
+
| `DE` | Germany | Partial | Partial | Partial | 15 of 16 Länder: **no Bavaria** |
|
|
191
|
+
| `PT` | Portugal | Yes | Partial | Partial | The cadastre does not cover Lisbon, Porto or Coimbra |
|
|
192
|
+
| `AT` `NL` `BE` `PL` `CZ` `DK` `NO` `FI` `EE` | Austria, Netherlands, Belgium, Poland, Czechia, Denmark, Norway, Finland, Estonia | Yes | Yes | Yes | Belgium is slow (3-15 s) |
|
|
193
|
+
| `CH` | Switzerland | Yes | Partial | Yes | Not in cantons that publish no parcels (e.g. Vaud) |
|
|
194
|
+
| `LT` `SI` `SK` `BG` `LU` `LI` `IS` `CY` | Lithuania, Slovenia, Slovakia, Bulgaria, Luxembourg, Liechtenstein, Iceland, Cyprus | Yes | Yes | Yes | |
|
|
195
|
+
| `GR` · `LV` | Greece · Latvia | With the country set | Yes | Yes | |
|
|
196
|
+
| `IE` | Ireland | With `country: 'IE'` | Partial | Partial | Numeric SP_ID |
|
|
197
|
+
| `SE` | Sweden | Agricultural blocks | Agricultural blocks | No | Not property units |
|
|
198
|
+
| `HR` | Croatia | No | ARKOD only | No | Agricultural parcels of the Paying Agency, not the cadastre |
|
|
199
|
+
| `UK` | United Kingdom | No | Scotland | Scotland | |
|
|
200
|
+
|
|
201
|
+
Not covered: Hungary, Romania and the rest (`CoverageError`). Terrain and ground motion work wherever a parcel outline exists, with `lat`/`lng` outside the seven analysis countries. Data comes from each official source, so availability follows theirs.
|
|
113
202
|
|
|
114
203
|
## Pricing
|
|
115
204
|
|
|
116
|
-
| Plan | Price | Calls / month |
|
|
117
|
-
|
|
118
|
-
| Free | €0, forever |
|
|
119
|
-
| Developer | €19 / month | 5,000 |
|
|
120
|
-
| Startup | €49 / month | 15,000 |
|
|
121
|
-
| Growth | €99 / month | 50,000 |
|
|
205
|
+
| Plan | Price | Calls / month | Prepaid overage per 1,000 |
|
|
206
|
+
|------|-------|---------------|---------------------------|
|
|
207
|
+
| Free | €0, forever | 250 | €10 |
|
|
208
|
+
| Developer | €19 / month | 5,000 | €5 |
|
|
209
|
+
| Startup | €49 / month | 15,000 | €4 |
|
|
210
|
+
| Growth | €99 / month | 50,000 | €2.50 |
|
|
211
|
+
|
|
212
|
+
Overage prices are net (VAT apart) and are charged from a prepaid balance you top up in the portal; with the balance at zero the API answers `429`, never debt.
|
|
122
213
|
|
|
123
|
-
The same key works with the Python SDK (`pip install catastrogps`) and the MCP server for AI agents ([`catastro-gps-mcp`](https://www.npmjs.com/package/catastro-gps-mcp)).
|
|
214
|
+
The same key works with the Python SDK (`pip install catastrogps`), the Go SDK and the MCP server for AI agents ([`catastro-gps-mcp`](https://www.npmjs.com/package/catastro-gps-mcp)).
|
|
124
215
|
|
|
125
216
|
## License
|
|
126
217
|
|
package/dist/index.d.mts
CHANGED
|
@@ -14,11 +14,33 @@ interface CatastroGPSOptions {
|
|
|
14
14
|
interface CountryOption<C extends string = CountryCode> {
|
|
15
15
|
country?: C;
|
|
16
16
|
}
|
|
17
|
+
declare const ADDRESS_COUNTRY_CODES: readonly ["ES", "FR", "IT", "DE", "AT", "NL", "BE", "PL", "CH", "CZ", "DK", "NO", "FI", "EE", "LV", "LT", "SI", "SK", "BG", "GR", "CY", "LU", "LI", "IS", "IE", "UK", "PT"];
|
|
18
|
+
type AddressCountryCode = (typeof ADDRESS_COUNTRY_CODES)[number];
|
|
19
|
+
declare const UNITS_COUNTRY_CODES: readonly ["ES", "PV", "NA"];
|
|
20
|
+
type UnitsCountryCode = (typeof UNITS_COUNTRY_CODES)[number];
|
|
21
|
+
interface PrepaidOverage {
|
|
22
|
+
enabled: boolean;
|
|
23
|
+
balance?: number;
|
|
24
|
+
unitPrice?: number;
|
|
25
|
+
remainingUnits?: number;
|
|
26
|
+
}
|
|
27
|
+
interface BurstLimit {
|
|
28
|
+
limit?: number;
|
|
29
|
+
remaining?: number;
|
|
30
|
+
resetSeconds?: number;
|
|
31
|
+
}
|
|
32
|
+
interface FincaCap {
|
|
33
|
+
cap?: number;
|
|
34
|
+
used?: number;
|
|
35
|
+
}
|
|
17
36
|
interface Quota {
|
|
18
37
|
plan?: string;
|
|
19
38
|
limit?: number;
|
|
20
39
|
remaining?: number;
|
|
21
40
|
resetsAt?: string;
|
|
41
|
+
overage?: PrepaidOverage;
|
|
42
|
+
rateLimit?: BurstLimit;
|
|
43
|
+
fincaCap?: FincaCap;
|
|
22
44
|
}
|
|
23
45
|
interface Parcel {
|
|
24
46
|
refCatastral: string;
|
|
@@ -117,6 +139,233 @@ interface ResolveResult {
|
|
|
117
139
|
candidates: ResolveCandidate[];
|
|
118
140
|
ambiguous: boolean;
|
|
119
141
|
}
|
|
142
|
+
interface AddressCandidatesQuery {
|
|
143
|
+
q?: string;
|
|
144
|
+
country?: AddressCountryCode;
|
|
145
|
+
street?: string;
|
|
146
|
+
number?: number;
|
|
147
|
+
municipality?: string;
|
|
148
|
+
postcode?: string;
|
|
149
|
+
limit?: number;
|
|
150
|
+
}
|
|
151
|
+
interface AddressCandidate {
|
|
152
|
+
refCatastral: string;
|
|
153
|
+
pais: 'ES' | 'PV' | 'NA' | string;
|
|
154
|
+
direccion: string;
|
|
155
|
+
numero?: number;
|
|
156
|
+
codigoPostal?: string;
|
|
157
|
+
municipio: string;
|
|
158
|
+
provincia: string;
|
|
159
|
+
latitud: number;
|
|
160
|
+
longitud: number;
|
|
161
|
+
confianza: number;
|
|
162
|
+
coincideNumero: boolean;
|
|
163
|
+
coincideMunicipio: boolean;
|
|
164
|
+
enCopia: boolean;
|
|
165
|
+
direccionCatastro?: string;
|
|
166
|
+
uso?: string;
|
|
167
|
+
viviendas?: number;
|
|
168
|
+
anioConstruccion?: number;
|
|
169
|
+
}
|
|
170
|
+
interface AddressCandidatesResult {
|
|
171
|
+
consulta: {
|
|
172
|
+
texto: string;
|
|
173
|
+
calle?: string;
|
|
174
|
+
numero?: number;
|
|
175
|
+
municipio?: string;
|
|
176
|
+
codigoPostal?: string;
|
|
177
|
+
};
|
|
178
|
+
candidatos: AddressCandidate[];
|
|
179
|
+
attribution: string;
|
|
180
|
+
}
|
|
181
|
+
interface Unit {
|
|
182
|
+
refCatastral: string;
|
|
183
|
+
escalera: string;
|
|
184
|
+
planta: string;
|
|
185
|
+
puerta: string;
|
|
186
|
+
uso: string;
|
|
187
|
+
superficie: number;
|
|
188
|
+
descripcion: string;
|
|
189
|
+
participacion?: number;
|
|
190
|
+
anio?: number;
|
|
191
|
+
direccion?: string;
|
|
192
|
+
}
|
|
193
|
+
interface Construction {
|
|
194
|
+
escalera: string;
|
|
195
|
+
planta: string;
|
|
196
|
+
puerta: string;
|
|
197
|
+
uso: string;
|
|
198
|
+
superficie: number;
|
|
199
|
+
descripcion: string;
|
|
200
|
+
}
|
|
201
|
+
interface UnitsPageData {
|
|
202
|
+
refCatastral: string;
|
|
203
|
+
direccion?: string;
|
|
204
|
+
codigoPostal?: string;
|
|
205
|
+
municipio?: string;
|
|
206
|
+
provincia?: string;
|
|
207
|
+
usoGeneral?: string;
|
|
208
|
+
superficieTotal?: number;
|
|
209
|
+
anioConstruccion?: number;
|
|
210
|
+
participacion?: string;
|
|
211
|
+
totalUnidades: number;
|
|
212
|
+
totalUnidadesFinca: number;
|
|
213
|
+
unidades: Unit[];
|
|
214
|
+
construcciones?: Construction[];
|
|
215
|
+
truncated: boolean;
|
|
216
|
+
nextCursor?: string;
|
|
217
|
+
dataSource: 'clone' | 'catastro' | string;
|
|
218
|
+
dataDate: string;
|
|
219
|
+
attribution: string;
|
|
220
|
+
}
|
|
221
|
+
interface UnitsPage {
|
|
222
|
+
cursor?: string;
|
|
223
|
+
etag?: string;
|
|
224
|
+
notModified: boolean;
|
|
225
|
+
data: UnitsPageData;
|
|
226
|
+
}
|
|
227
|
+
interface UnitsResult {
|
|
228
|
+
refCatastral: string;
|
|
229
|
+
direccion?: string;
|
|
230
|
+
codigoPostal?: string;
|
|
231
|
+
municipio?: string;
|
|
232
|
+
provincia?: string;
|
|
233
|
+
usoGeneral?: string;
|
|
234
|
+
anioConstruccion?: number;
|
|
235
|
+
totalUnidadesFinca: number;
|
|
236
|
+
unidades: Unit[];
|
|
237
|
+
construcciones: Construction[];
|
|
238
|
+
dataSource: string;
|
|
239
|
+
dataDate: string;
|
|
240
|
+
attribution: string;
|
|
241
|
+
changed: boolean;
|
|
242
|
+
pages: UnitsPage[];
|
|
243
|
+
}
|
|
244
|
+
interface GetUnitsOptions {
|
|
245
|
+
country?: UnitsCountryCode;
|
|
246
|
+
previous?: UnitsResult;
|
|
247
|
+
}
|
|
248
|
+
interface LocatedOptions extends CountryOption<Exclude<CountryCode, 'UK' | 'HR'>> {
|
|
249
|
+
lat?: number;
|
|
250
|
+
lng?: number;
|
|
251
|
+
}
|
|
252
|
+
interface DataSource {
|
|
253
|
+
name?: string;
|
|
254
|
+
provider?: string;
|
|
255
|
+
license?: string;
|
|
256
|
+
attribution?: string;
|
|
257
|
+
url?: string;
|
|
258
|
+
resolution?: string;
|
|
259
|
+
edition?: string;
|
|
260
|
+
}
|
|
261
|
+
type BlockStatus = 'ok' | 'no_data' | 'unavailable';
|
|
262
|
+
interface ProtectedSite {
|
|
263
|
+
code: string;
|
|
264
|
+
name: string;
|
|
265
|
+
type?: 'SPA' | 'SCI' | 'SPA_SCI' | string;
|
|
266
|
+
designation?: string;
|
|
267
|
+
country?: string;
|
|
268
|
+
overlap_pct?: number | null;
|
|
269
|
+
}
|
|
270
|
+
interface Terrain {
|
|
271
|
+
refcat: string;
|
|
272
|
+
country: string;
|
|
273
|
+
relief: {
|
|
274
|
+
status: BlockStatus;
|
|
275
|
+
elevation_m?: {
|
|
276
|
+
mean: number;
|
|
277
|
+
min: number;
|
|
278
|
+
max: number;
|
|
279
|
+
};
|
|
280
|
+
slope?: {
|
|
281
|
+
mean_pct: number;
|
|
282
|
+
mean_deg: number;
|
|
283
|
+
max_pct: number;
|
|
284
|
+
class: string;
|
|
285
|
+
max_class: string;
|
|
286
|
+
share_over_10_pct: number;
|
|
287
|
+
classes_pct: Record<string, number>;
|
|
288
|
+
};
|
|
289
|
+
aspect?: {
|
|
290
|
+
dominant: string;
|
|
291
|
+
dominant_share_pct: number;
|
|
292
|
+
mean_deg: number | null;
|
|
293
|
+
flat_share_pct: number;
|
|
294
|
+
sectors_pct: Record<string, number>;
|
|
295
|
+
};
|
|
296
|
+
sample?: {
|
|
297
|
+
method: string;
|
|
298
|
+
cells: number;
|
|
299
|
+
resolution_m: number;
|
|
300
|
+
};
|
|
301
|
+
source?: DataSource;
|
|
302
|
+
};
|
|
303
|
+
protected_areas: {
|
|
304
|
+
status: BlockStatus;
|
|
305
|
+
intersects?: boolean;
|
|
306
|
+
inside?: boolean;
|
|
307
|
+
max_overlap_pct?: number | null;
|
|
308
|
+
natura2000?: ProtectedSite[];
|
|
309
|
+
national?: ProtectedSite[];
|
|
310
|
+
method?: string;
|
|
311
|
+
sources?: DataSource[];
|
|
312
|
+
};
|
|
313
|
+
climate?: {
|
|
314
|
+
status: BlockStatus;
|
|
315
|
+
baseline?: Record<string, number>;
|
|
316
|
+
recent?: Record<string, number>;
|
|
317
|
+
[key: string]: unknown;
|
|
318
|
+
};
|
|
319
|
+
calculated_at?: string;
|
|
320
|
+
provenance?: string;
|
|
321
|
+
}
|
|
322
|
+
interface GroundMotion {
|
|
323
|
+
refcat: string;
|
|
324
|
+
country: string;
|
|
325
|
+
status: BlockStatus;
|
|
326
|
+
reason?: 'no_reflectors' | 'outside_coverage' | 'parcel_too_large' | string;
|
|
327
|
+
period?: {
|
|
328
|
+
from: string;
|
|
329
|
+
to: string;
|
|
330
|
+
label: string;
|
|
331
|
+
};
|
|
332
|
+
ground_motion?: {
|
|
333
|
+
class: string;
|
|
334
|
+
worst_class?: string;
|
|
335
|
+
vertical: {
|
|
336
|
+
mean_mm_year: number;
|
|
337
|
+
max_subsidence_mm_year?: number;
|
|
338
|
+
max_uplift_mm_year?: number;
|
|
339
|
+
std_mm_year?: number;
|
|
340
|
+
acceleration_mm_year2?: number;
|
|
341
|
+
rmse_mm?: number;
|
|
342
|
+
};
|
|
343
|
+
east_west?: {
|
|
344
|
+
mean_mm_year: number;
|
|
345
|
+
std_mm_year?: number;
|
|
346
|
+
};
|
|
347
|
+
yearly_displacement?: Array<{
|
|
348
|
+
year: number;
|
|
349
|
+
mm: number;
|
|
350
|
+
}>;
|
|
351
|
+
cells_with_data: number;
|
|
352
|
+
cells_considered: number;
|
|
353
|
+
coverage_pct: number;
|
|
354
|
+
basis?: 'parcel' | 'surroundings' | string;
|
|
355
|
+
cell_size_m?: number;
|
|
356
|
+
};
|
|
357
|
+
source?: DataSource;
|
|
358
|
+
calculated_at?: string;
|
|
359
|
+
provenance?: string;
|
|
360
|
+
}
|
|
361
|
+
type MarketData = Record<string, unknown>;
|
|
362
|
+
type ScoreData = Record<string, unknown>;
|
|
363
|
+
type ValueHistory = Record<string, unknown>;
|
|
364
|
+
type Comparison = Record<string, unknown>;
|
|
365
|
+
interface CompareItem {
|
|
366
|
+
reference: string;
|
|
367
|
+
country: EnrichmentCountryCode;
|
|
368
|
+
}
|
|
120
369
|
|
|
121
370
|
declare class ExportResource {
|
|
122
371
|
private readonly client;
|
|
@@ -124,6 +373,14 @@ declare class ExportResource {
|
|
|
124
373
|
file(reference: string, format: ExportFormat, options?: CountryOption): Promise<ArrayBuffer>;
|
|
125
374
|
}
|
|
126
375
|
|
|
376
|
+
declare class FincasResource {
|
|
377
|
+
private readonly client;
|
|
378
|
+
constructor(client: CatastroGPS);
|
|
379
|
+
searchAddress(query: string | AddressCandidatesQuery): Promise<AddressCandidatesResult>;
|
|
380
|
+
pages(refcat14: string, options?: GetUnitsOptions): AsyncGenerator<UnitsPage>;
|
|
381
|
+
units(refcat14: string, options?: GetUnitsOptions): Promise<UnitsResult>;
|
|
382
|
+
}
|
|
383
|
+
|
|
127
384
|
interface PointQuery extends CountryOption {
|
|
128
385
|
lat: number;
|
|
129
386
|
lng: number;
|
|
@@ -137,6 +394,12 @@ declare class ParcelsResource {
|
|
|
137
394
|
geometry(reference: string, options?: CountryOption<Exclude<CountryCode, 'UK'>>): Promise<ParcelGeometry>;
|
|
138
395
|
solar(reference: string, options?: CountryOption<EnrichmentCountryCode>): Promise<SolarEstimate>;
|
|
139
396
|
agriculture(reference: string, options?: CountryOption<EnrichmentCountryCode>): Promise<AgricultureData>;
|
|
397
|
+
terrain(reference: string, options?: LocatedOptions): Promise<Terrain>;
|
|
398
|
+
groundMotion(reference: string, options?: LocatedOptions): Promise<GroundMotion>;
|
|
399
|
+
market(reference: string, options?: CountryOption<EnrichmentCountryCode>): Promise<MarketData>;
|
|
400
|
+
score(reference: string, options?: CountryOption<EnrichmentCountryCode>): Promise<ScoreData>;
|
|
401
|
+
valueHistory(reference: string, options?: CountryOption<EnrichmentCountryCode | 'AT'>): Promise<ValueHistory>;
|
|
402
|
+
compare(parcels: CompareItem[]): Promise<Comparison>;
|
|
140
403
|
}
|
|
141
404
|
|
|
142
405
|
declare const DEFAULT_BASE_URL = "https://api.catastrogps.es";
|
|
@@ -147,10 +410,18 @@ interface RequestOptions {
|
|
|
147
410
|
query?: Query;
|
|
148
411
|
body?: unknown;
|
|
149
412
|
raw?: boolean;
|
|
413
|
+
ifNoneMatch?: string;
|
|
414
|
+
}
|
|
415
|
+
interface ConditionalResponse<T> {
|
|
416
|
+
data?: T;
|
|
417
|
+
etag?: string;
|
|
418
|
+
notModified: boolean;
|
|
419
|
+
quota?: Quota;
|
|
150
420
|
}
|
|
151
421
|
declare class CatastroGPS {
|
|
152
422
|
readonly parcels: ParcelsResource;
|
|
153
423
|
readonly export: ExportResource;
|
|
424
|
+
readonly fincas: FincasResource;
|
|
154
425
|
lastQuota?: Quota;
|
|
155
426
|
private readonly apiKey;
|
|
156
427
|
private readonly baseUrl;
|
|
@@ -158,18 +429,23 @@ declare class CatastroGPS {
|
|
|
158
429
|
private readonly maxRetries;
|
|
159
430
|
private readonly fetchImpl;
|
|
160
431
|
constructor(options?: CatastroGPSOptions);
|
|
432
|
+
searchAddressCandidates(query: string | AddressCandidatesQuery): Promise<AddressCandidatesResult>;
|
|
433
|
+
getUnits(refcat14: string, options?: GetUnitsOptions): Promise<UnitsResult>;
|
|
434
|
+
iterUnitPages(refcat14: string, options?: GetUnitsOptions): AsyncGenerator<UnitsPage>;
|
|
161
435
|
resolve(text: string, options?: {
|
|
162
436
|
hint?: string;
|
|
163
437
|
}): Promise<ResolveResult>;
|
|
164
438
|
request<T>(method: 'GET' | 'POST', path: string, options?: RequestOptions): Promise<T>;
|
|
439
|
+
conditionalRequest<T>(method: 'GET' | 'POST', path: string, options?: RequestOptions): Promise<ConditionalResponse<T>>;
|
|
165
440
|
private once;
|
|
166
441
|
private buildUrl;
|
|
167
442
|
private shouldRetry;
|
|
168
443
|
private retryDelayMs;
|
|
169
444
|
private captureQuota;
|
|
170
445
|
}
|
|
446
|
+
declare function readQuota(headers: Headers): Quota | undefined;
|
|
171
447
|
|
|
172
|
-
declare const VERSION = "1.
|
|
448
|
+
declare const VERSION = "1.2.0";
|
|
173
449
|
|
|
174
450
|
declare class CatastroGPSError extends Error {
|
|
175
451
|
readonly status?: number;
|
|
@@ -195,8 +471,20 @@ declare class NotFoundError extends CatastroGPSError {
|
|
|
195
471
|
declare class ValidationError extends CatastroGPSError {
|
|
196
472
|
name: string;
|
|
197
473
|
}
|
|
474
|
+
declare class PlaceNameError extends ValidationError {
|
|
475
|
+
name: string;
|
|
476
|
+
get location(): {
|
|
477
|
+
lat: number;
|
|
478
|
+
lng: number;
|
|
479
|
+
address?: string;
|
|
480
|
+
label?: string;
|
|
481
|
+
} | undefined;
|
|
482
|
+
}
|
|
198
483
|
declare class CoverageError extends CatastroGPSError {
|
|
199
484
|
name: string;
|
|
485
|
+
get country(): string | undefined;
|
|
486
|
+
get feature(): string | undefined;
|
|
487
|
+
get supportedCountries(): string[];
|
|
200
488
|
}
|
|
201
489
|
declare class AmbiguousReferenceError extends CatastroGPSError {
|
|
202
490
|
name: string;
|
|
@@ -208,6 +496,8 @@ declare class AmbiguousReferenceError extends CatastroGPSError {
|
|
|
208
496
|
}
|
|
209
497
|
declare class QuotaExceededError extends CatastroGPSError {
|
|
210
498
|
name: string;
|
|
499
|
+
quota?: Quota;
|
|
500
|
+
get prepaidBalanceEmpty(): boolean;
|
|
211
501
|
}
|
|
212
502
|
declare class RateLimitError extends CatastroGPSError {
|
|
213
503
|
name: string;
|
|
@@ -215,6 +505,7 @@ declare class RateLimitError extends CatastroGPSError {
|
|
|
215
505
|
}
|
|
216
506
|
declare class ServiceUnavailableError extends CatastroGPSError {
|
|
217
507
|
name: string;
|
|
508
|
+
retryAfterSeconds?: number;
|
|
218
509
|
}
|
|
219
510
|
declare class ServerError extends CatastroGPSError {
|
|
220
511
|
name: string;
|
|
@@ -226,4 +517,4 @@ declare class NetworkError extends CatastroGPSError {
|
|
|
226
517
|
name: string;
|
|
227
518
|
}
|
|
228
519
|
|
|
229
|
-
export { type AddressMatch, type AgricultureData, AmbiguousReferenceError, AuthenticationError, COUNTRY_CODES, CatastroGPS, CatastroGPSError, type CatastroGPSOptions, type CountryCode, type CountryOption, CoverageError, DEFAULT_BASE_URL, DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT_MS, ENRICHMENT_COUNTRY_CODES, type EnrichmentCountryCode, type ExportFormat, type FetchLike, ForbiddenError, NetworkError, NotFoundError, type Parcel, type ParcelGeometry, type PointMatch, type PointQuery, type Quota, QuotaExceededError, RateLimitError, type ResolveCandidate, type ResolveResult, ServerError, ServiceUnavailableError, type SolarEstimate, TimeoutError, VERSION, ValidationError };
|
|
520
|
+
export { ADDRESS_COUNTRY_CODES, type AddressCandidate, type AddressCandidatesQuery, type AddressCandidatesResult, type AddressCountryCode, type AddressMatch, type AgricultureData, AmbiguousReferenceError, AuthenticationError, type BlockStatus, type BurstLimit, COUNTRY_CODES, CatastroGPS, CatastroGPSError, type CatastroGPSOptions, type CompareItem, type Comparison, type ConditionalResponse, type Construction, type CountryCode, type CountryOption, CoverageError, DEFAULT_BASE_URL, DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT_MS, type DataSource, ENRICHMENT_COUNTRY_CODES, type EnrichmentCountryCode, type ExportFormat, type FetchLike, type FincaCap, ForbiddenError, type GetUnitsOptions, type GroundMotion, type LocatedOptions, type MarketData, NetworkError, NotFoundError, type Parcel, type ParcelGeometry, PlaceNameError, type PointMatch, type PointQuery, type PrepaidOverage, type ProtectedSite, type Quota, QuotaExceededError, RateLimitError, type ResolveCandidate, type ResolveResult, type ScoreData, ServerError, ServiceUnavailableError, type SolarEstimate, type Terrain, TimeoutError, UNITS_COUNTRY_CODES, type Unit, type UnitsCountryCode, type UnitsPage, type UnitsPageData, type UnitsResult, VERSION, ValidationError, type ValueHistory, readQuota };
|