Volver al catálogo
Season 44 15 Episodios 1h 3m 2026

GeoDjango and PostGIS

v6.0 — Edición 2026. Un completo curso en audio sobre la creación de aplicaciones web espaciales utilizando GeoDjango y PostGIS. Grabado en 2026, cubriendo la versión 6.0 de GeoDjango.

Análisis geoespacial Aplicaciones web espaciales Bases de datos
GeoDjango and PostGIS
Reproduciendo ahora
Click play to start
0:00
0:00
1
El poder de los frameworks web espaciales
Este episodio presenta GeoDjango y PostGIS como una potente combinación para crear aplicaciones web geográficas. Aprenderás por qué las bases de datos tradicionales tienen dificultades con los datos espaciales y cómo las extensiones espaciales resuelven este problema.
4m 04s
2
Geometry vs Geography en PostGIS
Este episodio explora los tipos de datos de PostGIS, centrándose específicamente en la diferencia entre los tipos Geometry y Geography. Aprenderás cuándo utilizar matemáticas cartesianas en un plano y cuándo cálculos esféricos terrestres.
4m 00s
3
Configurando tu entorno espacial
Este episodio cubre la configuración inicial de un proyecto con GeoDjango y PostGIS. Aprenderás a habilitar la extensión PostGIS y a configurar los ajustes de Django para conectarte a un backend espacial.
4m 24s
4
Sistemas de referencia de coordenadas y SRIDs
Este episodio desglosa los sistemas de referencia de coordenadas y los SRIDs. Aprenderás qué es WGS84 y por qué proyectar correctamente los datos de tus mapas es crucial para medir distancias con precisión.
4m 30s
5
Diseñando modelos geográficos
Este episodio demuestra cómo diseñar modelos geográficos en GeoDjango. Aprenderás a definir los atributos PointField y MultiPolygonField para almacenar datos espaciales en tu aplicación Django.
3m 46s
6
La API de GDAL y OGR
Este episodio presenta el wrapper de la API de GDAL y OGR dentro de GeoDjango. Aprenderás a inspeccionar y leer archivos vectoriales externos como Shapefiles de forma nativa en Python antes de importarlos.
4m 25s
7
Ingesta de datos espaciales con LayerMapping
Este episodio trata sobre la automatización de la importación de datos espaciales. Aprenderás a utilizar la utilidad LayerMapping para mapear datos externos de un Shapefile directamente en tus modelos de GeoDjango sin esfuerzo.
4m 05s
8
La API de GEOS: Geometría al estilo Python
Este episodio se centra en la API de GEOS para la manipulación de geometría al estilo Python. Aprenderás a realizar operaciones topológicas como uniones e intersecciones en memoria sin consultar la base de datos.
3m 59s
9
Dominando los spatial lookups
Este episodio explica los lookups de consultas geográficas en el ORM de Django. Aprenderás a utilizar filtros espaciales para encontrar relaciones, como qué puntos están contenidos dentro de unos límites específicos.
4m 33s
10
Consultas de distancia de alto rendimiento
Este episodio aborda las consultas de proximidad y distancia de alto rendimiento. Aprenderás a utilizar los lookups de distancia y el objeto de distancia geográfica para encontrar ubicaciones cercanas de manera eficiente.
4m 17s
11
Funciones geográficas de base de datos
Este episodio explora las funciones espaciales de base de datos accesibles a través de GeoDjango. Aprenderás a calcular áreas, extraer centroides y generar GeoJSON directamente en la capa de la base de datos.
4m 13s
12
Datos Raster en PostGIS
Este episodio presenta los rasters de PostGIS y los RasterFields de GeoDjango. Aprenderás a almacenar y consultar datos espaciales continuos, como modelos de elevación o mapas de temperatura.
4m 11s
13
Geolocalización con GeoIP2
Este episodio cubre la geolocalización basada en IP utilizando el módulo GeoIP2 de GeoDjango. Aprenderás a mapear las direcciones IP de los usuarios a ciudades y países utilizando los conjuntos de datos de MaxMind.
4m 27s
14
Pruebas de aplicaciones espaciales
Este episodio se centra en las pruebas de aplicaciones espaciales en GeoDjango. Aprenderás a configurar tu suite de pruebas, manejar bases de datos de plantillas de PostGIS y establecer los privilegios de usuario.
4m 04s
15
Desplegando aplicaciones GeoDjango
Este episodio concluye la serie analizando las consideraciones de despliegue para las aplicaciones GeoDjango. Aprenderás sobre la seguridad de hilos en GDAL y cómo configurar tus procesos WSGI para evitar bloqueos.
4m 16s

Episodios

1

El poder de los frameworks web espaciales

4m 04s

Este episodio presenta GeoDjango y PostGIS como una potente combinación para crear aplicaciones web geográficas. Aprenderás por qué las bases de datos tradicionales tienen dificultades con los datos espaciales y cómo las extensiones espaciales resuelven este problema.

Descargar
Hola, soy Alex de DEV STORIES DOT EU. GeoDjango y PostGIS, episodio 1 de 15. ¿Alguna vez has intentado calcular la distancia entre dos puntos de latitud y longitud usando una query SQL normal? Normalmente acabas escribiendo un bloque de trigonometría enorme y frágil solo para averiguar qué cafetería está más cerca. Las bases de datos estándar simplemente no entienden el espacio físico. Resolver este problema con los datos es exactamente lo que vemos hoy en El Poder de los Frameworks Web Espaciales. La gente suele pensar que almacenar datos geográficos solo significa añadir dos columnas decimales a una tabla de base de datos, una para la latitud y otra para la longitud. Esto es un error común. Si estás montando un sistema de rutas para reparto de comida y necesitas encontrar el restaurante más cercano a un cliente, una base de datos estándar trata esas coordenadas como números floating-point arbitrarios. No sabe que la Tierra es una esfera. No puede calcular eficientemente límites, intersecciones ni distancias reales. Te ves obligado a traerte miles de registros a la memoria de tu aplicación y hacer los cálculos tú mismo. Aquí es donde entra en juego una base de datos espacial. PostGIS es una extensión espacial para la base de datos PostgreSQL. Cambia la forma fundamental en que se almacenan los datos. En lugar de dos columnas numéricas separadas, almacenas un único objeto de geometry o geography. Una base de datos espacial entiende de forma nativa las matemáticas del mundo físico. Sabe qué son un punto, una línea y un polígono. Si quieres encontrar todos los restaurantes en un radio de dos kilómetros de un usuario, PostGIS utiliza índices espaciales especializados para encontrar la respuesta al instante a nivel de base de datos. Pero una base de datos inteligente es solo la mitad de la solución. Todavía necesitas conectar esa lógica espacial con tu aplicación web. Esto nos lleva a GeoDjango. GeoDjango es un framework geográfico de primer nivel integrado directamente en Django. Actúa como puente entre tu base de datos espacial y la lógica de tu aplicación. GeoDjango extiende el Object-Relational Mapper estándar de Django para que pueda entender las geometrías de PostGIS. Interactúas con los datos geográficos exactamente igual que con los modelos de base de datos normales. En lugar de escribir queries SQL espaciales raw, usas Python. Puedes filtrar los resultados de la base de datos basándote en relaciones espaciales, como comprobar si el polígono de la zona de reparto de un restaurante contiene el punto de la dirección de un usuario concreto. GeoDjango traduce tu código Python a las queries de PostGIS correctas. Incluso incluye map widgets para el panel de administración de Django, para que puedas crear y modificar datos geográficos visualmente out of the box. Juntos, PostGIS y GeoDjango forman un stack increíblemente potente. PostGIS se encarga del trabajo matemático pesado en la capa de almacenamiento, y GeoDjango proporciona una interfaz de Python limpia para servir esos datos a tus usuarios. Dejas de pelear con trigonometría compleja y empiezas a construir features reales basadas en la ubicación. Aquí está la clave. El verdadero poder de un framework espacial no es solo dibujar líneas en un mapa web. Es sacar las matemáticas espaciales complejas completamente del código de tu aplicación y llevarlas a un motor de base de datos construido específicamente para entender la geometría. Si te resultan útiles estos deep dives, puedes apoyar el programa buscando DevStoriesEU en Patreon. Eso es todo por hoy. Gracias por escuchar, ve a construir algo genial.
2

