Упорядочивание координат полигона для построения

У меня есть сетка модели, состоящая из множества ячеек, для которых я хотел бы построить затененный многоугольник на matplotlib basemap.

Используя pyproj, я сначала спроецировал точки, прежде чем создать полигон, используя класс Polygon shapely.geometry для извлечения внешних координат сетки. Затем я возвращаю их обратно в WGS84 для передачи моей функции построения графика:

grid_x_mesh, grid_y_mesh = pyproj.transform(wgs84, nplaea, grid_lons, grid_lats)
grid_x = grid_x_mesh.ravel()
grid_y = grid_y_mesh.ravel()
grid_poly = Polygon(zip(grid_x, grid_y))
grid_x, grid_y = grid_poly.exterior.coords.xy
grid_plons, grid_plats = pyproj.transform(nplaea, wgs84, grid_x, grid_y)

Затем, используя метод matplotlib.basemap, я спроецировал координаты WSG84 на проекцию карты (в данном случае nplaea) и

grid_poly_x, grid_poly_y = m(grid_plons, grid_plats)
grid_poly_xy = zip(grid_poly_x, grid_poly_y)
grid_poly = Polygon(grid_poly_xy, facecolor='red', alpha=0.4)
plt.gca().add_patch(grid_poly)

При попытке сделать это я получаю перекрестный шаблон, который, как я полагаю, должен выполнять упорядочение координат, которые я предоставил функции многоугольника.

Я бы подумал, что это связано либо с тем, как я извлек внешние координаты, либо просто с порядком списков координат, когда я создал окончательный многоугольник для построения.

Есть ли умный способ заказать их правильно, если это проблема?

Построенный многоугольник введите здесь описание изображения

Крупный план введите здесь описание изображения


person ryanjdillon    schedule 07.02.2014    source источник


Ответы (2)


Я согласен, что есть некоторое неправильное расположение координат сетки. Как был создан grid_lons? Возможно, более чистый способ использования Pyproj с геометрией Shapely — использовать относительно новую функцию shapely.ops.transform. Например:

import pyproj
from shapely.geometry import Polygon, Point
from shapely.ops import transform
from functools import partial

project = partial(
    pyproj.transform,
    pyproj.Proj(init='epsg:4326'),  # WGS84 geographic
    pyproj.Proj(init='epsg:3575'))  # North Pole LAEA Europe

# Example grid cell, in long/lat
poly_g = Polygon(((5, 52), (5, 60), (15, 60), (15, 52), (5, 52)))

# Transform to projected system
poly_p = transform(project, poly_g)

Правильность координат должна быть сохранена посредством преобразования (при условии, что они изначально были нормальными).

person Mike T    schedule 11.02.2014
comment
Можно ли тогда построить их с помощью matplotlib.basemap, если они не были спроецированы с помощью метода map(), который включает размеры карты? - person ryanjdillon; 12.02.2014
comment
Я признаю, что никогда не использовал matplotlib.basemap, но похоже, что он обрабатывает свои собственные проекции с входными данными lon/lat (хороший пример) - person Mike T; 13.02.2014

Таааак... очевидно, метод shapely.geometry.Polygon рисовал многоугольник со всеми внутренними координатами сетки, что я понял из-за того, что grid_plons и grid_plats имели ту же длину, что и массив координат сетки np.ravel().

В итоге я просто вручную извлек внешние координаты из массивов координат сетки, прежде чем передать их методу Polygon (см. ниже). Хотя я думаю, что может быть более красивый и общий способ сделать это.

Метод извлечения вручную:

grid_x_mesh, grid_y_mesh = pyproj.transform(wgs84, nplaea, grid_lons, grid_lats)

# The coordinates must be ordered in the order they are to be drawn
[grid_x.append(i) for i in grid_x_mesh[0,:]]
[grid_x.append(i) for i in grid_x_mesh[1:-1,-1]]
# Note that these two sides of the polygon are appended in reverse
[grid_x.append(i) for i in (grid_x_mesh[-1,:])[::-1]]
[grid_x.append(i) for i in (grid_x_mesh[1:-1,0])[::-1]]

[grid_y.append(i) for i in grid_y_mesh[0,:]]
[grid_y.append(i) for i in grid_y_mesh[1:-1,-1]]
[grid_y.append(i) for i in (grid_y_mesh[-1,:])[::-1]]
[grid_y.append(i) for i in (grid_y_mesh[1:-1,0])[::-1]]

grid_poly = Polygon(zip(grid_x, grid_y))
person ryanjdillon    schedule 13.03.2014