The control argument of the polarMap() family and trajMap(), deprecated in favour of type in openairmaps 0.9.0, has been removed. The deprecated facet argument (from polarMapStatic()) is also no longer recognised. Please use type instead; the polarMap() family will raise an error pointing to type if either is used. Note that control in networkMap() is unaffected.
trajMapStatic() and trajLevelMapStatic() have both been removed from openairmaps. Users should now use openair::trajPlot() or openair::trajLevel() directly.
The "layer control" menus of the polarMap() family and trajMap() now list type levels in the order of their factor levels (e.g., "Monday" before "Tuesday"), and multiple pollutants in the order they were given, rather than the order they first appear in the data.
trajMap() and trajLevelMap() now take latitude before longitude, in line with the rest of the package. Both now default to NULL, and are guessed from data in the same way as the polarMap() family.
trajMap() now uses cols = "turbo" by default, in line with the rest of the package. It also now errors if colour is neither a column of data nor a valid colour, rather than silently passing it on to {leaflet} (e.g., when a column name is misspelled).
The default vgm in krigingMap() now has a range of 50 rather than 50,000. As the data are in latitude and longitude, {gstat} measures this in kilometres, so the previous default was far larger than intended.
polar_data now includes the site code as a column, and columns have been reordered to better match the return values of openair::importUKAQ().
polarMap() and annulusMap() gain the breaks argument, in line with the breaks argument now in openair::polarPlot() and openair::polarAnnulus(). This bins the markers' colour scale into discrete intervals, and can take a numeric vector of breakpoints, a single number of intervals, or a list created using openair::breakOpts(). In all cases, a single set of breakpoints is calculated across all of the markers so that they can share a legend. breaks overrides limits if both are provided.
Shared legends in the polarMap() family have been standardised, and now reflect the colour scale {openair} actually used to draw the markers:
Markers with a discrete colour scale now get a shared legend of labelled colours, as long as all markers are binned into the same intervals. limits (now supported by openair::polarFreq()) can also be passed to freqMap() via ... to get a shared continuous legend. As openair::polarFreq() uses trans = "sqrt" by default, trans = FALSE must also be passed for this legend to be drawn.
Legend labels and colours now exactly match those used by {openair}, and are the same for dynamic and static maps (e.g., "0 to 50" rather than "0 – 50" in dynamic freqMap(), pollroseMap() and windroseMap() legends).
Dynamic legends now consistently use alpha for their opacity.
Continuous legends are no longer drawn if the colour scale has been transformed using trans (e.g., polarMap(trans = "log10")), as they would be misleading. This includes freqMap() by default, as openair::polarFreq() uses trans = "sqrt". Discrete legends are unaffected, as {openair} bins the untransformed values.
{openairmaps} now re-exports breakOpts() and colourOpts() from {openair}.
addPolarMarkers() and addPolarDiffMarkers() gain the progress argument, in line with the polarMap() family, so the progress bar shown while the markers are created can be turned off.
Added pointMap(), which summarises pollutant data at each site (e.g., the mean concentration) and shows it as coloured circles on a dynamic or static map. It shares its arguments (statistic, breaks, limits, etc.) with krigingMap() and voronoiMap(), but draws no interpolated surface. All three functions also gain popup and label arguments, which work like those in polarMap() (e.g., to show site names or types when clicking on or hovering over a site marker). If popup or label includes the pollutant, the site statistic is shown, labelled as such (e.g., "NO2 (max)"). Any other numeric columns are averaged at each site.
pointMap(), krigingMap() and voronoiMap() gain the type argument, in line with the polarMap() family. Each type level is summarised (and interpolated) separately, but all levels share one colour scale. In dynamic maps, type levels can be switched between using a "layer control" menu (customised using control.collapsed, control.position and control.autotext), and in static maps they appear in separate panels (arranged using static.nrow). Other arguments can be passed to openair::cutData() using ....
Added addTrajLevel(), which allows users to add gridded trajectory statistics (calculated using openair::trajLevel()) to any leaflet map, much like addTrajPaths() does for individual trajectories. This offers more control over groups and layerIds than trajLevelMap(), which now uses addTrajLevel() internally.
addTrajPaths() gains a markerColor argument, allowing the point markers along a trajectory to be coloured independently of the trajectory line itself (e.g., by a continuously-varying pollutant). trajMap() now uses this internally instead of duplicating addTrajPaths()'s marker/line-drawing logic.
addTrajPaths() is now much faster when layerId is used, as the points along each trajectory are added to the map in a single call rather than one at a time. The layer IDs themselves are unchanged.
trajLevelMap() now passes ... to openair::cutData() (e.g., type = "season", hemisphere = "southern"), in line with trajMap(). Its pollutant argument also now defaults to NULL, in line with the rest of the package.
The popups in trajMap(), addTrajPaths(), trajLevelMap() and addTrajLevel() have been restyled to match those in networkMap(). For trajectory paths, arrival and trajectory dates now always show the time, and the colour variable in trajMap() (e.g., a pollutant) is shown in its own row at the bottom of the popup. For gridded trajectories, the popup leads with the value and a description of the statistic, followed by the grid cell location, count and (if used) the type level.
buildPopup() popups have also been restyled to match those in networkMap(), with each column shown as a grey label alongside its value. This also applies to popups built automatically when several popup columns are passed to the polarMap() family, pointMap(), krigingMap() and voronoiMap().
buildPopup() gains the name argument, which sets the name of the new popup column ("popup" by default). buildPopup() now errors if this column already exists in data, rather than returning duplicated popup.x and popup.y columns.
networkMap() can now take any option passed to openair::importMeta(). This behaviour supersedes all of the functionality within searchNetwork(), which has been removed. It also no longer overwrites the default year argument, and so behaves identically to openair::importMeta().
trajMap(), trajLevelMap(), krigingMap() and voronoiMap() now accept any number of basemaps through provider, which can be named to customise their labels in the layer control menu (e.g., c("Default" = "OpenStreetMap", "Satellite" = "Esri.WorldImagery")), in line with polarMap() and networkMap().
The "layer control" menu is now built the same way across all interactive maps. In particular, only the first basemap is shown when multiple are provided, and a single basemap is no longer listed in the menu as there is nothing to switch to.
Static maps gain the api_key argument, passed to the equivalent argument in ggspatial::annotation_map_tile().
Markers which {openair} fails to draw (e.g., due to insufficient data at a site) are now consistently skipped by the polarMap() family. Previously, dynamic maps would show a broken image in their place (and list it in the layer control menu), and static maps would error.
The polarMap() family no longer errors when a single pollutant is passed to popup or label (e.g., polarMap(polar_data, "no2", popup = "no2")). Pollutants in popups and labels now show their mean at each marker, labelled as such (e.g., "NO2 (mean)"), whether one or several popup columns are given. Other numeric columns are averaged and labelled the same way, so a single non-pollutant numeric popup or label (e.g., polarMap(polar_data, "nox", popup = "no2")) no longer errors either.
diffMap() no longer errors when multiple columns are passed to popup.
Columns of data named "popup" or "label" can now be used in the popup and label arguments of the polarMap() family, pointMap(), krigingMap() and voronoiMap(). Previously, they could be overwritten by the package's own popup and label columns (e.g., polarMap(popup = "label") showed "NA" in every popup, and pointMap(popup = c("popup", "site")) showed no popups at all).
addPolarMarkers() now drops rows where the chosen pollutant is missing, rather than where no2 is missing. Previously, it would error if data did not contain a no2 column.
polarMap(limits = "fixed") now uses the same upper as the markers when calculating the shared limits, so the limits better cover the markers' colour scales.
percentileMap(intervals = "fixed") now passes percentile and ... to openair::percentileRose() when calculating the shared intervals, so they cover all of the plotted percentiles.
The colours in the dynamic percentileMap() legend now match those of the markers.
freqMap(breaks = "fixed") no longer errors when trans is passed via ....
percentileMap() no longer warns that "fixed" intervals only work with a single pollutant when several pollutants are given, unless intervals = "fixed" was explicitly set. As before, each marker then uses its own intervals. This warning (also given by polarMap(), annulusMap() and freqMap()) now names the relevant argument.
The legend title of freqMap(statistic = "frequency") is now capitalised ("Frequency"), in line with the other polarMap() family legends.
The warning given by diffMap() when before and after don't match now refers to type, rather than the removed control argument.
krigingMap() and voronoiMap() now give an informative error if pollutant is not provided, in line with the polarMap() family.
krigingMap() and voronoiMap() now give an informative error if statistic isn't recognised.
Static krigingMap() and voronoiMap() maps now respect provider, rather than always using OpenStreetMap. Both functions also now validate provider in the same way as the polarMap() family.
krigingMap() and voronoiMap() no longer leave sites or parts of the surface uncoloured when the data fall outside breaks. The outermost breaks are now expanded to cover the data (e.g., breaks = c(50, 100, 150) becomes c(25, 100, 200) for data ranging from 25 to 200), and values equal to the lowest break are now included. This also applies to the new pointMap().
krigingMap(statistic = "sd") and voronoiMap(statistic = "sd") now treat the standard deviation of sites with a single measurement as missing, rather than using the measurement itself.
krigingMap() and voronoiMap() now give values outside limits the colour of the nearest limit, as in {openair}. Previously, they were left uncoloured. This also applies to the new pointMap().
krigingMap() and voronoiMap() now give an informative error if more than one pollutant is given, or if the pollutant, popup or label columns can't be found in data. Previously, multiple pollutants gave a cryptic error, and a missing popup or label column was silently ignored.
krigingMap() no longer prints {gstat}'s progress (e.g., "[inverse distance weighted interpolation]") for every type level. This can be turned back on using args.idw or args.krige (e.g., args.idw = list(debug.level = 1)). voronoiMap() also no longer warns that "attribute variables are assumed to be spatially constant", and static maps in the polarMap() family no longer warn that "st_point_on_surface may not give correct results for longitude/latitude data".
Dynamic krigingMap() and voronoiMap() legends now use alpha for their opacity, rather than always being semi-transparent. This also applies to trajMap() and addTrajLevel() (and therefore trajLevelMap()).
trajMap() and addTrajPaths() now support data with multiple receptors, as returned by openair::importTraj(). Previously, trajectories arriving at different receptors at the same time were joined into a single path.
trajLevelMap() now respects the control.collapsed and control.position arguments, which were previously ignored. Note that this means the layer control is now expanded by default (control.collapsed = FALSE), in line with trajMap().
addTrajLevel() now respects lng and lat. Previously, openair::trajLevel() would error unless the columns were named "lon" and "lat".
addTrajPaths() popups now respect lng and lat. Previously, the latitude and longitude rows were blank unless the columns were named "lon" and "lat".
trajLevelMap() and addTrajLevel() now use the correct ordinal suffix in their legend titles and popups when statistic = "difference" (e.g., "11th" rather than "11st", and "1st" rather than "1th"). Decimal percentiles now always use "th" (e.g., "92.5th" rather than "92.5nd"), including in pointMap(), krigingMap() and voronoiMap() popups.
trajMap(), trajLevelMap() and networkMap() now validate provider in the same way as the polarMap() family, giving an informative error for unrecognised basemaps and accepting the same shorthand names (e.g., "cartolight").
Dynamic maps now error if more than one legend.position or control.position is given. networkMap() now checks control.position even when control isn't used.
buildPopup() now summarises Date columns (using fun.dttm) and logical columns (using fun.character). Previously, it would error if either was included in columns.
buildPopup() now shows columns in the order given in columns. Previously, character columns were always shown first, followed by numeric and then date columns.
quickTextHTML() now correctly formats "m/s2".
The entire polarMap() family now defaults to annotate = FALSE, which removes many of the "captions" added automatically since {openair} v.3.1.0. These can be restored by passing annotate = TRUE to ....
trajLevelMap() has gained breaks in line with openair::trajLevel().
trajMapStatic() and trajLevelMapStatic() now call openair::trajMap() and openair::trajLevel(), respectively. This is an advancement towards complete removal, which will happen in a future version of openairmaps.
{openairmaps} now depends on a minimum R version of 4.1.0 and no longer exports the {magrittr} pipe (%>%). Users are encouraged to use the base R pipe (|>) instead. In most cases, this is a drop-in replacement.
{openairmaps} now requires a a minimum {openair} version of 3.0.0. Polar markers are therefore now produced using ggplot2. This has allowed the theme argument to be added to the polarMap() family, which allows for extensive customisation of polar markers. This has included the following changes:
key has been replaced with key.position, in line with deprecations in {openair}.
Polar markers will inherit any styling set using ggplot2::theme_set(). This may be unfavourable, but can be partially overriden using the new theme argument.
The polarMapStatic() family have been removed. The trajMapStatic() family are still exported but have been deprecated.
The polarMap() gains the theme argument for customising the ggplot2 theme of the markers.
Added a new 'spatial interpolation' family of functions, which rely on the suggested {stars}, {terra} and {gstat} packages. These functions are most useful for dense air quality networks, and can be useful for identifying spatial patterns and hotspots of air pollution.
krigingMap() allows for smooth spatial interpolation, either using simple inverse distance weighting or full point kriging.
voronoiMap() uses terra::voronoi to create a polygonal map of 'closest observations'.
Polar marker functions (both the polarMap() family and addPolarMarkers()) can now be run asynchronously if the user sets mirai::daemons(). Internally, this uses purrr::in_parallel().
The progress bar shown when progress = TRUE now better reflects the actual time until function completion.
networkMap() can now use source = 'imperial', in line with updates to {openair}.
This release includes several changes to make {openairmaps} more lightweight.
{ggspatial}, {prettymapr} and {ggtext}, the packages which support static mapping, have been moved to Suggests from Imports. This gives the package a smaller size for users who only use {openairmaps} for interactive mapping. On first trying to use a static mapping function, users will be prompted to install these packages.
{mgcv} has been moved to Suggests as it is only used in one place (trajLevelMap(smooth = TRUE))
convertPostcode() now uses {curl} over {httr}.
Removed dependency on {forcats}.
Removed suggested dependency on {worldmet}.
Pairwise statistics (e.g., "robust_slope") are now supported by polarMap(). (#72)
The polarMap() family has gained the progress argument, allowing users to switch the progress bar on and off.
trajMapStatic() has gained the size and linewidth arguments, which directly map onto the arguments in ggplot2::geom_point() and ggplot2::geom_path(), respectively. These can either be a column of the data (like colour), or can be an absolute value (e.g., 2L). Note that, by default, linewidth takes the value of size, but both can be set independently.
Vectors greater than length 1 passed to popup in the polarMap() argument will no longer error when type = NULL.
... will successfully pass to openair::cutData() in the polarMap() and trajMap() families of functions.
The default diffMap() colour scale will no longer appear inverted compared to openair::polarDiff().
Fixed an issue in which quickTextHTML() would incorrectly format non breaking spaces when doing, e.g., quickTextHTML("ug/m3").
The order in which trajMapStatic() draws points and paths has been tweaked, which should ensure that markers are drawn on top of their respective path, rather than on top of all paths.
buildPopup() will now work correctly if no type is provided.
BREAKING: The polarMapStatic() family is now powered by {ggspatial} rather than {ggmap} as it does not require an API key. This means the ggmap argument has been removed and the provider argument has been added. Other benefits of this switch include a greater number of available base maps (see: rosm::osm.types()) and the ability to simply change the extent of the map axes using ggplot2::coord_sf(). (#52)
BREAKING: The control and facet arguments have been deprecated in favour of type in all functions. These arguments will eventually be removed, but as of this version of {openairmaps} users will be warned away from their use. This brings {openairmaps} in-line with the {openair} package.
BREAKING: The names and cols arguments of buildPopup() have been coalesced into a single columns argument for less verbose function usage.
BREAKING: The collapse.control argument has been renamed to control.collapsed and the draw.legend argument to legend. This is to allow these options to sit more nicely with their new argument family members - legend.title, legend.title.autotext, legend.position, and so on.
The polarMapStatic() family of functions have been combined with the polarMap() family, with static maps available to be accessed using the static argument. (#59) The polarMapStatic() family are therefore deprecated, and will later be removed from {openairmaps}. The justification for this is as follows:
The combined functions allows for a more simple, consistent API for users (e.g., avoiding needing to switch between facet and control).
The use of the static argument allows for simple switching between dynamic and static maps. For example, a researcher may wish to use the dynamic maps for data exploration, but then switch to a static map for placement into a PDF report.
Recent developments have meant that the arguments and capability of these functions have started to align regardless (e.g., provider, crs).
Combining these functions has reduced repetition in the source code of {openairmaps}, reducing the likelihood of oversights and bugs, and allowing for more rapid development.
The crs argument has been added to the polarMap() and polarMapStatic() families and to searchNetwork(). This argument allows for users to specify that their data is using an alternative coordinate system to the standard longitude/latitude (e.g., the British National Grid CRS). Alternate CRS will be re-projected to longitude/latitude for plotting as this is expected by {leaflet} / {ggspatial}. (#56)
Users now have greater control over the positions of legends and layer control menus, and the titles of legends, throughout {openairmaps} functions, including the polarMap() family, trajMap() family, and networkMap().
Popups for the dynamic polarMap() family will now be near the top of the plot rather than the centre. This will obscure less of the plot itself while the marker is visible. (#55)
quickTextHTML()'s lookup table has gained new pollutants and units, and ignores the input case of text more consistently.
Two examples of the use of {openairmaps} with {shiny} have been added to the package. Run shiny::runExample(package = "openairmaps") to view these. (#60)
Legends drawn by the polarMapStatic() function should now render using more recent versions of {ggplot2}.
The addTrajPaths() layerId argument is now implemented in a sensible way to ensure each geometry has a unique layerId and can therefore be interacted with in a {shiny} context.
layerId is now the base on which the actual layerId is built, with each real layerId in the form BASE-LN-PN where LN is the line number and PN is the point number. For example, if layerId = "traj", the first point of the first line has the ID "traj-1-1", the second point of the first line has ID "traj-1-2", the first point of the second line has ID "traj-2-1", and so on."illegal" file path characters can now be used in the columns provided to the type argument of the polarMap() family. Most relevant to most users is that this will allow them to provide their own custom HTML tags - e.g., for formatting superscripts, subscripts, and so on. (#63)
The colours in the legend of networkMap() now better align with the actual colours of the markers, and the layer control menu when control = "variable" is now presented in a nicer order with clearer labels.
This is a minor release of {openairmaps}, released mainly to fix an issue with {ggmap} but also adding some new functionality for polar marker maps.
BREAKING: The arguments of addPolarMarkers() have been rejigged to move "data" after "pollutant", owing to the new use of leaflet::getMapData(). (#45)
BREAKING: The default arguments of some polarMap()-family functions have changed from, e.g., NULL to "free" or "fixed". (#34)
BREAKING: Due to changes in {ggmap}, all static polar plotting functions now require users to provide their own ggmap object. The zoom argument has also been removed. This is specifically related to the partnership of Stamen and Stadia which has put the stamen tiles behind an API. See https://maps.stamen.com/stadia-partnership/ and https://github.com/dkahle/ggmap/issues/353 for more information. (#52)
Several "limit" arguments can now take one of three options: "fixed" (which forces all markers to share scales), "free" (which allows them to use different scales), or a numeric vector to define the scales. (#34) These arguments and their defaults include:
polarMap(): upper (fixed); limits (free)annulusMap(): limits (free)freqMap(): breaks (free)percentileMap(): intervals (fixed)Added searchNetwork(), which allows users to find local air quality monitoring sites by specifying a target latitude and longitude. Function arguments allow the site metadata to be subset (for example, by site type, pollutants measured, or distance from the target).
Added convertPostcode(), which converts a valid UK postcode to a latitude/longitude pair. This is intended to be used with searchNetwork().
The "data" argument of addPolarMarkers() and addTrajPaths() and both the "before" and "after" arguments of addPolarDiffMarkers() now default to leaflet::getMapData(map). This makes their use less verbose when creating multiple polar plots with the same underlying data, which will likely be a common use-case. (#45)
networkMap() popups now contain links to the associated network websites. For example, the popup for London Marylebone Road in networkMap("aurn") now contains a link to https://uk-air.defra.gov.uk/networks/site-info?site_id=MY1. All networks are supported with the exception of "europe". (#39)
addPolarMarkers() and addPolarDiffMarkers() now have all of the "options" arguments of leaflet::addMarkers(). This means that, for example, polar markers can be clustered (https://leafletjs.com/reference.html#marker). (#38)
The polarMap() family and networkMap() provider argument can now take a named vector. The names will be used in the layer control menu, if length(provider) > 1. (#42)
This is a minor release adding a range of quality of life features, adding two new experimental functions, and fixing a few bugs.
trajMapStatic() and trajLevelMapStatic() have been added as two new experimental functions to provide {ggplot2} equivalents of openair::trajPlot() and openair::trajLevel(). (#28)
{ggplot2} incarnation of the trajectory plotting functions, but whether they will sit in {openair}, {ggopenair} or {openairmaps} and what they will be named is not clear.The control and facet arguments of all polar marker mapping functions (static and interactive) and trajectory mapping functions are now passed to openair::cutData().
The popup argument of all interactive polar marker mapping functions can now take a vector of column names. If more than one column is provided, it is automatically passed to buildPopup() using its default values.
trajLevelMap() now has the control argument, which maps directly onto the type argument of openair::trajLevel(). Like other control arguments elsewhere in {openairmaps}, this creates a "layer control" menu.
networkMap() now uses different coloured markers for different networks. If more than one network is specified, and draw.legend is set to TRUE, a legend will also be drawn for quick identification of different data sources. (#30)
Deprecations are now managed by the {lifecycle} package. This currently only applies to the type argument.
Fixed issues where multiple addPolarMarkers() chained together would all show the same plot.
Fixed issue where ... and pollutant weren't being passed to addPolarMarkers(). (#27)
Fixed issue in trajMap() caused by recent updates to {dplyr} and {forcats}.
Fixed issue where polarMapStatic() and others would turn factor facet levels into characters.
cutData(), will now be honoured by the facet argument. (#31)Fixed issue where polarMapStatic() and others would error when trying to draw a legend.
This is a minor release containing several important new features that expand the scope of the package. This also comes with several minor breaking changes to improve consistency within {openairmaps} and with {openair}.
BREAKING: The fig.width, fig.height, iconHeight and iconWidth arguments have been replaced with d.fig and d.icon. There are two main justifications behind this:
This ensures consistency across all of {openairmaps}, making it easier to switch between the static and HTML map types.
Polar markers are almost always going to be circular (i.e., width = height) so having one argument will streamline things. If users wish to have non-circular markers, a vector of length two in the form c(width, height) will provide the same functionality.
BREAKING: The arguments in addPolarMarkers() have been put in a more sensible order, leading with data, pollutant and fun.
BREAKING: The date argument from networkMap() has been replaced by year. (#26)
Added "static" equivalents of all of the polar marker maps written in {ggplot2}. While interactive HTML maps are preferred, the static equivalents may be more appropriate for, e.g., academic publications. (#19)
The {ggplot2} functions can be identified by "Static" being appended to the function name. For example, polarMap() is the {leaflet} polar plot map, whereas polarMapStatic() is the {ggplot2} equivalent.
Currently, "static" versions of the trajectory maps are served by openair::trajPlot() and openair::trajLevel(), but there may be space in future to have ggmap equivalents of these in openairmaps.
Added diffMap() and diffMapStatic() which are to openair::polarDiff() what polarMap() and polarMapStatic() are to openair::polarPlot() (#17). Also added addPolarDiffMarkers(), which is the equivalent of addPolarMarkers(). (#25)
Added alpha as an argument to all of the directional analysis polar mapping functions, not just polarMap(). (#14)
Fixed alpha to work on both Windows and MacOS by forcing the use of the "cairo" device to save plots. (#14)
Polar marker maps and addPolarMarkers() now show a progress bar when creating the markers takes more than a few seconds (most commonly in polarMap() and annulusMap(), particularly with multiple pollutants/control groups).
networkMap() can now pass the new year option to importMeta().
This is a patch release primarily to fix a few bugs in {openairmaps}, and implement a new default colour scheme after a recent {openair} update.
"turbo" colour palette rather than "jet" by default, which is still a rainbow palette but with more perceptually uniform colours.Fixed issue with polar marker maps (e.g., polarMap()) and the generic addPolarMarkers() function where lat/lon info in the Southern Hemisphere would misalign markers. Hat tip to Deanna Tuxford and James for noticing this issue. (#18)
Fixed an issue with networkMap() where control = "variable" would fail to show all pollutants.
This is a minor release, mainly focusing on enhancing the ability for polar markers to have shared colour scales, but also incorporating new features for network visualisation.
All directional analysis maps can now have their limits provided (can be "limits", "breaks", "percentiles", etc., depending on function). This was always possible through ..., but it is now explicitly listed as an option. (#12)
If limits are defined in a directional analysis function, a shared legend will now be drawn at the top-right of the map. This functionality can be disabled by setting draw.legend to FALSE. (#12)
Added the buildPopup() function, which allows users to easily construct HTML popups for use with the "popup" argument of directional analysis maps (or leaflet maps more widely).
The default options for fig.width and fig.height are now 3.5 rather than 4. This appears to remove some visual artefacts and makes the axis labels more legible.
networkMap() now supports multiple sources. For example, using source = c("aurn", "saqn") will show both the AURN and SAQN on one map. This may be useful if users are interested in air quality in a specific region of the UK (e.g., users may wish to locate AURN, AQE and locally managed sites near to a given urban centre). (#16)
networkMap() now supports source = "local".
Multiple basemap providers can now be used with networkMap().
networkMap(), trajMap() and all polar directional analysis maps have gained the collapse.control argument, which controls whether the control menu starts collapsed or not. It defaults to FALSE, which means the control menu is not collapsed.
All documentation has been improved; function parameters are more consistent between functions and arguments passed to openair via ... are now explicitly listed.
polarMap() as it only ever worked for polarMap().This is a patch release designed to fix a major bug in v0.5.0.
This is a minor release centred around the addition of the control argument, which allows for arbitrary columns to be used in "layer control" menus.
All functions now use latitude and longitude to distinguish between site types. Therefore, "type" is now deprecated. Maps using the old system will still render, but popups will not be displayed. For most users, to restore previous site labels simply rewrite type = "site" as popup = "site". (#10)
The default values for "pollutant" have all been removed. Any users relying on this default should update their code to explicitly state pollutant = "nox".
All functions now possess the "control" argument, which allows users to create a "layer control" menu with any arbitrary column. Appropriate columns may be those produced using openair::cutData(), openair::splitByDate(), or a user-defined dplyr::case_when()/dplyr::if_else() column transformation. (#9)
All functions now possess the "popup" and "label" arguments, which control pop-up and hover-over labels, respectively. This allows users to define any popup or label column, even non-unique ones. For example, multiple sites can be labelled with identical site types. (#10)
All functions now try to guess the latitude/longitude column if not provided, similar to {leaflet}. (#10)
Updated many error messages and warnings to use {cli} and be broadly more descriptive.
trajMap() can now be coloured by date.
Fixed issue with trajMap() that would cause user-defined colours not to work.
This is a patch release adding a small number of refinements.
polar_data column names changed from "latitude" to "longitude" to "lat" and "lon" to reflect the defaults of the polarMap() family.
trajMap() and trajLevelMap() now use the argument names "latitude" and "longitude" to match those of the polarMap() family.
trajLevelMap() now contains the lat.inc and lon.inc arguments.This is a patch release to fix a bug with trajLevelMap().
trajLevelMap() now works where statistic = "frequency" without a "pollutant".This is the first CRAN release of {openairmaps}.
There are currently three streams of functionality in openairmaps:
networkMap() visualises any of the openair::importMeta() networks.
polarMap() and family allow for any of the openair directional analysis plots to be used as leaflet markers.
trajMap() and family are leaflet equivalents to openair::trajPlot() and openair::trajMap().
There are two main classes of functions:
*Map() functions are easy-to-use functions which create leaflet maps from the ground-up. These are the most similar to openair functions.
add*() functions are more flexible and allow users to add layers to existing leaflet maps. These are designed to be similar to the leaflet "add" functions like addMarkers().