# نمایش نقشهٔ تصویری



<span id="overview"></span>

نقشهٔ تصویری از کنار هم قرار گرفتن تصویرهای کوچکی به نام **تایل** ساخته می‌شود. این نقشه برای نمایش در سایت و ساخت تصویر ثابت مناسب است. اگر می‌خواهید رنگ‌ها، نوشته‌ها یا لایه‌های نقشه را تغییر دهید، [نقشهٔ برداری](/dashboard/docs/tile-vector) انتخاب مناسب‌تری است.

<span id="use-cases"></span>

## با این نقشه چه کارهایی می‌توان کرد؟

- نقشه‌ای در سایت نمایش دهید که کاربر بتواند آن را جابه‌جا و بزرگ‌نمایی کند.
- تصویری ثابت از یک نقطه یا محدوده، مثلاً برای صفحهٔ سفارش، دریافت کنید.

<span id="raster-overview"></span>

## نقشه را به صفحه اضافه کنید

برای نمایش نقشه از **MapLibre GL JS**، کتابخانه‌ای برای نمایش نقشه در مرورگر، استفاده می‌کنیم. یک [کلید عمومی](/dashboard/docs/authentication#کلید-عمومی-برای-مرورگر) با دسترسی نقشهٔ تصویری بسازید و مبدأ سایت خود را در تنظیمات کلید ثبت کنید.

قطعهٔ زیر را در صفحهٔ HTML خود قرار دهید و `YOUR_PUBLIC_API_KEY` را با کلید عمومی جایگزین کنید. اگر صفحهٔ آماده ندارید، کد تب «HTML کامل» را در یک فایل با پسوند `.html` قرار دهید. برای راه‌اندازی سرور محلی، [راهنمای اولین نقشه](/dashboard/docs/quick-start-map) را ببینید.


### قطعه کد

```html
<link href="https://cdn.balad.ir/balad-static-files/platform/maplibre/5.24.0/maplibre-gl.css" rel="stylesheet">
<div id="map" style="height: 400px"></div>
<script src="https://cdn.balad.ir/balad-static-files/platform/maplibre/5.24.0/maplibre-gl.js"></script>
<script>
const map = new maplibregl.Map({
  container: "map",
  style: "https://tile-raster.services.balad.ir/styles/raster.json?api_key=YOUR_PUBLIC_API_KEY",
  center: [51.389, 35.6892],
  zoom: 12,
  minZoom: 3,
  attributionControl: { compact: false },
});
</script>
```


### HTML کامل

```html
<!doctype html>
<html lang="fa" dir="rtl">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>نقشه تصویری بلد</title>
<link href="https://cdn.balad.ir/balad-static-files/platform/maplibre/5.24.0/maplibre-gl.css" rel="stylesheet">
<style>html, body, #map { margin: 0; width: 100%; height: 100%; }</style>
<div id="map"></div>
<script src="https://cdn.balad.ir/balad-static-files/platform/maplibre/5.24.0/maplibre-gl.js"></script>
<script>
const map = new maplibregl.Map({
  container: "map",
  style: "https://tile-raster.services.balad.ir/styles/raster.json?api_key=YOUR_PUBLIC_API_KEY",
  center: [51.389, 35.6892],
  zoom: 12,
  minZoom: 3,
  attributionControl: { compact: false },
});
</script>
</html>
```




پس از بارگذاری صفحه، نقشه‌ای می‌بینید که می‌توانید آن را جابه‌جا و بزرگ‌نمایی کنید.

## مرکز، بزرگ‌نمایی و نشانگر

در کد بالا، `center` نقطهٔ شروع نقشه به ترتیب **طول جغرافیایی، عرض جغرافیایی** است. `zoom` میزان نزدیکی نما را مشخص می‌کند؛ مثلاً تغییر آن از `12` به `15` خیابان‌ها را از نزدیک‌تر نشان می‌دهد.

```javascript
center: [51.389, 35.6892],
zoom: 15,
```

برای نمایش مکان موردنظر، این کد را پس از ساخت `map` و داخل همان تگ `script` قرار دهید:

```javascript
new maplibregl.Marker()
  .setLngLat([51.389, 35.6892])
  .addTo(map);
```

برای افزودن نام یا آدرس به نشانگر، [نمونهٔ پنجرهٔ اطلاعات](/dashboard/docs/tile-vector#اطلاعات-یک-مکان-را-نمایش-دهید) را ببینید.

## نمایش منبع نقشه

طبق قوانین بلد، نام و کپی‌رایت بلد و OpenStreetMap باید روی نقشه قابل مشاهده بماند. حذف آن ممکن است به بسته‌شدن حساب شما منجر شود. نمونه‌های این صفحه اطلاعات منبع را روی نقشه نمایش می‌دهند؛ آن‌ها را حذف یا پنهان نکنید.

<span id="raster-style"></span>
<span id="raster-tile"></span>
<span id="نقشه-تصویری-با-maplibre-1"></span>

اگر نقشه دیده نمی‌شود، کلید عمومی، دسترسی نقشهٔ تصویری، مبدأ مجاز و ارتفاع بخش نقشه را بررسی کنید.

## تصویر ثابت نقشه

برای ساخت تصویر ثابت از نقطه یا محدوده، از کلید خصوصی روی سرور استفاده کنید. خروجی هر دو روش، تصویر JPEG است.

<span id="static-image-center"></span>

## دریافت تصویر ثابت با مرکز

`GET https://tile-raster.services.balad.ir/tiles/image/{z},{lon},{lat}/{width}x{height}[@{scale}x].jpg`

یک تصویر ثابت از نقشه با مرکز، سطح بزرگ‌نمایی و اندازه مشخص برمی‌گرداند. برای پیش‌نمایش سفارش، رسید یا اشتراک‌گذاری موقعیت مناسب است.

### تصویر ثابت با نشانگر


#### cURL

```bash
curl --get "https://tile-raster.services.balad.ir/tiles/image/15,51.3890,35.6892/640x360@2x.jpg" \
  --data-urlencode "pin=1" \
  -H "Authorization: Bearer <BALAD_API_KEY>" \
  --fail --output map.jpg
```


#### Python

```python
# Install: pip install httpx
from pathlib import Path

import httpx

url = "https://tile-raster.services.balad.ir/tiles/image/15,51.3890,35.6892/640x360@2x.jpg"
params = {
    "pin": "1",
}
response = httpx.get(
    url,
    params=params,
    headers={"Authorization": "Bearer <BALAD_API_KEY>"},
    timeout=10.0,
)
response.raise_for_status()
Path("map.jpg").write_bytes(response.content)
```


#### Go

```go
package main

import (
	"fmt"
	"io"
	"net/http"
	"net/url"
	"os"
)

func main() {
	endpoint, err := url.Parse("https://tile-raster.services.balad.ir/tiles/image/15,51.3890,35.6892/640x360@2x.jpg")
	if err != nil {
		panic(err)
	}
	query := endpoint.Query()
	query.Set("pin", "1")
	endpoint.RawQuery = query.Encode()
	request, err := http.NewRequest("GET", endpoint.String(), nil)
	if err != nil {
		panic(err)
	}
	request.Header.Set("Authorization", "Bearer <BALAD_API_KEY>")
	response, err := http.DefaultClient.Do(request)
	if err != nil {
		panic(err)
	}
	defer response.Body.Close()
	if response.StatusCode < 200 || response.StatusCode >= 300 {
		panic(fmt.Sprintf("HTTP %d", response.StatusCode))
	}
	file, err := os.Create("map.jpg")
	if err != nil {
		panic(err)
	}
	defer file.Close()
	if _, err := io.Copy(file, response.Body); err != nil {
		panic(err)
	}
}
```


#### PowerShell

```powershell
$url = "https://tile-raster.services.balad.ir/tiles/image/15,51.3890,35.6892/640x360@2x.jpg"
$params = @{
    pin = "1"
}
$query = ($params.GetEnumerator() | ForEach-Object {
    [uri]::EscapeDataString([string]$_.Key) + "=" + [uri]::EscapeDataString([string]$_.Value)
}) -join "&"
$url += "?" + $query
$headers = @{ Authorization = "Bearer <BALAD_API_KEY>" }
Invoke-WebRequest -Uri $url -Headers $headers -UseBasicParsing -OutFile "map.jpg"
```


#### PHP

```php
<?php
// Install: composer require guzzlehttp/guzzle
require __DIR__ . "/vendor/autoload.php";

$client = new \GuzzleHttp\Client();
$response = $client->get("https://tile-raster.services.balad.ir/tiles/image/15,51.3890,35.6892/640x360@2x.jpg", [
    "headers" => ["Authorization" => "Bearer <BALAD_API_KEY>"],
    "query" => [
        "pin" => "1",
    ],
    "timeout" => 10,
]);
if (file_put_contents("map.jpg", $response->getBody()->getContents()) === false) {
    throw new RuntimeException("Could not save image");
}
```


#### Node.js

```javascript
// Node.js 18+
async function main() {
  const url = new URL("https://tile-raster.services.balad.ir/tiles/image/15,51.3890,35.6892/640x360@2x.jpg");
  const params = {
    pin: "1",
  };
  url.search = new URLSearchParams(params).toString();
  const response = await fetch(url, {
    headers: { Authorization: "Bearer <BALAD_API_KEY>" },
  });
  if (!response.ok) throw new Error("HTTP " + response.status);
  const { writeFile } = await import("node:fs/promises");
  await writeFile("map.jpg", Buffer.from(await response.arrayBuffer()));
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});
```




[![تصویر واقعی نقشه با مرکز ۵۱٫۳۸۹۰ و ۳۵٫۶۸۹۲، بزرگ‌نمایی ۱۵ و نشانگر؛ فلش‌ها عرض ۶۴۰ و ارتفاع ۳۶۰ درخواست را نشان می‌دهند](/dashboard/docs/assets/static-center-parameters.webp)](/dashboard/docs/assets/static-center-parameters.webp)

در این نمونه `pin=1` نشانگر را در مرکز قرار می‌دهد. اندازهٔ درخواستی `640x360` است و با `@2x`، فایل خروجی ۱۲۸۰ در ۷۲۰ پیکسل خواهد بود.

### تأثیر بزرگ‌نمایی

هر دو تصویر زیر مرکز یکسانی دارند. در `z=13` محدودهٔ بیشتری دیده می‌شود و در `z=16` نمای خیابان‌ها نزدیک‌تر است.

[![دو خروجی واقعی با مرکز یکسان: بزرگ‌نمایی ۱۳ محدودهٔ بیشتر و بزرگ‌نمایی ۱۶ نمای نزدیک‌تر را نشان می‌دهد](/dashboard/docs/assets/static-zoom-compare.webp)](/dashboard/docs/assets/static-zoom-compare.webp)

### پاسخ

```http
HTTP/1.1 200 OK
Content-Type: image/jpeg

<binary jpeg image>
```

### پارامترها

| نام | نوع | اجباری | پیش‌فرض | توضیح |
| --- | --- | --- | --- | --- |
| `z` | `path integer` | بله | ندارد | سطح بزرگ‌نمایی تصویر. |
| `lon` | `path number` | بله | ندارد | طول جغرافیایی مرکز تصویر. |
| `lat` | `path number` | بله | ندارد | عرض جغرافیایی مرکز تصویر. |
| `width` | `path integer` | بله | ندارد | عرض تصویر خروجی بر حسب پیکسل. |
| `height` | `path integer` | بله | ندارد | ارتفاع تصویر خروجی بر حسب پیکسل. |
| `scale` | `path integer` | خیر | `1` | ضریب کیفیت تصویر؛ مثل `@2x`. |
| `pin` | `query boolean` | خیر | ندارد | در صورت مقدار `1`، نشانگر مرکز روی تصویر اضافه می‌شود. |

### فیلدهای پاسخ

| نام | نوع | توضیح |
| --- | --- | --- |
| `body` | `image/jpeg` | تصویر ثابت نقشه |
| `Cache-Control` | `header` | هدر کش پاسخ. |

### کدهای وضعیت

کدهای مستند این درخواست: `200`، `400`، `401`، `403`، `404`، `5xx`. [معنی کدها و راه بررسی خطا](/dashboard/docs/status-codes)

<span id="static-image-bbox"></span>

## دریافت تصویر ثابت از محدوده

`GET https://tile-raster.services.balad.ir/tiles/image/bbox/{minLon},{minLat},{maxLon},{maxLat}/{width}x{height}[@{scale}x].jpg`

تصویر ثابت نقشه را طوری تولید می‌کند که محدوده جغرافیایی مشخص‌شده داخل تصویر قرار بگیرد.

### تصویر ثابت از محدوده


#### cURL

```bash
curl --get "https://tile-raster.services.balad.ir/tiles/image/bbox/51.30,35.65,51.45,35.75/800x500.jpg" \
  -H "Authorization: Bearer <BALAD_API_KEY>" \
  --fail --output bbox.jpg
```


#### Python

```python
# Install: pip install httpx
from pathlib import Path

import httpx

url = "https://tile-raster.services.balad.ir/tiles/image/bbox/51.30,35.65,51.45,35.75/800x500.jpg"
response = httpx.get(
    url,
    headers={"Authorization": "Bearer <BALAD_API_KEY>"},
    timeout=10.0,
)
response.raise_for_status()
Path("bbox.jpg").write_bytes(response.content)
```


#### Go

```go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	request, err := http.NewRequest("GET", "https://tile-raster.services.balad.ir/tiles/image/bbox/51.30,35.65,51.45,35.75/800x500.jpg", nil)
	if err != nil {
		panic(err)
	}
	request.Header.Set("Authorization", "Bearer <BALAD_API_KEY>")
	response, err := http.DefaultClient.Do(request)
	if err != nil {
		panic(err)
	}
	defer response.Body.Close()
	if response.StatusCode < 200 || response.StatusCode >= 300 {
		panic(fmt.Sprintf("HTTP %d", response.StatusCode))
	}
	file, err := os.Create("bbox.jpg")
	if err != nil {
		panic(err)
	}
	defer file.Close()
	if _, err := io.Copy(file, response.Body); err != nil {
		panic(err)
	}
}
```


#### PowerShell

```powershell
$url = "https://tile-raster.services.balad.ir/tiles/image/bbox/51.30,35.65,51.45,35.75/800x500.jpg"
$headers = @{ Authorization = "Bearer <BALAD_API_KEY>" }
Invoke-WebRequest -Uri $url -Headers $headers -UseBasicParsing -OutFile "bbox.jpg"
```


#### PHP

```php
<?php
// Install: composer require guzzlehttp/guzzle
require __DIR__ . "/vendor/autoload.php";

$client = new \GuzzleHttp\Client();
$response = $client->get("https://tile-raster.services.balad.ir/tiles/image/bbox/51.30,35.65,51.45,35.75/800x500.jpg", [
    "headers" => ["Authorization" => "Bearer <BALAD_API_KEY>"],
    "timeout" => 10,
]);
if (file_put_contents("bbox.jpg", $response->getBody()->getContents()) === false) {
    throw new RuntimeException("Could not save image");
}
```


#### Node.js

```javascript
// Node.js 18+
async function main() {
  const url = new URL("https://tile-raster.services.balad.ir/tiles/image/bbox/51.30,35.65,51.45,35.75/800x500.jpg");
  const response = await fetch(url, {
    headers: { Authorization: "Bearer <BALAD_API_KEY>" },
  });
  if (!response.ok) throw new Error("HTTP " + response.status);
  const { writeFile } = await import("node:fs/promises");
  await writeFile("bbox.jpg", Buffer.from(await response.arrayBuffer()));
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});
```




[![تصویر واقعی یک محدودهٔ نقشه؛ کادر شماتیک، گوشهٔ کمینهٔ طول و عرض و گوشهٔ بیشینهٔ طول و عرض را نشان می‌دهد](/dashboard/docs/assets/static-bbox-parameters.webp)](/dashboard/docs/assets/static-bbox-parameters.webp)

چهار عدد محدوده به ترتیب `minLon,minLat,maxLon,maxLat` هستند. کادر بنفش برای توضیح ترتیب گوشه‌ها شماتیک است؛ تصویر خروجی ممکن است اطراف محدوده را هم نشان دهد.

### پاسخ

```http
HTTP/1.1 200 OK
Content-Type: image/jpeg

<binary jpeg image>
```

### پارامترها

| نام | نوع | اجباری | پیش‌فرض | توضیح |
| --- | --- | --- | --- | --- |
| `minLon` | `path number` | بله | ندارد | کمینه طول جغرافیایی محدوده. |
| `minLat` | `path number` | بله | ندارد | کمینه عرض جغرافیایی محدوده. |
| `maxLon` | `path number` | بله | ندارد | بیشینه طول جغرافیایی محدوده. |
| `maxLat` | `path number` | بله | ندارد | بیشینه عرض جغرافیایی محدوده. |
| `width` | `path integer` | بله | ندارد | عرض تصویر خروجی بر حسب پیکسل. |
| `height` | `path integer` | بله | ندارد | ارتفاع تصویر خروجی بر حسب پیکسل. |
| `scale` | `path integer` | خیر | `1` | ضریب کیفیت تصویر؛ مثل `@2x`. |

### فیلدهای پاسخ

| نام | نوع | توضیح |
| --- | --- | --- |
| `body` | `image/jpeg` | تصویر ثابت محدوده |
| `Cache-Control` | `header` | هدر کش پاسخ. |

### کدهای وضعیت

کدهای مستند این درخواست: `200`، `400`، `401`، `403`، `404`، `5xx`. [معنی کدها و راه بررسی خطا](/dashboard/docs/status-codes)