Geometry vs Geography en PostGIS

4m 00s

Este episodio explora los tipos de datos de PostGIS, centrándose específicamente en la diferencia entre los tipos Geometry y Geography. Aprenderás cuándo utilizar matemáticas cartesianas en un plano y cuándo cálculos esféricos terrestres.

Descargar
Hola, soy Alex de DEV STORIES DOT EU. GeoDjango y PostGIS, episodio 2 de 15. La ruta más corta entre dos puntos en la Tierra no es una línea recta, es una curva. Si tu base de datos trata la longitud y la latitud como un grid de X e Y convencional, tus queries de distancia van a estar completamente mal. Para solucionar esto, tienes que entender la diferencia entre los tipos de datos Geometry y Geography de PostGIS. Por defecto, las bases de datos espaciales operan en un plano bidimensional. Este es el tipo Geometry. Utiliza matemáticas cartesianas estándar. Si quieres calcular la distancia entre dos puntos, la base de datos básicamente traza una línea recta y aplica el teorema de Pitágoras. Este enfoque es increíblemente rápido y muy preciso para datos locales. Si estás mapeando una manzana, dibujando los muros de un edificio o marcando el límite exacto de un parque pequeño, la curvatura de la Tierra es insignificante. Un mapa plano funciona perfectamente. Los desarrolladores suelen asumir que pueden usar el tipo Geometry para todo. Almacenan coordenadas GPS globales, que son grados de longitud y latitud, dentro de una columna Geometry plana. Cuando le piden a la base de datos que calcule una distancia, devuelve un número sin sentido en grados, en lugar de metros o millas. Para obtener distancias del mundo real con el tipo Geometry en áreas grandes, tienes que traducir continuamente tus datos a proyecciones de mapas específicas y localizadas. Precisamente por esto, PostGIS ofrece el tipo Geography. El tipo Geography modela la Tierra como una esfera. En concreto, utiliza de forma nativa el sistema de referencia espacial WGS84. Cuando guardas coordenadas en una columna Geography, la base de datos entiende que la superficie es curva. Cuando le pides una distancia, no traza una línea plana. Calcula una ruta de círculo máximo. Piensa en medir la ruta de un vuelo de Nueva York a Londres. Si usas el tipo Geometry en un mapa plano estándar sin proyectar, la base de datos calcula una línea recta que atraviesa directamente el grid. Si usas el tipo Geography, la base de datos calcula la verdadera distancia más corta siguiendo la curva de la Tierra, trazando el círculo máximo sobre el Atlántico. Mejor aún, el tipo Geography devuelve esta distancia en metros automáticamente. Te saltas por completo la necesidad de gestionar tú mismo proyecciones de mapas complejas. Aquí está la clave. Podrías llegar a la conclusión de que Geography es el tipo superior y debería reemplazar a Geometry por completo. Eso es falso. Calcular distancias en una esfera requiere mucha trigonometría. Exige mucha más potencia de procesamiento que las matemáticas de plano, haciendo que las operaciones con tipos Geography sean más lentas. Además, PostGIS soporta muchas menos funciones espaciales para Geography que para Geometry. Muchas operaciones geométricas avanzadas simplemente no se traducen a matemáticas esféricas. Tu elección depende completamente de la extensión física de tus datos. Usa el tipo Geography cuando tu aplicación almacene puntos a nivel global y necesite distancias precisas sin el overhead de gestionar proyecciones. Usa el tipo Geometry cuando tus datos estén confinados a una región local específica, o cuando necesites el máximo rendimiento absoluto y la suite completa de funciones espaciales. El tipo que elijas define la forma del mundo en el que vive tu base de datos. Gracias por pasar unos minutos conmigo. Hasta la próxima, cuídate.
3

Configurando tu entorno espacial

4m 24s

Este episodio cubre la configuración inicial de un proyecto con GeoDjango y PostGIS. Aprenderás a habilitar la extensión PostGIS y a configurar los ajustes de Django para conectarte a un backend espacial.

Descargar
Hola, soy Alex de DEV STORIES DOT EU. GeoDjango y PostGIS, episodio 3 de 15. Convertir tu base de datos estándar en un motor espacial requiere exactamente tres palabras de SQL, pero si las ejecutas en el contexto equivocado, tu aplicación Django fallará en su primera migración. Hoy nos centramos por completo en la configuración de tu entorno espacial. Comenzamos por la capa de base de datos. Ya tienes PostgreSQL funcionando y has creado una base de datos vacía para tu nuevo proyecto. En esta etapa, esa base de datos es completamente estándar. Solo entiende texto, enteros, fechas y tipos relacionales estándar. No tiene ni idea de lo que es una coordenada o un límite geográfico. Para cambiar eso, necesitas habilitar PostGIS. La gente suele tropezar aquí al asumir que instalar los packages de PostGIS en su servidor hace automáticamente que todas las bases de datos tengan capacidades espaciales. Ese no es el caso. La extensión espacial debe crearse dentro de la base de datos específica que usará tu proyecto. Debes conectarte directamente a esa nueva base de datos usando un cliente de base de datos o la command line. Una vez conectado, ejecutas el comando para crear la extensión llamada postgis. Esas tres palabras de SQL transforman el entorno al instante. PostgreSQL ejecuta el comando, cargando cientos de funciones espaciales y tipos de datos especializados en tu schema. También genera una system table crucial que almacena los sistemas de referencia espacial, que proporcionan las fórmulas matemáticas necesarias para proyectar coordenadas globales en una pantalla plana. Con la base de datos preparada, pasas a tu proyecto Django. Haces el bootstrap de un proyecto estándar y creas una nueva app. Llamemos a esta app world. Ahora, abre tu archivo settings. Se requieren dos modificaciones distintas para conectar Django y PostGIS. Primero, localiza tu array de installed apps. Tienes que añadir el módulo llamado django punto contrib punto gis. Este módulo es el core de GeoDjango. Carga los wrappers de Python para las librerías geográficas subyacentes, proporcionando los campos espaciales y los lookups de base de datos geográfica que usarás para escribir queries más adelante. También añades tu nueva app world a esta lista para que Django sepa que tiene que trackear sus modelos. Aquí está la clave. La segunda modificación ocurre en tu diccionario de configuración de base de datos. Django enruta todo el tráfico de la base de datos a través de un engine backend. Si dejas el engine configurado con el backend por defecto de PostgreSQL, Django tratará tu base de datos espacial como una base de datos relacional estándar. No sabrá cómo serializar un shape geográfico ni parsear de forma segura una bounding box query. Debes apuntar explícitamente el engine al backend PostGIS de GeoDjango. Cambias el valor del engine a django punto contrib punto gis punto db punto backends punto postgis. El resto del diccionario de conexión permanece idéntico. Sigues proporcionando el nombre de la base de datos, el user, la password, el host y el port exactamente igual que lo harías para un setup estándar. Cuando ejecutas tus migraciones iniciales, este nuevo backend toma el control. Se conecta a PostgreSQL e inmediatamente comprueba si existe la extensión PostGIS. Si olvidaste crear la extensión en la base de datos, el backend detectará que faltan los tipos espaciales y lanzará un error. Si la extensión está presente, la conexión tiene éxito. Ahora tienes un pipeline espacial completo. El verdadero poder de esta configuración específica es que, una vez que el backend postgis está conectado, la enorme complejidad de las queries de base de datos espacial queda completamente oculta tras el familiar Object Relational Mapper de Django. Eso es todo por este episodio. Gracias por escuchar, y ¡sigue programando!
4

