|
| 1 | +# PyOWM utility functions usage example |
| 2 | + |
| 3 | +PyOWM provides a few packages that contain utility functions. |
| 4 | + |
| 5 | +Some of them are specifically designed to be used by the core PyOWM classes but others you can use to make your life |
| 6 | +easier when operating PyOWM! |
| 7 | + |
| 8 | +All utility modules live inside the `pyowm.utils` package |
| 9 | + |
| 10 | +Here are most useful modules: |
| 11 | + |
| 12 | + * `config`: handling of PyOWM configuration |
| 13 | + * `formatting`: formatting of timestamp entities (Python native types, UNIX epochs and ISO-8601 strings) |
| 14 | + * `geo`: handling of geographic entities such as points, polygons and their geoJSON representation |
| 15 | + * `measureables`: conversions among physical units (eg. temperature, wind) |
| 16 | + * `timestamps`: human friendly timestamps generation |
| 17 | + |
| 18 | + |
| 19 | +## `config` module |
| 20 | +```python |
| 21 | +from pyowm.utils.config import get_default_config, get_default_config_for_subscription_type, \ |
| 22 | + get_default_config_for_proxy, get_config_from |
| 23 | + |
| 24 | +config_dict = get_default_config() # loads the default config dict |
| 25 | +config_dict = get_default_config_for_subscription_type('professional') # loads the config dict for the specified subscription type |
| 26 | +config_dict = get_config_from('/path/to/configfile.json') # loads the config dict from the specified JSON file |
| 27 | +config_dict = get_default_config_for_proxy('http_url', 'https_url') # loads the config dict to be used behind a proxy whose URLs are specified |
| 28 | +``` |
| 29 | + |
| 30 | +## `formatting` module |
| 31 | +```python |
| 32 | +from datetime import datetime as dt |
| 33 | +from pyowm.utils import formatting |
| 34 | + |
| 35 | +unix_value = formatting.timeformat(dt.today(), 'unix') # from datetime to UNIX |
| 36 | +iso_str_value = formatting.timeformat(dt.today(), 'iso') # from datetime to ISO-8601 string |
| 37 | +datetime_value = formatting.timeformat(1590100263, 'date') # from UNIX to datetime |
| 38 | +iso_str_value = formatting.timeformat(1590100263, 'iso') # from UNIX to ISO-8601 string |
| 39 | +datetime_value = formatting.timeformat('2020-05-21 22:31:03+00', 'date') # from ISO-8601 string to datetime |
| 40 | +unix_value = formatting.timeformat('2020-05-21 22:31:03+00', 'unix') # from ISO-8601 string to UNIX |
| 41 | +``` |
| 42 | + |
| 43 | +## `geo` module |
| 44 | + |
| 45 | +The module provides classes to represent geometry features: |
| 46 | + - `Point` |
| 47 | + - `Multipoint` (aka point set) |
| 48 | + - `Polygon` |
| 49 | + - `Multipolygon` (aka polygon set) |
| 50 | + |
| 51 | +Geometry features are used eg. in OWM Alert API to provide geographical boundaries for alert setting. |
| 52 | + |
| 53 | +PyOWM uses standard geometry types defined by the [GeoJSON Format Specification - RFC 7946](https://tools.ietf.org/html/rfc7946) data interchange format. |
| 54 | + |
| 55 | +### Common geometry methods |
| 56 | + |
| 57 | +All geometry types can be dumped to a GeoJSON string and to a Python `dict` |
| 58 | + |
| 59 | +```python |
| 60 | +from pyowm.utils import geo |
| 61 | +point = geo.Point(20.8, 30.9) |
| 62 | +point.geojson() # '{"type": "Point", "coordinates": [20.8, 30.9]}' |
| 63 | +point.to_dict() # {'type': 'Point', 'coordinates': [20.8, 30.9]} |
| 64 | +``` |
| 65 | + |
| 66 | +All geometry types also feature a static factory method: you provide the dictionary and the factory returns the object |
| 67 | +instance |
| 68 | + |
| 69 | +```python |
| 70 | +from pyowm.utils.geo import Point |
| 71 | +point_dict = {'type': 'Point', 'coordinates': [20.8, 30.9]} |
| 72 | +point = Point.from_dict(point_dict) |
| 73 | +``` |
| 74 | + |
| 75 | +Please refer to the GeoJSON specification about how to properly format the dictionaries to be given the factory methods |
| 76 | + |
| 77 | + |
| 78 | +### `Point` class |
| 79 | + |
| 80 | +A point is a couple of geographic coordinates: longitude and latitude |
| 81 | + |
| 82 | +```python |
| 83 | +from pyowm.utils import geo |
| 84 | +lon = 20.8 |
| 85 | +lat = 30.9 |
| 86 | +point = geo.Point(lon, lat) |
| 87 | +coords = point.lon, point.lat # 20.8, 30.9 |
| 88 | +``` |
| 89 | + |
| 90 | +As circle shapes are not part of the GeoJSON specification, you can approximate the circle having a specific `Point` instance |
| 91 | +at its center with a square polygon: we call it bounding square polygon. You just need to provide the radius of the |
| 92 | +circle you want to approximate (in kms): |
| 93 | + |
| 94 | +```python |
| 95 | +from pyowm.utils import geo |
| 96 | +point = geo.Point(20.8, 30.9) |
| 97 | +polygon = point.bounding_square_polygon(inscribed_circle_radius_km=2.0) # default radius: 10 km |
| 98 | +``` |
| 99 | + |
| 100 | +Please, notice that if you specify big values for the radius you need to take care about the projection of geographic |
| 101 | +coordinates on a proper geoid: this means that if you don't, the polygon will only _approximate_ a square. |
| 102 | + |
| 103 | + |
| 104 | +### From City IDs to `Point` objects |
| 105 | + |
| 106 | +The City ID Registry class can return the geopoints that correspond to one or more named cities: |
| 107 | + |
| 108 | +```python |
| 109 | +import pyowm |
| 110 | +owm = pyowm.OWM('your-API-key') |
| 111 | +reg = owm.city_id_registry() |
| 112 | +list_of_geopoints = reg.geopoints_for('London', country='GB') |
| 113 | +``` |
| 114 | + |
| 115 | +This, in combination with the `bounding_square_polygon` method, makes it possible to easily get polygons to cover large |
| 116 | +squared areas centered on largely spread city areas - such as London,GB itself: |
| 117 | + |
| 118 | +```python |
| 119 | +london_city_centre = geopoints[0] |
| 120 | +london_city_bounding_polygon = london_city_centre.bounding_square_polygon(inscribed_circle_radius_km=12) |
| 121 | +``` |
| 122 | + |
| 123 | +### `MultiPoint` class |
| 124 | + |
| 125 | +A `MultiPoint` object represent a set of `Point` objects |
| 126 | + |
| 127 | +```python |
| 128 | +from pyowm.utils.geo import Point, MultiPoint |
| 129 | +point_1 = Point(20.8, 30.9) |
| 130 | +point_2 = Point(1.2, 0.4) |
| 131 | + |
| 132 | +# many ways to instantiate |
| 133 | +multipoint = MultiPoint.from_points([point_1, point_2]) |
| 134 | +multipoint = MultiPoint([20.8, 30.9], [1.2, 0.4]) |
| 135 | + |
| 136 | +multipoint.longitudes # [20.8, 1.2] |
| 137 | +multipoint.latitudes # [30.9, 0.4] |
| 138 | +``` |
| 139 | + |
| 140 | + |
| 141 | +### `Polygon` class |
| 142 | + |
| 143 | +A `Polygon` object represents a shape made by a set of geopoints, connected by lines. Polygons are allowed to have "holes". |
| 144 | +Each line of a polygon must be closed upon itself: this means that the last geopoint defined for the line _must_ coincide |
| 145 | +with its first one. |
| 146 | + |
| 147 | +```python |
| 148 | +from pyowm.utils.geo import Polygon, Point |
| 149 | +point_1_coords = [2.3, 57.32] |
| 150 | +point_2_coords = [23.19, -20.2] |
| 151 | +point_3_coords = [-120.4, 19.15] |
| 152 | +point_1 = Point(point_1_coords) |
| 153 | +point_2 = Point(point_2_coords) |
| 154 | +point_3 = Point(point_3_coords) |
| 155 | + |
| 156 | + |
| 157 | +# many ways to instantiate |
| 158 | +line = [point_1_coords, point_2_coords, point_3_coords , point_1_coords] # last point equals the first point |
| 159 | +polygon = Polygon([line]) |
| 160 | +line = [point_1, point_2, point_3, point_1] # last point equals the first point |
| 161 | +polygon = Polygon.from_points([line]) |
| 162 | +``` |
| 163 | + |
| 164 | +# `MultiPolygon` class |
| 165 | + |
| 166 | +A `MultiPolygon` object represent a set of `Polygon` objects |
| 167 | +Same philosophy here as for `MultiPoint` class, polygons can cross: |
| 168 | + |
| 169 | +```python |
| 170 | +from pyowm.utils.geo import Point, Polygon, MultiPolygon |
| 171 | +point_1 = Point(20.8, 30.9) |
| 172 | +point_2 = Point(1.2, 0.4) |
| 173 | +point_3 = Point(49.9, 17.4) |
| 174 | +point_4 = Point(178.4, 78.3) |
| 175 | +polygon_1 = Polygon.from_points([point_1, point_2, point_3, point_1]) |
| 176 | +polygon_2 = Polygon.from_points([point_3, point_4, point_2, point_3]) |
| 177 | + |
| 178 | +multipoint = MultiPolygon.from_polygons([polygon_1, polygon_2]) |
| 179 | +``` |
| 180 | + |
| 181 | +### Building geometries |
| 182 | + |
| 183 | +There is a useful factory method for geometry types, which you can use to turn a geoJSON-formatted dictionary into the |
| 184 | +corresponding topology type: |
| 185 | + |
| 186 | +```python |
| 187 | +from pyowm.utils.geo import GeometryBuilder |
| 188 | +point_dict = { |
| 189 | + "type": "Point", |
| 190 | + "coordinates": [53, 37] |
| 191 | +} |
| 192 | +point = GeometryBuilder.build(point_dict) # this is a `Point` instance |
| 193 | + |
| 194 | +wrongly_formatted_dict = {"a": 1, "b": 99} |
| 195 | +GeometryBuilder.build(wrongly_formatted_dict) # you get an exception |
| 196 | +``` |
| 197 | + |
| 198 | + |
| 199 | +## `measurables` module |
| 200 | +This module provides utilities numeric conversions |
| 201 | + |
| 202 | +### Temperature |
| 203 | +You have a `dict` whose values represent temperature units in Kelvin: you can convert them to Fahrenheit and Celsius. |
| 204 | + |
| 205 | +```python |
| 206 | +from pyowm.utils import measurables |
| 207 | + |
| 208 | +fahrenheit_temperature_dict = measurables.kelvin_dict_to(kelvin_temperature_dict, 'fahrenheit') |
| 209 | +celsius_temperature_dict = measurables.kelvin_dict_to(kelvin_temperature_dict, 'celsius') |
| 210 | +``` |
| 211 | + |
| 212 | +### Wind |
| 213 | +On the same line as temperatures, you can convert wind values among meters/sec, kilometers/hour, miles/hour, knots and |
| 214 | +the Beaufort scale. The pivot unit of measure for wind is meters/sec |
| 215 | + |
| 216 | + |
| 217 | +```python |
| 218 | +from pyowm.utils import measurables |
| 219 | + |
| 220 | +kmhour_wind_dict = measurables.metric_wind_dict_to_km_h(msec_wind_dict) |
| 221 | +mileshour_wind_dict = measurables.metric_wind_dict_to_imperial(msec_wind_dict) |
| 222 | +knots_wind_dict = measurables.metric_wind_dict_to_knots(msec_wind_dict) |
| 223 | +beaufort_wind_dict = measurables.metric_wind_dict_to_beaufort(msec_wind_dict) |
| 224 | +``` |
| 225 | + |
| 226 | + |
| 227 | +## `timestamps` module |
| 228 | +```python |
| 229 | +from pyowm.utils import timestamps |
| 230 | + |
| 231 | +timestamps.now() # Current time in `datetime.datetime` object (default) |
| 232 | +timestamps.now('unix') # epoch |
| 233 | +timestamps.now('iso') # ISO8601-formatted str (YYYY-MM-DD HH:MM:SS+00) |
| 234 | + |
| 235 | +timestamps.tomorrow() # Tomorrow at this time |
| 236 | +timestamps.tomorrow(18, 7) # Tomorrow at 6:07 PM |
| 237 | +timestamps.yesterday(11, 27) # Yesterday at 11:27 AM |
| 238 | + |
| 239 | +timestamps.next_three_hours() # 3 hours from now |
| 240 | +timestamps.last_three_hours(date=timestamps.tomorrow()) # tomorrow but 3 hours before this time |
| 241 | + |
| 242 | +timestamps.next_hour() |
| 243 | +timestamps.last_hour(date=timestamps.yesterday()) # yesterday but 1 hour before this time |
| 244 | + |
| 245 | + |
| 246 | +# And so on with: next_week/last_week/next_month/last_month/next_year/last_year |
| 247 | +``` |
0 commit comments