4

Plotly Python API 可以使用 MapBox (ScatterMapbox) 制作精美的交互式地图,但无法控制地图范围。例如,如果您希望将图像保存为 PDF 或 PNG 文件并且不希望用户以交互方式缩放,那么能够控制地图范围很重要。

我面临的问题是无法直接表明您只想查看某个区域。例如,无法表明您希望地图仅显示佛罗里达州。

但是,您可以设置地图的中心和缩放级别。当您知道要显示的框的纬度/经度坐标并且您知道 CENTER 坐标时,是否有一个公式可以用来定义 ZOOM 级别?

例如,如果我希望地图以坐标 (center_lat, center_long) 为中心并进行缩放,以使可见部分具有西南坐标 (sw_lat, sw_long) 和东北坐标 (ne_lat, ne_long),什么是 MapBox ZOOM我必须提供的水平?

我意识到该公式可能取决于地图投影,这就是为什么我要具体使用 MapBox 和 Plotly。此外,我在 SO 上看到了类似的问题,但这些问题似乎都与通过 JS 使用 MapBox 相关,而不是在 Plotly Python API 中,这让我很难将解决方案翻译成我认为可以使用的东西。

4

2 回答 2

3

这是我为这个 Dash 应用程序所做的。

我创建了一个dict包含一些具有纬度、经度和缩放级别的区域。

regions = {
    'world': {'lat': 0, 'lon': 0, 'zoom': 1},
    'europe': {'lat': 50, 'lon': 0, 'zoom': 3},
    'north_america': {'lat': 40, 'lon': -100, 'zoom': 2},
    'south_america': {'lat': -15, 'lon': -60, 'zoom': 2},
    'africa': {'lat': 0, 'lon': 20, 'zoom': 2},
    'asia': {'lat': 30, 'lon': 100, 'zoom': 2},
    'oceania': {'lat': -10, 'lon': 130, 'zoom': 2},
}

然后我将Graph对象集中在使用dropdown-region Dropdown.

import plotly.graph_objs as go

@app.callback(
    output=Output('graph-geo', 'figure'),
    inputs=[Input('dropdown-map-style', 'value'),
            Input('dropdown-region', 'value')]
)
def _update_graph(map_style, region):

    layout = go.Layout(
        title='graph-title',
        mapbox=dict(
            accesstoken=mapbox_access_token,
            bearing=0,
            # center Graph object on region selected with 'dropdown-region'
            center=dict(
                lat=regions[region]['lat'],
                lon=regions[region]['lon'],
            ),
            pitch=0,
            zoom=regions[region]['zoom'],
            style=map_style,
        ),
    )
    data = go.Data([
        # data for the Graph object...
        go.Scattermapbox(...)
    ])

完整代码在这里

于 2017-10-24T20:18:18.040 回答
3

通过反复试验,我发现这个设置缩放的公式做得不错。我通过使用不同的边界框和理想的缩放级别测试地图并将其绘制到最合适的位置来确定它。

def calc_zoom(min_lat,max_lat,min_lng,max_lng):
  width_y = max_lat - min_lat
  width_x = max_lng - min_lng
  zoom_y = -1.446*math.log(width_y) + 7.2753
  zoom_x = -1.415*math.log(width_x) + 8.7068
  return min(round(zoom_y,2),round(zoom_x,2))
于 2019-03-13T15:50:12.607 回答