@datosgeo-atdt/geo-ui 0.4.8 → 0.6.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 CHANGED
@@ -1,346 +1,352 @@
1
- # @atdt/geo-ui
2
-
3
- Librería de componentes reutilizables en React para aplicaciones geoespaciales. Incluye visualización de mapas con PMTiles, unión con datos tabulares CSV y estilos temáticos (booleano y Jenks).
4
-
5
- ## Características
6
-
7
- - **MapaPMTiles**: Componente para renderizar mapas vectoriales usando MapLibre GL y PMTiles
8
- - **Join CSV**: Unión automática de datos tabulares con geometrías vectoriales
9
- - **Estilos temáticos**: Soporte para modo booleano y clasificación Jenks
10
- - **TypeScript**: Completamente tipado para mejor experiencia de desarrollo
11
- - **Sin SSR**: Diseñado para aplicaciones client-side (React puro, Vite, CRA)
12
-
13
- ## Instalación
14
-
15
- ```bash
16
- npm install @atdt/geo-ui maplibre-gl pmtiles papaparse @mapbox/vector-tile pbf
17
- ```
18
-
19
- **Importante**: Las dependencias `react` y `react-dom` son peer dependencies (versión 18+).
20
-
21
- ## Uso Básico
22
-
23
- ### Importar el componente
24
-
25
- ```tsx
26
- import { MapaPMTiles } from '@atdt/geo-ui';
27
- import '@atdt/geo-ui/style.css';
28
- ```
29
-
30
- ### Ejemplo básico (usando valores por defecto)
31
-
32
- La biblioteca incluye **integrada** la URL del PMTiles de entidades de México, por lo que no necesitas especificar `pmtilesUrl`, `sourceLayer` ni `joinGeomKey` si trabajas con entidades:
33
-
34
- ```tsx
35
- import React from 'react';
36
- import { MapaPMTiles } from '@atdt/geo-ui';
37
- import '@atdt/geo-ui/style.css';
38
-
39
- function App() {
40
- return (
41
- <MapaPMTiles
42
- csvUrl="https://example.com/datos.csv"
43
- field="valor"
44
- mode="boolean"
45
- width="100%"
46
- height={600}
47
- />
48
- );
49
- }
50
-
51
- export default App;
52
- ```
53
-
54
- ### Ejemplo con csvUrl (especificando PMTiles personalizado)
55
-
56
- ```tsx
57
- import React from 'react';
58
- import { MapaPMTiles } from '@atdt/geo-ui';
59
- import '@atdt/geo-ui/style.css';
60
-
61
- function App() {
62
- return (
63
- <MapaPMTiles
64
- pmtilesUrl="https://example.com/custom.pmtiles"
65
- sourceLayer="mi-capa"
66
- joinGeomKey="ID"
67
- csvUrl="https://example.com/datos.csv"
68
- field="valor"
69
- mode="boolean"
70
- width="100%"
71
- height={600}
72
- />
73
- );
74
- }
75
-
76
- export default App;
77
- ```
78
-
79
- ### Ejemplo con csvFile (archivo local)
80
-
81
- ```tsx
82
- import React, { useState } from 'react';
83
- import { MapaPMTiles } from '@atdt/geo-ui';
84
- import '@atdt/geo-ui/style.css';
85
-
86
- function App() {
87
- const [csvFile, setCsvFile] = useState<File | null>(null);
88
-
89
- return (
90
- <div>
91
- <input
92
- type="file"
93
- accept=".csv"
94
- onChange={(e) => setCsvFile(e.target.files?.[0] || null)}
95
- />
96
- {csvFile && (
97
- <MapaPMTiles
98
- csvFile={csvFile}
99
- field="poblacion"
100
- mode="jenks"
101
- jenksK={5}
102
- />
103
- )}
104
- </div>
105
- );
106
- }
107
-
108
- export default App;
109
- ```
110
-
111
- ### Ejemplo con fitToIds (zoom y filtrado por entidades)
112
-
113
- Muestra **solo** las entidades seleccionadas y ajusta el mapa automáticamente a su extensión (sin animación):
114
-
115
- ```tsx
116
- // Mostrar solo Ciudad de México
117
- <MapaPMTiles
118
- csvUrl="https://example.com/datos.csv"
119
- fitToIds="09"
120
- />
121
-
122
- // Mostrar múltiples entidades (Ciudad de México, Estado de México y Jalisco)
123
- <MapaPMTiles
124
- csvUrl="https://example.com/datos.csv"
125
- fitToIds={["09", "15", "14"]}
126
- />
127
- ```
128
-
129
- **Ventajas de usar `fitToIds`:**
130
- - No necesitas configurar `pmtilesUrl` (está integrado)
131
- - Filtra automáticamente para mostrar solo las entidades seleccionadas
132
- - Calcula y ajusta el bbox combinado sin animación de zoom
133
- - Carga directo en la vista correcta
134
-
135
- ### Ejemplo con municipios
136
-
137
- Cuando usas `fitToIds`, puedes habilitar la visualización de municipios con `showMunicipios`:
138
-
139
- ```tsx
140
- // Mostrar municipios con datos (aplica el mismo modo que entidades)
141
- <MapaPMTiles
142
- csvUrl="https://example.com/datos-entidades.csv"
143
- fitToIds="01"
144
- showMunicipios={true}
145
- municipiosCsvUrl="https://example.com/datos-municipios.csv"
146
- municipiosField="poblacion"
147
- mode="jenks"
148
- />
149
-
150
- // Mostrar solo contornos de municipios (sin datos)
151
- <MapaPMTiles
152
- csvUrl="https://example.com/datos-entidades.csv"
153
- fitToIds={["09", "15"]}
154
- showMunicipios={true}
155
- />
156
- ```
157
-
158
- **Características de la capa de municipios:**
159
- - ✅ URL del PMTiles de municipios integrada
160
- - ✅ Filtrado automático por CVE_ENT de las entidades seleccionadas
161
- - ✅ Join con CVEGEO en mayúsculas
162
- - Aplica el mismo modo (boolean/jenks) que las entidades si proporcionas CSV
163
- - Si no proporcionas CSV, solo muestra contornos (outline)
164
- - El contorno de entidades se hace más grueso cuando se muestran municipios
165
-
166
- ## Props
167
-
168
- ### Props Obligatorias
169
-
170
- | Prop | Tipo | Descripción |
171
- |------|------|-------------|
172
- | `csvUrl` o `csvFile` | `string \| File` | URL del CSV remoto o archivo File local. **Al menos uno debe estar presente** |
173
-
174
- ### Props Opcionales
175
-
176
- | Prop | Tipo | Default | Descripción |
177
- |------|------|---------|-------------|
178
- | `pmtilesUrl` | `string` | `"https://www.datosgeoespaciales.atdt.gob.mx/datalake/pmtiles/componente/entidad.pmtiles"` | URL del archivo PMTiles remoto. **Por defecto usa el PMTiles de entidades de México** |
179
- | `sourceLayer` | `string` | `"entidad"` | Nombre de la capa vectorial dentro del PMTiles |
180
- | `joinGeomKey` | `string` | `"cvegeo"` | Campo de la geometría para hacer el join (también usado como `promoteId`) |
181
- | `joinCsvKey` | `string` | `joinGeomKey` | Campo del CSV para hacer el join |
182
- | `field` | `string` | `"valor"` | Campo del CSV con los valores a visualizar |
183
- | `mode` | `"boolean" \| "jenks"` | `"boolean"` | Modo de estilo: booleano o clasificación Jenks |
184
- | `width` | `string \| number` | `"100%"` | Ancho del mapa |
185
- | `height` | `string \| number` | `520` | Alto del mapa (en px si es número) |
186
- | `initialView` | `object` | `{center: [-102, 23], zoom: 4}` | Vista inicial del mapa (ignorado si se usa `fitToIds`) |
187
- | `initialView.center` | `[number, number]` | `[-102, 23]` | Centro inicial [lng, lat] |
188
- | `initialView.zoom` | `number` | `4` | Zoom inicial |
189
- | `fitToIds` | `string \| string[]` | `undefined` | ID o array de IDs de features para filtrar y hacer zoom automático (sin animación) |
190
- | `bboxField` | `string` | `"bbox"` | Campo con bbox precalculado en PMTiles |
191
- | `jenksK` | `number` | `5` | Número de clases para clasificación Jenks |
192
- | `showMunicipios` | `boolean` | `false` | Habilita la visualización de municipios (requiere `fitToIds`) |
193
- | `municipiosCsvUrl` | `string` | `undefined` | URL del CSV para unir con municipios (opcional) |
194
- | `municipiosCsvFile` | `File` | `undefined` | Archivo CSV para unir con municipios (opcional) |
195
- | `municipiosField` | `string` | `"valor"` | Campo del CSV de municipios con los valores a visualizar |
196
-
197
- ## Modos de Estilo
198
-
199
- ### Modo Boolean
200
-
201
- Pinta las geometrías en dos colores según el valor:
202
-
203
- - `value === 1` → **#66827f** (verde azulado)
204
- - `value === 0 / null / undefined` → **#f3f3f3** (gris claro)
205
-
206
- ```tsx
207
- <MapaPMTiles
208
- mode="boolean"
209
- {...otherProps}
210
- />
211
- ```
212
-
213
- ### Modo Jenks
214
-
215
- Clasifica los valores numéricos usando el algoritmo Jenks Natural Breaks y aplica una rampa de colores:
216
-
217
- - De **#f3f3f3** (gris claro) a **#66827f** (verde azulado)
218
- - Número de clases controlado por `jenksK` (default: 5)
219
-
220
- ```tsx
221
- <MapaPMTiles
222
- mode="jenks"
223
- jenksK={7}
224
- {...otherProps}
225
- />
226
- ```
227
-
228
- ## Formato CSV
229
-
230
- El archivo CSV debe tener:
231
-
232
- - **Header row** con nombres de columnas
233
- - Una columna con el **join key** que coincida con el campo `joinGeomKey` de las geometrías
234
- - Una columna con los **valores** especificada en `field`
235
-
236
- Ejemplo:
237
-
238
- ```csv
239
- CVE_ENT,nombre,valor
240
- 01,Aguascalientes,1
241
- 02,Baja California,0
242
- 09,Ciudad de México,1
243
- ```
244
-
245
- ## Interactividad del Mapa
246
-
247
- El componente tiene **interactividad desactivada** por defecto para mantener un estilo estático:
248
-
249
- - `boxZoom`: false
250
- - `doubleClickZoom`: false
251
- - `dragRotate`: false
252
- - `keyboard`: false
253
- - `scrollZoom`: false
254
- - `touchPitch`: false
255
- - `dragPan`: false
256
- - `touchZoomRotate`: true (permitido)
257
-
258
- ## Notas CORS
259
-
260
- Para consumir PMTiles y CSV de dominios externos, asegúrate de que:
261
-
262
- 1. El servidor tenga configurado CORS adecuadamente
263
- 2. Para PMTiles, el servidor debe soportar **Range requests** (HTTP 206)
264
- 3. Headers necesarios:
265
- ```
266
- Access-Control-Allow-Origin: *
267
- Access-Control-Allow-Headers: Range
268
- Accept-Ranges: bytes
269
- ```
270
-
271
- ## Tecnologías
272
-
273
- - **React 18+**
274
- - **TypeScript**
275
- - **MapLibre GL JS**: Renderizado de mapas vectoriales
276
- - **PMTiles**: Formato de tiles vectoriales eficiente
277
- - **PapaParse**: Parsing de CSV
278
- - **Vite**: Build tool
279
-
280
- ## Build y Desarrollo
281
-
282
- ### Desarrollo local
283
-
284
- ```bash
285
- npm install
286
- npm run dev
287
- ```
288
-
289
- ### Build de producción
290
-
291
- ```bash
292
- npm run build
293
- ```
294
-
295
- Esto genera:
296
-
297
- - `dist/geo-ui.js` (ES module)
298
- - `dist/geo-ui.umd.cjs` (UMD)
299
- - `dist/index.d.ts` (TypeScript definitions)
300
- - `dist/style.css` (estilos de MapLibre GL)
301
-
302
- ### Publicar a npm
303
-
304
- ```bash
305
- # Asegúrate de estar autenticado en npm
306
- npm login
307
-
308
- # Incrementa versión (patch, minor, major)
309
- npm version patch
310
-
311
- # Publica (ejecutará automáticamente build por prepublishOnly)
312
- npm publish --access public
313
- ```
314
-
315
- **Nota**: Para paquetes con scope `@atdt/`, necesitas usar `--access public` la primera vez.
316
-
317
- ## Estructura del Proyecto
318
-
319
- ```
320
- geo-ui/
321
- ├── src/
322
- │ ├── components/
323
- │ │ └── MapaPMTiles.tsx # Componente principal
324
- │ ├── utils/
325
- │ │ ├── csv.ts # Utilidades para parsear CSV
326
- │ │ ├── jenks.ts # Algoritmo Jenks Natural Breaks
327
- │ │ └── pmtilesFeatureSearch.ts # Búsqueda de features y bbox
328
- └── index.ts # Entry point
329
- ├── dist/ # Build output (generado)
330
- ├── package.json
331
- ├── tsconfig.json
332
- ├── vite.config.ts
333
- └── README.md
334
- ```
335
-
336
- ## Licencia
337
-
338
- ISC
339
-
340
- ## Autor
341
-
342
- Dirección de Datos Geográficos - ATDT
343
-
344
- ## Contribuciones
345
-
346
- Issues y pull requests son bienvenidos en [GitLab](https://gitlab.com/atdt-desarrollogeo/componentes).
1
+ # @atdt/geo-ui
2
+
3
+ Librería de componentes reutilizables en React para aplicaciones geoespaciales. Incluye visualización de mapas con PMTiles, unión con datos tabulares CSV y estilos temáticos (booleano y Jenks).
4
+
5
+ ## Características
6
+
7
+ - **MapaPMTiles**: Componente para renderizar mapas vectoriales usando MapLibre GL y PMTiles
8
+ - **Join CSV**: Unión automática de datos tabulares con geometrías vectoriales
9
+ - **Estilos temáticos**: Soporte para modo booleano y clasificación Jenks
10
+ - **TypeScript**: Completamente tipado para mejor experiencia de desarrollo
11
+ - **Sin SSR**: Diseñado para aplicaciones client-side (React puro, Vite, CRA)
12
+
13
+ ## Instalación
14
+
15
+ ```bash
16
+ npm install @atdt/geo-ui maplibre-gl pmtiles papaparse @mapbox/vector-tile pbf
17
+ ```
18
+
19
+ **Importante**: Las dependencias `react` y `react-dom` son peer dependencies (versión 18+).
20
+
21
+ ## Uso Básico
22
+
23
+ ### Importar el componente
24
+
25
+ ```tsx
26
+ import { MapaPMTiles } from '@atdt/geo-ui';
27
+ import '@atdt/geo-ui/style.css';
28
+ ```
29
+
30
+ ### Ejemplo básico (usando valores por defecto)
31
+
32
+ La biblioteca incluye **integrada** la URL del PMTiles de entidades de México, por lo que no necesitas especificar `pmtilesUrl`, `sourceLayer` ni `joinGeomKey` si trabajas con entidades:
33
+
34
+ ```tsx
35
+ import React from 'react';
36
+ import { MapaPMTiles } from '@atdt/geo-ui';
37
+ import '@atdt/geo-ui/style.css';
38
+
39
+ function App() {
40
+ return (
41
+ <MapaPMTiles
42
+ csvUrl="https://example.com/datos.csv"
43
+ field="valor"
44
+ mode="boolean"
45
+ width="100%"
46
+ height={600}
47
+ />
48
+ );
49
+ }
50
+
51
+ export default App;
52
+ ```
53
+
54
+ ### Ejemplo con csvUrl (especificando PMTiles personalizado)
55
+
56
+ ```tsx
57
+ import React from 'react';
58
+ import { MapaPMTiles } from '@atdt/geo-ui';
59
+ import '@atdt/geo-ui/style.css';
60
+
61
+ function App() {
62
+ return (
63
+ <MapaPMTiles
64
+ pmtilesUrl="https://example.com/custom.pmtiles"
65
+ sourceLayer="mi-capa"
66
+ joinGeomKey="ID"
67
+ csvUrl="https://example.com/datos.csv"
68
+ field="valor"
69
+ mode="boolean"
70
+ width="100%"
71
+ height={600}
72
+ />
73
+ );
74
+ }
75
+
76
+ export default App;
77
+ ```
78
+
79
+ ### Ejemplo con csvFile (archivo local)
80
+
81
+ ```tsx
82
+ import React, { useState } from 'react';
83
+ import { MapaPMTiles } from '@atdt/geo-ui';
84
+ import '@atdt/geo-ui/style.css';
85
+
86
+ function App() {
87
+ const [csvFile, setCsvFile] = useState<File | null>(null);
88
+
89
+ return (
90
+ <div>
91
+ <input
92
+ type="file"
93
+ accept=".csv"
94
+ onChange={(e) => setCsvFile(e.target.files?.[0] || null)}
95
+ />
96
+ {csvFile && (
97
+ <MapaPMTiles
98
+ csvFile={csvFile}
99
+ field="poblacion"
100
+ mode="jenks"
101
+ jenksK={5}
102
+ />
103
+ )}
104
+ </div>
105
+ );
106
+ }
107
+
108
+ export default App;
109
+ ```
110
+
111
+ ### Ejemplo con fitToIds (zoom y filtrado por entidades)
112
+
113
+ Muestra **solo** las entidades seleccionadas y ajusta el mapa automáticamente a su extensión (sin animación):
114
+
115
+ ```tsx
116
+ // Mostrar solo Ciudad de México
117
+ <MapaPMTiles
118
+ csvUrl="https://example.com/datos.csv"
119
+ fitToIds="09"
120
+ />
121
+
122
+ // Mostrar múltiples entidades (Ciudad de México, Estado de México y Jalisco)
123
+ <MapaPMTiles
124
+ csvUrl="https://example.com/datos.csv"
125
+ fitToIds={["09", "15", "14"]}
126
+ />
127
+ ```
128
+
129
+ **Ventajas de usar `fitToIds`:**
130
+ - No necesitas configurar `pmtilesUrl` (está integrado)
131
+ - Filtra automáticamente para mostrar solo las entidades seleccionadas
132
+ - Calcula y ajusta el bbox combinado sin animación de zoom
133
+ - Carga directo en la vista correcta
134
+
135
+ ### Ejemplo con showMunicipios (visualización municipal)
136
+
137
+ Cuando activas `showMunicipios={true}`, el componente cambia a **nivel municipal**:
138
+ - La **entidad** se muestra solo como **contorno** (outline grueso)
139
+ - Los **municipios** dentro de esa entidad se muestran con el **relleno temático** (boolean o jenks)
140
+ - Los datos CSV se unen usando el **cvegeo municipal** (5 dígitos)
141
+
142
+ ```tsx
143
+ // Mostrar municipios de Ciudad de México (09)
144
+ // El CSV debe tener cvegeo municipal (ej: "09002", "09010", etc.)
145
+ <MapaPMTiles
146
+ csvUrl="https://example.com/datos_municipales.csv"
147
+ fitToIds="09"
148
+ showMunicipios={true}
149
+ mode="jenks"
150
+ jenksK={5}
151
+ />
152
+
153
+ // Mostrar municipios de múltiples entidades
154
+ <MapaPMTiles
155
+ csvUrl="https://example.com/datos_municipales.csv"
156
+ fitToIds={["09", "15", "14"]}
157
+ showMunicipios={true}
158
+ />
159
+ ```
160
+
161
+ **¿Cómo funciona?**
162
+ 1. `fitToIds="09"` extrae automáticamente `cve_ent="09"` (primeros 2 dígitos)
163
+ 2. Filtra y muestra **todos los municipios** con `cve_ent="09"`
164
+ 3. La entidad "09" se dibuja solo como contorno
165
+ 4. Los municipios se rellenan según los valores del CSV unidos por `cvegeo` (5 dígitos)
166
+
167
+ **Formato CSV para municipios:**
168
+ ```csv
169
+ cvegeo,nombre,valor
170
+ 09002,Azcapotzalco,150
171
+ 09003,Coyoacán,200
172
+ 09010,Álvaro Obregón,175
173
+ ```
174
+
175
+ ## Props
176
+
177
+ ### Props Obligatorias
178
+
179
+ | Prop | Tipo | Descripción |
180
+ |------|------|-------------|
181
+ | `csvUrl` o `csvFile` | `string \| File` | URL del CSV remoto o archivo File local. **Al menos uno debe estar presente** |
182
+
183
+ ### Props Opcionales
184
+
185
+ | Prop | Tipo | Default | Descripción |
186
+ |------|------|---------|-------------|
187
+ | `pmtilesUrl` | `string` | `"https://www.datosgeoespaciales.atdt.gob.mx/datalake/pmtiles/componente/entidad.pmtiles"` | URL del archivo PMTiles remoto. **Por defecto usa el PMTiles de entidades de México** |
188
+ | `sourceLayer` | `string` | `"entidad"` | Nombre de la capa vectorial dentro del PMTiles |
189
+ | `joinGeomKey` | `string` | `"cvegeo"` | Campo de la geometría para hacer el join (también usado como `promoteId`) |
190
+ | `joinCsvKey` | `string` | `joinGeomKey` | Campo del CSV para hacer el join |
191
+ | `field` | `string` | `"valor"` | Campo del CSV con los valores a visualizar |
192
+ | `mode` | `"boolean" \| "jenks"` | `"boolean"` | Modo de estilo: booleano o clasificación Jenks |
193
+ | `width` | `string \| number` | `"100%"` | Ancho del mapa |
194
+ | `height` | `string \| number` | `520` | Alto del mapa (en px si es número) |
195
+ | `initialView` | `object` | `{center: [-102, 23], zoom: 4}` | Vista inicial del mapa (ignorado si se usa `fitToIds`) |
196
+ | `initialView.center` | `[number, number]` | `[-102, 23]` | Centro inicial [lng, lat] |
197
+ | `initialView.zoom` | `number` | `4` | Zoom inicial |
198
+ | `fitToIds` | `string \| string[]` | `undefined` | ID o array de IDs de features para filtrar y hacer zoom automático (sin animación) |
199
+ | `bboxField` | `string` | `"bbox"` | Campo con bbox precalculado en PMTiles |
200
+ | `jenksK` | `number` | `5` | Número de clases para clasificación Jenks |
201
+ | `showMunicipios` | `boolean` | `false` | Activa modo municipal: muestra municipios con datos temáticos y entidad como contorno |
202
+
203
+ ## Modos de Estilo
204
+
205
+ ### Modo Boolean
206
+
207
+ Pinta las geometrías en dos colores según el valor:
208
+
209
+ - `value === 1` → **#66827f** (verde azulado)
210
+ - `value === 0 / null / undefined` → **#f3f3f3** (gris claro)
211
+
212
+ ```tsx
213
+ <MapaPMTiles
214
+ mode="boolean"
215
+ {...otherProps}
216
+ />
217
+ ```
218
+
219
+ ### Modo Jenks
220
+
221
+ Clasifica los valores numéricos usando el algoritmo Jenks Natural Breaks y aplica una rampa de colores:
222
+
223
+ - De **#f3f3f3** (gris claro) a **#66827f** (verde azulado)
224
+ - Número de clases controlado por `jenksK` (default: 5)
225
+
226
+ ```tsx
227
+ <MapaPMTiles
228
+ mode="jenks"
229
+ jenksK={7}
230
+ {...otherProps}
231
+ />
232
+ ```
233
+
234
+ ## Formato CSV
235
+
236
+ El archivo CSV debe tener:
237
+
238
+ - **Header row** con nombres de columnas
239
+ - Una columna con el **join key** que coincida con el campo `joinGeomKey` de las geometrías
240
+ - Una columna con los **valores** especificada en `field`
241
+
242
+ Ejemplo:
243
+
244
+ ```csv
245
+ CVE_ENT,nombre,valor
246
+ 01,Aguascalientes,1
247
+ 02,Baja California,0
248
+ 09,Ciudad de México,1
249
+ ```
250
+
251
+ ## Interactividad del Mapa
252
+
253
+ El componente tiene **interactividad desactivada** por defecto para mantener un estilo estático:
254
+
255
+ - `boxZoom`: false
256
+ - `doubleClickZoom`: false
257
+ - `dragRotate`: false
258
+ - `keyboard`: false
259
+ - `scrollZoom`: false
260
+ - `touchPitch`: false
261
+ - `dragPan`: false
262
+ - `touchZoomRotate`: true (permitido)
263
+
264
+ ## Notas CORS
265
+
266
+ Para consumir PMTiles y CSV de dominios externos, asegúrate de que:
267
+
268
+ 1. El servidor tenga configurado CORS adecuadamente
269
+ 2. Para PMTiles, el servidor debe soportar **Range requests** (HTTP 206)
270
+ 3. Headers necesarios:
271
+ ```
272
+ Access-Control-Allow-Origin: *
273
+ Access-Control-Allow-Headers: Range
274
+ Accept-Ranges: bytes
275
+ ```
276
+
277
+ ## Tecnologías
278
+
279
+ - **React 18+**
280
+ - **TypeScript**
281
+ - **MapLibre GL JS**: Renderizado de mapas vectoriales
282
+ - **PMTiles**: Formato de tiles vectoriales eficiente
283
+ - **PapaParse**: Parsing de CSV
284
+ - **Vite**: Build tool
285
+
286
+ ## Build y Desarrollo
287
+
288
+ ### Desarrollo local
289
+
290
+ ```bash
291
+ npm install
292
+ npm run dev
293
+ ```
294
+
295
+ ### Build de producción
296
+
297
+ ```bash
298
+ npm run build
299
+ ```
300
+
301
+ Esto genera:
302
+
303
+ - `dist/geo-ui.js` (ES module)
304
+ - `dist/geo-ui.umd.cjs` (UMD)
305
+ - `dist/index.d.ts` (TypeScript definitions)
306
+ - `dist/style.css` (estilos de MapLibre GL)
307
+
308
+ ### Publicar a npm
309
+
310
+ ```bash
311
+ # Asegúrate de estar autenticado en npm
312
+ npm login
313
+
314
+ # Incrementa versión (patch, minor, major)
315
+ npm version patch
316
+
317
+ # Publica (ejecutará automáticamente build por prepublishOnly)
318
+ npm publish --access public
319
+ ```
320
+
321
+ **Nota**: Para paquetes con scope `@atdt/`, necesitas usar `--access public` la primera vez.
322
+
323
+ ## Estructura del Proyecto
324
+
325
+ ```
326
+ geo-ui/
327
+ ├── src/
328
+ ├── components/
329
+ │ │ └── MapaPMTiles.tsx # Componente principal
330
+ ├── utils/
331
+ │ │ ├── csv.ts # Utilidades para parsear CSV
332
+ │ │ ├── jenks.ts # Algoritmo Jenks Natural Breaks
333
+ │ │ └── pmtilesFeatureSearch.ts # Búsqueda de features y bbox
334
+ │ └── index.ts # Entry point
335
+ ├── dist/ # Build output (generado)
336
+ ├── package.json
337
+ ├── tsconfig.json
338
+ ├── vite.config.ts
339
+ └── README.md
340
+ ```
341
+
342
+ ## Licencia
343
+
344
+ ISC
345
+
346
+ ## Autor
347
+
348
+ Dirección de Datos Geográficos - ATDT
349
+
350
+ ## Contribuciones
351
+
352
+ Issues y pull requests son bienvenidos en [GitLab](https://gitlab.com/atdt-desarrollogeo/componentes).