Skip to content

Instantly share code, notes, and snippets.

@JeffJacobson
Created February 12, 2026 19:56
Show Gist options
  • Select an option

  • Save JeffJacobson/e665be39d3e1cfd89f97d07ebb2a6982 to your computer and use it in GitHub Desktop.

Select an option

Save JeffJacobson/e665be39d3e1cfd89f97d07ebb2a6982 to your computer and use it in GitHub Desktop.
Create CSV scale list from ArcGIS Pro
# Scale levels from https://developers.arcgis.com/documentation/demos/zoom-calculator/zoomCalculator.html
from collections import OrderedDict
from typing import Literal, TypedDict, NamedTuple
class ScaleItemDict(TypedDict):
scale: float
suggestion: str
zoom_scale_lookups = dict[int, ScaleItemDict](
{
-1: {
"scale": 591657527.591555, # zoom of 0 for Image Tile Layers
"suggestion": "World",
},
0: {
"scale": 295828763.795777, # zoom of 0 for Vector Tile Layers
"suggestion": "World",
},
1: {
"scale": 147914381.897889,
"suggestion": "World",
},
2: {
"scale": 73957190.948944,
"suggestion": "Continent",
},
3: {
"scale": 36978595.474472,
"suggestion": "Continent",
},
4: {
"scale": 18489297.737236,
"suggestion": "Countries",
},
5: {
"scale": 9244648.868618,
"suggestion": "Country",
},
6: {
"scale": 4622324.434309,
"suggestion": "States / Provinces",
},
7: {
"scale": 2311162.217155,
"suggestion": "Counties",
},
8: {
"scale": 1155581.108577,
"suggestion": "Counties",
},
9: {
"scale": 577790.554289,
"suggestion": "County",
},
10: {
"scale": 288895.277144,
"suggestion": "Metropolitan Area",
},
11: {
"scale": 144447.638572,
"suggestion": "Cities",
},
12: {
"scale": 72223.819286,
"suggestion": "City",
},
13: {
"scale": 36111.909643,
"suggestion": "Town",
},
14: {
"scale": 18055.954822,
"suggestion": "Neighborhood",
},
15: {
"scale": 9027.977411,
"suggestion": "Streets",
},
16: {
"scale": 4513.988705,
"suggestion": "City block",
},
17: {
"scale": 2256.994353,
"suggestion": "Buildings",
},
18: {
"scale": 1128.497176,
"suggestion": "Building",
},
19: {
"scale": 564.248588,
"suggestion": "Houses",
},
20: {
"scale": 282.124294,
"suggestion": "Houses",
},
21: {
"scale": 141.062147,
"suggestion": "Houses",
},
22: {
"scale": 70.5310735, # zoom of 23 for image tile layers
"suggestion": "House property",
},
23: {
"scale": 35.2655368, # zoom of 23 for vector tile layers
"suggestion": "House",
},
}
)
# Reverse the order of the scales
zoom_scale_lookups = OrderedDict(sorted(zoom_scale_lookups.items(), reverse=True))
class ScaleSuggestionTuple(NamedTuple):
scale: float
suggestion: str
def get_scale_info(layer_type: Literal["Image", "Vector"] | None = None):
for zoom_level, scale_item in zoom_scale_lookups.items():
current_scale = scale_item["scale"]
current_suggestion = scale_item["suggestion"]
current_image_zoom_level = zoom_level
current_vector_zoom_level = current_image_zoom_level - 1
# skip if negative zoom level integer
if (layer_type == "Vector" and current_vector_zoom_level < 0) or (
layer_type == "Image" and current_image_zoom_level < 0
):
continue
if layer_type == "Vector":
current_suggestion = f"{current_vector_zoom_level} - {current_suggestion}"
elif layer_type == "Image":
current_suggestion = f"{current_image_zoom_level} - {current_suggestion}"
else:
current_suggestion = f"{current_suggestion} (Image: {current_image_zoom_level} / Vector: {current_vector_zoom_level})"
yield ScaleSuggestionTuple(current_scale, current_suggestion)
import argparse
import csv
from sys import stdout
from . import get_scale_info
def main():
arg_parser = argparse.ArgumentParser(
description="Creates a CSV list of scales for use with ArcGIS Pro"
)
arg_parser.add_argument(
"layer_type", choices=("Image", "Vector"), default=None, nargs="?"
)
args = arg_parser.parse_args()
w = csv.writer(stdout, "excel", lineterminator="\n")
for t in get_scale_info(args.layer_type):
w.writerow(t)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment