Загрузка .geojson через API Mapbox

Вопрос или проблема

Через веб-интерфейс Mapbox я могу загрузить файл .geojson (zonas1.geojson) в набор данных, экспортировать его в тайлсет, а затем создать стиль с этими данными. Как я могу сделать ту же процедуру через API, отправив весь файл, экспортировав его в тайлсет и опубликовав стиль? Я использую Python.

import requests 
import boto3  
from botocore.exceptions import NoCredentialsError  
import json  

# Начальные настройки
mapbox_username="xxxxxxx"  
access_token = 'xxxxxxxxxxxxxxxxxxx'  
local_file_path="/home/sonia/rede/mapbox/zonas1.geojson"  для отправки
tileset_name="xxxxxxxxxxx-1djoi"  

def get_s3_credentials():
    print("Поиск учетных данных S3...")
    url = f'https://api.mapbox.com/uploads/v1/{mapbox_username}/credentials?access_token={access_token}'
    
    response = requests.post(url)
    print(f"Ответ учетных данных: {response.status_code}, {response.text}")

    если response.status_code == 200:
        print("Учетные данные успешно получены!")
        return response.json()  
    else:
        raise Exception(f"Ошибка учетных данных S3: {response.text}") 


def upload_to_s3(credentials, local_file_path):
    print("Загрузка в S3...")
    session = boto3.Session(
        aws_access_key_id=credentials['accessKeyId'],
        aws_secret_access_key=credentials['secretAccessKey'],
        aws_session_token=credentials['sessionToken'],
    )
    
    s3 = session.resource('s3')  
    bucket_name = credentials['bucket']  
    object_key = credentials['key'] 

    try:
        s3.Bucket(bucket_name).upload_file(local_file_path, object_key)
        print(f"Успешная загрузка в бакет: {bucket_name}, ключ: {object_key}")  
        return bucket_name, object_key  
    except NoCredentialsError:
        print("Учетные данные не найдены.")  
    except Exception as e:
        print(f"Ошибка загрузки в S3: {e}")  

# Шаг 3: Начать процесс загрузки
def start_upload(bucket, key):
    print("Начинаем загрузку тайлсета...")
    url = f'https://api.mapbox.com/uploads/v1/{mapbox_username}?access_token={access_token}'
    upload_url = f"http://{bucket}.s3.amazonaws.com/{key}"  # URL файла в S3

    data = {
        "url": upload_url,
        "tileset": f"{mapbox_username}.{tileset_name}",
    }
    
    headers = {
        "Content-Type": "application/json",  # Тип содержимого
        "Cache-Control": "no-cache"  # Управление кэшем
    }
    
    response = requests.post(url, headers=headers, data=json.dumps(data))
    print(f": {response.status_code}, {response.text}")

    если response.status_code == 201:
        print("Успешная загрузка!")  
        return response.json() 
    else:
        print(f": {response.text}") 

try:
    credentials = get_s3_credentials()  
    bucket, key = upload_to_s3(credentials, local_file_path)  
    upload_response = start_upload(bucket, key)  
    print(f": {upload_response}")  
except Exception as e:
    print(f": {e}")  

Я могу отправить файл в тайлсет, но не могу отправить тот же файл в набор данных, чтобы он оказал влияние на стиль.

Ответ или решение

Конечно, давайте рассмотрим, как можно загрузить файл .geojson в Mapbox через API, экспортировать его в тайлсет и затем опубликовать стиль, используя Python. Ниже представлены основные этапы этого процесса:

Шаг 1: Получение учетных данных для S3

Для начала, вам необходимо получить временные учетные данные для загрузки файла на S3:

def get_s3_credentials():
    print("Запрашиваем учетные данные S3...")
    url = f'https://api.mapbox.com/uploads/v1/{mapbox_username}/credentials?access_token={access_token}'

    response = requests.post(url)
    if response.status_code == 200:
        print("Учетные данные получены успешно!")
        return response.json()  
    else:
        raise Exception(f"Ошибка при получении учетных данных S3: {response.text}") 

