Fiona y Shapely: paquetes para lectura, escritura y análisis de datos vectoriales

Descripción general

Fiona

Fiona es una biblioteca en Python para la lectura y escritura de datos geoespaciales. Su código está enlazado con GDAL, desarrollada en C/C++.

A diferencia de otras bibliotecas basadas en GDAL (ej. osgeo.gdal/osgeo.ogr, con ejemplos en Python GDAL/OGR Cookbook), Fiona está diseñada para seguir el estilo estándar de entrada-salida (IO) de Python, mediante protocolos y tipos de datos típicos de Python, tales como archivos, diccionarios, mapeos e iteradores, en lugar de clases específicas de la implementación C/C++ de GDAL.

Fiona está hecha para ser “simple y confiable”. Está integrada con otras bibliotecas geoespaciales de Python como pyproj, Rtree y Shapely.

Shapely

Shapely es una biblioteca en Python para la manipulación y análisis de objetos geométricos planos. Está basada en la biblioteca GEOS, programada en C/C++.

Shapely no se ocupa de formatos de datos o sistemas de coordenadas, pero puede integrarse con bibliotecas que lo hacen (ej. Fiona, pyproj).

Tanto Fiona como Shapely son utilizadas por la biblioteca geopandas, para el análisis avanzado de datos geoespaciales.

Ejemplos de uso

Análisis de distribución de especies de murciélagos en Costa Rica

Se analiza la distribución de especies de murciélagos en Costa Rica con base en varias divisiones del territorio. Se utilizan las siguientes fuentes de datos:

Los pasos del procedimiento a seguir son:

  1. Obtención de datos.

  2. Creación de un archivo GeoPackage con todas las capas.

  3. Conteo de especies en cada polígono de las capas.

Bibliotecas

import os
import requests
import zipfile

import csv

import fiona
import fiona.crs
from shapely.geometry import Point, mapping, shape

from owslib.wfs import WebFeatureService
from geojson import dump

1. Obtención de datos

Registros de presencia de murciélagos

Se descargan en un archivo CSV desde una consulta al portal de GBIF.

# Descarga de archivo CSV comprimido en ZIP mediante solicitud tipo GET

response = requests.get('https://api.gbif.org/v1/occurrence/download/request/0105729-210914110416597.zip', 
                        allow_redirects=True)
open('datos/murcielagos.zip', 'wb').write(response.content)
793319
# Descompresión

with zipfile.ZipFile("datos/murcielagos.zip") as zipfile:
    zipfile.extractall("datos/")
# Cambio de nombre del archivo CSV

os.rename("datos/0105729-210914110416597.csv", "datos/murcielagos.csv")
Capas geoespaciales de Costa Rica

Se descargan como archivos GeoJON desde servicios WFS.

Áreas silvestres protegidas (ASP)

Lista de capas del servidor WFS del Sinac:

# Clase WebFeatureService de owslib.wfs

wfs = WebFeatureService(url='http://geos1pne.sirefor.go.cr/wfs', version='1.1.0')
list(wfs.contents)
['PNE:bosque_decidio',
 'PNE:bosque_maduro',
 'PNE:bosque_secundario',
 'PNE:bosque_palmas',
 'PNE:corredoresbiologicos',
 'PNE:registro_nacional_humedales',
 'PNE:areas_silvestres_protegidas',
 'PNE:areas_conservacion']

Otras propiedades del objeto WebFeatureService:

# Título
wfs.identification.title
'PNE Web Map Service'
# Operaciones
[operation.name for operation in wfs.operations]
['GetCapabilities',
 'DescribeFeatureType',
 'GetFeature',
 'GetGmlObject',
 'LockFeature',
 'GetFeatureWithLock',
 'Transaction']

Las operaciones y sus parámetros están documentados en http://opengeospatial.github.io/e-learning/wfs/text/operations.html.

Operación GetCapabilities:

# Solicitud de metadatos del servicio

