Export Options

In order to provide the user the opportunity to make use of their shapes outside of the Madrona environment, Madrona provides an Export option which allows the user to export individual shapes and arrays of shapes in a variety of formats.

Exporting as kmz and exporting as image are both built in to Lingcod and will appear by default in the Export drop-down menu.

Exporting as shapefile requires the enabling of a urlpattern as explained below.

Atom links for each of these Export options can be found in madrona/kmlapp/templates/placemarks.kml.

as kmz (Google Earth)

as image (PNG)

as shapefile

The Export as shapefile option can be enabled by adding a view, a model, and a couple tweaks to the exportable model.

The following example will walk you through the steps of enabling the export as shapefile option using a sample model MyBioregion.

The following view (bio_shapefile in this example) will utilize the built-in ShpResponder class to generate a shapefile from our exportable model (MyBioregion).

Note

This view is actually equipped to handle multiple instances of MyBioregion that may have been selected by the user for exporting.

from madrona.common import utils
from madrona.sharing.utils import get_viewable_object_or_respond
from madrona.shapes.views import ShpResponder
from django.template.defaultfilters import slugify

def bio_shapefile(request, instances):
    from mybioregions.models import MyBioregion, BioregionShapefile
    bios = []
    for inst in instances:
        viewable, response = inst.is_viewable(request.user)
        if not viewable:
            return response

        if isinstance(inst, MyBioregion):
            inst.convert_to_shp()
            bios.append(inst)
        else:
            pass # ignore anything else

    filename = '_'.join([slugify(inst.name) for inst in instances])
    pks = [bio.pk for bio in bios]
    qs = BioregionShapefile.objects.filter(bio_id_num__in=pks)
    if len(qs) == 0:
        return HttpResponse(
            "Nothing in the query set; you don't want an empty shapefile",
            status=404
        )
    shp_response = ShpResponder(qs)
    shp_response.file_name = slugify(filename[0:8])
    return shp_response()

In order for this view to function, the exportable model (MyBioregion) will need a convert_to_shp function.

def convert_to_shp(self):
    '''
    Port the Bioregion attributes over to the BioregionShapefile model so we can export the shapefile.
    '''
    bsf, created = BioregionShapefile.objects.get_or_create(bioregion=self)
    if created or bsf.date_modified < self.date_modified:
        bsf.name = self.name
        bsf.bio_id_num = self.pk
        bsf.geometry = self.output_geom
        #short_name = self.name
        if self.collection:
            bsf.group = self.collection
            bsf.group_name = self.collection.name
        #units based on the settings variable DISPLAY_AREA_UNITS (currently sq miles)
        bsf.area_sq_mi = area_in_display_units(self.output_geom)
        bsf.author = self.user.username
        bsf.aoi_modification_date = self.date_modified
        bsf.save()
    return bsf

And the following link entry should be added to the model’s (MyBioregion) Options class.

links = (
    alternate('Shapefile',
        'mybioregions.views.bio_shapefile',
        select='multiple single',
        type='application/zip',
    ),
)

This convert_to_shp function requires an additional model (BioregionShapefile in our example). This additional model will provide the fields you wish to have present in the attribute table of the exported shapefile.

class BioregionShapefile(models.Model):
    """
    This model will provide the correct fields for the export of shapefiles using the django-shapes app.
    """
    geometry = models.PolygonField(srid=settings.GEOMETRY_DB_SRID,blank=True,null=True)
    name = models.CharField(max_length=255)
    bio_id_num = models.IntegerField(blank=True, null=True)
    group = models.ForeignKey(Folder, null=True, blank=True)
    group_name = models.CharField(blank=True, max_length=255, null=True)
    area_sq_mi = models.FloatField(blank=True,null=True)
    author = models.CharField(blank=True, max_length=255,null=True)
    bioregion = models.OneToOneField(MyBioregion, related_name="bioregion")
    bio_modification_date = models.DateTimeField(blank=True, null=True)
    date_modified = models.DateTimeField(blank=True, null=True, auto_now_add=True)
    objects = models.GeoManager()

Implementing all of the above should provide a working Export as shapefile feature for your individual model.

Once you have this in place for an individual model, implementing the Export as shapefile feature for an array, or group of models is simple:

Augment your view to reflect the minor changes seen below (including the possibility of a Folder instance):

def bio_shapefile(request, instances):
    from mybioregions.models import MyBioregion, Folder, BioregionShapefile
    bios = []
    for inst in instances:
        viewable, response = inst.is_viewable(request.user)
        if not viewable:
            return response

        if isinstance(inst, MyBioregion):
            inst.convert_to_shp()
            bios.append(inst)
        elif isinstance(inst, Folder):
            for bio in inst.feature_set(recurse=True,feature_classes=[MyBioregion]):
                bio.convert_to_shp()
                bios.append(bio)
        else:
            pass # ignore anything else

    filename = '_'.join([slugify(inst.name) for inst in instances])
    pks = [bio.pk for bio in bios]
    qs = BioregionShapefile.objects.filter(bio_id_num__in=pks)
    if len(qs) == 0:
        return HttpResponse(
            "Nothing in the query set; you don't want an empty shapefile",
            status=404
        )
    shp_response = ShpResponder(qs)
    shp_response.file_name = slugify(filename[0:8])
    return shp_response()

This change will simply loop through the individual shapes in any Folder instance, generating a shapefile record from each of the shapes contained within that array.

And finally, add the following link entry to the Options class in your array model (Folder in this example):

links = (
    alternate('Shapefile',
        'mybioregions.views.bio_shapefile',
        select='multiple single',
        type='application/zip',
    ),
)

And you should now have the ability to export shapes and folders of shapes as shapefiles.

Table Of Contents

Previous topic

Workspace Documents

Next topic

Madrona/Django Management Commands

This Page