Sistemas de referencia de coordenadas y SRIDs

4m 30s

Este episodio desglosa los sistemas de referencia de coordenadas y los SRIDs. Aprenderás qué es WGS84 y por qué proyectar correctamente los datos de tus mapas es crucial para medir distancias con precisión.

Descargar
Hola, soy Alex de DEV STORIES DOT EU. GeoDjango y PostGIS, episodio 4 de 15. Si intentas medir la huella de un edificio usando latitud y longitud, tus números serán completamente inútiles. Eso es porque la latitud y la longitud son solo ángulos desde el centro de la Tierra, no distancias físicas. Para convertir esos ángulos en medidas útiles como metros o pies, necesitas un Coordinate Reference System y un SRID. Una coordenada como 48 grados norte y 2 grados este es solo un par de números en bruto. Sin contexto, tu base de datos no sabe cómo mapear esos números al mundo físico. Ese contexto proviene del Spatial Reference System Identifier, comúnmente llamado SRID. Un SRID es simplemente un integer que vincula tus datos de coordenadas en bruto a un modelo matemático específico de la Tierra. Por defecto, los campos geometry de GeoDjango usan un SRID de 4326. Este integer representa el sistema de coordenadas WGS84. Es el modelo estándar utilizado por los satélites GPS y la mayoría de las librerías de web mapping. Almacena datos usando grados de latitud y longitud. WGS84 es excelente para localizar puntos en cualquier lugar del planeta. Sin embargo, es un sistema geográfico, lo que significa que modela la Tierra como una forma tridimensional. Aquí está la clave. No puedes calcular con precisión distancias planas o áreas usando grados. La distancia física entre dos líneas de longitud se reduce a medida que te mueves desde el ecuador hacia los polos. Si intentas encontrar todas las cafeterías a menos de 500 metros de un punto usando el SRID 4326, la base de datos tiene que realizar cálculos esféricos pesados al vuelo, lo cual es lento y a menudo impreciso. Para solucionar esto, usas sistemas de coordenadas proyectadas. Un sistema proyectado aplana matemáticamente una porción específica de la Tierra curva sobre una cuadrícula bidimensional. Una vez que el área está aplanada, las coordenadas cambian de ángulos a unidades de longitud estándar, como metros o pies. Esto hace que los cálculos de distancia sean rápidos y precisos usando geometría básica. Tu elección de SRID depende completamente del alcance de tu aplicación. Si estás construyendo un sistema global de seguimiento de vuelos, almacenas tus datos usando WGS84 y el SRID 4326. Tus puntos abarcan todo el mundo, así que necesitas un sistema global, incluso si los cálculos de distancia son un poco más complejos. Si estás construyendo una aplicación de planificación urbana local para medir los límites exactos de las propiedades, usar WGS84 es un error. En su lugar, asignas un sistema de coordenadas proyectadas local a tu campo espacial. Por ejemplo, podrías usar un sistema de coordenadas State Plane específico con su propio SRID único. Estos sistemas locales están hechos a medida. Minimizan la distorsión que ocurre cuando aplanas una esfera, pero solo para esa zona geográfica específica. Al configurar tus modelos en GeoDjango, defines el SRID directamente en el campo espacial. Si no haces nada, su valor por defecto es 4326. Si quieres una proyección localizada en metros, le pasas ese integer específico a la definición del campo. GeoDjango entonces trata toda la geometría en esa columna de acuerdo con ese modelo matemático específico. El SRID correcto asegura que tus cálculos de distancia no se distorsionen a medida que tus datos se alejan del ecuador. Gracias por escuchar. ¡Hasta la próxima!
5

Diseñando modelos geográficos

3m 46s

Este episodio demuestra cómo diseñar modelos geográficos en GeoDjango. Aprenderás a definir los atributos PointField y MultiPolygonField para almacenar datos espaciales en tu aplicación Django.

Descargar
Hola, soy Alex de DEV STORIES DOT EU. GeoDjango y PostGIS, episodio 5 de 15. Quieres añadir datos de ubicación a tu aplicación, así que podrías pensar en añadir dos simples float fields para latitud y longitud a tu base de datos. Pero hacer eso te deja completamente fuera de las spatial queries avanzadas, cálculos de distancia e intersecciones geométricas. Para desbloquear esas capacidades, necesitas spatial types adecuados, lo que nos lleva a diseñar models geográficos. Pasar de los models estándar de Django a los models de GeoDjango solo requiere un pequeño cambio en tus imports. En lugar de tirar de los models de base de datos estándar de Django, importas los models del módulo contrib geográfico. Este módulo personalizado proporciona un drop-in replacement. Te da acceso a todos los field types estándar de Django, como characters e integers, a la vez que introduce de forma transparente los spatial types en la misma definición de class. Imagina un escenario en el que estás construyendo un model WorldBorder para almacenar datos de países. Defines la class del model igual que cualquier otra. Asignas un character field para el nombre del país, un integer field para la población y un float field para la superficie total. Para gestionar la geometría real del mapa, añades un campo geográfico directamente junto a los demás. Para un país, usarías un MultiPolygonField. Mientras que un PointField es perfecto para almacenar un único par de coordenadas como una capital, un MultiPolygonField puede representar fronteras nacionales complejas, incluyendo naciones con múltiples masas terrestres desconectadas o islas en alta mar. Cuando adjuntas este campo espacial a tu model, estás definiendo un sistema de coordenadas por debajo. Cada campo geográfico depende de un Identificador del Sistema de Referencia Espacial, conocido como el SRID. El SRID le dice a la base de datos cómo proyectar los números de coordenadas en bruto sobre la forma real de la Tierra. Si no configuras explícitamente este valor, GeoDjango pone por defecto el SRID a 4326. Ese integer específico se refiere al estándar WGS84, que es exactamente el mismo sistema de coordenadas que usa el hardware GPS estándar. Si tus datos de origen dependen de una proyección local diferente, simplemente le pasas el integer de destino al parámetro SRID justo dentro de la definición del field. Aquí es donde la cosa se pone interesante. Los desarrolladores familiarizados con el ORM de Django saben que, para que una columna sea rápida de consultar, debes pasar explícitamente un flag de index de base de datos a la definición del field. Como las spatial queries son inherentemente pesadas, podrías asumir que necesitas configurar manualmente indexes especializados para tus columnas de geometría. Pues no. Los campos geográficos en GeoDjango funcionan de manera diferente. Incluyen un parámetro específico para el spatial indexing, y viene por defecto en true. Cuando ejecutas tus migrations, GeoDjango le dice automáticamente a la base de datos subyacente que construya un index espacial especializado. Obtienes consultas de bounding box de alto rendimiento y búsquedas de intersecciones geográficas out of the box, con cero configuración extra. El verdadero punto fuerte de diseñar models de esta manera es que desmitifica por completo los datos espaciales. Un polígono enorme y complejo que representa un continente se convierte en una property más de tu object de Python, lista para ser guardada y consultada junto a un simple recuento de población. Eso es todo por hoy. Gracias por escuchar, ve a construir algo genial.
6

