openforis-whisp 3.0.0a1__py3-none-any.whl → 3.0.0a3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
openforis_whisp/utils.py CHANGED
@@ -238,11 +238,11 @@ def generate_random_polygon(
238
238
  center_point = Point(center_lon, center_lat)
239
239
 
240
240
  # Use buffer with resolution to control vertices for smaller vertex counts
241
- if vertex_count <= 50:
241
+ if vertex_count <= 20:
242
242
  poly = center_point.buffer(radius_degrees, resolution=vertex_count // 4)
243
243
 
244
- # Manual vertex creation for higher vertex counts
245
- if vertex_count > 50:
244
+ # Manual vertex creation for higher vertex counts (sine wave distortions for realistic shapes)
245
+ if vertex_count > 20:
246
246
  angles = np.linspace(0, 2 * math.pi, vertex_count, endpoint=False)
247
247
 
248
248
  base_radius = radius_degrees
@@ -319,6 +319,10 @@ def generate_test_polygons(
319
319
  """
320
320
  Generate synthetic test polygons with exact vertex count control.
321
321
 
322
+ **Deprecated**: This is a legacy alias for generate_random_polygons().
323
+ Use generate_random_polygons() for new code, which provides additional
324
+ features like save_path and seed parameters.
325
+
322
326
  This utility is useful for testing WHISP processing with controlled test data,
323
327
  especially when you need polygons with specific characteristics (area, complexity).
324
328
 
@@ -326,10 +330,6 @@ def generate_test_polygons(
326
330
  ----------
327
331
  bounds : list or ee.Geometry
328
332
  Either a list of [min_lon, min_lat, max_lon, max_lat] or an Earth Engine Geometry.
329
- Examples:
330
- - Simple bounds: [-81.0, -19.3, -31.5, 9.6]
331
- - EE Geometry: ee.FeatureCollection('USDOS/LSIB_SIMPLE/2017').filter(
332
- ee.Filter.eq('country_na', 'Brazil')).first().geometry()
333
333
  num_polygons : int, optional
334
334
  Number of polygons to generate (default: 25)
335
335
  min_area_ha : float, optional
@@ -344,36 +344,153 @@ def generate_test_polygons(
344
344
  Returns
345
345
  -------
346
346
  dict
347
- GeoJSON FeatureCollection with generated polygons. Each feature includes:
348
- - internal_id: Sequential ID starting from 1
349
- - requested_vertices: Number of vertices requested
350
- - actual_vertices: Actual number of vertices created
347
+ GeoJSON FeatureCollection with generated polygons.
348
+
349
+ See Also
350
+ --------
351
+ generate_random_polygons : Recommended replacement with additional options
352
+ """
353
+ return generate_random_polygons(
354
+ bounds=bounds,
355
+ num_polygons=num_polygons,
356
+ min_area_ha=min_area_ha,
357
+ max_area_ha=max_area_ha,
358
+ min_number_vert=min_number_vert,
359
+ max_number_vert=max_number_vert,
360
+ )
361
+
362
+
363
+ def generate_random_features(
364
+ bounds,
365
+ feature_type="point",
366
+ num_features=10,
367
+ seed=None,
368
+ min_area_ha=1,
369
+ max_area_ha=10,
370
+ min_number_vert=10,
371
+ max_number_vert=20,
372
+ multipolygon_pct=20,
373
+ min_parts=2,
374
+ max_parts=4,
375
+ save_path=None,
376
+ return_path=False,
377
+ ):
378
+ """
379
+ Generate random test features (points, polygons, or mixed) with exact geographic bounds control.
380
+
381
+ This utility is useful for testing WHISP processing with random feature data,
382
+ especially when you need features with specific geographic characteristics.
383
+ For polygon features, reuses the production polygon generation logic from
384
+ generate_random_polygon() to ensure consistency.
385
+
386
+ Parameters
387
+ ----------
388
+ bounds : list or ee.Geometry
389
+ Either a list of [min_lon, min_lat, max_lon, max_lat] or an Earth Engine Geometry.
390
+ Examples:
391
+ - Simple bounds: [-81.0, -19.3, -31.5, 9.6]
392
+ - EE Geometry: ee.FeatureCollection('USDOS/LSIB_SIMPLE/2017').filter(
393
+ ee.Filter.eq('country_na', 'Brazil')).first().geometry()
394
+ feature_type : str, optional
395
+ Type of features to generate:
396
+ - 'point': Random points
397
+ - 'polygon': Single-part polygons
398
+ - 'mixed': Blend of single polygons and multipolygons (default: 'point')
399
+ num_features : int, optional
400
+ Number of features to generate (default: 10)
401
+ seed : int or None, optional
402
+ Random seed for reproducibility. None = different each run to avoid GEE caching (default: None)
403
+ min_area_ha : float, optional
404
+ Minimum area in hectares for polygons (default: 1)
405
+ max_area_ha : float, optional
406
+ Maximum area in hectares for polygons (default: 10)
407
+ min_number_vert : int, optional
408
+ Minimum vertices per polygon (default: 10)
409
+ max_number_vert : int, optional
410
+ Maximum vertices per polygon (default: 20)
411
+ multipolygon_pct : float, optional
412
+ Percentage of features that are multipolygons for 'mixed' type (0-100, default: 20)
413
+ min_parts : int, optional
414
+ Minimum polygon parts per multipolygon (default: 2)
415
+ max_parts : int, optional
416
+ Maximum polygon parts per multipolygon (default: 4)
417
+ save_path : str or Path, optional
418
+ Directory path where to save the GeoJSON file. If None, file is not saved (default: None)
419
+ return_path : bool, optional
420
+ If True, return the file path instead of the GeoJSON dict. Only used if save_path is provided (default: False)
421
+
422
+ Returns
423
+ -------
424
+ dict or Path
425
+ If save_path is None: GeoJSON FeatureCollection dict
426
+ If save_path is provided and return_path=False: GeoJSON FeatureCollection dict
427
+ If save_path is provided and return_path=True: Path to saved GeoJSON file
428
+
429
+ All features include:
430
+ - internal_id: Sequential feature ID
431
+ - geometry_type: 'Point', 'Polygon', or 'MultiPolygon' (for distinguishing feature types)
432
+
433
+ For polygons, features include:
434
+ - requested_vertices: Requested vertex count
435
+ - actual_vertices: Actual vertices created
351
436
  - requested_area_ha: Target area in hectares
352
437
  - actual_area_ha: Actual area in hectares
353
438
 
354
439
  Examples
355
440
  --------
356
441
  >>> import openforis_whisp as whisp
357
- >>> import ee
358
442
  >>>
359
- >>> # Using simple bounds (list)
360
- >>> bounds_list = [-81.0, -19.3, -31.5, 9.6]
361
- >>> geojson = whisp.generate_test_polygons(bounds_list, num_polygons=100)
443
+ >>> # Generate random points (in-memory)
444
+ >>> bounds = [-81.0, -19.3, -31.5, 9.6]
445
+ >>> geojson = whisp.generate_random_features(bounds, feature_type='point', num_features=50)
362
446
  >>>
363
- >>> # Using Earth Engine Geometry
364
- >>> brazil = ee.FeatureCollection('USDOS/LSIB_SIMPLE/2017').filter(
365
- ... ee.Filter.eq('country_na', 'Brazil')
366
- ... ).first().geometry()
367
- >>> geojson = whisp.generate_test_polygons(brazil, num_polygons=100,
368
- ... min_area_ha=100, max_area_ha=1000)
447
+ >>> # Generate and save to file
448
+ >>> from pathlib import Path
449
+ >>> save_dir = Path.home() / 'downloads'
450
+ >>> geojson = whisp.generate_random_features(
451
+ ... bounds,
452
+ ... feature_type='polygon',
453
+ ... num_features=100,
454
+ ... save_path=save_dir
455
+ ... )
369
456
  >>>
370
- >>> # Save to file
371
- >>> import json
372
- >>> with open('test_polygons.geojson', 'w') as f:
373
- ... json.dump(geojson, f)
457
+ >>> # Generate mixed geometries and return file path
458
+ >>> file_path = whisp.generate_random_features(
459
+ ... bounds,
460
+ ... feature_type='mixed',
461
+ ... num_features=100,
462
+ ... multipolygon_pct=30,
463
+ ... min_parts=2,
464
+ ... max_parts=5,
465
+ ... save_path=save_dir,
466
+ ... return_path=True
467
+ ... )
374
468
  """
469
+ # Validate feature_type
470
+ if feature_type not in ("point", "polygon", "mixed"):
471
+ raise ValueError(
472
+ f"feature_type must be 'point', 'polygon', or 'mixed' (got {feature_type!r})"
473
+ )
474
+
475
+ # Validate num_features
476
+ if num_features < 1:
477
+ raise ValueError(f"num_features must be at least 1 (got {num_features})")
478
+
479
+ # Validate multipolygon_pct
480
+ if not (0 <= multipolygon_pct <= 100):
481
+ raise ValueError(
482
+ f"multipolygon_pct must be between 0-100 (got {multipolygon_pct})"
483
+ )
484
+
485
+ # Validate min/max parts
486
+ if min_parts < 2:
487
+ raise ValueError(f"min_parts must be at least 2 (got {min_parts})")
488
+ if min_parts > max_parts:
489
+ raise ValueError(
490
+ f"min_parts ({min_parts}) cannot be greater than max_parts ({max_parts})"
491
+ )
375
492
 
376
- # Handle Earth Engine Geometry or simple bounds
493
+ # Extract and validate bounds
377
494
  if hasattr(bounds, "bounds"): # It's an ee.Geometry
378
495
  logger.logger.info("Extracting bounds from Earth Engine Geometry...")
379
496
  try:
@@ -404,7 +521,13 @@ def generate_test_polygons(
404
521
  " - An Earth Engine Geometry (ee.Geometry, ee.Feature.geometry(), etc.)"
405
522
  )
406
523
 
407
- # Validate parameters
524
+ # Validate bounds
525
+ if min_lon >= max_lon:
526
+ raise ValueError(f"min_lon ({min_lon}) must be less than max_lon ({max_lon})")
527
+ if min_lat >= max_lat:
528
+ raise ValueError(f"min_lat ({min_lat}) must be less than max_lat ({max_lat})")
529
+
530
+ # Validate vertex and area parameters
408
531
  if min_number_vert > max_number_vert:
409
532
  raise ValueError(
410
533
  f"min_number_vert ({min_number_vert}) cannot be greater than max_number_vert ({max_number_vert})"
@@ -413,75 +536,321 @@ def generate_test_polygons(
413
536
  raise ValueError(
414
537
  f"min_area_ha ({min_area_ha}) cannot be greater than max_area_ha ({max_area_ha})"
415
538
  )
416
- if num_polygons < 1:
417
- raise ValueError(f"num_polygons must be at least 1 (got {num_polygons})")
418
539
 
419
- logger.logger.info(
420
- f"Generating {num_polygons} test polygons with {min_number_vert}-{max_number_vert} vertices..."
421
- )
540
+ # Set random seed if provided
541
+ if seed is not None:
542
+ random.seed(seed)
543
+ np.random.seed(seed)
544
+
545
+ logger.logger.info(f"Generating {num_features} test {feature_type} features...")
422
546
 
423
547
  features = []
424
548
 
425
- # Pre-generate all random values
426
- vertex_counts = np.random.randint(
427
- min_number_vert, max_number_vert + 1, num_polygons
428
- )
429
- target_areas = np.random.uniform(min_area_ha, max_area_ha, num_polygons)
549
+ if feature_type == "point":
550
+ # Generate point features
551
+ for i in range(num_features):
552
+ lon = random.uniform(min_lon, max_lon)
553
+ lat = random.uniform(min_lat, max_lat)
554
+ feature = {
555
+ "type": "Feature",
556
+ "properties": {
557
+ "internal_id": i + 1,
558
+ "name": f"Point_{i+1}",
559
+ "geometry_type": "Point",
560
+ },
561
+ "geometry": {"type": "Point", "coordinates": [lon, lat]},
562
+ }
563
+ features.append(feature)
564
+
565
+ elif feature_type == "polygon":
566
+ # Generate single polygon features - reuse production polygon generation
567
+ vertex_counts = np.random.randint(
568
+ min_number_vert, max_number_vert + 1, num_features
569
+ )
430
570
 
431
- for i in range(num_polygons):
432
- if i > 0 and i % 250 == 0:
433
- logger.logger.info(
434
- f"Generated {i}/{num_polygons} polygons ({i/num_polygons*100:.0f}%)..."
571
+ for i in range(num_features):
572
+ if i > 0 and i % 250 == 0:
573
+ logger.logger.info(
574
+ f"Generated {i}/{num_features} polygons ({i/num_features*100:.0f}%)..."
575
+ )
576
+
577
+ polygon, actual_area = generate_random_polygon(
578
+ min_lon,
579
+ min_lat,
580
+ max_lon,
581
+ max_lat,
582
+ min_area_ha=min_area_ha,
583
+ max_area_ha=max_area_ha,
584
+ vertex_count=vertex_counts[i],
435
585
  )
436
586
 
437
- requested_vertices = vertex_counts[i]
587
+ actual_vertex_count = len(list(polygon.exterior.coords)) - 1
588
+
589
+ properties = {
590
+ "internal_id": i + 1,
591
+ "geometry_type": "Polygon",
592
+ "requested_vertices": int(vertex_counts[i]),
593
+ "actual_vertices": int(actual_vertex_count),
594
+ "requested_area_ha": round(random.uniform(min_area_ha, max_area_ha), 2),
595
+ "actual_area_ha": round(actual_area, 2),
596
+ }
597
+
598
+ feature = {
599
+ "type": "Feature",
600
+ "properties": properties,
601
+ "geometry": mapping(polygon),
602
+ }
603
+
604
+ features.append(feature)
605
+
606
+ else: # mixed
607
+ # Generate blend of single polygons and multipolygons
608
+ num_multipolygons = int(num_features * multipolygon_pct / 100)
609
+ num_polygons = num_features - num_multipolygons
610
+
611
+ # Generate single polygons
612
+ if num_polygons > 0:
613
+ vertex_counts = np.random.randint(
614
+ min_number_vert, max_number_vert + 1, num_polygons
615
+ )
438
616
 
439
- polygon, actual_area = generate_random_polygon(
440
- min_lon,
441
- min_lat,
442
- max_lon,
443
- max_lat,
444
- min_area_ha=target_areas[i] * 0.9,
445
- max_area_ha=target_areas[i] * 1.1,
446
- vertex_count=requested_vertices,
447
- )
617
+ for i in range(num_polygons):
618
+ if i > 0 and i % 250 == 0:
619
+ logger.logger.info(
620
+ f"Generated {i}/{num_features} features ({i/num_features*100:.0f}%)..."
621
+ )
622
+
623
+ polygon, actual_area = generate_random_polygon(
624
+ min_lon,
625
+ min_lat,
626
+ max_lon,
627
+ max_lat,
628
+ min_area_ha=min_area_ha,
629
+ max_area_ha=max_area_ha,
630
+ vertex_count=vertex_counts[i],
631
+ )
632
+
633
+ actual_vertex_count = len(list(polygon.exterior.coords)) - 1
634
+
635
+ properties = {
636
+ "internal_id": i + 1,
637
+ "geometry_type": "Polygon",
638
+ "requested_vertices": int(vertex_counts[i]),
639
+ "actual_vertices": int(actual_vertex_count),
640
+ "requested_area_ha": round(
641
+ random.uniform(min_area_ha, max_area_ha), 2
642
+ ),
643
+ "actual_area_ha": round(actual_area, 2),
644
+ }
645
+
646
+ feature = {
647
+ "type": "Feature",
648
+ "properties": properties,
649
+ "geometry": mapping(polygon),
650
+ }
651
+
652
+ features.append(feature)
653
+
654
+ # Generate multipolygons
655
+ if num_multipolygons > 0:
656
+ for i in range(num_multipolygons):
657
+ if i > 0 and i % 50 == 0:
658
+ logger.logger.info(
659
+ f"Generated {num_polygons + i}/{num_features} features ({(num_polygons + i)/num_features*100:.0f}%)..."
660
+ )
661
+
662
+ num_parts = random.randint(min_parts, max_parts)
663
+ polygon_parts = []
664
+ total_area_ha = 0
665
+
666
+ # Generate a target total area for this multipolygon
667
+ target_total_area = random.uniform(min_area_ha, max_area_ha)
668
+ # Divide target area among parts (with some randomness)
669
+ part_areas = []
670
+ remaining_area = target_total_area
671
+ for part_idx in range(num_parts):
672
+ if part_idx == num_parts - 1:
673
+ # Last part gets all remaining area
674
+ part_area = remaining_area
675
+ else:
676
+ # Distribute remaining area with randomness
677
+ max_for_part = remaining_area * 0.8
678
+ part_area = random.uniform(remaining_area * 0.3, max_for_part)
679
+ part_areas.append(part_area)
680
+ remaining_area -= part_area
681
+
682
+ for part, area_budget in enumerate(part_areas):
683
+ # Generate each part in the full bounds (randomization spreads them naturally)
684
+ polygon, actual_area = generate_random_polygon(
685
+ min_lon,
686
+ min_lat,
687
+ max_lon,
688
+ max_lat,
689
+ min_area_ha=area_budget * 0.8,
690
+ max_area_ha=area_budget * 1.2,
691
+ vertex_count=random.randint(min_number_vert, max_number_vert),
692
+ )
693
+
694
+ polygon_parts.append([list(polygon.exterior.coords)])
695
+ total_area_ha += actual_area
696
+
697
+ properties = {
698
+ "internal_id": num_polygons + i + 1,
699
+ "geometry_type": "MultiPolygon",
700
+ "num_parts": num_parts,
701
+ "total_area_ha": round(total_area_ha, 2),
702
+ }
703
+
704
+ feature = {
705
+ "type": "Feature",
706
+ "properties": properties,
707
+ "geometry": {
708
+ "type": "MultiPolygon",
709
+ "coordinates": polygon_parts,
710
+ },
711
+ }
712
+
713
+ features.append(feature)
448
714
 
449
- actual_vertex_count = len(list(polygon.exterior.coords)) - 1
715
+ geojson = {"type": "FeatureCollection", "features": features}
450
716
 
451
- properties = {
452
- "internal_id": i + 1,
453
- "requested_vertices": int(requested_vertices),
454
- "actual_vertices": int(actual_vertex_count),
455
- "requested_area_ha": round(target_areas[i], 2),
456
- "actual_area_ha": round(actual_area, 2),
457
- }
717
+ logger.logger.info(f"Generated {num_features} test {feature_type} features!")
458
718
 
459
- feature = {
460
- "type": "Feature",
461
- "properties": properties,
462
- "geometry": mapping(polygon),
463
- }
719
+ # Save to file if save_path is provided
720
+ if save_path is not None:
721
+ import json
464
722
 
465
- features.append(feature)
723
+ save_path = Path(save_path)
724
+ save_path.mkdir(parents=True, exist_ok=True)
466
725
 
467
- logger.logger.info(f"Generated {num_polygons} polygons!")
726
+ output_file = save_path / f"{feature_type}s_{num_features}_features.geojson"
468
727
 
469
- # Print summary statistics
470
- actual_vertex_counts = [f["properties"]["actual_vertices"] for f in features]
471
- requested_vertex_counts = [f["properties"]["requested_vertices"] for f in features]
728
+ with open(output_file, "w") as f:
729
+ json.dump(geojson, f, indent=2)
472
730
 
473
- logger.logger.info(
474
- f"Vertex count - Requested: {min(requested_vertex_counts)}-{max(requested_vertex_counts)}, "
475
- f"Actual: {min(actual_vertex_counts)}-{max(actual_vertex_counts)}"
476
- )
731
+ logger.logger.info(f"GeoJSON saved to: {output_file}")
732
+
733
+ if return_path:
734
+ return output_file
477
735
 
478
- actual_area_counts = [f["properties"]["actual_area_ha"] for f in features]
479
- requested_area_counts = [f["properties"]["requested_area_ha"] for f in features]
736
+ return geojson
480
737
 
481
- logger.logger.info(
482
- f"Area (ha) - Requested: {min(requested_area_counts):.1f}-{max(requested_area_counts):.1f}, "
483
- f"Actual: {min(actual_area_counts):.1f}-{max(actual_area_counts):.1f}"
738
+
739
+ def generate_random_points(bounds, num_features=10, seed=None, save_path=None):
740
+ """
741
+ Generate random test points with optional save.
742
+
743
+ Simplified wrapper around generate_random_features for point-only generation.
744
+
745
+ Parameters
746
+ ----------
747
+ bounds : list or ee.Geometry
748
+ Either a list of [min_lon, min_lat, max_lon, max_lat] or an Earth Engine Geometry.
749
+ num_features : int, optional
750
+ Number of points to generate (default: 10)
751
+ seed : int or None, optional
752
+ Random seed for reproducibility (default: None)
753
+ save_path : str or Path, optional
754
+ Directory path where to save the GeoJSON file. If None, file is not saved (default: None)
755
+
756
+ Returns
757
+ -------
758
+ dict or Path
759
+ If save_path is None: GeoJSON FeatureCollection dict
760
+ If save_path is provided: Path to saved GeoJSON file
761
+
762
+ Examples
763
+ --------
764
+ >>> import openforis_whisp as whisp
765
+ >>>
766
+ >>> bounds = [-81.0, -19.3, -31.5, 9.6]
767
+ >>> geojson = whisp.generate_random_points(bounds, num_features=100)
768
+ >>>
769
+ >>> # Generate and save
770
+ >>> from pathlib import Path
771
+ >>> file_path = whisp.generate_random_points(
772
+ ... bounds,
773
+ ... num_features=500,
774
+ ... save_path=Path.home() / 'downloads'
775
+ ... )
776
+ """
777
+ return generate_random_features(
778
+ bounds=bounds,
779
+ feature_type="point",
780
+ num_features=num_features,
781
+ seed=seed,
782
+ save_path=save_path,
783
+ return_path=True if save_path else False,
484
784
  )
485
785
 
486
- geojson = {"type": "FeatureCollection", "features": features}
487
- return geojson
786
+
787
+ def generate_random_polygons(
788
+ bounds,
789
+ num_polygons=25,
790
+ min_area_ha=1,
791
+ max_area_ha=10,
792
+ min_number_vert=10,
793
+ max_number_vert=20,
794
+ seed=None,
795
+ save_path=None,
796
+ ):
797
+ """
798
+ Generate random test polygons with optional save.
799
+
800
+ Wrapper around generate_random_features for polygon-only generation.
801
+ Uses the same production-quality polygon generation as generate_test_polygons.
802
+
803
+ Parameters
804
+ ----------
805
+ bounds : list or ee.Geometry
806
+ Either a list of [min_lon, min_lat, max_lon, max_lon] or an Earth Engine Geometry.
807
+ num_polygons : int, optional
808
+ Number of polygons to generate (default: 25)
809
+ min_area_ha : float, optional
810
+ Minimum area in hectares (default: 1)
811
+ max_area_ha : float, optional
812
+ Maximum area in hectares (default: 10)
813
+ min_number_vert : int, optional
814
+ Minimum number of vertices per polygon (default: 10)
815
+ max_number_vert : int, optional
816
+ Maximum number of vertices per polygon (default: 20)
817
+ seed : int or None, optional
818
+ Random seed for reproducibility (default: None)
819
+ save_path : str or Path, optional
820
+ Directory path where to save the GeoJSON file. If None, file is not saved (default: None)
821
+
822
+ Returns
823
+ -------
824
+ dict or Path
825
+ If save_path is None: GeoJSON FeatureCollection dict
826
+ If save_path is provided: Path to saved GeoJSON file
827
+
828
+ Examples
829
+ --------
830
+ >>> import openforis_whisp as whisp
831
+ >>>
832
+ >>> bounds = [-81.0, -19.3, -31.5, 9.6]
833
+ >>> geojson = whisp.generate_random_polygons(bounds, num_polygons=50)
834
+ >>>
835
+ >>> # Generate and save
836
+ >>> from pathlib import Path
837
+ >>> file_path = whisp.generate_random_polygons(
838
+ ... bounds,
839
+ ... num_polygons=100,
840
+ ... min_area_ha=5,
841
+ ... max_area_ha=50,
842
+ ... save_path=Path.home() / 'downloads'
843
+ ... )
844
+ """
845
+ return generate_random_features(
846
+ bounds=bounds,
847
+ feature_type="polygon",
848
+ num_features=num_polygons,
849
+ seed=seed,
850
+ min_area_ha=min_area_ha,
851
+ max_area_ha=max_area_ha,
852
+ min_number_vert=min_number_vert,
853
+ max_number_vert=max_number_vert,
854
+ save_path=save_path,
855
+ return_path=True if save_path else False,
856
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: openforis-whisp
3
- Version: 3.0.0a1
3
+ Version: 3.0.0a3
4
4
  Summary: Whisp (What is in that plot) is an open-source solution which helps to produce relevant forest monitoring information and support compliance with deforestation-related regulations.
5
5
  License: MIT
6
6
  Keywords: whisp,geospatial,data-processing
@@ -1,7 +1,7 @@
1
- openforis_whisp/__init__.py,sha256=-r_9LFxbV6d-o4s0_huhaXxve6GIzCwl3pXKuJo6ixE,3663
2
- openforis_whisp/advanced_stats.py,sha256=_bP_ApeaAdOF41WvabOhUNGL9Tt35AesUjNjqnHs8wo,76730
3
- openforis_whisp/data_checks.py,sha256=WiYhoTedPs1MqSv4T978nDF3_WDYyg8YmHRi9mQXXqI,25203
4
- openforis_whisp/data_conversion.py,sha256=sr2j_q6YjxVTicytimOMO8-RYohD1oyWWrgbg6WsLSw,18796
1
+ openforis_whisp/__init__.py,sha256=s42Q0VJdzm8mgnxfYg1hUEJPM2VLWIva2h-mdKyr444,3538
2
+ openforis_whisp/advanced_stats.py,sha256=tvhgNTCGlT3aYecUPP6QCTO0FRrjk0qjs95NoVZvIt4,90935
3
+ openforis_whisp/data_checks.py,sha256=KwgD72FA_n7joiJadGRpzntd2sLo0aqGNbOjRkB8iQI,32293
4
+ openforis_whisp/data_conversion.py,sha256=L2IsiUyQUt3aHgSYGbIhgPGwM7eyS3nLVEoNO9YqQeM,21888
5
5
  openforis_whisp/datasets.py,sha256=aGJy0OYN4d0nsH3_IOYlHl-WCB7KFwZwMJ-dBi5Hc5Y,53470
6
6
  openforis_whisp/logger.py,sha256=9M6_3mdpoiWfC-pDwM9vKmB2l5Gul6Rb5rNTNh-_nzs,3054
7
7
  openforis_whisp/parameters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -10,11 +10,11 @@ openforis_whisp/parameters/lookup_context_and_metadata.csv,sha256=KgK0ik_Gd4t_Nq
10
10
  openforis_whisp/parameters/lookup_gaul1_admin.py,sha256=cQr5liRdXi85QieTxrz4VAkn0COvRCp82ZV0dYFWOio,474980
11
11
  openforis_whisp/parameters/lookup_gee_datasets.csv,sha256=UDvZrQsL5rXJn6CW6P3wofUrPLRmUFZWt6ETbXaxBMs,17454
12
12
  openforis_whisp/pd_schemas.py,sha256=W_ocS773LHfc05dJqvWRa-bRdX0wKFoNp0lMxgFx94Y,2681
13
- openforis_whisp/reformat.py,sha256=mIooJ3zfSTDY3_Mx3OAW4jpfQ72q3zasG9tl58PdfN4,33729
13
+ openforis_whisp/reformat.py,sha256=MPjP5lb218GTcTpd_Qvbj5ER_8EY4JjLDteQaS5OZCQ,32620
14
14
  openforis_whisp/risk.py,sha256=d_Di5XB8BnHdVXG56xdHTcpB4-CIF5vo2ZRMQRG7Pek,34420
15
- openforis_whisp/stats.py,sha256=mzzd3oU3RnJQPfeWoUBuMDTIw2FCAzWXHCt53ZuQ__A,64895
16
- openforis_whisp/utils.py,sha256=5HHtbK62Swn4-jnlSe1Jc-hVnJhLKMuDW0_ayHY7mIg,17130
17
- openforis_whisp-3.0.0a1.dist-info/LICENSE,sha256=nqyqICO95iw_iwzP1t_IIAf7ZX3DPbL_M9WyQfh2q1k,1085
18
- openforis_whisp-3.0.0a1.dist-info/METADATA,sha256=dAlxg3DFtpIw5fCbZyrO2hOhtJSg7DYxtbN71ez3S2Y,16684
19
- openforis_whisp-3.0.0a1.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
20
- openforis_whisp-3.0.0a1.dist-info/RECORD,,
15
+ openforis_whisp/stats.py,sha256=nVzQpSu7BoSb2S6HheLeoK_pmguZ9Lyw0ZfbTTMVq4Q,63720
16
+ openforis_whisp/utils.py,sha256=Q-EwhUaohk63WCx7Rr5VuR3X-oGtgILZDc8JsjbWhgg,30538
17
+ openforis_whisp-3.0.0a3.dist-info/LICENSE,sha256=nqyqICO95iw_iwzP1t_IIAf7ZX3DPbL_M9WyQfh2q1k,1085
18
+ openforis_whisp-3.0.0a3.dist-info/METADATA,sha256=6xuNhUpQWyzKU3m13FnJ7SX39jAVry1YEKNAdH0D2to,16684
19
+ openforis_whisp-3.0.0a3.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
20
+ openforis_whisp-3.0.0a3.dist-info/RECORD,,