CLI Tool to convert map place takeout data from CSV to either GeoJson or GPX. Note : this repository has been 100% coded with an AI Agentic workflow.
Find a file
2026-01-05 17:16:14 +01:00
src Vibecode tool to truly takeout google places 2026-01-05 17:16:14 +01:00
.gitignore Vibecode tool to truly takeout google places 2026-01-05 17:16:14 +01:00
deno.json Vibecode tool to truly takeout google places 2026-01-05 17:16:14 +01:00
DISTRIBUTION.md Vibecode tool to truly takeout google places 2026-01-05 17:16:14 +01:00
main.ts Vibecode tool to truly takeout google places 2026-01-05 17:16:14 +01:00
README.md Vibecode tool to truly takeout google places 2026-01-05 17:16:14 +01:00

gmapsConvert

Convert Google Maps CSV exports to GeoJSON or GPX format using the Nominatim geocoding service.

Features

  • Converts Google Maps saved places (CSV format) to GeoJSON or GPX
  • Batch processing: Process multiple CSV files at once using glob patterns
  • Waypoint colors: Customize waypoint colors with hex codes or named colors (compatible with OsmAnd)
  • Uses OpenStreetMap's Nominatim API for geocoding
  • Supports both GeoJSON and GPX 1.1 output formats
  • Auto-detects output format from file extension
  • Auto-generates smart collection names from filenames
  • Custom collection naming with -n flag
  • Respects Nominatim's rate limiting (1 request/second)
  • Reports failed geocoding attempts
  • Simple CLI interface

Requirements

No requirements! Download the pre-built binary for your platform from the releases page.

Option 2: Running from Source

  • Deno 2.x or higher

Installation

Using Pre-built Binary

  1. Download the appropriate binary for your platform:

    • macOS (Apple Silicon): gmaps-convert-macos-arm64
    • macOS (Intel): gmaps-convert-macos-x64
    • Windows: gmaps-convert-windows-x64.exe
    • Linux (x64): gmaps-convert-linux-x64
    • Linux (ARM64): gmaps-convert-linux-arm64
  2. Make it executable (macOS/Linux only):

    chmod +x gmaps-convert-macos-arm64
    
  3. Run it:

    ./gmaps-convert-macos-arm64 input/restaurants.csv
    
  4. (Optional) Move to PATH for global access:

    # macOS/Linux
    sudo mv gmaps-convert-macos-arm64 /usr/local/bin/gmaps-convert
    
    # Now use from anywhere
    gmaps-convert ~/Downloads/places.csv
    

From Source

Clone this repository:

git clone <repository-url>
cd gmapsConvert

No additional installation steps required - Deno handles all dependencies automatically.

Usage

Using Pre-built Binary

# Basic usage (defaults to GeoJSON format)
./gmaps-convert input/restaurants.csv

# Convert to GPX format
./gmaps-convert input/restaurants.csv -f gpx

# Auto-detect format from file extension
./gmaps-convert input/restaurants.csv -d output/places.gpx

# Specify output file
./gmaps-convert input/restaurants.csv -d output/places.geojson

# Custom collection name
./gmaps-convert my_paris_places.csv -n "Best Places in Paris"

# Show help
./gmaps-convert --help

Using Deno (From Source)

Basic Usage

Convert a CSV file to GeoJSON (default format):

deno task convert input/restaurants.csv

This creates restaurants.geojson in the current working directory.

Convert to GPX format:

deno task convert input/restaurants.csv -f gpx

This creates restaurants.gpx in the current working directory.

Specify Output File and Format

Use the -d flag to specify a custom output path:

# GeoJSON format (auto-detected from extension)
deno task convert input/restaurants.csv -d output/my-places.geojson

# GPX format (auto-detected from extension)
deno task convert input/restaurants.csv -d output/my-places.gpx

# Explicit format flag (overrides extension)
deno task convert input/restaurants.csv -f gpx -d output/my-places.json