La API de GDAL y OGR

4m 25s

Este episodio presenta el wrapper de la API de GDAL y OGR dentro de GeoDjango. Aprenderás a inspeccionar y leer archivos vectoriales externos como Shapefiles de forma nativa en Python antes de importarlos.

Descargar
Hola, soy Alex de DEV STORIES DOT EU. GeoDjango y PostGIS, episodio 6 de 15. Te entregan un archivo espacial enorme —un Shapefile de ESRI o un GeoJSON— y necesitas saber qué atributos contiene. Tu primer impulso podría ser instalar un programa GIS de escritorio pesado solo para echar un vistazo. No hace falta. GeoDjango puede leer estos archivos de forma nativa directamente en la shell de Python usando la API de GDAL y OGR. Si los sistemas de información geográfica son una caja de herramientas, la Geospatial Data Abstraction Library es el traductor universal. Técnicamente, GDAL maneja datos raster como imágenes de satélite, mientras que su compañero OGR maneja datos vectoriales como puntos, líneas y polígonos. GeoDjango incluye un wrapper pitónico para la librería OGR, dándote una forma directa de inspeccionar casi cualquier formato de archivo vectorial del planeta. Supongamos que te has descargado un shapefile que contiene las fronteras de todos los países del mundo. Antes de escribir un script para ingerir estos datos, necesitas saber exactamente cómo está estructurado. Empiezas importando el objeto DataSource del módulo GDAL de GeoDjango. Creas un nuevo data source pasándole el file path de tu shapefile. Este objeto ahora representa todo tu dataset espacial descargado. Un data source organiza su información espacial en layers. Puedes pedirle al data source el número de layers. Un Shapefile de ESRI tradicionalmente solo contiene un layer, pero formatos como GeoPackages pueden contener docenas. Recuperas ese primer layer usando su index, exactamente igual que al sacar un elemento de una lista estándar de Python. Aquí está la clave. El objeto layer es donde ocurre la verdadera introspección. Actúa como un contenedor para registros espaciales individuales, que la API llama features. Puedes pedirle al layer que devuelva su número total de features. Para nuestro archivo de fronteras mundiales, el recuento debería coincidir más o menos con el número de países en la Tierra. También puedes preguntarle al layer por su tipo de geometry. Esto confirma si los datos consisten en puntos, líneas o polígonos. Para las fronteras de los países, el tipo normalmente devolverá MultiPolygon. A continuación, necesitas saber qué metadatos están asociados a esas formas. Puedes preguntarle al layer por sus fields. Esto devuelve una lista de strings que representan los nombres de las columnas de atributos. Podrías ver nombres correspondientes a un código de país interno, un nombre común y un recuento de población. Incluso puedes profundizar un nivel más. Accediendo a un feature individual del layer por su index, puedes inspeccionar un solo país. Puedes preguntarle a ese feature específico por el valor de su field de nombre común. También puedes acceder al objeto geometry específico de ese feature y pedirle que devuelva sus coordenadas como well-known text o GeoJSON. Ahora has mapeado exactamente qué formas contiene el archivo, los nombres de sus atributos y la estructura de sus registros. Has hecho todo esto puramente a través de Python, sin escribir un script de importación a base de datos ni depender de software de visualización externo. El wrapper de GDAL convierte tu shell estándar de Python en una lente exploratoria para datos espaciales, permitiéndote validar archivos externos antes de que un solo registro toque tu base de datos. Eso es todo por este episodio. Gracias por escuchar, y ¡sigue creando!
7

Ingesta de datos espaciales con LayerMapping

4m 05s

Este episodio trata sobre la automatización de la importación de datos espaciales. Aprenderás a utilizar la utilidad LayerMapping para mapear datos externos de un Shapefile directamente en tus modelos de GeoDjango sin esfuerzo.

Descargar
Hola, soy Alex de DEV STORIES DOT EU. GeoDjango y PostGIS, episodio 7 de 15. Importar manualmente miles de polígonos geográficos y sus metadatos puede llevar días. Tus archivos de origen tienen nombres de columna crípticos y tipos incompatibles, pero tu base de datos exige una estructura estricta. La solución es la utilidad LayerMapping de GeoDjango, que gestiona todo este proceso de ingesta con un solo diccionario. Al trabajar con datos espaciales, a menudo recibes archivos vectoriales como los Shapefiles de ESRI. Estos archivos contienen tanto las formas geométricas de las ubicaciones como los datos de atributos asociados a esas formas. Sin embargo, los archivos externos rara vez coinciden con el esquema de tu base de datos. Un Shapefile podría tener una columna de población abreviada como POP2005 y un código de país como ISO2. Tu modelo Django impecable, llamémoslo WorldBorder, tiene campos con nombres claros y tipos estrictos para esos mismos atributos. Quizás te tiente usar importaciones manuales de SQL o herramientas de base de datos como pgAdmin para transferir estos datos a PostGIS. LayerMapping ofrece un enfoque completamente diferente. Es una utilidad programática para scripts de Python. Se integra directamente en tu proyecto Django, conectando archivos espaciales externos directamente con tu ORM. Aquí está la clave. El núcleo de LayerMapping es un sencillo diccionario de Python. Las claves de este diccionario son los nombres de los campos de tu modelo Django. Los valores son los nombres en formato string de los atributos en tu archivo de origen. Por ejemplo, tu diccionario mapea el campo name de tu modelo Django al atributo NAME del Shapefile. Mapea el campo de población de tu modelo a POP2005, y el campo de código ISO a ISO2. También mapeas el campo de geometría de tu modelo al tipo de geometría del Shapefile, que normalmente se representa con un string como MULTIPOLYGON. Para automatizar esto, escribes un pequeño archivo de Python, normalmente llamado load script. Dentro de este script, importas tu modelo WorldBorder y la herramienta LayerMapping. Defines tu diccionario de mapeo. Luego, creas una nueva instancia de LayerMapping. A esta instancia le pasas tres datos obligatorios. Primero, tu modelo Django. Segundo, la ruta del archivo Shapefile de origen. Tercero, el diccionario de mapeo que acabas de crear. También puedes proporcionar argumentos opcionales para controlar el comportamiento de la ingesta. Si tus datos de origen ya están en el sistema de referencia espacial exacto que espera tu base de datos, puedes indicarle a la utilidad que no realice transformaciones de coordenadas. Esto se salta cálculos innecesarios y acelera la importación. Finalmente, llamas al método save en tu instancia de LayerMapping. Cuando ejecutas este script, la utilidad toma el control por completo. Abre el Shapefile, itera sobre cada elemento geográfico y utiliza tu diccionario para alinear los atributos desordenados del archivo con los campos estrictos de tu modelo. Traduce automáticamente la geometría en crudo a un formato que PostGIS entiende, y guarda los registros en tu base de datos. Puedes indicarle al método save que lance una excepción ante el primer error que encuentre, o puedes dejar que se ejecute y simplemente loguear cualquier elemento problemático en tu terminal. La conclusión más importante es que LayerMapping desacopla por completo la estructura rígida de los archivos espaciales externos del diseño limpio de tu base de datos, permitiéndote ingestar datasets masivos con tan solo unas pocas líneas de Python. Antes de terminar, si te ha gustado el programa y quieres ayudarnos a seguir adelante, puedes apoyarnos buscando DevStoriesEU en Patreon. Eso es todo por este episodio. ¡Gracias por escuchar y a seguir programando!
8

La API de GEOS: Geometría al estilo Python

3m 59s

