Skip to main content

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

  • 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 operations
  • shapely: For geometry manipulation
  • numpy: For numerical operations
  • scipy: For spatial algorithms
  • folium: For creating interactive maps
  • branca: For colormap generation
  • matplotlib: 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=True, **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 True)
  • kwargs: Additional arguments to pass to GeoDataFrame constructor

Class Methods

from_file
StandardGeodataframe.from_file(file_path, crs="EPSG:4326", remove_geni=True, **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 True)
  • kwargs: Additional arguments for gdp.read_file()
from_geodataframe
StandardGeodataframe.from_geodataframe(gdf, crs="EPSG:4326", remove_geni=True)

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 True)

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=True, 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 True)
  • 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

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

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:

  1. Extend the GeoDataFrameAdapter class with a new implementation
  2. Implement the required methods to match the interface
  3. Update the _InputTransformer class 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

  1. Clone the testing branch repository
  2. 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 functionality
  • test_convert.py: Tests for KML conversion utilities
  • test_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

  1. Update Tests: Any new functionality must include corresponding tests
  2. Run Tests: Ensure all tests pass before submitting a pull request
  3. Documentation: Follow the existing code style and update documentation
  4. Code Quality: Follow PEP 8 style guidelines for Python code
  5. Compatibility: Maintain backward compatibility when possible

Adding New Features

When adding new functionality, consider the following:

  1. Is it consistent with existing APIs?
  2. Does it follow the extensibility patterns already established?
  3. Is it well-documented with docstrings and example usage?
  4. Are there comprehensive tests covering the new functionality?

Implementing Support for GeoPolars

If you're interested in implementing GeoPolars support:

  1. Create a new adapter class that implements the GeoDataFrameAdapter interface
  2. Update the _InputTransformer to detect and handle GeoPolars dataframes
  3. Add tests to ensure compatibility with existing functionality
  4. 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

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

geokitten-0.1.2.tar.gz (4.5 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

geokitten-0.1.2-py3-none-any.whl (30.7 kB view details)

Uploaded Python 3

File details

Details for the file geokitten-0.1.2.tar.gz.

File metadata

  • Download URL: geokitten-0.1.2.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

Hashes for geokitten-0.1.2.tar.gz
Algorithm Hash digest
SHA256 c05e5e6516c98b5d15eb5bc96647cab213aa07a3ed1a54e221d554202a62d685
MD5 f9b1877214ccab984dc1c96f3cde3641
BLAKE2b-256 09431fcb1113a03872b38ba88049a69a52820168462e8e75df0415744e49691c

See more details on using hashes here.

File details

Details for the file geokitten-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: geokitten-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 30.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.0

File hashes

Hashes for geokitten-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 cf16928c0df2e4e2e2c1ec10c12e29e2a63c93d7f4dcb3e6b6a1dc805be8ec70
MD5 b65cd4e1d8e7f7f75af4af80b35b0a51
BLAKE2b-256 bba568706c742396370c47a86d915cb3d0e09bc2a297048b44d1bdf95c832eab

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page