# Parámetros de la solicitud
params = dict(service='WFS', version='1.1.0', request='GetCapabilities')

# Solicitud
response = requests.get("http://geos1pne.sirefor.go.cr/wfs", params=params)

# Despliegue del contenido de la respuesta
response.content
b'<?xml version="1.0" encoding="UTF-8"?>\r\n<wfs:WFS_Capabilities version="1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.opengis.net/wfs" xmlns:wfs="http://www.opengis.net/wfs" xmlns:ows="http://www.opengis.net/ows" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="http://www.opengis.net/wfs http://addaxgeos1:10080/geoserver/PNE/wfs?service=wfs/schemas/wfs/1.1.0/wfs.xsd" xmlns:Aguas="Aguas" updateSequence="6170">\r\n    <ows:ServiceIdentification>\r\n        <ows:Title>PNE Web Map Service</ows:Title>\r\n        <ows:Abstract>Servicio de mapas de Patrimonio Natural del Estado.</ows:Abstract>\r\n        <ows:Keywords>\r\n            <ows:Keyword>WFS</ows:Keyword>\r\n            <ows:Keyword>WMS</ows:Keyword>\r\n            <ows:Keyword>PNE</ows:Keyword>\r\n            <ows:Keyword>Patrimonio</ows:Keyword>\r\n            <ows:Keyword>Natural</ows:Keyword>\r\n            <ows:Keyword>Estado</ows:Keyword>\r\n        </ows:Keywords>\r\n        <ows:ServiceType>WFS</ows:ServiceType>\r\n        <ows:ServiceTypeVersion>1.1.0</ows:ServiceTypeVersion>\r\n        <ows:Fees>NONE</ows:Fees>\r\n        <ows:AccessConstraints>NONE</ows:AccessConstraints>\r\n    </ows:ServiceIdentification>\r\n    <ows:ServiceProvider>\r\n        <ows:ProviderName>The ancient geographes INC</ows:ProviderName>\r\n        <ows:ServiceContact>\r\n            <ows:IndividualName>Claudius Ptolomaeus</ows:IndividualName>\r\n            <ows:PositionName>Chief geographer</ows:PositionName>\r\n            <ows:ContactInfo>\r\n                <ows:Phone>\r\n                    <ows:Voice />\r\n                    <ows:Facsimile />\r\n                </ows:Phone>\r\n                <ows:Address>\r\n                    <ows:DeliveryPoint />\r\n                    <ows:City>Alexandria</ows:City>\r\n                    <ows:AdministrativeArea />\r\n                    <ows:PostalCode />\r\n                    <ows:Country>Egypt</ows:Country>\r\n                    <ows:ElectronicMailAddress />\r\n                </ows:Address>\r\n            </ows:ContactInfo>\r\n        </ows:ServiceContact>\r\n    </ows:ServiceProvider>\r\n    <ows:OperationsMetadata>\r\n        <ows:Operation name="GetCapabilities">\r\n            <ows:DCP>\r\n                <ows:HTTP>\r\n                    <ows:Get xlink:href="http://geos1pne.sirefor.go.cr/GeoserviciosPNE/wfs?service=wfs&amp;" />\r\n                    <ows:Post xlink:href="http://geos1pne.sirefor.go.cr/GeoserviciosPNE/wfs?service=wfs&amp;" />\r\n                </ows:HTTP>\r\n            </ows:DCP>\r\n            <ows:Parameter name="AcceptVersions">\r\n                <ows:Value>1.0.0</ows:Value>\r\n                <ows:Value>1.1.0</ows:Value>\r\n            </ows:Parameter>\r\n            <ows:Parameter name="AcceptFormats">\r\n                <ows:Value>text/xml</ows:Value>\r\n            </ows:Parameter>\r\n        </ows:Operation>\r\n        <ows:Operation name="DescribeFeatureType">\r\n            <ows:DCP>\r\n                <ows:HTTP>\r\n                    <ows:Get xlink:href="http://geos1pne.sirefor.go.cr/GeoserviciosPNE/wfs?service=wfs&amp;" />\r\n                    <ows:Post xlink:href="http://geos1pne.sirefor.go.cr/GeoserviciosPNE/wfs?service=wfs&amp;" />\r\n                </ows:HTTP>\r\n            </ows:DCP>\r\n            <ows:Parameter name="outputFormat">\r\n                <ows:Value>text/xml; subtype=gml/3.1.1</ows:Value>\r\n            </ows:Parameter>\r\n        </ows:Operation>\r\n        <ows:Operation name="GetFeature">\r\n            <ows:DCP>\r\n                <ows:HTTP>\r\n                    <ows:Get xlink:href="http://geos1pne.sirefor.go.cr/GeoserviciosPNE/wfs?service=wfs&amp;" />\r\n                    <ows:Post xlink:href="http://geos1pne.sirefor.go.cr/GeoserviciosPNE/wfs?service=wfs&amp;" />\r\n                </ows:HTTP>\r\n            </ows:DCP>\r\n            <ows:Parameter name="resultType">\r\n                <ows:Value>results</ows:Value>\r\n                <ows:Value>hits</ows:Value>\r\n            </ows:Parameter>\r\n            <ows:Parameter name="outputFormat">\r\n                <ows:Value>text/xml; subtype=gml/3.1.1</ows:Value>\r\n                <ows:Value>GML2</ows:Value>\r\n                <ows:Value>KML</ows:Value>\r\n                <ows:Value>SHAPE-ZIP</ows:Value>\r\n                <ows:Value>application/gml+xml; version=3.2</ows:Value>\r\n                <ows:Value>application/json</ows:Value>\r\n                <ows:Value>application/vnd.google-earth.kml xml</ows:Value>\r\n                <ows:Value>application/vnd.google-earth.kml+xml</ows:Value>\r\n                <ows:Value>csv</ows:Value>\r\n                <ows:Value>gml3</ows:Value>\r\n                <ows:Value>gml32</ows:Value>\r\n                <ows:Value>json</ows:Value>\r\n                <ows:Value>text/xml; subtype=gml/2.1.2</ows:Value>\r\n                <ows:Value>text/xml; subtype=gml/3.2</ows:Value>\r\n            </ows:Parameter>\r\n            <ows:Constraint name="LocalTraverseXLinkScope">\r\n                <ows:Value>2</ows:Value>\r\n            </ows:Constraint>\r\n        </ows:Operation>\r\n        <ows:Operation name="GetGmlObject">\r\n            <ows:DCP>\r\n                <ows:HTTP>\r\n                    <ows:Get xlink:href="http://geos1pne.sirefor.go.cr/GeoserviciosPNE/wfs?service=wfs&amp;" />\r\n                    <ows:Post xlink:href="http://geos1pne.sirefor.go.cr/GeoserviciosPNE/wfs?service=wfs&amp;" />\r\n                </ows:HTTP>\r\n            </ows:DCP>\r\n        </ows:Operation>\r\n        <ows:Operation name="LockFeature">\r\n            <ows:DCP>\r\n                <ows:HTTP>\r\n                    <ows:Get xlink:href="http://geos1pne.sirefor.go.cr/GeoserviciosPNE/wfs?service=wfs&amp;" />\r\n                    <ows:Post xlink:href="http://geos1pne.sirefor.go.cr/GeoserviciosPNE/wfs?service=wfs&amp;" />\r\n                </ows:HTTP>\r\n            </ows:DCP>\r\n            <ows:Parameter name="releaseAction">\r\n                <ows:Value>ALL</ows:Value>\r\n                <ows:Value>SOME</ows:Value>\r\n            </ows:Parameter>\r\n        </ows:Operation>\r\n        <ows:Operation name="GetFeatureWithLock">\r\n            <ows:DCP>\r\n                <ows:HTTP>\r\n                    <ows:Get xlink:href="http://geos1pne.sirefor.go.cr/GeoserviciosPNE/wfs?service=wfs&amp;" />\r\n                    <ows:Post xlink:href="http://geos1pne.sirefor.go.cr/GeoserviciosPNE/wfs?service=wfs&amp;" />\r\n                </ows:HTTP>\r\n            </ows:DCP>\r\n            <ows:Parameter name="resultType">\r\n                <ows:Value>results</ows:Value>\r\n                <ows:Value>hits</ows:Value>\r\n            </ows:Parameter>\r\n            <ows:Parameter name="outputFormat">\r\n                <ows:Value>text/xml; subtype=gml/3.1.1</ows:Value>\r\n                <ows:Value>GML2</ows:Value>\r\n                <ows:Value>KML</ows:Value>\r\n                <ows:Value>SHAPE-ZIP</ows:Value>\r\n                <ows:Value>application/gml+xml; version=3.2</ows:Value>\r\n                <ows:Value>application/json</ows:Value>\r\n                <ows:Value>application/vnd.google-earth.kml xml</ows:Value>\r\n                <ows:Value>application/vnd.google-earth.kml+xml</ows:Value>\r\n                <ows:Value>csv</ows:Value>\r\n                <ows:Value>gml3</ows:Value>\r\n                <ows:Value>gml32</ows:Value>\r\n                <ows:Value>json</ows:Value>\r\n                <ows:Value>text/xml; subtype=gml/2.1.2</ows:Value>\r\n                <ows:Value>text/xml; subtype=gml/3.2</ows:Value>\r\n            </ows:Parameter>\r\n        </ows:Operation>\r\n        <ows:Operation name="Transaction">\r\n            <ows:DCP>\r\n                <ows:HTTP>\r\n                    <ows:Get xlink:href="http://geos1pne.sirefor.go.cr/GeoserviciosPNE/wfs?service=wfs&amp;" />\r\n                    <ows:Post xlink:href="http://geos1pne.sirefor.go.cr/GeoserviciosPNE/wfs?service=wfs&amp;" />\r\n                </ows:HTTP>\r\n            </ows:DCP>\r\n            <ows:Parameter name="inputFormat">\r\n                <ows:Value>text/xml; subtype=gml/3.1.1</ows:Value>\r\n            </ows:Parameter>\r\n            <ows:Parameter name="idgen">\r\n                <ows:Value>GenerateNew</ows:Value>\r\n                <ows:Value>UseExisting</ows:Value>\r\n                <ows:Value>ReplaceDuplicate</ows:Value>\r\n            </ows:Parameter>\r\n            <ows:Parameter name="releaseAction">\r\n                <ows:Value>ALL</ows:Value>\r\n                <ows:Value>SOME</ows:Value>\r\n            </ows:Parameter>\r\n        </ows:Operation>\r\n    </ows:OperationsMetadata>\r\n    <FeatureTypeList>\r\n        <Operations>\r\n            <Operation>Query</Operation>\r\n            <Operation>Insert</Operation>\r\n            <Operation>Update</Operation>\r\n            <Operation>Delete</Operation>\r\n            <Operation>Lock</Operation>\r\n        </Operations><FeatureType xmlns:PNE="PNE"><Name>PNE:bosque_decidio</Name><Title>Bosque Deciduo</Title><Abstract/><ows:Keywords><ows:Keyword>features</ows:Keyword><ows:Keyword>shp_bosque_decidio</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:5367</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>-86.55148683928066 2.2077648187972607</ows:LowerCorner><ows:UpperCorner>-81.3770756753309 11.781591560078915</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:PNE="PNE"><Name>PNE:bosque_maduro</Name><Title>Bosque Maduro</Title><Abstract/><ows:Keywords><ows:Keyword>features</ows:Keyword><ows:Keyword>shp_bosque_maduro</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:5367</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>-86.55148683928066 2.2077648187972607</ows:LowerCorner><ows:UpperCorner>-81.3770756753309 11.781591560078915</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:PNE="PNE"><Name>PNE:bosque_secundario</Name><Title>Bosque Secundario</Title><Abstract/><ows:Keywords><ows:Keyword>features</ows:Keyword><ows:Keyword>shp_bosque_secundario</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:5367</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>-86.55148683928066 2.2077648187972607</ows:LowerCorner><ows:UpperCorner>-81.3770756753309 11.781591560078915</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:PNE="PNE"><Name>PNE:bosque_palmas</Name><Title>Bosque de Palmas</Title><Abstract/><ows:Keywords><ows:Keyword>features</ows:Keyword><ows:Keyword>shp_bosque_palmas</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:5367</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>-86.55148683928066 2.2077648187972607</ows:LowerCorner><ows:UpperCorner>-81.3770756753309 11.781591560078915</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:PNE="PNE"><Name>PNE:corredoresbiologicos</Name><Title>Corredores Biol\xc3\xb3gicos</Title><Abstract/><ows:Keywords><ows:Keyword>features</ows:Keyword><ows:Keyword>shp_corredoresbiologicos</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:5367</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>-86.55148683928067 2.2077648187972607</ows:LowerCorner><ows:UpperCorner>-81.3770756753309 11.781591560078915</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:PNE="PNE"><Name>PNE:registro_nacional_humedales</Name><Title>Registro Nacional de Humedales</Title><Abstract/><ows:Keywords><ows:Keyword>features</ows:Keyword><ows:Keyword>shp_registro_nacional_humedales</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:5367</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>-86.55148683927726 2.2077648187245025</ows:LowerCorner><ows:UpperCorner>-81.37707567533441 11.78159155969892</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:PNE="PNE"><Name>PNE:areas_silvestres_protegidas</Name><Title>\xc3\x81reas Silvestres Protegidas</Title><Abstract/><ows:Keywords><ows:Keyword>features</ows:Keyword><ows:Keyword>shp_areassilvestresprotegidas</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:5367</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>-86.55148683928066 2.2077648187972607</ows:LowerCorner><ows:UpperCorner>-81.3770756753309 11.781591560078915</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:PNE="PNE"><Name>PNE:areas_conservacion</Name><Title>\xc3\x81reas de Conservaci\xc3\xb3n</Title><Abstract/><ows:Keywords><ows:Keyword>shp_areasdeconservacion</ows:Keyword><ows:Keyword>features</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:5367</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>-86.55148683928066 2.2077648187972607</ows:LowerCorner><ows:UpperCorner>-81.3770756753309 11.781591560078915</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType>    </FeatureTypeList>\r\n    <ogc:Filter_Capabilities>\r\n        <ogc:Spatial_Capabilities>\r\n            <ogc:GeometryOperands>\r\n                <ogc:GeometryOperand>gml:Envelope</ogc:GeometryOperand>\r\n                <ogc:GeometryOperand>gml:Point</ogc:GeometryOperand>\r\n                <ogc:GeometryOperand>gml:LineString</ogc:GeometryOperand>\r\n                <ogc:GeometryOperand>gml:Polygon</ogc:GeometryOperand>\r\n            </ogc:GeometryOperands>\r\n            <ogc:SpatialOperators>\r\n                <ogc:SpatialOperator name="Disjoint" />\r\n                <ogc:SpatialOperator name="Equals" />\r\n                <ogc:SpatialOperator name="DWithin" />\r\n                <ogc:SpatialOperator name="Beyond" />\r\n                <ogc:SpatialOperator name="Intersects" />\r\n                <ogc:SpatialOperator name="Touches" />\r\n                <ogc:SpatialOperator name="Crosses" />\r\n                <ogc:SpatialOperator name="Within" />\r\n                <ogc:SpatialOperator name="Contains" />\r\n                <ogc:SpatialOperator name="Overlaps" />\r\n                <ogc:SpatialOperator name="BBOX" />\r\n            </ogc:SpatialOperators>\r\n        </ogc:Spatial_Capabilities>\r\n        <ogc:Scalar_Capabilities>\r\n            <ogc:LogicalOperators />\r\n            <ogc:ComparisonOperators>\r\n                <ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>\r\n                <ogc:ComparisonOperator>GreaterThan</ogc:ComparisonOperator>\r\n                <ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>\r\n                <ogc:ComparisonOperator>GreaterThanEqualTo</ogc:ComparisonOperator>\r\n                <ogc:ComparisonOperator>EqualTo</ogc:ComparisonOperator>\r\n                <ogc:ComparisonOperator>NotEqualTo</ogc:ComparisonOperator>\r\n                <ogc:ComparisonOperator>Like</ogc:ComparisonOperator>\r\n                <ogc:ComparisonOperator>Between</ogc:ComparisonOperator>\r\n                <ogc:ComparisonOperator>NullCheck</ogc:ComparisonOperator>\r\n            </ogc:ComparisonOperators>\r\n            <ogc:ArithmeticOperators>\r\n                <ogc:SimpleArithmetic />\r\n                <ogc:Functions>\r\n                    <ogc:FunctionNames>\r\n                        <ogc:FunctionName nArgs="1">abs</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">abs_2</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">abs_3</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">abs_4</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">acos</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">AddCoverages</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-1">Affine</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-2">Aggregate</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">area</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">area2</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="3">AreaGrid</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">asin</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">atan</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">atan2</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-1">BandMerge</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-2">BandSelect</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-6">BarnesSurface</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="3">between</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">boundary</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">boundaryDimension</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">Bounds</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-2">buffer</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-2">BufferFeatureCollection</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="3">bufferWithSegments</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="7">Categorize</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">ceil</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">centroid</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">classify</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-2">Clip</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">CollectGeometries</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">Collection_Average</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">Collection_Bounds</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="0">Collection_Count</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">Collection_Max</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">Collection_Median</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">Collection_Min</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">Collection_Nearest</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">Collection_Sum</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">Collection_Unique</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-2">Concatenate</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">contains</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-1">Contour</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">convert</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">convexHull</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">cos</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">Count</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">CropCoverage</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">crosses</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">dateFormat</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">dateParse</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">densify</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">difference</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">dimension</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">disjoint</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">disjoint3D</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">distance</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">distance3D</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">double2bool</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">endAngle</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">endPoint</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">env</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">envelope</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">EqualInterval</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">equalsExact</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="3">equalsExactTolerance</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">equalTo</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">exp</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">exteriorRing</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="3">Feature</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">floor</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">geometryType</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">geomFromWKT</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">geomLength</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-3">GeorectifyCoverage</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-1">GetFullCoverage</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">getGeometryN</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">getX</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">getY</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">getz</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">greaterEqualThan</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">greaterThan</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-3">Grid</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-5">Heatmap</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="0">id</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">IEEEremainder</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="3">if_then_else</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="0">Import</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="11">in10</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="3">in2</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="4">in3</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="5">in4</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="6">in5</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="7">in6</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="8">in7</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="9">in8</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="10">in9</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">InclusionFeatureCollection</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">int2bbool</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">int2ddouble</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">interiorPoint</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">interiorRingN</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-5">Interpolate</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">intersection</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-2">IntersectionFeatureCollection</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">intersects</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">intersects3D</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">isClosed</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="0">isCoverage</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">isEmpty</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">isInstanceOf</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">isLike</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">isNull</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">isometric</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">isRing</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">isSimple</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">isValid</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="3">isWithinDistance</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="3">isWithinDistance3D</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">Jenks</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">length</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">lessEqualThan</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">lessThan</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-1">list</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">log</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="4">LRSGeocode</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-4">LRSMeasure</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="5">LRSSegment</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">max</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">max_2</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">max_3</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">max_4</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">min</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">min_2</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">min_3</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">min_4</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">mincircle</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">minimumdiameter</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">minrectangle</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">modulo</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">MultiplyCoverages</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-2">Nearest</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">not</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">notEqualTo</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">numberFormat</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="5">numberFormat2</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">numGeometries</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">numInteriorRing</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">numPoints</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">octagonalenvelope</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="3">offset</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">overlaps</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-2">PagedUnique</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-1">parameter</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">parseBoolean</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">parseDouble</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">parseInt</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">parseLong</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="0">pi</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-1">PointBuffers</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">pointN</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-6">PointStacker</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-1">PolygonExtraction</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">polygonize</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">pow</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">property</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">PropertyExists</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">Quantile</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-1">Query</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="0">random</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-1">RangeLookup</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-1">RasterAsPointCollection</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-2">RasterZonalStatistics</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="5">Recode</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-2">RectangularClip</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">relate</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="3">relatePattern</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-1">reproject</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-1">ReprojectGeometry</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-3">rescaleToPixels</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">rint</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">round</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">round_2</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">roundDouble</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-5">ScaleCoverage</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">setCRS</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">simplify</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">sin</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-2">Snap</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">splitPolygon</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">sqrt</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">StandardDeviation</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">startAngle</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">startPoint</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">StoreCoverage</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">strCapitalize</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">strConcat</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">strEndsWith</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">strEqualsIgnoreCase</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">strIndexOf</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="4">stringTemplate</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">strLastIndexOf</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">strLength</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">strMatches</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="3">strPosition</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="4">strReplace</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">strStartsWith</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="3">strSubstring</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">strSubstringStart</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">strToLowerCase</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">strToUpperCase</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">strTrim</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="3">strTrim2</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">StyleCoverage</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">symDifference</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">tan</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">toDegrees</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">toRadians</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">touches</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">toWKT</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">Transform</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-2">union</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">UnionFeatureCollection</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">Unique</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">UniqueInterval</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="-4">VectorToRaster</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="3">VectorZonalStatistics</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="1">vertices</ogc:FunctionName>\r\n                        <ogc:FunctionName nArgs="2">within</ogc:FunctionName>\r\n                    </ogc:FunctionNames>\r\n                </ogc:Functions>\r\n            </ogc:ArithmeticOperators>\r\n        </ogc:Scalar_Capabilities>\r\n        <ogc:Id_Capabilities>\r\n            <ogc:FID />\r\n            <ogc:EID />\r\n        </ogc:Id_Capabilities>\r\n    </ogc:Filter_Capabilities>\r\n</wfs:WFS_Capabilities>'