Este episodio se centra en la API de GEOS para la manipulación de geometría al estilo Python. Aprenderás a realizar operaciones topológicas como uniones e intersecciones en memoria sin consultar la base de datos.

Descargar
Hola, soy Alex de DEV STORIES DOT EU. GeoDjango y PostGIS, episodio 8 de 15. Quizás pienses que cada vez que necesitas fusionar dos Polygons o encontrar una intersección espacial, tienes que escribir una query y esperar a que la base de datos devuelva una respuesta. La realidad es que puedes hacer cálculos espaciales complejos directamente en tu shell de Python sin tocar para nada una conexión a la base de datos. Eso es exactamente de lo que hablamos hoy: la API GEOS y la geometría Pythonic. Un error común con GeoDjango es pensar que PostGIS se encarga de todo el trabajo pesado espacial. Aunque PostGIS es increíblemente potente, la API GEOS te permite hacer operaciones geométricas completamente en memoria local. GEOS significa Geometry Engine Open Source. Es una librería de C++ altamente optimizada, pero GeoDjango te da un potente wrapper llamado el object GEOSGeometry. Este object te permite crear, manipular y analizar geometrías puramente en Python. Aquí es donde la cosa se pone interesante. Un object GEOSGeometry no parece un wrapper torpe alrededor de una librería de C. Actúa exactamente como un container nativo de Python. Si tienes un LineString con diez puntos, puedes ejecutar la función length estándar de Python sobre él para ver que tiene diez coordenadas. Puedes iterar sobre un Polygon con un for-loop estándar para extraer sus anillos individuales, o usar un índice para sacar un punto específico de una geometría MultiPoint. Se comportan igual que las conocidas listas o tuplas de coordenadas. El verdadero poder se desbloquea cuando aplicas operaciones topológicas. Imagina que estás montando una aplicación de logística y tienes dos zonas de entrega superpuestas definidas como Polygons de GEOS. Necesitas encontrar el área exacta donde se superponen estas dos zonas. No necesitas guardar estas zonas en un model ni ejecutar una query en la base de datos. En su lugar, puedes generar la superposición instantáneamente en memoria. Primero, instancias dos objects GEOSGeometry que representan tus zonas de entrega. Luego, simplemente llamas al method intersection en el primer Polygon, pasando el segundo Polygon como argumento. Como la API es profundamente Pythonic, también puedes usar simplemente el operador bitwise AND. Literalmente escribes Polygon uno, un ampersand, y Polygon dos. Esto devuelve un object GEOSGeometry totalmente nuevo que representa la forma superpuesta exacta. Tienes acceso a un conjunto completo de estas operaciones espaciales. Si necesitas encontrar el área cubierta por la primera zona de entrega pero estrictamente fuera de la segunda, usas el method difference, o el operador minus normal de Python. Si quieres fusionarlas en una zona enorme, usas el method union, o el operador bitwise OR pipe. Incluso puedes generar nuevas formas de la nada. Llamar al method buffer en una geometría Point con un argumento de anchura calcula y devuelve instantáneamente un Polygon que representa un círculo perfecto dibujado alrededor de ese punto. Como todo depende del motor de C++ subyacente, estos cálculos ocurren extremadamente rápido. La conclusión clave aquí es que la API GEOS te da un motor espacial independiente en memoria, permitiéndote validar geometrías, calcular buffers y encontrar intersecciones antes de que un solo byte de datos llegue a tu base de datos. Eso es todo por este episodio. ¡Nos vemos en la próxima!
9

Dominando los spatial lookups

4m 33s

Este episodio explica los lookups de consultas geográficas en el ORM de Django. Aprenderás a utilizar filtros espaciales para encontrar relaciones, como qué puntos están contenidos dentro de unos límites específicos.

Descargar
Hola, soy Alex de DEV STORIES DOT EU. GeoDjango y PostGIS, episodio 9 de 15. Olvídate de escribir comparaciones de coordenadas masivas. Tienes la ubicación de un usuario y una zona de entrega, y necesitas saber si se superponen. Hacer esto matemáticamente implica comprobar cientos de aristas de polígonos en la lógica de tu aplicación. En cambio, GeoDjango lo reduce todo a una operación de base de datos. Hoy dominamos los lookups espaciales. Si has usado Django, conoces la sintaxis de doble guion bajo para filtrar querysets. Añades algo como doble guion bajo exact o doble guion bajo in al nombre de un campo. GeoDjango extiende esta misma sintaxis para ejecutar relaciones topológicas complejas de PostGIS. Las relaciones topológicas son simplemente reglas sobre cómo las geometrías comparten espacio. ¿Se tocan? ¿Se superponen? ¿Está una completamente dentro de la otra? GeoDjango te da tipos de lookup dedicados para hacer estas preguntas directamente en tus consultas del ORM. El lookup espacial más común y permisivo es intersects. Si filtras un campo de geometría con doble guion bajo intersects, la base de datos devuelve los registros donde las dos geometrías comparten alguna porción de espacio. Pueden cruzarse, tocarse en un límite, o una puede envolver completamente a la otra. Mientras haya algún espacio compartido, intersects se evalúa como true. A menudo, necesitas más precisión que una simple intersección. Necesitas límites estrictos. Aquí es donde contains y within entran en juego. Los desarrolladores confunden estos dos constantemente. Esta es la clave. La diferencia es puramente direccional. Si la geometría A contiene a la geometría B, entonces la geometría B está dentro de la geometría A. Piensa en una caja y una canica. La caja contiene la canica. La canica está dentro de la caja. Eliges el lookup basándote en qué geometría está en la columna de tu base de datos y qué geometría estás pasando como argumento del filter. Imagina un escenario concreto. Tienes una tabla de base de datos de casas, y cada casa tiene una geometría de punto que representa su ubicación. La ciudad acaba de publicar un nuevo polígono que define una zona de inundación. Necesitas encontrar todas las casas que están perfectamente dentro de esa zona de riesgo. No haces una query a la zona de inundación para ver qué contiene. Haces la query a las casas. Llamas a filter en el modelo de la casa, haces referencia al campo de geometría de punto, añades doble guion bajo within, y pasas el polígono de la zona de inundación como valor. Cuando ejecutas esa query, Django traduce tu lookup de doble guion bajo en una llamada a una función nativa de PostGIS, específicamente ST_Within. El motor de la base de datos evalúa las geometrías usando sus índices espaciales optimizados. Comprueba si cada coordenada del punto de la casa está dentro del interior del polígono de la zona de inundación. Si la casa está exactamente en el borde del polígono, no se considera within. La contención estricta significa que el interior de la primera geometría debe estar completamente dentro del interior de la segunda geometría. Si inviertes el escenario, digamos que estás haciendo una query a una tabla de base de datos de barrios para encontrar el que rodea una ubicación de usuario específica, usas doble guion bajo contains. Filtras el campo del polígono del barrio, añades doble guion bajo contains, y pasas el punto del usuario. La lógica es idéntica por debajo, pero el orden de los argumentos espaciales pasados a PostGIS se invierte. Entender esta lógica direccional evita fallos silenciosos y querysets vacíos. Al mapear las operaciones de PostGIS directamente a los keyword arguments de Django, filtras datasets espaciales masivos de forma eficiente sin escribir raw SQL. La geometría por la que estás filtrando siempre dicta la dirección de tu lookup espacial. Gracias por escucharnos. ¡Hasta la próxima!
10

Consultas de distancia de alto rendimiento

4m 17s

Este episodio aborda las consultas de proximidad y distancia de alto rendimiento. Aprenderás a utilizar los lookups de distancia y el objeto de distancia geográfica para encontrar ubicaciones cercanas de manera eficiente.

