text: # -*- coding: utf-8 -*-
  # Copyright 2018-2020 Streamlit Inc.
  #
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  #
  #    http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  """A wrapper for simple PyDeck scatter charts."""
  
  import copy
  import json
  from typing import Any, Dict
  
  import pandas as pd
  
  import streamlit.elements.deck_gl_json_chart as deck_gl_json_chart
  
  # Map used as the basis for st.map.
  _DEFAULT_MAP = dict(deck_gl_json_chart.EMPTY_MAP)  # type: Dict[str, Any]
  _DEFAULT_MAP["mapStyle"] = "mapbox://styles/mapbox/light-v10"
  
  # Other default parameters for st.map.
  _DEFAULT_COLOR = [200, 30, 0, 160]
  _ZOOM_LEVELS = [
      360,
      180,
      90,
      45,
      22.5,
      11.25,
      5.625,
      2.813,
      1.406,
      0.703,
      0.352,
      0.176,
      0.088,
      0.044,
      0.022,
      0.011,
      0.005,
      0.003,
      0.001,
      0.0005,
  ]
  
  
  def _get_zoom_level(distance):
      """Get the zoom level for a given distance in degrees.
  
      See https://wiki.openstreetmap.org/wiki/Zoom_levels for reference.
  
      Parameters
      ----------
      distance : float
          How many degrees of longitude should fit in the map.
  
      Returns
      -------
      int
          The zoom level, from 0 to 29.
  
      """
  
      for i in range(len(_ZOOM_LEVELS) - 1):
          if _ZOOM_LEVELS[i + 1] < distance <= _ZOOM_LEVELS[i]:
              return i
  
  
  def to_deckgl_json(data, zoom):
  
      if data is None or data.empty:
          return json.dumps(_DEFAULT_MAP)
  
      if "lat" in data:
          lat = "lat"
      elif "latitude" in data:
          lat = "latitude"
      else:
          raise Exception('Map data must contain a column named "latitude" or "lat".')
  
      if "lon" in data:
          lon = "lon"
      elif "longitude" in data:
          lon = "longitude"
      else:
          raise Exception('Map data must contain a column called "longitude" or "lon".')
  
      if data[lon].isnull().values.any() or data[lat].isnull().values.any():
          raise Exception("Latitude and longitude data must be numeric.")
  
      data = pd.DataFrame(data)
  
      min_lat = data[lat].min()
      max_lat = data[lat].max()
      min_lon = data[lon].min()
      max_lon = data[lon].max()
      center_lat = (max_lat + min_lat) / 2.0
      center_lon = (max_lon + min_lon) / 2.0
      range_lon = abs(max_lon - min_lon)
      range_lat = abs(max_lat - min_lat)
  
      if zoom == None:
          if range_lon > range_lat:
              longitude_distance = range_lon
          else:
              longitude_distance = range_lat
          zoom = _get_zoom_level(longitude_distance)
  
      lon_col_index = data.columns.get_loc(lon)
      lat_col_index = data.columns.get_loc(lat)
      final_data = []
      for _, row in data.iterrows():
          final_data.append(
              {"lon": float(row[lon_col_index]), "lat": float(row[lat_col_index])}
          )
  
      default = copy.deepcopy(_DEFAULT_MAP)
      default["initialViewState"]["latitude"] = center_lat
      default["initialViewState"]["longitude"] = center_lon
      default["initialViewState"]["zoom"] = zoom
      default["layers"] = [
          {
              "@@type": "ScatterplotLayer",
              "getPosition": "@@=[lon, lat]",
              "getRadius": 10,
              "radiusScale": 10,
              "radiusMinPixels": 3,
              "getFillColor": _DEFAULT_COLOR,
              "data": final_data,
          }
      ]
      return json.dumps(default)
  