LayerMapping en Django

Photo by Denise Jans on Unsplash

¿Qué es LayerMapping?

LayerMapping es una clase que proporciona una forma de mapear el contenido de archivos de datos espaciales vectoriales (por ejemplo, shapefiles) en modelos GeoDjango.

🔍 El contexto

En un proyecto en el que estoy trabajando estoy haciendo uso de archivos de datos espaciales vectoriales, específicamente shapefiles. El primer reto que se me presentó no fue tan complejo, ya que está en la documentación oficial de Django, básicamente quería guardar la información de un archivo .shp en un modelo en Django.

from django.contrib.gis.db import modelsclass TestGeo(models.Model):
name = models.CharField(max_length=25)
poly = models.PolygonField(srid=4269)
def __str__(self):
return 'Name: %s' % self.name
>>> from django.contrib.gis.utils import LayerMapping
>>> from geoapp.models import TestGeo
>>> mapping = {'name' : 'str',
'poly' : 'POLYGON',
}
>>> lm = LayerMapping(TestGeo, 'test_poly.shp', mapping)
>>> lm.save(verbose=True)

❓El problema

El problema se presentó cuando completé el modelo y adicioné una ForeignKey, ya que el archivo .shp no contenía ese valor, por lo tanto lo tenia que extraer de otro sector del código y pasarlo como un valor estático y adicionarlo de alguna manera antes para que la función save de la clase LayerMapping pudiera guardar toda la información de manera correcta y no saliera un error de que la información no se guardaba porque estaba enviando la llave foránea vacía.

from django.contrib.gis.db import modelsclass TestGeo(models.Model):
name = models.CharField(max_length=25)
poly = models.PolygonField(srid=4269)
city = models.ForeignKey(model_city, on_delete=models.CASCADE)
def __str__(self):
return 'Name: %s' % self.name

⚡ La solución

Después de investigar encontré la solución que finalmente me ayudó a dar la solución a mi problema y la cual decidí documentar en español por si alguien la llega a necesitar en el futuro, ya que estos temas son tan específicos que existen muy pocos ejemplos en español y en inglés.

class CustomLayerMapping(LayerMapping):

def __init__(self, *args, **kwargs):
self.custom = kwargs.pop('custom', {})
super(CustomLayerMapping, self).__init__(*args, **kwargs)
def feature_kwargs(self, feature):
kwargs = super(CustomLayerMapping, self).feature_kwargs(feature)
kwargs.update(self.custom)
return kwargs
>>> from geoapp.models import TestGeo
>>> mapping = {'name' : 'str',
'poly' : 'POLYGON',
}
>>> custom = {'city': city}
>>> lm = CustomLayerMapping(TestGeo, 'test_poly.shp', mapping, custom=custom)
>>> lm.save(verbose=True)

Referencias

--

--

🚀 Software Engineer 🖥️ Backend Developer 🐍 Python & Django http://davidcasr.co/

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
David Castro

David Castro

🚀 Software Engineer 🖥️ Backend Developer 🐍 Python & Django http://davidcasr.co/