geowatch.demo.metrics_demo.demo_truth module

Functions to creates random “true” region and site models for demodata.

class geowatch.demo.metrics_demo.demo_truth.RegionModelGenerator[source]

Bases: object

Note

A good refactor to this random data design would be to have a class which holds all the parameters to generate random site / region models. For now we are using this as a placeholder to store constants.

Todo

Transfer the functionality of random_region_model here.

class geowatch.demo.metrics_demo.demo_truth.SiteModelGenerator[source]

Bases: object

Todo

Transfer the functionality of random_site_model here.

SITE_PHASES = ['No Activity', 'Site Preparation', 'Active Construction', 'Post Construction']
geowatch.demo.metrics_demo.demo_truth.random_region_model(region_id=None, region_poly=None, num_sites=3, num_observations=5, p_observe=0.5, p_transition=0.15, start_time=None, end_time=None, with_renderables=True, site_poly=None, rng=None, start_date=None, end_date=None, start_site_index=0)[source]

Generate a random region model with random sites and observation support.

The region model is generated simply by sampling a random polygon in geospace that isn’t too big or too small.

Then observation support simulates images that we have from this region. These supporting images might be from different simulated sensors or in different resolutions. They may contain partial coverage of the region.

The sites are randomly sampled polygons inside the region and are assigned to specific observation as they would be if they were generated for real imagery. Sites have a simple model that allows them to evolve over time, change shape / size and their phase label.

Parameters:
  • region_id (str | None) – Name of the region. If unspecified, a random one is created.

  • region_poly (kwimage.Polygon | shapely.geometry.Polygon | None) – if specified use this crs84 region polygon, otherwise make a random one.

  • num_sites (int) – number of random sites

  • num_observations (int) – number of random observations

  • p_observe (float) – the probability that a site model is annotated in any particular observation.

  • p_transition (float) – truth phase transition model. Currently just the probability the phase changes on any particular observation.

  • with_renderables (bool) – if False dont generate renderables.

  • start_time (Any) – min time coercable

  • end_time (Any) – max time coercable

  • site_poly (kwimage.Polygon | shapely.geometry.Polygon | None) – if specified, this polygon is used as the geometry for new site models. Note: all site models will get this geometry, so typically this is only used when num_sites=1.

  • rng (int | str | RandomState | None) – seed or random number generator

  • start_site_index (int) – the index of the first generated site. Defaults to 0

Returns:

A region model and its corresponding site models and renderables

Return type:

Tuple[geojson.FeatureCollection, List[geojson.FeatureCollection], List | None]

Example

>>> from geowatch.demo.metrics_demo.demo_truth import *  # NOQA
>>> region, sites, renderables = random_region_model(num_sites=2, num_observations=5, p_observe=0.5, rng=0)
>>> print('region = {}'.format(ub.urepr(region, nl=4, precision=6, sort=0)))
...
region = {

‘type’: ‘FeatureCollection’, ‘features’: [

{

‘type’: ‘Feature’, ‘geometry’: {

‘type’: ‘Polygon’, ‘coordinates’: …

}, ‘properties’: {

‘type’: ‘region’, ‘region_id’: ‘DR_R684’, ‘version’: ‘2.4.3’, ‘mgrs’: ‘51PXM’, ‘start_date’: ‘2011-05-28’, ‘end_date’: ‘2018-09-13’, ‘originator’: ‘demo-truth’, ‘model_content’: ‘annotation’, ‘comments’: ‘demo-data’,

},

}, {

‘type’: ‘Feature’, ‘geometry’: {

‘type’: ‘Polygon’, ‘coordinates’: …

}, ‘properties’: {

‘type’: ‘site_summary’, ‘status’: ‘positive_annotated’, ‘version’: ‘2.0.1’, ‘site_id’: ‘DR_R684_0000’, ‘mgrs’: ‘51PXM’, ‘start_date’: ‘2015-03-16’, ‘end_date’: ‘2018-09-13’, ‘score’: 1, ‘originator’: ‘demo’, ‘model_content’: ‘annotation’, ‘validated’: ‘True’, ‘misc_info’: {‘color’: [0.551139, 1.000000, 0.000000]},

},

}, {

‘type’: ‘Feature’, ‘geometry’: {

‘type’: ‘Polygon’, ‘coordinates’: …

}, ‘properties’: {

‘type’: ‘site_summary’, ‘status’: ‘positive_annotated’, ‘version’: ‘2.0.1’, ‘site_id’: ‘DR_R684_0001’, ‘mgrs’: ‘51PXM’, ‘start_date’: ‘2011-05-28’, ‘end_date’: ‘2018-09-13’, ‘score’: 1, ‘originator’: ‘demo’, ‘model_content’: ‘annotation’, ‘validated’: ‘True’, ‘misc_info’: {‘color’: [1.000000, 0.367780, 0.000000]},

},

},

],

}

