Tools for geospatial data processing and visualization
Project description
GeoKitten
A Python package for standardizing, converting, and visualizing geospatial data with an emphasis on simplicity and extensibility.
Table of Contents
- Features
- Installation
- Dependencies
- Quick Start
- Module Overview
- Usage Examples
- Extensibility
- Contributing
- Documentation
- License
- Author
Features
- Standardize GeoDataFrames with consistent CRS, valid geometries, and handling of Z-coordinates and polygon holes
- Convert between KML files and GeoDataFrames with proper formatting and metadata
- Visualize spatial data with interactive HTML maps supporting both categorical and continuous data
Installation
pip install geokitten
Dependencies
geopandas: For spatial data operationsshapely: For geometry manipulationnumpy: For numerical operationsscipy: For spatial algorithmsfolium: For creating interactive mapsbranca: For colormap generationmatplotlib: For color schemes- Additional dependencies:
os,typing,pandas,fiona,xml.etree.ElementTree,xml.dom.minidom
Quick Start
import geopandas as gpd
from geokitten import (
StandardGeodataframe,
KMLsToGeodataframe,
GeodataframeToKMLs,
InteractiveCategoricalHtmlMap
)
# Standardize a GeoDataFrame
gdf = gpd.read_file("path/to/shapefile.shp")
standard_gdf = StandardGeodataframe.from_geodataframe(gdf)
# Add surface area in square kilometers
standard_gdf = standard_gdf.get_km2_surface_area()
# Convert KML files to a consolidated GeoDataFrame
kml_converter = KMLsToGeodataframe("path/to/kml_directory")
kml_gdf = kml_converter.consolidate(id_column_name="RegionID")
# Create an interactive map
map_creator = InteractiveCategoricalHtmlMap(
gdf=standard_gdf,
color_column="region",
tooltip_columns=["region", "SURF_A_KM2"]
)
map_creator.create(
color_scheme="Set1",
fill_opacity=0.7,
title="Regional Map",
output_file="regional_map.html"
)
Module Overview
1. StandardGeodataframe Class
The StandardGeodataframe class extends the GeoPandas GeoDataFrame to provide standardization and additional functionality for working with geospatial data.
Constructor
StandardGeodataframe(gdf_input, crs="EPSG:4326", remove_geni=False, **kwargs)
- gdf_input: Input GeoDataFrame or file path to be standardized
- crs: Coordinate reference system to standardize to (defaults to "EPSG:4326")
- remove_geni: Whether to remove "geni" (holes) from polygons (defaults to False)
- kwargs: Additional arguments to pass to GeoDataFrame constructor
Class Methods
from_file
StandardGeodataframe.from_file(file_path, crs="EPSG:4326", remove_geni=False, **kwargs)
Creates a StandardGeodataframe from a file path.
- file_path: Path to the geospatial file (shp, geojson, etc.)
- crs: Target CRS (defaults to "EPSG:4326")
- remove_geni: Whether to remove polygon holes (defaults to False)
- kwargs: Additional arguments for gdp.read_file()
from_geodataframe
StandardGeodataframe.from_geodataframe(gdf, crs="EPSG:4326", remove_geni=False)
Creates a StandardGeodataframe from an existing GeoDataFrame.
- gdf: Input GeoDataFrame
- crs: Target CRS (defaults to "EPSG:4326")
- remove_geni: Whether to remove polygon holes (defaults to False)
Methods
get_interior_points
get_interior_points(geometry_column='geometry', inplace=False, column_name='interior_point')
Calculates a point that is guaranteed to be inside each geometry.
- geometry_column: Name of the geometry column (defaults to 'geometry')
- inplace: Whether to add the interior points to the GeoDataFrame (defaults to False)
- column_name: Name of the column to store interior points if inplace=True (defaults to 'interior_point')
- Returns: GeoDataFrame with interior points or a GeoSeries of interior points if inplace=False
substract_overlapping_geometries
substract_overlapping_geometries(column_name, args, remove_geni=False, inplace=False)
Subtracts overlapping geometries based on specified criteria.
- column_name: Name of the column containing identifiers for geometries
- args: Either a tuple ([target_ids], [subtractor_ids]) or a dictionary {target_id: [subtractor_ids]}
- remove_geni: Whether to remove holes created by subtraction (defaults to False)
- inplace: Whether to modify the GeoDataFrame in place (defaults to False)
- Returns: Modified GeoDataFrame if inplace=False
get_m2_surface_area
get_m2_surface_area(inplace=False, column_name='SURF_A_M2')
Calculates the surface area of each geometry in square meters.
- inplace: Whether to add the area to the GeoDataFrame (defaults to False)
- column_name: Name of the column to store areas if inplace=True (defaults to 'SURF_A_M2')
- Returns: GeoDataFrame with area column or a Series of areas if inplace=False
get_km2_surface_area
get_km2_surface_area(inplace=False, column_name='SURF_A_KM2')
Calculates the surface area of each geometry in square kilometers.
- inplace: Whether to add the area to the GeoDataFrame (defaults to False)
- column_name: Name of the column to store areas if inplace=True (defaults to 'SURF_A_KM2')
- Returns: GeoDataFrame with area column or a Series of areas if inplace=False
2. KML Converter Classes
KMLsToGeodataframe
Converts KML files in a directory into a consolidated GeoDataFrame.
Constructor
KMLsToGeodataframe(kml_input_dir)
- kml_input_dir: Directory containing KML files to process
Methods
consolidate
consolidate(id_column_name='Name', verbose=True)
Consolidates all KML files in the directory into a single GeoDataFrame.
- id_column_name: Column name for the KML file identifiers (defaults to 'Name')
- verbose: Whether to print progress information (defaults to True)
- Returns: Consolidated GeoDataFrame containing data from all KML files
GeodataframeToKMLs
Converts a GeoDataFrame into individual KML files.
Constructor
GeodataframeToKMLs(gdf_input, id_column_name="Name")
- gdf_input: Input GeoDataFrame or file path
- id_column_name: Column name containing identifiers for KML files
Methods
kml_metadata_format
kml_metadata_format(output_dir, verbose=True)
Saves each row of the GeoDataFrame as an individual KML file with proper formatting.
- output_dir: Directory to save the KML files
- verbose: Whether to print progress information (defaults to True)
KMLsToKMLsProperFormat
Transforms KML files into a standardized format.
Constructor
KMLsToKMLsProperFormat(kml_input_dir, output_dir, id_column_name="Name")
- kml_input_dir: Directory containing KML files to process
- output_dir: Directory to save the transformed KML files
- id_column_name: Column name for the KML file identifiers (defaults to 'Name')
Methods
transform_format
transform_format(verbose=True)
Transforms KML files into a standardized format and saves them in the output directory.
- verbose: Whether to print progress information (defaults to True)
3. HTML Map Generator Classes
InteractiveCategoricalHtmlMap
Creates categorical interactive choropleth maps.
Constructor
InteractiveCategoricalHtmlMap(gdf, color_column, tooltip_columns=None)
- gdf: GeoDataFrame containing spatial data
- color_column: Column name in the GeoDataFrame for categorical coloring
- tooltip_columns: List of column names to include in tooltips (defaults to None)
Methods
create
create(color_scheme='tab20', set_custom_colors=None, fill_opacity=0.5, line_opacity=1.0, line_weight=1, location=None, zoom_start=None, title=None, legend_name=None, output_file='categorical_map.html')
Generates a categorical choropleth map and saves it as an HTML file.
- color_scheme: Color scheme name (e.g., 'tab20', 'Set1') (defaults to 'tab20')
- set_custom_colors: List of custom hex color codes (defaults to None)
- fill_opacity: Opacity of polygon fill (0-1) (defaults to 0.5)
- line_opacity: Opacity of polygon borders (0-1) (defaults to 1.0)
- line_weight: Width of polygon borders (defaults to 1)
- location: Center coordinates [lat, lon] for map (defaults to None, auto-calculated)
- zoom_start: Initial zoom level (defaults to None, auto-calculated)
- title: Title for the map (defaults to None)
- legend_name: Name for the legend (defaults to None)
- output_file: Filename to save the HTML map (defaults to 'categorical_map.html')
- Returns: The created folium.Map object
Example Output:
InteractiveContinuousHtmlMap
Creates continuous interactive choropleth maps.
Constructor
InteractiveContinuousHtmlMap(gdf, color_column, tooltip_columns=None)
- gdf: GeoDataFrame containing spatial data
- color_column: Column name in the GeoDataFrame for continuous coloring
- tooltip_columns: List of column names to include in tooltips (defaults to None)
Methods
create
create(color_scheme='viridis', fill_opacity=0.5, line_opacity=1.0, line_weight=1, location=None, zoom_start=None, title=None, legend_name=None, output_file='continuous_map.html')
Generates a continuous choropleth map and saves it as an HTML file.
- color_scheme: Matplotlib colormap name (e.g., 'viridis', 'coolwarm') (defaults to 'viridis')
- fill_opacity: Opacity of polygon fill (0-1) (defaults to 0.5)
- line_opacity: Opacity of polygon borders (0-1) (defaults to 1.0)
- line_weight: Width of polygon borders (defaults to 1)
- location: Center coordinates [lat, lon] for map (defaults to None, auto-calculated)
- zoom_start: Initial zoom level (defaults to None, auto-calculated)
- title: Title for the map (defaults to None)
- legend_name: Name for the legend (defaults to None)
- output_file: Filename to save the HTML map (defaults to 'continuous_map.html')
- Returns: The created folium.Map object
Example Output:
Usage Examples
StandardGeodataframe
from geokitten import StandardGeodataframe
import geopandas as gpd
# Create from file with default settings
gdf = StandardGeodataframe.from_file("path/to/shapefile.shp")
# Create with custom CRS and keeping polygon holes
gdf = StandardGeodataframe.from_file(
"path/to/shapefile.shp",
crs="EPSG:3857",
remove_geni=False
)
# Create from existing GeoDataFrame
gpd_gdf = gpd.read_file("path/to/shapefile.shp")
gdf = StandardGeodataframe.from_geodataframe(gpd_gdf)
# Add interior points as a column
gdf.get_interior_points(inplace=True, column_name="centroid")
# Calculate surface area in square kilometers
gdf_with_area = gdf.get_km2_surface_area(inplace=True)
# Subtract overlapping geometries using tuple arguments
gdf.substract_overlapping_geometries(
column_name="region_id",
args=(["target_region"], ["overlapping_region1", "overlapping_region2"]),
inplace=True
)
# Subtract overlapping geometries using dictionary arguments
subtraction_dict = {
"target_region1": ["overlapping_region1", "overlapping_region2"],
"target_region2": ["overlapping_region3"]
}
result = gdf.substract_overlapping_geometries(
column_name="region_id",
args=subtraction_dict,
remove_geni=True,
inplace=False
)
KML Converters
from geokitten import KMLsToGeodataframe, GeodataframeToKMLs, KMLsToKMLsProperFormat
# Convert KML files to a GeoDataFrame
kml_converter = KMLsToGeodataframe("path/to/kml_directory")
kml_gdf = kml_converter.consolidate(id_column_name="RegionID", verbose=True)
# Convert a GeoDataFrame to KML files
converter = GeodataframeToKMLs(kml_gdf, id_column_name="RegionID")
converter.kml_metadata_format("path/to/output_directory", verbose=True)
# Transform KML files to standardized format
transformer = KMLsToKMLsProperFormat(
kml_input_dir="path/to/raw_kml_files",
output_dir="path/to/formatted_kml_files",
id_column_name="RegionID"
)
transformer.transform_format(verbose=True)
HTML Map Generators
from geokitten import InteractiveCategoricalHtmlMap, InteractiveContinuousHtmlMap
# Create a categorical map
cat_map_creator = InteractiveCategoricalHtmlMap(
gdf=gdf,
color_column="region",
tooltip_columns=["region", "population", "SURF_A_KM2"]
)
cat_map = cat_map_creator.create(
color_scheme="Set1",
fill_opacity=0.7,
line_opacity=0.9,
line_weight=2,
title="Regional Map",
legend_name="Regions",
output_file="regional_map.html"
)
# Create a continuous map
cont_map_creator = InteractiveContinuousHtmlMap(
gdf=gdf,
color_column="population_density",
tooltip_columns=["region", "population_density", "SURF_A_KM2"]
)
cont_map = cont_map_creator.create(
color_scheme="coolwarm",
fill_opacity=0.7,
title="Population Density Map",
legend_name="Population Density",
output_file="density_map.html"
)
Extensibility
GeoKitten is designed with extensibility in mind. While it currently supports GeoPandas for handling geospatial data, the architecture (particularly the standardize module) is built to accommodate future extensions like GeoPolar support.
GeoDataFrameAdapter
The GeoDataFrameAdapter class provides a unified interface that can be extended to support other geospatial data frame implementations beyond GeoPandas. This adapter pattern allows the package to evolve to support new spatial dataframe libraries without breaking existing functionality.
from geokitten import StandardGeodataframe
# The current implementation uses GeoPandas under the hood
standard_gdf = StandardGeodataframe.from_file("path/to/shapefile.shp")
# In the future, GeoPolar or other implementations could be supported
# through the same interface without changing user code
Adding New Implementations
To add support for GeoPolar or other spatial dataframe libraries:
- Extend the
GeoDataFrameAdapterclass with a new implementation - Implement the required methods to match the interface
- Update the
_InputTransformerclass to detect and handle the new implementation
This architecture ensures that as the geospatial Python ecosystem evolves, GeoKitten can adapt without requiring significant changes to user code or the core API.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Development Setup
- Clone the testing branch repository
- Install development dependencies:
"geopandas>=0.9.0", "numpy>=1.23.4", "geopandas>=0.14.2", "pandas>=2.2.2", "shapely>=2.0.2", "pytest>=8.3.5", "fiona>=1.8.22", "folium>=0.14.0", "branca>=0.6.0", "matplotlib>=3.7.1", "pytest>=8.3"
Testing
GeoKitten includes a comprehensive test suite located in the tests/ directory. The tests include:
test_standardize.py: Tests for the StandardGeodataframe class and related functionalitytest_convert.py: Tests for KML conversion utilitiestest_visualize.py: Tests for HTML map generation
The tests/tests_files/ directory contains sample data files used for testing.
Before submitting a pull request, please ensure that all tests pass:
pytest tests/*.py
If you're adding new functionality, please add appropriate tests in the tests/ directory.
Guidelines for Contributors
- Update Tests: Any new functionality must include corresponding tests
- Run Tests: Ensure all tests pass before submitting a pull request
- Documentation: Follow the existing code style and update documentation
- Code Quality: Follow PEP 8 style guidelines for Python code
- Compatibility: Maintain backward compatibility when possible
Adding New Features
When adding new functionality, consider the following:
- Is it consistent with existing APIs?
- Does it follow the extensibility patterns already established?
- Is it well-documented with docstrings and example usage?
- Are there comprehensive tests covering the new functionality?
Implementing Support for GeoPolars
If you're interested in implementing GeoPolars support:
- Create a new adapter class that implements the
GeoDataFrameAdapterinterface - Update the
_InputTransformerto detect and handle GeoPolars dataframes - Add tests to ensure compatibility with existing functionality
- Update documentation to include GeoPolars examples
Documentation
For full documentation, visit github(GeoKitten).
License
This project is licensed under the MIT License - see the LICENSE file for details.
Author
- Sergio A. Pelayo Escalera - sergioapelayoe@gmail.com
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file geokitten-0.1.3.tar.gz.
File metadata
- Download URL: geokitten-0.1.3.tar.gz
- Upload date:
- Size: 4.5 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f8d4b7a10a0da4f0614cf273e1c1049a02ee8f7fe2915f1a48f4b33d5a38fa38
|
|
| MD5 |
516c8467607c91fdaf1de02b7a103bad
|
|
| BLAKE2b-256 |
eee1f9de31c12db305778c1a771c9ad6a53cc68aafafe53cca276975fef7a606
|
File details
Details for the file geokitten-0.1.3-py3-none-any.whl.
File metadata
- Download URL: geokitten-0.1.3-py3-none-any.whl
- Upload date:
- Size: 30.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b8af4a6f34d3e3ff08afbd929c19b6fc5e15873021a9ecfa78f031ca610f6afa
|
|
| MD5 |
20177dff3d175bc373e7d1a61d3d4afa
|
|
| BLAKE2b-256 |
7430e0c5ef573014cb9ff317b11d445661c85a8da1a82edf05d1aaf5274b1c63
|