Повторный список последних пунктов - PullRequest
1 голос
/ 13 июня 2019

Приведенный ниже код считывает данные о местонахождении действительных ASOS (станций наблюдения за погодой) по всему миру.Я хотел бы использовать этот список в будущем как список точек для построения графика данных, но многие станции расположены слишком близко друг к другу, чтобы их можно было просматривать в масштабе страны или даже на уровне штата.Я хотел бы уменьшить плотность станций, которые нанесены на карту.Ниже приведен некоторый код, который отображает все станции в США / южной Канаде:

import re

fh = open('../498/stations.txt', 'r')
lines = fh.readlines()

data = []
for line in lines:
    comment_match = re.search('^!', line)
    blank_match = re.search('^\s*$', line)
    header_match = re.search('\d{2}-\w{3}-\d{2}|CD\s+STATION', line)
    if comment_match or blank_match or header_match:
        None
    else:
        ICAO = line[20:24].strip()
        if len(ICAO) == 4:
            CD = line[0:3].strip()
            if len(CD) == 0:
                CD = None
            STATION = line[3:20].strip()
            LATLON = line[39:54]
            if LATLON[5] == 'S':
                LAT = float("{0:.2f}".format(-(float(LATLON[0:2])+float(LATLON[3:5])/60.)))
            if LATLON[5] == 'N':
                LAT = float("{0:.2f}".format((float(LATLON[0:2])+float(LATLON[3:5])/60.)))
            if LATLON[14] == 'W':
                LON = float("{0:.2f}".format(-(float(LATLON[8:11])+float(LATLON[12:14])/60.)))
            if LATLON[14] == 'E':
                LON = float("{0:.2f}".format((float(LATLON[8:11])+float(LATLON[12:14])/60.)))
            ELEV = int(line[54:59].strip())
            C = line[81:-1]
            stn_dict = {'name':STATION, 'id':ICAO, 'state':CD, 'country':C, 'lat':LAT, 'lon':LON, 'elev':ELEV}
            data.append(stn_dict)

import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib.pyplot as plt

extent = [-130,-60,20,60]

fig = plt.figure(figsize=(15,12))
ax = fig.add_subplot(111,projection=ccrs.Miller())
ax.coastlines(resolution='50m')
ax.add_feature(cfeature.STATES.with_scale('50m'))
ax.set_extent(extent,crs=ccrs.Miller())

for stndict in data:
    if stndict['lon'] > extent[0] and stndict['lon'] < extent[1] and stndict['lat'] > extent[2] and stndict['lat'] < extent[3]:
        plt.plot(stndict['lon'], stndict['lat'], color='blue', marker='o',
         transform=ccrs.PlateCarree())

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

Существуют ли библиотеки, которые облегчили бы эту задачу?

1 Ответ

0 голосов
/ 14 июня 2019

MetPy имеет функцию reduce_point_density, которая может делать то, что вы хотите.Эта функция принимает местоположение вашей станции в виде (количество точек) х размеров (например, 2 или 3), а также радиус, минимальное расстояние до ближайшей точки в результате.В результате получается логический массив, который можно использовать в качестве маски для выбора точек интереса.Вы можете использовать его следующим образом:

from metpy.calc import reduce_point_density
import numpy as np
point_locs = np.array([(10, 50), (11, 49), (35, 40)])
mask = reduce_point_density(point_locs, 4.)
keep_points = point_locs[mask]

Вы также можете при желании передать массив значений приоритета, который позволяет контролировать, какие точки предпочтительно выбираются для сохранения.Более крупный пример использования reduce_point_density - здесь .

...