How to Process E7 Integer Coordinates in Google Timeline Data
The google-timeline-visualizer detects E7 integer coordinates by checking if values exceed 1,000,000 and divides them by 10⁷ to normalize them into standard decimal degrees.
Google Timeline exports often store latitude and longitude as E7 integers—values multiplied by 10⁷ (10 million)—particularly in Android and iOS Takeout files. The mahlernim/google-timeline-visualizer repository handles this conversion automatically through its core parsing logic, ensuring consistent coordinate representation regardless of the export format.
Understanding the E7 Coordinate Format
E7 is a fixed-point integer representation used by mobile GPS systems to store geographic coordinates without floating-point precision issues. In this format, 37.5° becomes 375000000 and 127.0° becomes 1270000000. The visualizer must detect these scaled integers and convert them back to decimal degrees for mapping and analysis.
According to the source code in visualizer.py, the normalization logic resides in the parse_coordinate helper function (lines 42-61), which serves as the primary entry point for all coordinate processing.
The parse_coordinate Implementation
The parse_coordinate function implements a robust pipeline for handling heterogeneous Google Timeline data.
Input Normalization and Cleaning
Before detecting the coordinate format, the function sanitizes inputs to handle various export variants:
- Removes the
geo:URI prefix commonly found in Google location strings - Strips whitespace and the degree symbol (
°) from coordinate strings - Discards query parameters that appear after
?characters - Handles dictionary inputs containing
latLngorpointfields
This preprocessing ensures that strings like "geo:37.5,127.0?z=15" and "37.5°, 127.0°" both resolve to clean comma-separated values.
E7 Detection and Conversion Logic
The critical detection heuristic appears in the conversion phase:
- The function splits the cleaned string into latitude and longitude components
- It converts both values to
floatfor comparison - If either component's absolute value exceeds 1,000,000, the function assumes E7 encoding
- Both values are divided by 10,000,000 (10⁷) to yield decimal degrees
This threshold-based approach works because legitimate decimal degree coordinates never exceed 180.0, while E7 values always exceed 1 million for any realistic geographic location.
Range Validation
After conversion, the function enforces geographic bounds according to Web Mercator projection limits:
- Latitude must fall within ±85.05112878 degrees
- Longitude must fall within ±180 degrees
Coordinates outside these ranges return None, filtering out corrupted or malformed Timeline entries.
Supported Input Format Variations
The parser handles three distinct input types common in Google exports:
Raw comma-separated strings
parse_coordinate("37.5,127.0") # Returns (37.5, 127.0)
parse_coordinate("375000000,1270000000") # Returns (37.5, 127.0)
Geo URI format
parse_coordinate("geo:37.5,127.0") # Returns (37.5, 127.0)
Dictionary structures
parse_coordinate({"latLng": "37.5,127.0"}) # Returns (37.5, 127.0)
Practical Code Examples
As verified by the test suite in tests/test_parser.py (lines 85-90), the following patterns demonstrate proper E7 handling:
from visualizer import parse_coordinate
# Standard decimal degrees (already normalized)
assert parse_coordinate("37.5,127.0") == (37.5, 127.0)
# E7 integer representation from mobile exports
# 375000000 represents 37.5°, 1270000000 represents 127.0°
assert parse_coordinate("375000000,1270000000") == (37.5, 127.0)
# Geo URI with optional query parameters
assert parse_coordinate("geo:37.5,127.0?time=123456") == (37.5, 127.0)
# Invalid latitude exceeding Web Mercator limits
assert parse_coordinate("91,127") is None
# Null or empty input handling
assert parse_coordinate(None) is None
Summary
- E7 coordinates are 10⁷-scaled integers used in Android/iOS Google Timeline exports to preserve precision
- The
parse_coordinatefunction invisualizer.py(lines 42-61) automatically detects E7 format by checking if absolute values exceed 1,000,000 - Normalization divides detected E7 values by 10,000,000 to convert them to decimal degrees
- The parser supports multiple input formats including raw strings,
geo:URIs, and dictionary objects - Range validation ensures coordinates conform to Web Mercator bounds (±85.05112878° latitude, ±180° longitude)
Frequently Asked Questions
What exactly are E7 coordinates in Google Timeline data?
E7 coordinates are latitude and longitude values multiplied by 10⁷ (10 million) and stored as integers. This format eliminates floating-point precision errors in JSON exports and is commonly used in Android and iOS Takeout files. For example, the coordinate 37.5° becomes the integer 375000000.
How does the visualizer distinguish between E7 and regular decimal degrees?
The parse_coordinate function checks if the absolute value of either coordinate component exceeds 1,000,000. Since valid decimal degrees never exceed 180.0, any value above this threshold is treated as an E7 integer and divided by 10,000,000 to normalize it.
What happens if I pass coordinates with a "geo:" prefix or degree symbols?
The parser automatically cleans inputs by removing the geo: prefix, stripping whitespace, discarding degree symbols (°), and ignoring query parameters after ? characters. This ensures that variations like "geo:37.5,127.0" and "37.5°, 127.0°" are processed correctly.
What does the function return for invalid coordinates?
If coordinates fall outside the valid Web Mercator range (latitude beyond ±85.05112878 or longitude beyond ±180), or if the input is malformed, parse_coordinate returns None rather than raising an exception. This allows the visualizer to skip corrupted Timeline entries gracefully.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →