def test_geojson_bounds(obj): """Get bounds of mock geojson objects""" bbox = mercantile.geojson_bounds(obj) assert bbox.west == -1.0 assert bbox.south == -2.0 assert bbox.east == 1.0 assert bbox.north == 2.0
def bounding_tile(ctx, input, seq): """Print the Web Mercator tile at ZOOM level bounding GeoJSON [west, south, east, north] bounding boxes, features, or collections read from stdin. Input may be a compact newline-delimited sequences of JSON or a pretty-printed ASCII RS-delimited sequence of JSON (like https://tools.ietf.org/html/rfc8142 and https://tools.ietf.org/html/rfc7159). Example: \b echo "[-105.05, 39.95, -105, 40]" | mercantile bounding-tile [426, 775, 11] """ src = iter(normalize_input(input)) first_line = next(src) # If input is RS-delimited JSON sequence. if first_line.startswith(RS): def feature_gen(): buffer = first_line.strip(RS) for line in src: if line.startswith(RS): if buffer: yield json.loads(buffer) buffer = line.strip(RS) else: buffer += line else: yield json.loads(buffer) else: def feature_gen(): yield json.loads(first_line) for line in src: yield json.loads(line) for obj in feature_gen(): if isinstance(obj, list): bbox = obj if len(bbox) == 2: bbox += bbox elif len(bbox) != 4: raise click.BadParameter("{0}".format(bbox), param=input, param_hint="input") elif isinstance(obj, dict): if "bbox" in obj: bbox = obj["bbox"] else: bbox = mercantile.geojson_bounds(obj) west, south, east, north = bbox vals = mercantile.bounding_tile(west, south, east, north, truncate=False) output = json.dumps(vals) if seq: click.echo(RS) click.echo(output)
def tiles(ctx, zoom, input, seq): """Lists Web Mercator tiles at ZOOM level intersecting GeoJSON [west, south, east, north] bounding boxen, features, or collections read from stdin. Output is a JSON [x, y, z] array. Input may be a compact newline-delimited sequences of JSON or a pretty-printed ASCII RS-delimited sequence of JSON (like https://tools.ietf.org/html/rfc8142 and https://tools.ietf.org/html/rfc7159). Example: \b $ echo "[-105.05, 39.95, -105, 40]" | mercantile tiles 12 [852, 1550, 12] [852, 1551, 12] [853, 1550, 12] [853, 1551, 12] """ src = iter(normalize_input(input)) first_line = next(src) # If input is RS-delimited JSON sequence. if first_line.startswith(RS): def feature_gen(): buffer = first_line.strip(RS) for line in src: if line.startswith(RS): if buffer: yield json.loads(buffer) buffer = line.strip(RS) else: buffer += line else: yield json.loads(buffer) else: def feature_gen(): yield json.loads(first_line) for line in src: yield json.loads(line) for obj in feature_gen(): if isinstance(obj, list): bbox = obj if len(bbox) == 2: bbox += bbox elif len(bbox) != 4: raise click.BadParameter("{0}".format(bbox), param=input, param_hint="input") elif isinstance(obj, dict): if "bbox" in obj: bbox = obj["bbox"] else: bbox = mercantile.geojson_bounds(obj) west, south, east, north = bbox epsilon = 1.0e-10 if east != west and north != south: # 2D bbox # shrink the bounds a small amount so that # shapes/tiles round trip. west += epsilon south += epsilon east -= epsilon north -= epsilon for tile in mercantile.tiles(west, south, east, north, [zoom], truncate=False): vals = (tile.x, tile.y, zoom) output = json.dumps(vals) if seq: click.echo(RS) click.echo(output)