Home

Awesome

GeoDex

GeoDex is tool to find tile indices for geospatial work on satellite imagery. Given (1) a geojson file containing at least one polygon boundary and (2) a zoom level, GeoDex will return all satellite imagery tile indices that at least partially overlap the boundary. Returned tile indices can be written to a text file for further processing.

Installation

pip install geodex

Basic usage example 1

Specify only a geojson file and zoom:

geodex test/roi_single.geojson 12

Returns:

2494 2126 12
2494 2125 12
2493 2126 12
2493 2125 12

Basic usage example 2

Also specify output format string:

geodex test/roi_single.geojson 12 'google' --output-format "{z}-{x}-{y}"

Returns:

12-2494-2126
12-2494-2125
12-2493-2126
12-2493-2125

Typical usage

Write output of boundary to text file Note that using > like below will overwrite tile_indices.txt if it exists.

geodex zone_1.geojson 15 'tms' > tile_indices.txt

Avoid overwrite by appending multiple outputs to text file using >>

geodex zone_1.geojson 15 'tms' >> tile_indices.txt
geodex zone_17.geojson 15 'tms' >> tile_indices.txt

Additional details

GeoDex is optimized to use very little RAM (compared to our previous tool, cover.js). It uses a depth-first search algorithm that continually returns tile indices instead of storing all tiles in memory at once (see toy example below). This ensures that the program won't crash due to memory overflow as full tile lists can grow to a few gigabytes. The total runtime generally depends on the number of tiles (determined by boundary size and zoom level) as well as the roughness of the boundary.

Tile indexing is built on top of pyGeoTile.

Toy example

<img src="./depth_search_toy_example.gif" width="450" />

Scripting with GeoDex

The command line functionality is mostly insulated from the core code. Therefore, you can incorporate this algorithm into a script by catching sys.stdout as follows:

import subprocess
from ast import literal_eval

# Run geojson through GeoDex, get tiles
std_result = subprocess.run(['geodex', '/Users/wronk/Builds/looking-glass/preds/bounds/hcmc-simple.geojson', str(15), '--output-format', '({z}, {x}, {y})'], stdout=subprocess.PIPE)

# Convert from bytes to string, then to tuples
tile_inds_string = std_result.stdout.decode('utf-8').split('\n')
tile_inds_tuple = [literal_eval(ti) for ti in tile_inds_string if len(ti) > 0]

GeoDex was developed during a project to map high-voltage electricity lines that was supported by the World Bank.

See also

GeoDex has some overlapping functionality with mercantile as both can get all indices within a bounding region. If your geojson specifies a single rectangle, Mercantile can be faster. However, GeoDex will also properly handle geojsons specifying an arbitrary (non-rectangular) polygon or multiple polygons within the same geojson. Additionally, GeoDex uses pyGeoTile to obtain tile indices for specific bounding regions, so it has some added features like the ability to request all three handle three major tile formats (Google, TMS, and QuadTree).