A Python library for mapping locations with interactive filtering and visualization capabilities
Project description
Map Locations
A Python library and CLI tool for mapping locations with interactive filtering and visualization capabilities.
Author: Lavi Shpigelman
Features
- 📍 Interactive Maps: Create beautiful, interactive maps using Folium
- 🗺️ Multiple Tile Providers: Support for OpenStreetMap, Google Maps, and Google Satellite
- 🏷️ Tag-based Filtering: Filter locations by tags and types
- 🎨 Color-coded Types: Different location types are displayed with distinct colors
- 📝 Toggle Labels: Show/hide location names on the map
- 📊 Multiple Export Formats: Export to KML, GeoJSON, and HTML
- 📁 YAML Configuration: Simple YAML format for location data
- 🖥️ CLI Interface: Command-line tool for easy map generation
Installation
From PyPI (when published)
pip install map-locations
From Source
# Clone the repository
git clone https://github.com/shpigi/map-locations.git
cd map-locations
# Install in development mode
pip install -e .
# Or install with development dependencies
pip install -e ".[dev]"
Development Setup
# Install with all development tools
make install-dev
# Set up pre-commit hooks
make setup-dev
Quick Start
1. Create a locations file
Create a YAML file with your locations:
locations:
- name: "Galerie Vivienne"
type: "passage"
latitude: 48.8667
longitude: 2.3397
tags: ["historic"]
neighborhood: "2nd arrondissement"
date_added: "2025-07-19"
date_of_visit: "YYYY-MM-DD"
- name: "Passage des Panoramas"
type: "passage"
latitude: 48.87111
longitude: 2.34167
tags: ["historic"]
neighborhood: "2nd arrondissement"
date_added: "2025-07-19"
date_of_visit: "YYYY-MM-DD"
2. Generate a map
# Using the CLI tool
map-locations locations.yaml --output map.html
# Or using Python
python -c "
from map_locations import load_locations_from_yaml, show_locations_grouped
locations = load_locations_from_yaml('locations.yaml')
show_locations_grouped(locations, map_filename='map.html')
"
3. Export to different formats
# Export to all formats (JSON, CSV, GeoJSON, KML, HTML)
map-locations locations.yaml --format all --output exports/locations
# Export to specific format
map-locations locations.yaml --format json --output exports/locations.json
map-locations locations.yaml --format csv --output exports/locations.csv
map-locations locations.yaml --format geojson --output exports/locations.geojson
map-locations locations.yaml --format kml --output exports/locations.kml
map-locations locations.yaml --format html --output exports/locations.html
4. Import into Google My Maps
You can easily import your exported KML files into Google My Maps for additional features. See the Google My Maps Integration section below for detailed instructions.
For AI Agents
This package is designed to be AI-agent friendly with comprehensive type hints, clear function signatures, and utility functions for common operations.
Core Data Structure
from map_locations import Location
# Location is a TypedDict with the following structure:
Location = {
"name": str, # Required: Location name
"type": str, # Required: Location type/category
"latitude": float, # Required: Latitude coordinate
"longitude": float, # Required: Longitude coordinate
"tags": List[str], # Optional: List of tags for filtering
"neighborhood": str, # Optional: Neighborhood or area name
"date_added": str, # Optional: Date when added (YYYY-MM-DD)
"date_of_visit": str, # Optional: Date of visit (YYYY-MM-DD)
}
Quick AI Agent Usage Examples
from map_locations import (
load_locations_from_yaml,
create_sample_locations,
get_location_summary,
filter_locations_by_type,
validate_location_data,
show_locations_grouped,
export_to_all_formats,
)
# Load existing data or create sample data
locations = load_locations_from_yaml("my_locations.yaml")
# OR
locations = create_sample_locations()
# Get summary of available data
summary = get_location_summary(locations)
print(f"Total locations: {summary['total_count']}")
print(f"Available types: {summary['types']}")
print(f"Available tags: {summary['tags']}")
# Validate data for issues
issues = validate_location_data(locations)
if issues['missing_required']:
print(f"Data issues found: {issues}")
# Filter and visualize
restaurants = filter_locations_by_type(locations, ["restaurant", "cafe"])
show_locations_grouped(restaurants, "restaurants_map.html")
# Export to multiple formats
export_to_all_formats(locations, "exports/my_locations")
Available Functions for AI Agents
Data Loading and Validation
load_locations_from_yaml(yaml_path: str) -> List[Location]create_sample_locations() -> List[Location]validate_location_data(locations: List[Location]) -> Dict[str, List[str]]
Data Analysis
get_location_summary(locations: List[Location]) -> Dict[str, Any]get_available_types(locations: List[Location]) -> List[str]get_available_tags(locations: List[Location]) -> List[str]get_available_neighborhoods(locations: List[Location]) -> List[str]
Filtering
filter_locations_by_type(locations: List[Location], types: List[str]) -> List[Location]filter_locations_by_tags(locations: List[Location], tags: List[str]) -> List[Location]filter_locations_by_neighborhood(locations: List[Location], neighborhoods: List[str]) -> List[Location]
Visualization
show_locations_grouped(locations: List[Location], group_by: str = "type", map_filename: str = "map.html")show_locations_with_filtering(locations: List[Location], map_filename: str = "map.html")show_locations_with_google_maps(locations: List[Location], map_filename: str = "map.html")
Export
export_to_json(locations: List[Location], output_path: str)export_to_csv(locations: List[Location], output_path: str)export_to_geojson(locations: List[Location], output_path: str)export_to_kml(locations: List[Location], output_path: str)export_to_all_formats(locations: List[Location], base_path: str)
Common AI Agent Workflows
1. Data Exploration
from map_locations import load_locations_from_yaml, get_location_summary
locations = load_locations_from_yaml("data.yaml")
summary = get_location_summary(locations)
print(f"Dataset contains {summary['total_count']} locations")
print(f"Types: {summary['types']}")
print(f"Top types: {dict(sorted(summary['type_counts'].items(), key=lambda x: x[1], reverse=True)[:5])}")
2. Data Validation
from map_locations import validate_location_data
issues = validate_location_data(locations)
if any(issues.values()):
print("Data validation issues found:")
for category, problems in issues.items():
if problems:
print(f" {category}: {problems}")
else:
print("✅ Data validation passed")
3. Filtered Analysis
from map_locations import filter_locations_by_type, filter_locations_by_tags
# Get all food-related locations
food_locations = filter_locations_by_type(locations, ["restaurant", "cafe", "bar"])
# Get all historic sites
historic_sites = filter_locations_by_tags(locations, ["historic"])
# Create maps for each category
show_locations_grouped(food_locations, "food_map.html")
show_locations_grouped(historic_sites, "historic_map.html")
4. Complete Workflow
from map_locations import (
load_locations_from_yaml,
validate_location_data,
get_location_summary,
filter_locations_by_type,
show_locations_grouped,
export_to_all_formats,
)
# Load and validate
locations = load_locations_from_yaml("locations.yaml")
issues = validate_location_data(locations)
if issues['missing_required']:
print("❌ Data has issues, please fix before proceeding")
exit(1)
# Analyze
summary = get_location_summary(locations)
print(f"✅ Loaded {summary['total_count']} valid locations")
# Filter and visualize
museums = filter_locations_by_type(locations, ["museum", "gallery"])
show_locations_grouped(museums, "museums_map.html")
# Export
export_to_all_formats(locations, "exports/complete_dataset")
print("✅ All exports completed")
Tile Providers
The library supports multiple tile providers for different map styles:
OpenStreetMap (Default)
- Cost: Free
- Usage: No API key required
- Best for: General use, open data
Google Maps
- Cost: Free for personal use, requires API key for commercial use
- Usage: No API key required for personal use
- Best for: Familiar interface, detailed street data
Google Satellite
- Cost: Free for personal use, requires API key for commercial use
- Usage: No API key required for personal use
- Best for: Aerial views, terrain analysis
Note: Google Maps tiles are free for personal use but may require an API key and payment for commercial use or high-volume usage. For commercial applications, consider using the official Google Maps JavaScript API.
Location Data Format
Each location in your YAML file should include:
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | ✅ | Location name |
type |
string | ✅ | Location type (determines color) |
latitude |
float | ✅ | Latitude coordinate |
longitude |
float | ✅ | Longitude coordinate |
tags |
list | ❌ | Array of tags for filtering |
neighborhood |
string | ❌ | Neighborhood or area |
date_added |
string | ❌ | Date added to collection |
date_of_visit |
string | ❌ | date of visit (use "YYYY-MM-DD") |
Example Location Entry
- name: "Passage du Grand Cerf"
type: "passage"
latitude: 48.86483
longitude: 2.34933
tags: ["architecture", "glass roof"]
neighborhood: "2nd arrondissement"
date_added: "2025-07-19"
date_of_visit: "YYYY-MM-DD"
CLI Usage
The CLI supports multiple formats with a single command structure:
Available Formats
html- Interactive HTML map (default)json- JSON formatcsv- CSV formatgeojson- GeoJSON formatkml- KML format with grouped folders for Google Mapsall- All formats including HTML
Basic Usage
# Create HTML map (default)
map-locations locations.yaml --output map.html
# Export to specific format
map-locations locations.yaml --format json --output locations.json
map-locations locations.yaml --format kml --output locations.kml
# Export to all formats (including HTML)
map-locations locations.yaml --format all --output locations
Advanced Options
# Create map with Google Maps tiles
map-locations locations.yaml --tile-provider google_maps --output map.html
# Create map with Google Satellite view
map-locations locations.yaml --tile-provider google_satellite --output map.html
# Group by different fields
map-locations locations.yaml --group-by neighborhood --output map.html
map-locations locations.yaml --group-by date_added --output map.html
See also: Grouping Options and Tile Provider Options for more examples.
Note: For importing into Google My Maps, use the KML format. See Google My Maps Integration for details.
Google My Maps Integration
Export your locations to KML format and import them into Google My Maps for enhanced features:
# Export to KML for Google My Maps
map-locations locations.yaml --format kml --output my_locations.kml
Steps to import into Google My Maps:
- Go to Google My Maps
- Click "Create a new map"
- Click "Import" in the left panel
- Upload your KML file
- Your locations will appear with all details preserved
Google My Maps Features:
- 📱 Mobile Access: View maps on smartphones and tablets
- 👥 Sharing: Share maps via link or email
- 🎨 Custom Styling: Change colors, icons, and labels
- 📝 Collaboration: Allow others to edit your maps
- 🗺️ Offline Access: Download maps for offline use
- 📍 Custom Markers: Add custom icons and descriptions
- 🗂️ Layers: Organize locations into different layers
Grouping Options
# Group by neighborhood (default)
map-locations locations.yaml --group-by neighborhood
# Group by location type
map-locations locations.yaml --group-by type
# Group by date added
map-locations locations.yaml --group-by date_added
# Group by date of visit
map-locations locations.yaml --group-by date_of_visit
Tile Provider Options
# Use OpenStreetMap (default, free)
map-locations locations.yaml --tile-provider openstreetmap
# Use Google Maps (free for personal use)
map-locations locations.yaml --tile-provider google_maps
# Use Google Satellite (free for personal use)
map-locations locations.yaml --tile-provider google_satellite
Library Usage
Basic Map Generation
from map_locations import load_locations_from_yaml, show_locations_grouped
# Load locations from YAML
locations = load_locations_from_yaml("locations.yaml")
# Generate interactive map with grouping (defaults to type)
show_locations_grouped(locations, group_by="type", map_filename="map.html")
# Generate map with Google Maps tiles
show_locations_grouped(
locations,
group_by="type",
map_filename="map.html",
tile_provider="google_maps"
)
# Generate map with Google Satellite view
show_locations_grouped(
locations,
group_by="type",
map_filename="map.html",
tile_provider="google_satellite"
)
Grouping and Organization
from map_locations import load_locations_from_yaml, show_locations_grouped
locations = load_locations_from_yaml("locations.yaml")
# Group by type (default)
show_locations_grouped(locations, group_by="type", map_filename="type_map.html")
# Group by neighborhood
show_locations_grouped(locations, group_by="neighborhood", map_filename="neighborhood_map.html")
# Group by date added
show_locations_grouped(locations, group_by="date_added", map_filename="date_map.html")
See also: Grouping Options for CLI examples of all available grouping fields.
Data Loading
from map_locations import load_locations_from_yaml
# Load locations from YAML file
locations = load_locations_from_yaml("locations.yaml")
# Access location data
for location in locations:
print(f"Name: {location['name']}")
print(f"Type: {location.get('type', 'Unknown')}")
print(f"Tags: {location.get('tags', [])}")
print(f"Coordinates: {location['latitude']}, {location['longitude']}")
Development
Setup Development Environment
# Clone the repository
git clone https://github.com/shpigi/map-locations.git
cd map-locations
# Install with development dependencies
make install-dev
# Set up pre-commit hooks
make setup-dev
Note: This setup is also covered in the Installation section above.
Running Tests
# Run all tests
make test
# Run tests with coverage
pytest tests/ -v --cov=map_locations --cov-report=html
# Run specific test file
pytest tests/test_core.py -v
Code Quality
# Format code
make format
# Run linting (pre-commit checks on all files)
make lint
# Run linting on staged files only
make lint-staged
Pre-commit Hooks
This project uses pre-commit hooks to ensure code quality. The hooks will automatically run on every commit and include:
- Code Formatting: Black for code formatting, isort for import sorting
- Linting: Flake8 for style checking, MyPy for type checking
- File Checks: YAML validation, JSON validation, trailing whitespace removal
- Security: Private key detection, merge conflict detection
Setting up pre-commit hooks:
# Install pre-commit hooks (automatically done with setup-dev)
make setup-dev
# Or manually:
pre-commit install
Running pre-commit checks manually:
# Run all hooks on all files
pre-commit run --all-files
# Run specific hook
pre-commit run black
# Run hooks on staged files only
pre-commit run
Code Style Standards
This project follows strict code quality standards:
- Line Length: Maximum 100 characters
- Formatting: Black for code formatting, isort for imports
- Linting: Flake8 for style checking
- Type Checking: MyPy for type validation
- Documentation: Google-style docstrings
The pre-commit hooks will automatically enforce these standards.
Building and Publishing
# Build the package
make build
# Clean build artifacts
make clean
# Publish to PyPI (requires proper configuration)
make publish
Running Examples
# Run the basic usage example
python examples/basic_usage.py
# Test the CLI
make test-cli
Map Features
Interactive Elements
- Clickable Markers: Click on any location to see detailed popup with name, type, tags, and dates
- Zoom Controls: Zoom in/out with mouse wheel or controls
- Pan Navigation: Click and drag to move around the map
- Fullscreen Mode: Toggle fullscreen view
- Layer Control: Toggle visibility of different groups with the layer control panel
Color Coding
Different groups are automatically assigned colors from a predefined color palette:
- Group Colors: Each group (neighborhood, type, etc.) gets a unique color
- Color Palette: Red, blue, green, purple, orange, darkred, lightred, beige, darkblue, darkgreen, cadetblue
- Automatic Cycling: Colors cycle through the palette for multiple groups
- Fallback: Gray color for additional groups beyond the palette
Popup Information
- Detailed Popups: Click any marker to see comprehensive information including:
- Location name
- Type
- Tags
- Date added
- date of visit
- Tooltips: Hover over markers to see location names
- Layer Control: Toggle visibility of different groups using the layer control panel
Configuration
Grouping Options
The show_locations_grouped function allows you to group locations by any field in your YAML:
from map_locations import load_locations_from_yaml, show_locations_grouped
locations = load_locations_from_yaml("locations.yaml")
# Group by any field
show_locations_grouped(locations, group_by="type") # By type (default)
show_locations_grouped(locations, group_by="neighborhood") # By area
show_locations_grouped(locations, group_by="date_added") # By date
show_locations_grouped(locations, group_by="tags") # By tags
Map Styling
from map_locations import load_locations_from_yaml, show_locations_grouped
locations = load_locations_from_yaml("locations.yaml")
# Custom map options
show_locations_grouped(
locations,
group_by="type",
map_filename="custom_map.html"
)
See also: Tile Providers for available tile provider options and Tile Provider Options for CLI examples.
Examples
Paris Passages Map
The included example shows historic passages in Paris:
# Generate the Paris passages map grouped by type (default)
map-locations generate --input map_locations/maps/passages/locations.yaml --group-by type --output passages_map.html
This creates an interactive map of Paris's historic covered passages with:
- Locations grouped by type (default)
- Color-coded groups with layer controls
- Detailed popups showing name, type, tags, and dates
- Interactive layer panel to toggle group visibility
Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
Project details
Release history Release notifications | RSS feed
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 map_locations-0.2.1.tar.gz.
File metadata
- Download URL: map_locations-0.2.1.tar.gz
- Upload date:
- Size: 30.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b3a5e83c56c76428bbe3713603c39ea8c3a944c2255249b8d701e2e56131a48e
|
|
| MD5 |
5b05346124ea5e69242667f3c057ce71
|
|
| BLAKE2b-256 |
f3452256f04fec2712faf18bc89929d9b0048c8e429c7aeadb8e0f3da8265ede
|
File details
Details for the file map_locations-0.2.1-py3-none-any.whl.
File metadata
- Download URL: map_locations-0.2.1-py3-none-any.whl
- Upload date:
- Size: 18.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
001ffb3d9a73f66dbbb7c2e4ad985eebb1cb4d385faebeabdfc2c4beef0dc0b9
|
|
| MD5 |
252d6798f0ca765a2979ccea3a98d648
|
|
| BLAKE2b-256 |
49839ba800557d51103e05a477f844deb064e03edec7a6c9ddccdffc614b27ae
|