geowatch.demo.metrics_demo.demo_truth.random_observables(num_observations, start_time=None, end_time=None, rng=None)[source]

Create a random sequence of sensor observations

Parameters:
  • num_observations (int) – number of observations

  • start_time (Any) – min time coercable

  • end_time (Any) – max time coercable

  • rng – random seed or generator

Returns:

list of each item corresonding to a simulated observable

Return type:

List[dict]

Example

>>> # xdoctest: +SKIP("failing on CI. unsure why")
>>> from geowatch.demo.metrics_demo.demo_truth import *  # NOQA
>>> num_observations = 2
>>> observables = random_observables(1, rng=32)
>>> print('observables = {}'.format(ub.urepr(observables, nl=2)))
observables = [
    {
        'datetime': datetime.datetime(2018, 8, 3, 16, 55, 35, 398921),
        'mgrs_code': None,
        'sensor_name': 'demosat-2',
        'source': 'demosat-220180803T165535',
        'wld_polygon': None,
    },
]
geowatch.demo.metrics_demo.demo_truth.random_site_model(region_id, site_id, region_corners, observables, site_poly=None, p_observe=0.5, p_transition=0.15, rng=None)[source]

Make a dummy sequence somewhere within a region’s observed spacetime grid.

Parameters:
  • region_id (str) – the name of the region we generate this site for

  • site_id (str) – the name of the site

  • region_corners (ndarray) – corners of the region to embed this site in.

  • observables (List[Dict]) – information about opportunities to generate an observation

  • p_observe (float) – the probability that a site model is annotated in any particular observation.

  • p_transition (float) – truth phase transition model. Currently just the probability the phase changes on any particular observation.

  • site_poly (kwimage.Polygon | shapely.geometry.Polygon | None) – if specified, force the site to have this geometry.

  • rng – random state or seed

Returns:

site_summary, site

Return type:

Tuple[Dict, Dict]

Example

>>> # xdoctest: +SKIP("failing on CI. unsure why")
>>> from geowatch.demo.metrics_demo.demo_truth import *  # NOQA
>>> region_id = 'DR_0042'
>>> site_id = 'DR_0042_9001'
>>> rng = kwarray.ensure_rng(0)
>>> region_corners = kwimage.Boxes([[0, 0, 1, 1]], 'xywh').to_ltrb().corners()
>>> observables = random_observables(1, rng=rng)
>>> p_observe = 1.0
>>> site_summary, site = random_site_model(region_id, site_id, region_corners, observables,
>>>                                        p_observe=p_observe, rng=rng)
>>> print('site = {}'.format(ub.urepr(site, nl=4, sort=0)))
site = {
    'type': 'FeatureCollection',
    'features': [
        {
            'type': 'Feature',
            'geometry': {
                'type': 'Polygon',
                'coordinates': [[[0.759303, 0.749121], [0.717993, 0.763785], [0.719567, 0.797059], [0.751856, 0.810715], [0.776689, 0.799334], [0.779587, 0.762869], [0.759303, 0.749121]]],
            },
            'properties': {
                'type': 'site',
                'status': 'positive_annotated',
                'version': '2.0.1',
                'site_id': 'DR_0042_9001',
                'mgrs': None,
                'start_date': '2015-06-28',
                'end_date': '2015-06-28',
                'score': 1,
                'originator': 'demo',
                'model_content': 'annotation',
                'validated': 'True',
                'misc_info': {'color': [0.0, 1.0, 0.0]},
                'region_id': 'DR_0042',
            },
        },
        {
            'type': 'Feature',
            'geometry': {
                'type': 'MultiPolygon',
                'coordinates': [[[[0.719567, 0.797059], [0.717993, 0.763785], [0.759303, 0.749121], [0.779587, 0.762869], [0.776689, 0.799334], [0.751856, 0.810715]]]],
            },
            'properties': {
                'type': 'observation',
                'observation_date': '2015-06-28',
                'source': 'demosat-220150628T072421',
                'sensor_name': 'demosat-2',
                'current_phase': 'No Activity',
                'is_occluded': 'False',
                'is_site_boundary': 'True',
                'score': 1.0,
            },
        },
    ],
}