Descargar
Hola, soy Alex de DEV STORIES DOT EU. GeoDjango y PostGIS, episodio 10 de 15. Las queries de radio son el pan de cada día de las aplicaciones basadas en la ubicación. Si las escribes mal, tu base de datos calcula la distancia exacta a cada fila de tu tabla, forzando un full scan masivo. Si las escribes bien, tardan milisegundos. Las queries de distancia de alto rendimiento son la diferencia entre una app que va rapidísimo y una que crashea bajo carga. Un error común que cometen los desarrolladores es pensar en las queries espaciales de la misma manera que piensan en las matemáticas básicas. El enfoque más ingenuo es calcular la distancia precisa desde tu punto de destino a todos los demás puntos de la base de datos, y luego filtrar todo lo que sea mayor que tu radio máximo. Nunca deberías hacer esto. Calcular distancias reales en una esfera es muy pesado a nivel computacional. Si tu query filtra calculando primero la distancia, la base de datos no puede usar sus índices espaciales. Se ve obligada a comprobar cada fila una por una. Para mantener las queries rápidas, tienes que depender de lookups respaldados por índices. Antes de mirar los lookups de la base de datos, necesitas una forma clara de expresar la distancia en tu código Python. GeoDjango proporciona el objeto Distance, que normalmente se importa simplemente como la letra D mayúscula. Lo inicializas con una unidad y un valor. Por ejemplo, pasarle el argumento m i igual a cinco a este objeto crea una medida de exactamente cinco millas. Puedes usar kilómetros, metros o incluso grados. Esto normaliza la medida en Python antes de que la query llegue a la base de datos. Considera un escenario en el que estás implementando una feature que encuentra todas las cafeterías dentro de un radio de cinco millas del ping del GPS actual de un usuario. Tienes el punto de ubicación del usuario y quieres hacer una query a tu modelo de cafeterías. Podrías usar el lookup de distance less-than-or-equal. Escribes un filtro en la query donde tu campo de ubicación de la cafetería va seguido de un doble guion bajo y la palabra distance, un guion bajo y las letras l t e. Le pasas una tupla que contiene el punto del usuario y tu objeto Distance configurado en cinco millas. Esto funciona. Se traduce en una función de la base de datos que comprueba si la distancia es menor o igual a cinco millas. Pero, dependiendo de tu backend espacial y de cómo estén configuradas tus columnas, este lookup podría hacer más trabajo matemático del estrictamente necesario al calcular distancias exactas antes de hacer la comparación final. Aquí está la clave. Rara vez necesitas conocer la distancia exacta para filtrar un radio. Solo necesitas saber si el objeto está dentro del círculo. Aquí es donde el lookup dwithin se vuelve esencial. En lugar de distance less-than-or-equal, añades un doble guion bajo y la palabra dwithin a tu campo de ubicación. Le pasas exactamente el mismo punto del usuario y el objeto Distance de cinco millas. Por debajo, esto enruta directamente a la función ST DWithin de PostGIS. Esta función está altamente optimizada. Primero hace una comprobación rápida de bounding-box, que utiliza perfectamente tus índices espaciales. Dibuja un cuadrado aproximado alrededor de tu radio de cinco millas e inmediatamente descarta cualquier punto fuera de ese cuadrado sin hacer cálculos esféricos complejos. Solo realiza cálculos precisos y costosos para los pocos puntos que caen cerca del límite del círculo dentro de ese cuadrado. Si tu tabla de la base de datos utiliza columnas geography en lugar de columnas geometry básicas, PostGIS maneja la curvatura de la Tierra automáticamente, manteniendo al mismo tiempo el uso de índices rapidísimo. El hábito más valioso en la programación espacial es darte cuenta de que comprobar si un punto vive dentro de una forma siempre es más barato que sacar una cinta métrica para calcular la distancia exacta entre ellos. Gracias por pasar unos minutos conmigo. Hasta la próxima, cuídate.
11

Funciones geográficas de base de datos

4m 13s

Este episodio explora las funciones espaciales de base de datos accesibles a través de GeoDjango. Aprenderás a calcular áreas, extraer centroides y generar GeoJSON directamente en la capa de la base de datos.

Descargar
Hola, soy Alex de DEV STORIES DOT EU. GeoDjango y PostGIS, episodio 11 de 15. Tienes una base de datos llena de polígonos enormes y complejos, y tu frontend solo necesita mostrar un pin en el centro de cada uno. Si te traes esos polígonos raw a Python para calcular el centro, estás arrastrando megabytes de datos de coordenadas inútiles por la red. La solución es delegar esas matemáticas a la base de datos usando funciones geográficas de base de datos. Hay dos maneras de obtener información espacial, como el área o un punto central, en GeoDjango. La primera es consultar el registro de la base de datos, traerte toda la geometría a un objeto GEOS de Python y acceder a una propiedad como punto area en él. No hagas esto a menos que realmente necesites la geometría completa en Python. Traerte los límites de un parque nacional podría implicar cargar decenas de miles de vértices en memoria solo para calcular un único número. La segunda forma, mucho más eficiente, es decirle a PostGIS que calcule la respuesta y que solo devuelva el resultado final. Aquí es donde las funciones geográficas de base de datos, combinadas con el método annotate del ORM de Django, se vuelven esenciales. Veamos un escenario práctico. Estás creando una API que lista parques nacionales. Para el list view, el cliente solo necesita el nombre del parque, su área total y una única coordenada central para poner un pin en el mapa. No necesita el complejo polígono de los límites. En tu queryset de Django, usas el método annotate. Le dices que cree un nuevo atributo, quizá llamado park area, y lo igualas a la función Area actuando sobre tu columna de geometría. Junto a este, creas otro atributo llamado center point, igualado a la función Centroid sobre esa misma columna de geometría. Finalmente, restringes el output de la query solo al nombre y a tus dos nuevas anotaciones. Cuando se ejecuta esta query, PostGIS lee los datos raw de geometría en el disco. Ejecuta rutinas internas altamente optimizadas para calcular el área espacial y encontrar el punto central matemático. Luego, devuelve exactamente tres cosas por la red a tu aplicación Django: un string de texto para el nombre, un número para el área y una geometría de un solo punto para el centro. Te saltas por completo los costes de ancho de banda y memoria de transferir el polígono grande. Esta estrategia se aplica a muchas operaciones espaciales. Puedes usar la función Transform dentro de una anotación para convertir las coordenadas desde la proyección de almacenamiento de tu base de datos directamente a la proyección que necesita tu mapa web, como Web Mercator. La base de datos se encarga de las matemáticas antes incluso de que Python vea los datos. También puedes usar la función AsGeoJSON. Esto le dice a PostGIS que formatee los datos espaciales en un string de texto JSON estándar directamente en la base de datos. Cuando Django lo recibe, es solo texto listo para pasar directamente a tu frontend, evitando por completo el overhead de serialización de Python. También puedes aplicar funciones de agregación a querysets enteros. La función Extent analiza un grupo de geometrías y devuelve un único bounding box que las cubre todas. Si un usuario busca todos los parques en una región específica, devolver el Extent te da las coordenadas exactas necesarias para hacer zoom automáticamente en el mapa del frontend y que todos los resultados encajen a la perfección. Esta es la idea clave. Tu base de datos espacial es un motor de computación altamente especializado, no solo un contenedor de almacenamiento. Mantén tus cálculos espaciales pesados dentro de PostGIS, y mueve solo las respuestas calculadas por la red hasta Python. Eso es todo por este episodio. ¡Nos vemos en la próxima!
12