Шаг 2: Загрузка файла в S3

Затем, загружаем файл .geojson в S3:

def upload_to_s3(credentials, local_file_path):
    print("Загрузка на S3...")
    session = boto3.Session(
        aws_access_key_id=credentials['accessKeyId'],
        aws_secret_access_key=credentials['secretAccessKey'],
        aws_session_token=credentials['sessionToken'],
    )

    s3 = session.resource('s3')  
    bucket_name = credentials['bucket']  
    object_key = credentials['key'] 

    try:
        s3.Bucket(bucket_name).upload_file(local_file_path, object_key)
        print(f"Успешная загрузка в бакет: {bucket_name}, ключ: {object_key}")  
        return bucket_name, object_key  
    except NoCredentialsError:
        print("Учетные данные не найдены.")  
    except Exception as e:
        print(f"Ошибка загрузки в S3: {e}")  

Шаг 3: Начало процесса загрузки в тайлсет

После успешной загрузки на S3, начнем загрузку в тайлсет:

def start_upload(bucket, key):
    print("Начинаем загрузку тайлсета...")
    url = f'https://api.mapbox.com/uploads/v1/{mapbox_username}?access_token={access_token}'
    upload_url = f"http://{bucket}.s3.amazonaws.com/{key}"

    data = {
        "url": upload_url,
        "tileset": f"{mapbox_username}.{tileset_name}",
    }

    headers = {
        "Content-Type": "application/json",
        "Cache-Control": "no-cache"
    }

    response = requests.post(url, headers=headers, data=json.dumps(data))
    if response.status_code == 201:
        print("Успешная загрузка тайлсета!")  
        return response.json() 
    else:
        print(f"Ошибка загрузки тайлсета: {response.text}") 

Шаг 4: Экспорт в датасет

Так как вы хотите также загрузить данные в датасет для дальнейшего использования в стиле, следуйте следующим шагам. Правильный способ это сделать — использовать API Mapbox для создания датасета. Для этого используйте следующий код:

def create_dataset():
    print("Создаем датасет...")
    url = f'https://api.mapbox.com/datasets/v1/{mapbox_username}?access_token={access_token}'

    data = {
        "name": "Мой новый датасет",
        "description": "Датасет на основе geojson"
    }

    response = requests.post(url, json=data)
    if response.status_code == 201:
        print("Датасет успешно создан!")
        return response.json()
    else:
        print(f"Ошибка при создании датасета: {response.text}")

Шаг 5: Добавление данных в датасет и обновление стиля

Для того чтобы обновить стиль и добавить данные в датасет, вам необходимо будет дополнительно работать с API Mapbox Studio:

def update_style(style_id, dataset_id):
    print(f"Обновление стиля {style_id} с использованием датасета {dataset_id}...")
    url = f"https://api.mapbox.com/styles/v1/{mapbox_username}/{style_id}/tileset?access_token={access_token}"

    data = {
        "sources": {
            dataset_id: {
                "type": "vector",
                "url": f"mapbox://{mapbox_username}.{dataset_id}"
            }
        }
    }

    response = requests.patch(url, json=data)
    if response.status_code == 200:
        print("Стиль успешно обновлен!")
    else:
        print(f"Ошибка при обновлении стиля: {response.text}")

Пример полного потока:

Теперь вы можете использовать все вышеуказанные функции в основном потоке программы:

try:
    credentials = get_s3_credentials()  
    bucket, key = upload_to_s3(credentials, local_file_path)  
    upload_response = start_upload(bucket, key)  
    dataset_info = create_dataset()  
    update_style('your-style-id', dataset_info['id'])  # Замените 'your-style-id' на необходимый ID стиля
except Exception as e:
    print(f": {e}")  

Заключение

С приведенным выше кодом вы сможете загрузить файл .geojson в Mapbox, создать тайлсет и обновить стиль, используя API. Убедитесь, что у вас есть необходимые разрешения и токены доступа для всех используемых операций.

Оцените материал
Добавить комментарий

Капча загружается...