Example

>>> from geowatch.demo.metrics_demo.demo_truth import *  # NOQA
>>> region_id = 'DR_0042'
>>> site_id = 'DR_0042_9001'
>>> rng = kwarray.ensure_rng(0)
>>> region_corners = kwimage.Boxes([[0, 0, 1, 1]], 'xywh').to_ltrb().corners()
>>> observables = random_observables(10, rng=rng)
>>> p_observe = 1.0
>>> site_summary, site = random_site_model(region_id, site_id, region_corners, observables,
>>>                                        p_observe=p_observe, rng=rng)
>>> print('site_summary = {}'.format(ub.urepr(site_summary, nl=-1, sort=0)))
site_summary = {
    'type': 'Feature',
    'geometry': {
        'type': 'Polygon',
        'coordinates': [
            [
                [0.599483, 0.568633],
                [0.569207, 0.576066],
                [0.542041, 0.627691],
                [0.606987, 0.67388],
                [0.647289, 0.636873],
                [0.635087, 0.580387],
                [0.599483, 0.568633]
            ]
        ]
    },
    'properties': {
        'type': 'site_summary',
        'status': 'positive_annotated',
        'version': '2.0.1',
        'site_id': 'DR_0042_9001',
        'mgrs': None,
        'start_date': '2013-11-01',
        'end_date': '2019-08-21',
        'score': 1,
        'originator': 'demo',
        'model_content': 'annotation',
        'validated': 'True',
        'cache': {
            'color': [1.0, 0.36777954425013254, 0.0]
        }
    }
}

Example

>>> from geowatch.demo.metrics_demo.demo_truth import *  # NOQA
>>> region_id = 'DR_0042'
>>> site_id = 'DR_0042_9001'
>>> rng = kwarray.ensure_rng(42232)
>>> region_corners = kwimage.Boxes([[5, 7, 11, 13]], 'xywh').to_ltrb().corners()
>>> observables = random_observables(10, rng=rng)
>>> p_observe = 1.0
>>> site_summary, site = random_site_model(region_id, site_id, region_corners, observables,
>>>                                        p_observe=p_observe, rng=rng)
>>> # xdoctest: +REQUIRES(--show)
>>> # xdoctest: +REQUIRES(module:kwplot)
>>> import kwplot
>>> kwplot.autompl()
>>> import geopandas as gpd
>>> # Draw our true and perterbed site model
>>> site_gdf = gpd.GeoDataFrame.from_features(site[1:])
>>> total_poly = site_gdf['geometry'].unary_union
>>> minx, miny, maxx, maxy = total_poly.bounds
>>> fig = kwplot.figure(doclf=True, fnum=1)
>>> pnum_ = kwplot.PlotNums(nSubplots=len(site_gdf))
>>> for idx in range(len(site_gdf)):
>>>     row = site_gdf.iloc[idx: idx + 1]
>>>     item = row.iloc[0]
>>>     title = item['observation_date'] + ' ' + item['current_phase']
>>>     fig = kwplot.figure(pnum=pnum_(), title=title)
>>>     ax = fig.gca()
>>>     row.plot(ax=ax, alpha=0.5, color='limegreen', edgecolor='black')
>>>     row.centroid.plot(ax=ax, alpha=0.5, color='green')
>>>     ax.set_xlim(minx, maxx)
>>>     ax.set_ylim(miny, maxy)
>>> kwplot.show_if_requested()
geowatch.demo.metrics_demo.demo_truth.make_site_summary(observations, mgrs_code, site_id, status, summary_geom=None)[source]

Consolodate site observations into a site summary