Puede ver el XML de manera estructurada en https://jsonformatter.org/xml-parser

Operación GetFeature:

# Solicitud de capa WFS de ASP mediante GET, para retornarse como JSON

# Parámetros de la solicitud
params = dict(service='WFS',
              version='1.1.0', 
              request='GetFeature', 
              typeName='PNE:areas_silvestres_protegidas',
              srsName='urn:ogc:def:crs:EPSG::4326',
              outputFormat='json')

# Solicitud
response = requests.get("http://geos1pne.sirefor.go.cr/wfs", params=params)
# Descarga de la respuesta en un archivo GeoJSON

with open('datos/asp.geojson', 'w') as file:
   dump(response.json(), file)

2. Creación de un archivo GeoPackage con todas las capas

El archivo Geopackage se crea con el objetivo de mantener todas las capas en una misma estructura y así facilitar la manipulación de los datos.

Registros de presencia de murciélagos
# Esquema de la nueva capa de registros de presencia de murciélagos
# Se incluyen solo los campos más importantes para el análisis
schema = {'geometry':'Point',
          'properties':{'gbifID':'str',
                        'species':'str',
                        'decimalLatitude':'float',
                        'decimalLongitude':'float'
                       }}

# Inserción de registros en el archivo GeoPackage
with fiona.collection('datos/distribucion-murcielagos.gpkg', 
                mode='w',
                schema=schema,
                driver='GPKG',
                crs=fiona.crs.from_epsg(4326),
                layer='registros-murcielagos') as collection:
    with open('datos/murcielagos.csv') as file:
        reader = csv.DictReader(file, delimiter='\t')
        for row in reader:
            point = Point(float(row['decimalLongitude']), float(row['decimalLatitude']))
            collection.write({
                'properties': {
                    'gbifID':row['gbifID'],
                    'species':row['species'],
                    'decimalLatitude':row['decimalLatitude'],
                    'decimalLongitude':row['decimalLongitude']
                },
                'geometry':mapping(point)
            })                        