Direct Execution

You can also run the tool directly without using tasks:

deno run --allow-net --allow-read --allow-write main.ts input/restaurants.csv

Help

Show help information:

deno task convert --help

Collection Naming

The tool automatically generates a collection name for the output files based on the input filename. This name appears in:

  • GPX: <metadata><name> element
  • GeoJSON: metadata.name property

Auto-Generated Names

By default, the collection name is generated from the input filename:

  1. File extension (.csv) is removed
  2. Underscores (_) are replaced with spaces
  3. Multiple consecutive spaces are collapsed to a single space
  4. Smart title case is applied:
    • First word is always capitalized
    • Articles, prepositions, and conjunctions remain lowercase (except at start)
    • Dashes are preserved

Examples:

  • my_favorite_places.csv"My Favorite Places"
  • eat_and_drink.csv"Eat and Drink"
  • paris-restaurants.csv"Paris-restaurants"
  • best___places.csv"Best Places" (multiple underscores collapsed)

Custom Names

Use the -n or --name flag to specify a custom collection name:

# Using binary
./gmaps-convert my_places.csv -n "Best Coffee Shops in Paris"

# Using Deno
deno task convert my_places.csv -n "Mom's Favorite Restaurants"

Custom names are preserved exactly as provided (including capitalization and special characters).

Waypoint Colors

You can customize the color of waypoints using the -c, --color, or --colour flag. Colors are supported in both GPX and GeoJSON output formats.

Supported Color Formats

  1. Named colors (case-insensitive, 30 standard colors):

    gmaps-convert places.csv -c red -f gpx
    gmaps-convert places.csv -c darkgreen -f geojson
    
  2. Hex colors (3, 6, or 8 digit format):

    # 6-digit hex (RRGGBB)
    gmaps-convert places.csv -c "#FF0000" -f gpx
    
    # 3-digit hex (RGB - expands to RRGGBB)
    gmaps-convert places.csv -c "#F00" -f gpx
    
    # 8-digit hex with alpha/transparency (RRGGBBAA)
    gmaps-convert places.csv -c "#80FF0000" -f gpx  # 50% transparent red
    

    Note: Use quotes around hex colors to prevent shell interpretation of #.

Available Named Colors

aqua, black, blue, cyan, darkblue, darkcyan, darkgray, darkgreen, darkgrey, darkmagenta, darkred, darkyellow, fuchsia, gray, green, grey, lightgray, lightgrey, lime, magenta, maroon, navy, olive, purple, red, silver, teal, white, yellow, darkyellow

How Colors Work

  • GPX format: Colors are stored in the <extensions> section using multiple color tags for maximum compatibility. The tool writes all four fallback tags that OsmAnd and other GPX readers check:

    <wpt lat="48.8582599" lon="2.2945006">
      <name>Eiffel Tower</name>
      <extensions>
        <osmand:color xmlns:osmand="https://osmand.net">#FF0000</osmand:color>
        <osmand:colour xmlns:osmand="https://osmand.net">#FF0000</osmand:colour>
        <osmand:displaycolor xmlns:osmand="https://osmand.net">#FF0000</osmand:displaycolor>
        <osmand:displaycolour xmlns:osmand="https://osmand.net">#FF0000</osmand:displaycolour>
        <!-- other extensions -->
      </extensions>
    </wpt>
    

    Compatibility: Writing all four tags (color, colour, displaycolor, displaycolour) ensures the color is recognized by OsmAnd and other GPX applications, regardless of which tag name they check first.

  • GeoJSON format: Colors are stored as a color property in each feature's properties object.

    {
      "type": "Feature",
      "properties": {
        "title": "Eiffel Tower",
        "color": "#FF0000",
        ...
      }
    }
    
  • Batch mode: The same color is applied to all waypoints in all files when processing multiple files.

Color Examples

# Using pre-built binary with named color
./gmaps-convert places.csv -c blue -f gpx

