# Bing Satellite Map Downloader API (`t_wasfy/my-actor`) Actor

Download permitted Bing satellite map tiles and export selected areas as stitched PNG and georeferenced BigTIFF files.

- **URL**: https://apify.com/t\_wasfy/my-actor.md
- **Developed by:** [Tarek Wasfy](https://apify.com/t_wasfy) (community)
- **Categories:** Other, SEO tools, Automation
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.01 / actor start

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## XYZ Map Imagery Capture API

Apify Actor/API for downloading imagery from a user-supplied, permitted XYZ tile server. It stitches the selected bounding box and stores:

- `MOSAIC.png`
- `MOSAIC_EPSG3857.tif`, written directly as a disk-backed BigTIFF with embedded GeoTIFF georeferencing
- `OUTPUT` JSON and one Dataset summary row

All four destinations are also declared in `.actor/output_schema.json`, so Apify displays the PNG, BigTIFF, summary, and Dataset as clickable Actor outputs after a run.

The input is preconfigured with a Bing Satellite QuadKey template. The downloader accepts either standard `{z}`, `{x}`, `{y}` templates or `{q}`/`{quadkey}` templates; `{s}` and `{snum}` subdomains are supported.

### Test source

The included example is preconfigured for Bing Satellite QuadKey tiles:

```text
https://ecn.t{snum}.tiles.virtualearth.net/tiles/a{q}.jpeg?g=14574&mkt=de-DE&n=z
````

Check and follow the source's current attribution, license, acceptable-use, and rate-limit requirements before use. The API requires `confirmTileServerPermission: true` but cannot verify contractual permission automatically.

### Local test

```powershell
$env:APIFY_LOCAL_STORAGE_DIR = (Join-Path $PWD "storage")
Copy-Item .\INPUT_EXAMPLE.json .\storage\key_value_stores\default\INPUT.json -Force
python -m src.main
```

Install dependencies first with `python -m pip install -r requirements.txt`.

### Apify deployment

Create a new Actor from this folder or replace the source files of a test Actor, build it, then run it with `INPUT_EXAMPLE.json`. External deployment and publication are intentionally left to the account owner.

### Safety behavior

- Requires explicit permission confirmation.
- Accepts HTTP(S) XYZ templates only.
- Rejects missing or unknown placeholders.
- Caps zoom, parallelism, retries, timeout, decoded output size, and total tiles.
- Fails the whole run if any requested tile cannot be decoded, avoiding a silently incomplete map.
- Applies a configurable request delay and a descriptive User-Agent.

### BigTIFF streaming

The GeoTIFF path preserves PyMapStitcher's direct streaming design. The Actor creates a disk-backed `tifffile.memmap` with `bigtiff=True`, writes every decoded tile directly into its final pixel window, and flushes the file after downloading. The full raster is never assembled in RAM. The completed BigTIFF is then uploaded to the run's Key-value store with a streamed HTTP request instead of `read_bytes()`.

For local development (`APIFY_IS_AT_HOME=0`), no cloud token exists. The completed test files are therefore handed to the Apify SDK and written into `APIFY_LOCAL_STORAGE_DIR`. Cloud runs keep the streamed upload path.

PNG is an optional convenience preview. It is generated only for mosaics up to 100 million pixels; larger selections still produce the streamed BigTIFF and report `png_skipped_due_to_size: true`.

# Actor input Schema

## `tileUrl` (type: `string`):

Bing Satellite QuadKey URL is preconfigured. Use it only where your Bing Maps license and terms permit downloading and stitching.

## `confirmTileServerPermission` (type: `boolean`):

Required. The user is responsible for checking the tile server license and terms.

## `minLat` (type: `number`):

Southern latitude of the requested bounding box in WGS84 decimal degrees.

## `minLon` (type: `number`):

Western longitude of the requested bounding box in WGS84 decimal degrees.

## `maxLat` (type: `number`):

Northern latitude of the requested bounding box in WGS84 decimal degrees.

## `maxLon` (type: `number`):

Eastern longitude of the requested bounding box in WGS84 decimal degrees.

## `zoom` (type: `integer`):

XYZ/Web Mercator zoom level used to calculate the requested tile grid.

## `outputFormats` (type: `array`):

Select the streamed EPSG:3857 BigTIFF and optionally a PNG preview.

## `maxTiles` (type: `integer`):

The GeoTIFF is streamed directly to disk as BigTIFF; this limit protects the tile server and Actor runtime.

## `maxConcurrency` (type: `integer`):

Maximum number of tile requests processed concurrently.

## `rateLimitMs` (type: `integer`):

Minimum per-worker delay before each tile request to reduce load on the permitted server.

## `requestTimeoutSecs` (type: `integer`):

Maximum time in seconds to wait for an individual tile response.

## `retries` (type: `integer`):

Number of retry attempts after a tile request or image validation failure.

## `headers` (type: `object`):

Do not place secrets here unless your Actor storage and access are configured appropriately.

## Actor input object example

```json
{
  "tileUrl": "https://ecn.t{snum}.tiles.virtualearth.net/tiles/a{q}.jpeg?g=14574&mkt=de-DE&n=z",
  "confirmTileServerPermission": false,
  "minLat": 50.9,
  "minLon": 6.94,
  "maxLat": 50.914,
  "maxLon": 6.998,
  "zoom": 12,
  "outputFormats": [
    "geotiff",
    "png"
  ],
  "maxTiles": 500,
  "maxConcurrency": 4,
  "rateLimitMs": 100,
  "requestTimeoutSecs": 30,
  "retries": 2
}
```

# Actor output Schema

## `mosaicPng` (type: `string`):

Stitched PNG preview when requested and small enough to generate.

## `mosaicBigTiff` (type: `string`):

Direct-streamed GeoTIFF/BigTIFF in EPSG:3857.

## `summary` (type: `string`):

Machine-readable run summary, bounds, dimensions, and output file records.

## `dataset` (type: `string`):

Dataset row containing the complete output metadata.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "tileUrl": "https://ecn.t{snum}.tiles.virtualearth.net/tiles/a{q}.jpeg?g=14574&mkt=de-DE&n=z",
    "minLat": 50.9,
    "minLon": 6.94,
    "maxLat": 50.914,
    "maxLon": 6.998
};

// Run the Actor and wait for it to finish
const run = await client.actor("t_wasfy/my-actor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "tileUrl": "https://ecn.t{snum}.tiles.virtualearth.net/tiles/a{q}.jpeg?g=14574&mkt=de-DE&n=z",
    "minLat": 50.9,
    "minLon": 6.94,
    "maxLat": 50.914,
    "maxLon": 6.998,
}

# Run the Actor and wait for it to finish
run = client.actor("t_wasfy/my-actor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "tileUrl": "https://ecn.t{snum}.tiles.virtualearth.net/tiles/a{q}.jpeg?g=14574&mkt=de-DE&n=z",
  "minLat": 50.9,
  "minLon": 6.94,
  "maxLat": 50.914,
  "maxLon": 6.998
}' |
apify call t_wasfy/my-actor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=t_wasfy/my-actor",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Bing Satellite Map Downloader API",
        "description": "Download permitted Bing satellite map tiles and export selected areas as stitched PNG and georeferenced BigTIFF files.",
        "version": "1.0",
        "x-build-id": "nDFPedtbKMKfNUn2q"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/t_wasfy~my-actor/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-t_wasfy-my-actor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/t_wasfy~my-actor/runs": {
            "post": {
                "operationId": "runs-sync-t_wasfy-my-actor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/t_wasfy~my-actor/run-sync": {
            "post": {
                "operationId": "run-sync-t_wasfy-my-actor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "tileUrl",
                    "confirmTileServerPermission",
                    "minLat",
                    "minLon",
                    "maxLat",
                    "maxLon"
                ],
                "properties": {
                    "tileUrl": {
                        "title": "Permitted XYZ tile URL",
                        "type": "string",
                        "description": "Bing Satellite QuadKey URL is preconfigured. Use it only where your Bing Maps license and terms permit downloading and stitching.",
                        "default": "https://ecn.t{snum}.tiles.virtualearth.net/tiles/a{q}.jpeg?g=14574&mkt=de-DE&n=z"
                    },
                    "confirmTileServerPermission": {
                        "title": "I confirm this tile server permits this use",
                        "type": "boolean",
                        "description": "Required. The user is responsible for checking the tile server license and terms.",
                        "default": false
                    },
                    "minLat": {
                        "title": "South / min latitude",
                        "type": "number",
                        "description": "Southern latitude of the requested bounding box in WGS84 decimal degrees."
                    },
                    "minLon": {
                        "title": "West / min longitude",
                        "type": "number",
                        "description": "Western longitude of the requested bounding box in WGS84 decimal degrees."
                    },
                    "maxLat": {
                        "title": "North / max latitude",
                        "type": "number",
                        "description": "Northern latitude of the requested bounding box in WGS84 decimal degrees."
                    },
                    "maxLon": {
                        "title": "East / max longitude",
                        "type": "number",
                        "description": "Eastern longitude of the requested bounding box in WGS84 decimal degrees."
                    },
                    "zoom": {
                        "title": "XYZ zoom",
                        "minimum": 0,
                        "maximum": 24,
                        "type": "integer",
                        "description": "XYZ/Web Mercator zoom level used to calculate the requested tile grid.",
                        "default": 12
                    },
                    "outputFormats": {
                        "title": "Output formats",
                        "type": "array",
                        "description": "Select the streamed EPSG:3857 BigTIFF and optionally a PNG preview.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "png",
                                "geotiff"
                            ],
                            "enumTitles": [
                                "PNG mosaic",
                                "GeoTIFF/BigTIFF EPSG:3857"
                            ]
                        },
                        "default": [
                            "geotiff",
                            "png"
                        ]
                    },
                    "maxTiles": {
                        "title": "Maximum tile safety limit",
                        "minimum": 1,
                        "maximum": 5000,
                        "type": "integer",
                        "description": "The GeoTIFF is streamed directly to disk as BigTIFF; this limit protects the tile server and Actor runtime.",
                        "default": 500
                    },
                    "maxConcurrency": {
                        "title": "Parallel downloads",
                        "minimum": 1,
                        "maximum": 16,
                        "type": "integer",
                        "description": "Maximum number of tile requests processed concurrently.",
                        "default": 4
                    },
                    "rateLimitMs": {
                        "title": "Delay per request in milliseconds",
                        "minimum": 0,
                        "maximum": 10000,
                        "type": "integer",
                        "description": "Minimum per-worker delay before each tile request to reduce load on the permitted server.",
                        "default": 100
                    },
                    "requestTimeoutSecs": {
                        "title": "Request timeout",
                        "minimum": 5,
                        "maximum": 120,
                        "type": "integer",
                        "description": "Maximum time in seconds to wait for an individual tile response.",
                        "default": 30
                    },
                    "retries": {
                        "title": "Retries",
                        "minimum": 0,
                        "maximum": 5,
                        "type": "integer",
                        "description": "Number of retry attempts after a tile request or image validation failure.",
                        "default": 2
                    },
                    "headers": {
                        "title": "Optional HTTP headers",
                        "type": "object",
                        "description": "Do not place secrets here unless your Actor storage and access are configured appropriately."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