Datos Raster en PostGIS

4m 11s

Este episodio presenta los rasters de PostGIS y los RasterFields de GeoDjango. Aprenderás a almacenar y consultar datos espaciales continuos, como modelos de elevación o mapas de temperatura.

Descargar
Hola, soy Alex de DEV STORIES DOT EU. GeoDjango y PostGIS, episodio 12 de 15. Las formas vectoriales son geniales cuando quieres trazar una línea limpia alrededor del límite de una ciudad o localizar a un usuario. Pero, ¿qué pasa cuando necesitas mapear algo que no tiene límites definidos, como los cambios de temperatura en un continente o la elevación de una cordillera entera? No puedes dibujar un polígono para cada grado de temperatura. Aquí es donde entran en juego los datos raster en PostGIS. Si estás acostumbrado a trabajar con puntos, líneas y polígonos, los datos raster requieren un cambio de mentalidad. Los datos raster no están hechos de formas discretas. Son un grid continuo de píxeles, exactamente igual que una fotografía digital. Pero en lugar de valores de color rojo, verde y azul, cada píxel contiene un dato numérico específico. Ese dato podría ser la precipitación, el tipo de suelo o la altitud. Todo el grid está vinculado matemáticamente al mundo real mediante georreferenciación. Esto significa que la base de datos sabe exactamente dónde cae cada píxel en el mapa. En GeoDjango, manejar estos datos implica principalmente dos componentes: el RasterField y el objeto GDALRaster. RasterField es el tipo de columna de la base de datos. Lo añades a tu modelo de Django igual que harías con un campo de geometría. Esto le dice a PostGIS que asigne espacio internamente para los datos del grid. Pero no interactúas directamente con los bytes raw de la base de datos. Cuando sacas un raster de la base de datos, o antes de meter uno, usas GDALRaster. Este es un wrapper de Python para las librerías geoespaciales subyacentes. Te permite inspeccionar las propiedades del raster, como su escala, su sistema de referencia de coordenadas y los valores reales dentro de sus bandas. Una banda es simplemente una capa de datos en el grid. Una imagen estándar tiene tres bandas para el color, pero un mapa de elevación normalmente solo tiene una banda que representa la altura. Imagina un escenario concreto. Estás construyendo una aplicación para senderistas, y tienes un Modelo Digital de Elevación de una cordillera. Este modelo de elevación normalmente se proporciona como un archivo GeoTIFF. Primero, defines un modelo de Django para tu cordillera y le pones un RasterField. Luego, en tu código Python, instancias un GDALRaster pasándole la ruta del archivo a tu GeoTIFF. Django carga el archivo en memoria como un objeto GDALRaster. Asignas ese objeto al RasterField en tu modelo de montaña y llamas a save. PostGIS coge ese grid y lo guarda. Ahora, cuando un senderista sube su ruta GPS, puedes hacer una query a la base de datos para saber exactamente en qué píxel caen sus coordenadas. Extraes el valor de elevación guardado en ese píxel específico. Cuando vuelves a leer ese campo de la base de datos, Django te da un objeto GDALRaster de nuevo. Puedes pedirle a este objeto su ancho, su alto o su extensión espacial. Puedes acceder a los arrays de datos raw de los píxeles directamente en Python para hacer cálculos antes de enviar los datos al front end de tu aplicación. Aquí está la clave. Usas vectores para cosas que existen en un lugar específico, y usas rasters para cosas que existen en todas partes por toda un área. Al combinar ambos en PostGIS, tu aplicación puede relacionar objetos discretos, como una ruta de senderismo, con entornos continuos, como la altitud real del terreno bajo tus pies. Si quieres ayudar a que el programa siga adelante, puedes buscar DevStoriesEU en Patreon — tu apoyo significa mucho. Eso es todo por este episodio. Gracias por escuchar, ¡y sigue programando!
13

Geolocalización con GeoIP2

4m 27s

Este episodio cubre la geolocalización basada en IP utilizando el módulo GeoIP2 de GeoDjango. Aprenderás a mapear las direcciones IP de los usuarios a ciudades y países utilizando los conjuntos de datos de MaxMind.

Descargar
Hola, soy Alex de DEV STORIES DOT EU. GeoDjango y PostGIS, episodio 13 de 15. ¿Qué ocurre si necesitas saber dónde se encuentra un usuario para ofrecerle contenido local, pero no te ha otorgado permisos de GPS? Su dirección IP entrante contiene la respuesta. Esto es geolocalización con GeoIP2. Para que quede claro desde el principio, la geolocalización por IP no es una búsqueda de coordenadas precisa como la API de geolocalización de un navegador. Es una aproximación. Al buscar una dirección IP, consultas un dataset estático que asigna bloques de IP a áreas geográficas. Casi siempre te da el país correcto, y a menudo la ciudad correcta, pero no encontrará la dirección física real del usuario. Imagina un escenario donde un visitante llega a tu e-commerce. Quieres redirigirlo automáticamente al storefront localizado de su país o centrar un mapa en su región basándote únicamente en su dirección IPv4 o IPv6 entrante. GeoDjango proporciona el objeto GeoIP2 específicamente para gestionar este lookup offline. Antes de poder escribir cualquier lógica, necesitas tener las piezas adecuadas en su lugar. Primero, instalas la librería de Python geoip2 en tu entorno. Segundo, necesitas los datos reales. GeoIP2 utiliza datasets de MaxMind, generalmente las bases de datos gratuitas GeoLite2 City o Country. Descargas estos archivos, que tienen una extensión mmdb, y los colocas en tu servidor. Finalmente, en tus settings de Django, defines una variable llamada GEOIP_PATH y la apuntas al directorio que contiene esos archivos. Django espera encontrar archivos con nombres específicos, como GeoLite2-City punto mmdb, en esa carpeta. Con el setup completo, usar la herramienta solo requiere unos pocos pasos. Importas el objeto GeoIP2 del módulo django contrib gis geoip2 y lo instancias. Extraes el string de la dirección IP entrante de los headers de tu request, y lo pasas a uno de los métodos de lookup. Si solo necesitas una lógica de routing general, llamas al método country. Le pasas la dirección IP, y este devuelve un diccionario que contiene el código y el nombre del país. Si necesitas mayor granularidad para centrar un mapa, llamas al método city en su lugar. Este devuelve un diccionario más rico que contiene el nombre de la ciudad, la región y los valores aproximados de longitud y latitud. El método city también incluye los datos del país, por lo que solo necesitas hacer una llamada. Si simplemente quieres las coordenadas para pasárselas a otra función, existen métodos dedicados como coords que devuelven una tupla básica de longitud y latitud. También necesitas gestionar los errores de forma controlada. Si pasas una dirección IP no válida, o una dirección que simplemente no está presente en la base de datos de MaxMind, GeoIP2 no devuelve un diccionario vacío. Lanza una GeoIP2Exception. Debes envolver tus llamadas de lookup en un bloque try y proporcionar una ubicación de fallback por defecto para tu storefront cuando el lookup falle. Aquí está la clave de todo. El código en sí es esencialmente solo un lector de archivos optimizado. La precisión de tu geolocalización depende completamente de lo actualizada que esté la base de datos ubicada en tu directorio GEOIP_PATH. Las asignaciones de IP cambian constantemente. Si construyes un sistema de routing basado en GeoIP2, debes automatizar la descarga de nuevos archivos de base de datos regularmente, o tus redirecciones localizadas se volverán incorrectas de forma lenta y silenciosa. Eso es todo por hoy. ¡Hasta la próxima!
14

Pruebas de aplicaciones espaciales

