{
  "type": "map",
  "description": "Live UDF map.",
  "hasChildren": false,
  "propsSchema": {
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": "object",
    "properties": {
      "label": {
        "description": "Label above the map",
        "type": "string"
      },
      "param": {
        "description": "Canvas parameter for bounds [west, south, east, north]",
        "type": "string"
      },
      "sendParam": {
        "default": false,
        "description": "Whether to send the bounds to the canvas",
        "type": "boolean"
      },
      "centerLng": {
        "default": -74,
        "type": "number"
      },
      "centerLat": {
        "default": 40.7,
        "type": "number"
      },
      "zoom": {
        "default": 12,
        "type": "number"
      },
      "style": {
        "description": "Inline CSS styles as a plain CSS string (e.g., \"border-radius: 8px; overflow: hidden\")",
        "type": "string"
      },
      "layers": {
        "type": "array",
        "items": {
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "udf": {
                  "type": "string",
                  "description": "Name of the UDF"
                },
                "visible": {
                  "description": "Whether the layer is visible",
                  "type": "boolean"
                },
                "vizConfig": {
                  "description": "Visualization configuration for the layer",
                  "type": "object",
                  "propertyNames": {
                    "type": "string"
                  },
                  "additionalProperties": {}
                },
                "tile": {
                  "description": "Connect as tile mode. By default layers connect as viewport (fetches data for the current map view as a single request).",
                  "type": "boolean"
                }
              },
              "required": [
                "udf"
              ]
            },
            {
              "type": "string",
              "description": "Name of the UDF"
            }
          ],
          "description": "Layer configuration or UDF name"
        }
      },
      "mapStyle": {
        "description": "Map style",
        "type": "string",
        "enum": [
          "light",
          "dark",
          "satellite",
          "blank"
        ]
      },
      "autoFit": {
        "default": true,
        "description": "Automatically fit the map viewport to the loaded data bounds. When true, the map zooms once to frame the union of all layers' data after they first load, then leaves the viewport under user control (it does not re-fit on later pans or re-runs). When false, the map opens at centerLng/centerLat/zoom.",
        "type": "boolean"
      }
    },
    "required": [
      "layers"
    ],
    "description": "Interactive Mapbox map that renders live UDF layers. UDF names must use `{{double-brace}}` syntax. A UDF that returns a GeoDataFrame renders by default. A plain DataFrame renders only with a matching vizConfig — e.g. a DataFrame with an H3 `hex` column rendered via a `hexLayer` (H3HexagonLayer). A plain DataFrame with only lat/lon columns won't render here; use the `fused-map` widget's geojson layer for that.\n\n## Example — points\n\n```json\n{\n  \"type\": \"map\",\n  \"props\": {\n    \"centerLng\": -122.43,\n    \"centerLat\": 37.76,\n    \"zoom\": 11,\n    \"mapStyle\": \"dark\",\n    \"layers\": [\"{{my_udf}}\"]\n  }\n}\n```\n\n## Example — polygons\n\n```json\n{\n  \"type\": \"map\",\n  \"props\": {\n    \"centerLng\": -74,\n    \"centerLat\": 40.7,\n    \"zoom\": 10,\n    \"mapStyle\": \"dark\",\n    \"sendParam\": true,\n    \"autoFit\": true,\n    \"layers\": [\n      {\n        \"udf\": \"{{my_udf}}\"\n      }\n    ]\n  }\n}\n```\n\n## Example — tile layer\n\n```json\n{\n  \"type\": \"map\",\n  \"props\": {\n    \"layers\": [\n      {\n        \"udf\": \"{{my_udf}}\",\n        \"tile\": true,\n        \"vizConfig\": {\n          \"tileLayer\": {\n            \"@@type\": \"TileLayer\",\n            \"minZoom\": 0,\n            \"maxZoom\": 19,\n            \"tileSize\": 256\n          },\n          \"vectorLayer\": {\n            \"@@type\": \"GeoJsonLayer\",\n            \"stroked\": true,\n            \"filled\": false,\n            \"lineWidthMinPixels\": 1\n          }\n        }\n      }\n    ]\n  }\n}\n```\n\n## Example — H3 hexagons (plain DataFrame with a `hex` column)\n\n```json\n{\n  \"type\": \"map\",\n  \"props\": {\n    \"layers\": [\n      {\n        \"udf\": \"{{my_h3_udf}}\",\n        \"vizConfig\": {\n          \"hexLayer\": {\n            \"@@type\": \"H3HexagonLayer\",\n            \"stroked\": true,\n            \"filled\": true,\n            \"pickable\": true,\n            \"extruded\": false,\n            \"opacity\": 1,\n            \"coverage\": 0.9,\n            \"lineWidthMinPixels\": 5,\n            \"getHexagon\": \"@@=properties.hex\",\n            \"getFillColor\": [255, 165, 0, 180],\n            \"getLineColor\": [200, 200, 200, 255]\n          }\n        }\n      }\n    ]\n  }\n}\n```\n\n## Example — raster tile layer\n\n```json\n{\n  \"type\": \"map\",\n  \"props\": {\n    \"centerLng\": -122.43,\n    \"centerLat\": 37.76,\n    \"zoom\": 11,\n    \"mapStyle\": \"dark\",\n    \"layers\": [\n      {\n        \"udf\": \"{{my_raster_udf}}\",\n        \"tile\": true,\n        \"vizConfig\": {\n          \"tileLayer\": { \"@@type\": \"TileLayer\", \"minZoom\": 0, \"maxZoom\": 19, \"tileSize\": 256 },\n          \"rasterLayer\": { \"@@type\": \"BitmapLayer\", \"opacity\": 0.7 }\n        }\n      }\n    ]\n  }\n}\n```\n\nHere `my_raster_udf` returns a raster array (e.g. via `arr_to_plasma`)."
  }
}
