Area

The Area represents the spatial environment of the survey. It sets the spatial bounds of the survey so it should be the first building block defined. All of the methods used to generate Layer and Coverage blocks will require the Area as an input parameter.

Creating an Area

There are three main ways to create an Area.

  1. from a shapely Polygon

  2. from a shapefile

  3. from a value specifying the resulting area

We will take a look at examples of all three. First, let’s import prospect as prospect.

import prospect

From a shapely Polygon

We can create an Area from any shapely Polygon object. Let’s create a fairly simple polygon (a pentagon) and use it to create an Area.

from shapely.geometry import Polygon
pentagon = Polygon([(0, 0), (2, 0), (2, 1), (1, 2), (0, 1)])
area_shapely = prospect.Area(name='from shapely rectangle', shape=pentagon, vis=1.0)

Area objects have the following attributes: name, shape, vis, and df.

area_shapely.name
'from shapely rectangle'
area_shapely.shape
../_images/Area_10_0.svg
area_shapely.vis
1.0
area_shapely.df
name shape vis
0 from shapely rectangle POLYGON ((0.00000 0.00000, 2.00000 0.00000, 2.... 1.0

Of these, df is the most useful because it is a geopandas GeoDataFrame containing all of the other values.

geopandas provides some plotting options for GeoDataFrame objects, so we can visually examine the resulting Area in a matplotlib plot by calling the plot() method on the df attribute.

area_shapely.df.plot()
<AxesSubplot:>
../_images/Area_14_1.png

From a shapefile

Caution

If the shapefile contains more than one polygon, only the first polygon will be used. If you want to create an Area by combining multiple polygons, you will first have to dissolve them into a single polygon.

area_shp = prospect.Area.from_shapefile(name='from shapefile', path='./data/demo_area.shp', vis=1.0, encoding="utf-8")
area_shp.df.plot();
../_images/Area_18_0.png

Note

prospect has no difficulty dealing with polygons that have interior holes.

From an area value

The final way to construct an Area object is to create a square by specifying a desired area value and an origin. This is intended to be a convenient method for use in building hypothetical surveys. The following creates an Area with an area of 100.0 sq. units with a lower left corner at (20, 20).

area_value = prospect.Area.from_area_value(
    name='from value', 
    value=100.0, 
    origin=(20.0, 20.0), 
    vis=1.0
)
area_value.df.plot()
<AxesSubplot:>
../_images/Area_23_1.png

The vis parameter

Besides defining the spatial extent of the survey, the Area also defines the surface visibility parameter of the simulation. Like all parameters, the surface visibility can be defined with a single probability value or as a scipy.stats distribution. (In the future, I hope to add additional support for a raster “surface” of visibility.)

If a single value is inappropriate for your case, surface visibility can be modeled in a variety of ways. Both a truncated normal distribution (constrained between 0 and 1) and a Beta distribution could be good options. In the case of the Beta distribution, the following heuristic can be helpful:

If \(n\) artifacts were placed in a subset of that Area, how many artifacts, \(v\), would be visible to the surveyor, assuming a perfect ideal observation rate of 1.0 and a perfect surveyor skill of 1.0?

In that case, \(\alpha = v\) and \(\beta = n - v\).

For example, if you placed 10 artifacts in an area and expected 8 to be visible, you could create a Beta distribution like this.

from scipy.stats import beta
vis_dist = beta(a=8, b=2)

And now let’s examine the shape of that distribution.

Attention

seaborn, used here for plotting, is not a dependency of prospect so you may not have it installed.

import seaborn as sns
hist_8_2 = sns.distplot(vis_dist.rvs(100000))
hist_8_2.set_xlim(0,1);
/usr/share/miniconda/envs/prospect-docs/lib/python3.8/site-packages/seaborn/distributions.py:2619: FutureWarning: `distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).
  warnings.warn(msg, FutureWarning)
../_images/Area_29_1.png