---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
/tmp/ipykernel_281239/1231377834.py in <module>
     19         for row in reader:
     20             point = Point(float(row['decimalLongitude']), float(row['decimalLatitude']))
---> 21             collection.write({
     22                 'properties': {
     23                     'gbifID':row['gbifID'],

~/miniconda3/envs/pf3311/lib/python3.10/site-packages/fiona/collection.py in write(self, record)
    365     def write(self, record):
    366         """Stages a record for writing to disk."""
--> 367         self.writerecords([record])
    368 
    369     def validate_record(self, record):

~/miniconda3/envs/pf3311/lib/python3.10/site-packages/fiona/collection.py in writerecords(self, records)
    359         if self.mode not in ('a', 'w'):
    360             raise IOError("collection not open for writing")
--> 361         self.session.writerecs(records, self)
    362         self._len = self.session.get_length()
    363         self._bounds = None

KeyboardInterrupt: 
Áreas Silvestres Protegidas (ASP)
# Se agrega el archivo GeoJSON de ASP al GPKG

with fiona.open('datos/asp.geojson') as source:
    with fiona.open('datos/distribucion-murcielagos.gpkg', 'w', 'GPKG', source.schema, source.crs, layer='asp') as sink:
        for record in source:
            sink.write(record)

3. Conteo de especies en cada polígono de las capas

En ÁSP
# Conteo de especies en ASP

# Esquema de la capa con el total y la lista de especies por ASP
schema = {'geometry':'Unknown',
          'properties':{'id':'str',
                        'nombre_asp':'str',
                        'cantidad_especies':'int',
                        'lista_especies':'str'
                       }}

with fiona.collection('datos/distribucion-murcielagos.gpkg', 'r', layer='asp') as asp:
    
    i = 1 # contador de ASP, para imprimir el progreso del procedimiento
    
    with fiona.open('datos/asp-especies.geojson','w','GeoJSON', schema, asp.crs) as sink:
    
        for record_asp in asp:
            print(i, record_asp['properties']['siglas_cat'], record_asp['properties']['nombre_asp'])

            species_set = set() # conjunto de especies en el ASP

            with fiona.collection('datos/distribucion-murcielagos.gpkg', 'r', layer='registros-murcielagos') as registros:
                for registro in registros:
                    if (registro['properties']['species'] == ''):
                        continue
                    
                    if shape(record_asp['geometry']).contains(shape(registro['geometry'])):
                        species_set.add(registro['properties']['species'])

            print(len(species_set))
            print(', '.join(species_set))
            print('\n')

            i += 1
                
            sink.write({
                'properties': {
                    'id':record_asp['properties']['id'],
                    'nombre_asp':record_asp['properties']['nombre_asp'],
                    'cantidad_especies':len(species_set),
                    'lista_especies':', '.join(species_set)
                },
                'geometry':record_asp['geometry']
            }) 
# Se agrega el archivo GeoJSON de asp-especies al GPKG

with fiona.open('datos/asp-especies.geojson') as source:
    with fiona.open('datos/distribucion-murcielagos.gpkg', 'w', 'GPKG', source.schema, source.crs, layer='asp-especies') as sink:
        for record in source:
            sink.write(record)