Свои данные

Свои точки: GeoJSON

Источник хранит данные. Слой определяет, как они выглядят на карте.

1. Подготовьте FeatureCollection

Каждый объект состоит из geometry и properties. Координаты записываются как [долгота, широта], а не наоборот. Точки используют Point, пути — LineString, области — Polygon.

В этом примере properties.open управляет цветом и фильтром, properties.name — подписью.

json
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "id": "pickup-1",
      "geometry": {
        "type": "Point",
        "coordinates": [
          71.4252,
          51.1285
        ]
      },
      "properties": {
        "name": "Пункт Керуен",
        "open": true
      }
    }
  ]
}
Скачать полный GeoJSON пунктов ↗

2. Добавьте источник и слой

addSource регистрирует данные по id. Затем addLayer связывает этот источник с визуальным представлением. Несколько слоёв могут использовать один источник. В примере один слой рисует все пункты.

import * as sdk from "@umap-llc/map-react";

// HTML: <div id="map" style="height:480px;position:relative"></div>
const map = sdk.createMap({
  container: "map",
  style: "YOUR_STYLE_URL",
  accessToken: "YOUR_ACCESS_TOKEN",
  center: [71.423, 51.128],
  zoom: 14,
});

async function setupExample(map, sdk, report = console.log) {
  const response = await fetch(
    "https://developer.umap.kz/examples/data/branches.geojson",
  );
  if (!response.ok) throw new Error("Не удалось загрузить пункты выдачи");
  const data = await response.json();
  await map.addSource("branches", { type: "geojson", data });
  map.addLayer({
    id: "branches",
    type: "circle",
    source: "branches",
    "rendering-order": "overlay",
    paint: {
      "circle-radius": 9,
      "circle-color": ["match", ["get", "open"], true, "#1769e0", "#8492a6"],
    },
  });
  map.fitBounds(
    [
      [71.393, 51.102],
      [71.449, 51.143],
    ],
    { padding: 70, maxZoom: 14 },
  );
  const button = document.createElement("button");
  button.textContent = "Открыты сейчас";
  button.type = "button";
  button.style.cssText =
    "position:absolute;bottom:20px;left:16px;z-index:4;border:0;border-radius:12px;padding:12px 16px;background:#1769e0;color:white;font:600 13px system-ui;cursor:pointer";
  let onlyOpen = false;
  button.onclick = () => {
    onlyOpen = !onlyOpen;
    map.setFilter(
      "branches",
      onlyOpen ? ["==", ["get", "open"], true] : ["has", "name"],
    );
    button.textContent = onlyOpen ? "Все пункты" : "Открыты сейчас";
    button.setAttribute("aria-pressed", String(onlyOpen));
  };
  map.getContainer().append(button);
  const click = (event) => report(event.features?.[0]?.properties?.name ?? "");
  map.on("click", "branches", click);
  report("Учебная сеть пунктов выдачи · 8 адресов");
  return () => {
    button.remove();
    map.off("click", "branches", click);
  };
}

map.once("load", async () => {
  const cleanup = await setupExample(map, sdk);
  if (cleanup) map.once("remove", cleanup);
});

3. Измените данные без пересоздания карты

nextFeatureCollection — новая коллекция того же формата. Фильтр меняет отображение, а не удаляет исходные данные.

map.setData("branches", nextFeatureCollection);
map.setFilter("branches", ["==", ["get", "open"], true]);

4. Уберите слой

Сначала удаляйте все слои источника, затем сам источник.

map.removeLayer("branches");
await map.removeSource("branches");