Почему наблюдается снижение застроенной площади, полученной из данных LULC 250k Bhuvan API?

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

Я провожу статистический анализ застроенных территорий в нескольких деревнях в Телангане, Индия, используя данные LULC 250k по AOI из API Bhuvan.

При анализе данных за 2015-16 и 2017-18 я заметил снижение застроенной площади во многих регионах, что кажется противоречивым. Обычно застроенные территории, определяемые как земли с постройками, должны либо увеличиваться, либо оставаться стабильными со временем.

Изображение графика, показывающего то же самое:
Линия тренда застроенных площадей 10 случайных деревень за годы (2013-2018)

Вопрос:
Какова может быть причина этого снижения застроенной площади, и является ли это ожидаемым поведением для данного набора данных?

Я получил геометрии деревень из данных Shrid Polygons, доступных на SHRUG от Development Data Lab

Вот пример запроса к API, который я использую для получения данных (шаблон можно найти на сайте API Bhuvan > Тематическая статистика > LULC 250k по AOI):

import requests
import json
import re
from shapely import wkt
from shapely.geometry import Polygon
import logging
import time

# Настройка логирования
log_file="lulc_processing.log"
logging.basicConfig(level=logging.INFO, filename=log_file, filemode="a", format="%(asctime)s - %(levelname)s - %(message)s")

polygon = None  # Инициализация переменной полигон
tolerance = 0.000015  # Установка допустимой ошибки для упрощения полигона

def extract_json_from_html(html_text):
    """Извлечение данных JSON из HTML с использованием регулярных выражений."""
    json_pattern = re.compile(r'(\[.*\])', re.DOTALL)
    match = json_pattern.search(html_text)
    if match:
        json_str = match.group(1)
        try:
            return json.loads(json_str)
        except json.JSONDecodeError as e:
            logging.error(f"Ошибка декодирования JSON: {e}")
            print(f"Ошибка декодирования JSON: {e}")
            return None
    else:
        logging.error("Данные JSON не найдены в HTML")
        print("Данные JSON не найдены в HTML")
        return None

def get_lulc_data(year, polygon, token, option='json'):
    """Получение данных LULC для данного полигона."""
    base_url = "https://bhuvan-app1.nrsc.gov.in/api/lulc250k/curl_lulc250k.php"
    params = {
        "polygon": polygon,
        "year": year,
        "option": option,
        "token": token
    }

    headers = {
        "Content-Type": "application/json"
    }
    response = requests.post(base_url, headers=headers, params=params, timeout=30)
    logging.info(f"Код состояния ответа: {response.status_code}")
    print(f"Код состояния ответа: {response.status_code}")

    try:
        response.raise_for_status()
        if 'application/json' in response.headers.get('Content-Type', ''):
            return response.json()
        else:
            logging.warning("Получен ответ не в формате JSON")
            print("Получен ответ не в формате JSON")
            json_data = extract_json_from_html(response.text)
            logging.info(f"Извлеченные json из ответа: {response.text}")
            print(f"Извлеченные json из ответа: {response.text}")
            if json_data:
                return json_data
            else:
                logging.error("Не удалось извлечь JSON из HTML ответа")
                print("Не удалось извлечь JSON из HTML ответа")
                return None
    except requests.exceptions.HTTPError as err:
        logging.error(f"Произошла ошибка HTTP: {err}")
        print(f"Произошла ошибка HTTP: {err}")
        if response.status_code == 414:  # Обработка ошибки HTTP 414 (слишком длинный URI запроса)
            polygon = polygon.simplify(tolerance=tolerance)  # Упрощение полигона
            logging.info("Упрощенный полигон из-за ошибки HTTP 414")
            print(f"Упрощенный полигон с допуском {str(tolerance)} из-за ошибки HTTP 414")
        raise
    except ValueError as json_err:
        logging.error(f"Ошибка декодирования JSON: {json_err}")
        logging.error(f"Текст ответа: {response.text}")
        print(f"Ошибка декодирования JSON: {json_err}")
        print(f"Текст ответа: {response.text}")
        raise

def process_lulc_data(lulc_data):
    """Обработка данных LULC и классификация площадей по годам и использованию земли."""
    data_by_year = {}

    for record in lulc_data:
        year = record.get("Year", "")
        desc = record.get("LULC Description", "").strip() 
        # Удаление лишних пробелов
        area = float(record.get("Area in Sq. Km", 0))  # Убедитесь, что площадь является числом с плавающей точкой
        if desc != 'Built-up':
            continue
        if year not in data_by_year:
            data_by_year[year] = {}  # Создание нового словаря для года

        if desc in data_by_year[year]:
            data_by_year[year][desc] += area  # Добавление к существующей площади
        else:
            data_by_year[year][desc] = area  # Инициализация площади для этого описания

    return data_by_year

