Фолиум: отображение цветов при добавлении GeoJson на карту - PullRequest
0 голосов
/ 05 декабря 2018

У меня есть код в моем коде Python, который добавляет функции к моей карте фолиума.Каждая функция содержится в словаре (так называемые продукты), и каждая функция имеет словарь параметров (строка и атрибуты GeoJson).Я хочу раскрасить объект на основе одного из параметров.

Сначала я создаю список уникальных значений для параметра.Затем я сопоставляю цвет каждому уникальному значению:

orb_list = [value['relativeorbitnumber'] for key, value in products.items()]
orb_list = list(set(orb_list))

color_cycle = cycler(color=['#8e0038', '#8e0073', '#59008e'], fillColor=['#8e0038', '#8e0073', '#59008e'])

orb_colors=dict([[i, sty] for i, sty in zip(orb_list, cycle(color_cycle))])

Затем я создаю цикл, в котором извлекаю цвет и fillColor, соответствующий значению параметра объекта, и использую его в style_function:

for key,value in products.items():
    footprint = json.dumps(wkt.loads(products[key]['footprint']))
    fillColor = orb_colors[products[key]['relativeorbitnumber']]['fillColor']
    color = orb_colors[products[key]['relativeorbitnumber']]['color']
    feat = folium.GeoJson(footprint,
               style_function=lambda x: {'fillColor':fillColor,'color':color},
               highlight_function=lambda feature: {'fillcolor':'green','color':'green'},
               name='Footprint')

    feat.add_to(mapa)

Я думал, что это будет работать, однако все функции, кажется, окрашены последними "fillColor" и "color" в моем цикле.Кто-нибудь может объяснить, почему это так?Я предполагаю, что объекты не отображаются до завершения всех циклов, поэтому последние значения «color» и «fillColor» используются для всех объектов.Можете ли вы предложить, как мой код должен быть изменен, чтобы обойти эту проблему?Или, может быть, я все делаю неправильно, и вы можете предложить более чистый метод?

1 Ответ

0 голосов
/ 17 декабря 2018

Вы столкнулись с общей ошибкой в ​​Python замыканиях

Функция, которую вы передаете, например, style_function, не выполняется сразу в цикле, но позже.В это время fillColor будет извлечено из внешней области (поскольку она не определена во внутренней области, созданной выражением lambda), где оно будет иметь последнее значение в этой точке.

Комупродемонстрируйте, что происходит:

In [1]: out = []
   ...: for k in ('a', 'b', 'c'):
   ...:     l = lambda: k
   ...:     out.append(l)
   ...: [l() for l in out]
Out[1]: ['c', 'c', 'c']

Чтобы предотвратить это, вы можете передать (текущее) значение переменной в качестве аргумента по умолчанию в функцию, созданную лямбда-выражением, так что это значениеиспользуется, когда функция выполняется позже:

In [2]: out = []
   ...: for k in ('a', 'b', 'c'):
   ...:     l = lambda k=k: k
   ...:     out.append(l)
   ...: [l() for l in out]
Out[2]: ['a', 'b', 'c']

Или в вашем коде:

for key, value in products.items():
    footprint = json.dumps(wkt.loads(products[key]["footprint"]))
    fillColor = orb_colors[products[key]["relativeorbitnumber"]]["fillColor"]
    color = orb_colors[products[key]["relativeorbitnumber"]]["color"]
    feat = folium.GeoJson(
        footprint,
        style_function=lambda x, fillColor=fillColor, color=color: {
            "fillColor": fillColor,
            "color": color,
        },
        highlight_function=lambda feature: {"fillcolor": "green", "color": "green"},
        name="Footprint",
    )

    feat.add_to(mapa)

Это должно решить проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...