# Using Deno with hex color
deno task convert places.csv -c "#00FF00" -f gpx

# Batch processing with color (applies to all files)
./gmaps-convert input/*.csv -d output/ -f gpx -c red

# British spelling variant
gmaps-convert places.csv --colour purple -f gpx

# With transparency (50% opacity green)
gmaps-convert places.csv -c "#8000FF00" -f gpx

OsmAnd Compatibility

The GPX color implementation follows OsmAnd's GPX color extension standard, ensuring that colored waypoints display correctly in OsmAnd and other compatible applications.

Batch Processing

Process multiple CSV files at once using shell glob patterns or explicit file lists. All files will be geocoded and converted to the output directory.

Basic Batch Usage

Using glob patterns (shell expansion):

# Using binary
./gmaps-convert input/*.csv -d output/

# Using Deno
deno task convert input/*.csv -d output/

Using brace expansion:

# Process specific files
./gmaps-convert input/{eat,drink,hipster}.csv -d output/

# Process with format
deno task convert input/{eat,drink,hipster}.csv -d output/ -f gpx

Using explicit file list:

./gmaps-convert input/eat.csv input/drink.csv input/hipster.csv -d output/

Batch Processing Behavior

When processing multiple files:

  1. Output directory required: Use -d with a directory path ending in /

    • Creates the directory if it doesn't exist
    • Files are automatically named based on input filenames
  2. Auto-generated names: Collection names are automatically generated from each filename

    • The -n flag is ignored in batch mode (with a warning)
    • Each file gets its own collection name
  3. Format applies to all: The -f flag (or auto-detection) applies to all files

    # All files will be converted to GPX
    ./gmaps-convert input/*.csv -d output/ -f gpx
    
  4. Error handling: Processing continues even if individual files fail

    • Failed files are reported in the final summary
    • Exit code is 1 if any file fails
  5. Progress display: Shows per-file progress and batch summary

    Processing file 1/5: input/eat.csv
    Processing file 2/5: input/drink.csv
    ...
    

Batch Examples

Process all CSV files to GeoJSON:

./gmaps-convert input/*.csv -d output/

Process all CSV files to GPX:

deno task convert input/*.csv -d output/ -f gpx

Process specific files:

./gmaps-convert input/eat.csv input/drink.csv input/hipster.csv -d results/

Create output directory automatically:

# Directory will be created if it doesn't exist
./gmaps-convert input/*.csv -d new-directory/

Batch Output Example

============================================================
BATCH PROCESSING: 3 files
============================================================
Output directory: output/
Output format: GEOJSON
============================================================

────────────────────────────────────────────────────────────
Processing file 1/3: input/eat.csv
────────────────────────────────────────────────────────────
...

============================================================
BATCH PROCESSING SUMMARY
============================================================
Files processed: 3
  ✓ Successful: 3
  ✗ Failed: 0

Total entries: 120
  ✓ Successfully geocoded: 115
  ✗ Failed to geocode: 5

Output directory: output/

────────────────────────────────────────────────────────────
PER-FILE RESULTS
────────────────────────────────────────────────────────────
✓ eat.csv → eat.geojson
   75/77 geocoded
✓ drink.csv → drink.geojson
   30/31 geocoded
✓ hipster.csv → hipster.geojson
   10/12 geocoded

Shell Compatibility

Glob pattern expansion is handled by your shell (bash, zsh, fish, etc.) before the command runs:

  • Works: gmaps-convert input/*.csv -d output/ (shell expands *.csv to individual files)
  • Important: Glob patterns must match at least one file, or your shell will error

Windows users (PowerShell/CMD):

# PowerShell also supports glob expansion
.\gmaps-convert.exe input\*.csv -d output\

# Or use explicit lists
.\gmaps-convert.exe input\eat.csv input\drink.csv -d output\

CSV Format

The tool expects CSV files exported from Google Maps with the following columns:

  • Title - Place name (used for geocoding)
  • Note - Notes about the place
  • URL - Google Maps URL
  • Tags - Tags/categories
  • Comment - Additional comments

Note: Only the Title column is used for geocoding. Rows with empty titles are skipped silently.

Output Formats

GeoJSON Format (Default)

The tool generates a valid GeoJSON FeatureCollection with the following structure:

{
  "type": "FeatureCollection",
  "metadata": {
    "name": "My Favorite Places",
    "generated": "2026-01-05T12:00:00.000Z"
  },
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [longitude, latitude]
      },
      "properties": {
        "title": "Place Name",
        "color": "#FF0000",
        "display_name": "Full address from Nominatim",
        "type": "restaurant",
        "class": "amenity",
        "importance": 0.5,
        "place_id": 12345,
        "osm_type": "node",
        "osm_id": 67890
      }
    }
  ]
}

GPX Format

The tool can also generate GPX 1.1 (GPS Exchange Format) files compatible with GPS devices and mapping applications:

<?xml version="1.0" encoding="UTF-8"?>
<gpx version="1.1" creator="gmaps-convert" xmlns:osmand="https://osmand.net">
  <metadata>
    <name>My Favorite Places</name>
    <desc>Converted from Google Maps CSV export using gmaps-convert</desc>
    <time>2026-01-05T12:00:00.000Z</time>
    <bounds minlat="48.8582" minlon="2.2945" maxlat="48.8611" maxlon="2.3380"/>
  </metadata>
  <wpt lat="48.8582599" lon="2.2945006">
    <name>Eiffel Tower</name>
    <desc>Tour Eiffel, 5, Avenue Anatole France...</desc>
    <type>tower</type>
    <src>Nominatim</src>
    <extensions>
      <osmand:color xmlns:osmand="https://osmand.net">#FF0000</osmand:color>
      <osmand:colour xmlns:osmand="https://osmand.net">#FF0000</osmand:colour>
      <osmand:displaycolor xmlns:osmand="https://osmand.net">#FF0000</osmand:displaycolor>
      <osmand:displaycolour xmlns:osmand="https://osmand.net">#FF0000</osmand:displaycolour>
      <nominatim:place_id>89233259</nominatim:place_id>
      <nominatim:class>man_made</nominatim:class>
      <nominatim:importance>0.62</nominatim:importance>
      <nominatim:osm_type>way</nominatim:osm_type>
      <nominatim:osm_id>5013364</nominatim:osm_id>
      <!-- Additional Nominatim data in extensions -->
    </extensions>
  </wpt>
</gpx>

GPX files include:

  • Standard GPX waypoint data (name, description, type, coordinates)
  • Metadata with timestamp and bounding box
  • Waypoint colors with multiple fallback tags for broad compatibility (color, colour, displaycolor, displaycolour)
  • All Nominatim fields in custom extensions (place_id, osm_type, importance, etc.)
  • Compatible with GPS devices, mapping apps, and GIS software (especially OsmAnd)

Format Selection

The output format can be specified in three ways (in order of precedence):

  1. Explicit format flag (highest priority):

    gmaps-convert input.csv -f gpx
    gmaps-convert input.csv -f geojson
    
  2. Auto-detect from file extension:

    • .gpx → GPX format
    • .geojson or .json → GeoJSON format
    gmaps-convert input.csv -d output.gpx      # GPX format
    gmaps-convert input.csv -d output.geojson  # GeoJSON format
    
  3. Default to GeoJSON (if no format specified and no valid extension)

Extension Validation:

  • Valid extensions: .geojson, .json, .gpx
  • Invalid extensions (like .txt, .xml) will trigger a warning and default to GeoJSON
  • Use -f flag to override extension-based detection

Rate Limiting

This tool uses the public Nominatim API operated by OpenStreetMap. According to their usage policy:

  • Maximum 1 request per second
  • Proper User-Agent header is sent with all requests

Processing time: A CSV file with 100 places will take approximately 100 seconds to process due to rate limiting.

Error Handling

  • Rows with empty titles are skipped silently
  • Failed geocoding attempts are reported at the end of processing
  • Places that couldn't be found are not included in the output file
  • A summary shows successful and failed geocoding attempts
  • Batch mode: Processing continues even if individual files fail; failed files are reported in the final summary

Examples

Example 1: Convert to GeoJSON (default)

deno task convert input/eat.csv

Output: eat.geojson in current directory

Example 2: Convert to GPX format

deno task convert input/eat.csv -f gpx

Output: eat.gpx in current directory

Example 3: Auto-detect format from extension

deno task convert input/eat.csv -d output/restaurants.gpx

Output: output/restaurants.gpx (GPX format auto-detected)

Example 4: Custom output location with GeoJSON

deno task convert input/eat.csv -d output/restaurants.geojson

Output: output/restaurants.geojson

Example 5: Custom collection name

deno task convert my_paris_places.csv -n "Best Restaurants in Paris" -f gpx

Output: my_paris_places.gpx with metadata name "Best Restaurants in Paris"

Example 6: Process from a different directory

cd /path/to/your/data
deno run --allow-net --allow-read --allow-write /path/to/gmapsConvert/main.ts places.csv -f gpx

Output: places.gpx in /path/to/your/data/

Building from Source

If you want to create your own standalone executable:

Build for Current Platform

deno task build

This creates a gmaps-convert executable in the current directory (~95-100 MB).

Build for All Platforms

deno task build:all

This creates binaries for all supported platforms in the dist/ directory:

  • gmaps-convert-macos-arm64 - macOS Apple Silicon (M1/M2/M3)
  • gmaps-convert-macos-x64 - macOS Intel
  • gmaps-convert-windows-x64.exe - Windows x64
  • gmaps-convert-linux-x64 - Linux x64
  • gmaps-convert-linux-arm64 - Linux ARM64

Note: On first cross-compile, Deno will download the runtime for each target platform (~50MB per platform). These are cached for future builds.

Binary Details

  • Size: ~95-100 MB (includes slimmed-down Deno runtime)
  • No Runtime Required: Recipients don't need Deno installed
  • Permissions: Network, read, and write permissions are baked into the binary
  • Cross-Platform: Build for any platform from any platform

Sample Output

Reading CSV file: input/eat.csv
Found 77 valid entries to geocode

Geocoding locations (rate limited to 1 request/second)...

[1/77] Geocoding: Marino's Fish Bar - Rye
  ✓ Found: Marino's Fish Bar, 24, Tower Street, Rye, Wealden, East...
[2/77] Geocoding: Les Cèdres - Restaurant associatif
  ✓ Found: Les Cèdres, 7, Rue Charles de Gaulle, Grenoble, Isère,...
...

============================================================
SUMMARY
============================================================
Collection name: Eat
Total entries processed: 77
Successfully geocoded: 73
Failed to geocode: 4
Output format: GEOJSON
Output file: eat.geojson

============================================================
FAILED LOCATIONS
============================================================
- Unknown Place XYZ
  Reason: No results found

Attribution

This tool uses:

  • Nominatim by OpenStreetMap for geocoding
  • Deno runtime
  • Deno Standard Library for CSV parsing and path utilities

When using the generated GeoJSON files, please provide appropriate attribution to OpenStreetMap contributors as per the ODbL license.

License

This project is open source. See LICENSE file for details.

Contributing

Contributions are welcome! Please feel free to submit issues or pull requests.

Troubleshooting

"CSV file not found" error

Make sure the path to your CSV file is correct. Use relative or absolute paths.

"Import not found" errors

Run deno cache --reload main.ts to refresh dependencies.

Slow processing

This is expected due to Nominatim's rate limiting (1 request/second). Processing 100 places takes about 100 seconds.

No results for a place

Some place names may not geocode correctly if they're too generic or misspelled. Check the "FAILED LOCATIONS" section in the output for details.