4m 04s

Este episodio se centra en las pruebas de aplicaciones espaciales en GeoDjango. Aprenderás a configurar tu suite de pruebas, manejar bases de datos de plantillas de PostGIS y establecer los privilegios de usuario.

Descargar
Hola, soy Alex de DEV STORIES DOT EU. GeoDjango y PostGIS, episodio 14 de 15. Testear aplicaciones espaciales tiene una particularidad: tu base de datos de tests automatizada necesita instalar extensiones espaciales complejas a nivel de C antes incluso de que se ejecute el primer test. Si tu pipeline automatizado falla instantáneamente con errores de permisos, probablemente sea por esto. Hoy vamos a ver el Testing de Aplicaciones Espaciales. El primer requisito es estrictamente de configuración. Al ejecutar los tests, Django crea una base de datos de tests paralela para proteger tus datos de producción. Para GeoDjango, esta base de datos de tests debe ser espacial. Esto significa que los settings de tu base de datos deben usar explícitamente un motor espacial, como el backend de PostGIS que proporciona GeoDjango. No puedes usar el backend estándar de Postgres y simplemente añadir campos espaciales después. El backend espacial es el que le indica al test runner de Django que busque e inicialice las features espaciales necesarias. Aquí está la clave. El test runner estándar de Django crea una base de datos nueva, ejecuta tus migrations y empieza a ejecutar los tests. Pero para una aplicación GeoDjango, crear una base de datos nueva no es suficiente. La base de datos también debe cargar la extensión PostGIS. Esta no es una tabla SQL estándar. Es una extensión a nivel de sistema. Por defecto, PostgreSQL restringe quién puede crear extensiones por motivos de seguridad. Normalmente, requiere un usuario de base de datos con privilegios de superuser. Es precisamente aquí donde suelen fallar los pipelines de integración continua. Levantas un container de Postgres, le pasas un usuario de base de datos estándar y le dices a Django que ejecute los tests. Django se conecta, intenta crear la base de datos de tests, intenta ejecutar el comando para crear la extensión PostGIS y se encuentra con un error de permission denied. Para solucionar esto en un pipeline automatizado, el usuario de la base de datos que ejecuta los tests debe tener los privilegios necesarios. El enfoque más sencillo en un entorno aislado y desechable es otorgar temporalmente roles de superuser al usuario de test. Si tus políticas de seguridad prohíben el acceso de superuser incluso en un container temporal, tienes que configurar PostgreSQL para que ese usuario de test específico sea un owner de confianza de la base de datos de tests y tenga permiso explícito para crear la extensión PostGIS. Una vez creada la base de datos, GeoDjango necesita saber con qué está trabajando. Las distintas versiones de PostGIS soportan diferentes funciones espaciales. Durante el funcionamiento normal, GeoDjango hace una query a la base de datos para determinar la versión de PostGIS instalada. Sin embargo, en un entorno de test, puedes saltarte esta query definiendo un setting específico llamado PostGIS Version. Lo pasas como una tupla de tres números, que representan las versiones major, minor y patch. Configurar esto explícitamente puede acelerar la inicialización de los tests y actúa como medida de seguridad si la conexión a la base de datos tiene problemas durante la comprobación inicial de la versión. Ejecutar tests espaciales no se trata de escribir diferentes assertions. Es principalmente un reto de infraestructura. La conclusión más importante es que si el usuario de tu base de datos de tests no puede crear extensiones al vuelo, tus tests ni siquiera arrancarán. Corrige los privilegios de tu usuario de test para hacer bootstrap de PostGIS, y el resto de tu pipeline se comportará exactamente como una test suite estándar de Django. Gracias por dedicarme unos minutos. Hasta la próxima, cuídate.
15

Desplegando aplicaciones GeoDjango

4m 16s

Este episodio concluye la serie analizando las consideraciones de despliegue para las aplicaciones GeoDjango. Aprenderás sobre la seguridad de hilos en GDAL y cómo configurar tus procesos WSGI para evitar bloqueos.

Descargar
Hola, soy Alex de DEV STORIES DOT EU. GeoDjango y PostGIS, episodio 15 de 15. Tu app espacial funciona perfectamente en tu portátil. Haces el deploy en un servidor de producción, el tráfico se dispara y, de repente, la aplicación crashea en silencio. Sin traceback estándar de Python, solo procesos muertos. El problema es un conflicto de threads en lo más profundo de una librería en C. Hacer el deploy de aplicaciones GeoDjango requiere evitar exactamente esta trampa. Hacer el deploy de una aplicación web espacial es casi idéntico a hacer el deploy de un proyecto estándar de Django. El routing, las conexiones a la base de datos y la arquitectura del servidor siguen exactamente las mismas reglas. Pero GeoDjango conlleva una variable oculta. Esa variable es la Geospatial Data Abstraction Library, comúnmente conocida como GDAL. GDAL es una librería en C enorme y muy optimizada que hace el trabajo pesado para los formatos de datos geográficos y las transformaciones de coordenadas. Aquí está la clave. GDAL no es thread-safe. Esto explica por qué tu código funciona en local pero crashea en el servidor. El servidor de desarrollo local de Django gestiona las requests de forma secuencial. Rara vez provoca un acceso concurrente a la librería en C. Los servidores WSGI de producción están construidos de forma diferente. Para gestionar el alto tráfico de manera eficiente, servidores como Apache con mod_wsgi suelen levantar múltiples threads dentro de un único proceso. Python normalmente depende del Global Interpreter Lock para evitar que los threads colisionen. Sin embargo, las librerías en C gestionan su propia memoria completamente fuera del control de Python. Si dos threads de WSGI intentan ejecutar una función de GDAL simultáneamente, acceden al mismo espacio de memoria sin comprobaciones de seguridad. Un thread corrompe los datos que el otro thread está utilizando. Como esto ocurre a nivel de C, Python no puede lanzar una excepción estándar. El resultado es un segmentation fault. El proceso del servidor muere al instante, llevándose por delante cualquier request activa de los usuarios. Para solucionar esto, tienes que cambiar cómo tu servidor WSGI gestiona la concurrencia. Necesitas depender de procesos en lugar de threads. Los sistemas operativos aíslan los procesos entre sí, dándole a cada proceso su propio espacio de memoria dedicado. Si estás haciendo el deploy a producción de una app geográfica con mucho tráfico usando Apache y mod_wsgi, esto lo gestionas en la configuración del daemon. En lugar de configurar un número pequeño de procesos con un gran pool de threads, restringes los threads. Abres tu archivo de configuración de Apache y localizas la directiva WSGI daemon process. Junto al nombre de la aplicación, añades un parámetro que establezca explícitamente los threads a exactamente uno. Luego escalas la aplicación aumentando el número de procesos para gestionar la carga esperada. La misma lógica se aplica si usas un servidor como Gunicorn. Tienes que vincularlo a procesos worker estándar. Evitas cualquier worker class que introduzca threading o event loops asíncronos, porque inevitablemente provocarán las mismas colisiones de GDAL. Forzar a tu servidor WSGI a un modelo multiproceso y single-threaded garantiza que GDAL nunca colisione consigo mismo. El paso más crucial para que una app GeoDjango esté lista para producción es aislar tus librerías en C de la concurrencia de threads. Con esto concluimos toda nuestra serie sobre GeoDjango y PostGIS. La mejor manera de afianzar estos conceptos es leer la documentación oficial de Django y construir algo de forma práctica. Si tienes ideas sobre qué tecnología deberíamos cubrir a continuación, visita devstories dot eu y sugiere un tema. Gracias por escuchar. Cuidaos todos.