# Пример использования
polygon_wkt = "POLYGON ((78.38246377200005 19.861716572000034, 78.38200866600005 19.870488317000024, 78.38230791500007 19.877670315000046, 78.37761966700003 19.88036356400005, 78.36654742000007 19.879964565000023, 78.35958346600006 19.882857314000034, 78.35772748600004 19.874373519000073, 78.35867927100009 19.864879469000073, 78.36305038900008 19.865230004000068, 78.37797491800006 19.861941819000037, 78.38246377200005 19.861716572000034))"  # Пример WKT полигона

polygon = wkt.loads(polygon_wkt)

year="2014_15,2015_16"  # Укажите год
token = "xxxxxx"  # Замените на ваш токен
max_retries = 5
retry_delay = 5

# Механизм повторных попыток
retries = 0
lulc_data = None
while retries < max_retries:
    try:
        lulc_data = get_lulc_data(year, polygon, token)
        if lulc_data:
            break
        else:
            logging.warning(f"Нет данных LULC, повторная попытка... ({retries + 1}/{max_retries})")
            print(f"Нет данных LULC, повторная попытка... ({retries + 1}/{max_retries})")
    except Exception as e:
        logging.warning(f"Ошибка при получении данных LULC: {e}")
        print(f"Ошибка при получении данных LULC: {e}")
    retries += 1
    time.sleep(retry_delay)

# Обработка данных LULC
if lulc_data:
    processed_data = process_lulc_data(lulc_data)
    print("Обработанные данные LULC:", processed_data)
else:
    print("Не удалось получить данные LULC после нескольких попыток.")

Вот значения, которые я получаю:

Обработанные данные LULC: {'2014_15': {'Built-up': 0.06}, '2015_16': {'Built-up': 0.05}}

Если у кого-то есть опыт работы с API Bhuvan или аналогичными наборами данных, я буду признателен за любые идеи или разъяснения.

Примечание: Документация для API Bhuvan не была доступна, поэтому любые ссылки на официальные ресурсы также будут полезны.

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

Снижение площади застроенных территорий, которое вы наблюдаете в данных LULC 250k из API Bhuvan для Telangana, может вызвать ряд факторов, которые стоит рассмотреть. Понимание причин такого поведения данных может помочь в вашей статистической аналитике.

Возможные причины снижения застроенных площадей

  1. Классификация и методология сбора данных:

    • Разные годы могут соответствовать разным методологиям обработки и классификации данных. В некоторых случаях изменения в количестве или точности данных могут привести к различной интерпретации площади застроенных территорий. Если изменились протоколы обработки данных или источники информации, это могло повлиять на данные.
  2. Ошибки в данных:

    • Если данные получены из разных источников или с использованием разных методов, это может привести к несовпадению. Например, если в 2015-16 были учтены временные структуры или объекты, которые не были учтены в 2017-18, площадь может показаться уменьшенной.
  3. Изменения в землепользовании:

    • Возможно, происходят реальные изменения в использованию земли. Например, если часть застроенных территорий была демонтирована, признана заброшенной или переосмыслена, это может привести к снижению застроенной площади. Вы также могли столкнуться с случаями, когда вмешательства в естественную среду (например, восстанавливаемые территории или озеленение) увеличили площади, относящиеся к природным пространствам.
  4. Погодные или экологические изменения:

    • Влияние природных явлений, таких как наводнения или засухи, может оказать прямое воздействие на застроенные территории. Если они повредили или уничтожили существующие строения, это также может отражаться в данных.
  5. Технические аспекты API Bhuvan:
    • Важно учитывать, что API может иметь свои ограничения или особенности отображения данных. Не исключено, что изменения в API, в способе обработки запросов или передачи данных могут повлиять на полученные результаты.

Ожидаемое поведение данного набора данных

Данные LULC (Land Use Land Cover) должны отражать динамику землепользования. Их цель - отслеживать изменения и обеспечивать основы для принятия решений в сфере планирования и управления ресурсами. Однако, как показано выше, данные могут иметь вариативность в зависимости от множества факторов.

Рекомендации

  • Перепроверьте совпадение данных из разных лет и методов их получения.
  • Изучите документацию API Bhuvan, даже если она не столь очевидна - попытайтесь найти дополнительные источники информации, такие как форумы пользователей или публикации об использовании данного API.
  • Если возможно, проверьте данные с третьими источниками для оценки их точности и достоверности.

Эти аспекты помогут вам лучше понять вашу текущую ситуацию с данными застроенных территорий и оценить, насколько это является нормальным результатом работы с набором данных.

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

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