-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7a6fb01
commit ca8500d
Showing
17 changed files
with
384 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
from django.contrib import admin | ||
from bats_ai.core.models import GRTSCells | ||
|
||
@admin.register(GRTSCells) | ||
class GRTSCellsAdmin(admin.ModelAdmin): | ||
list_display = ('id', 'grts_cell_id', 'sample_frame_id', 'water_p', 'outside_p') # Add other fields you want to display in the list | ||
search_fields = ('id', 'grts_cell_id', 'sample_frame_id') # Add fields for searching | ||
list_filter = ('location_1_type', 'location_2_type') # Add fields for filtering |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import csv | ||
from django.core.management.base import BaseCommand | ||
from bats_ai.core.models import GRTSCells | ||
from django.core.exceptions import ValidationError | ||
|
||
|
||
class Command(BaseCommand): | ||
help = 'Import data from CSV file' | ||
|
||
def add_arguments(self, parser): | ||
parser.add_argument('csv_file', type=str, help='Path to the CSV file') | ||
|
||
def handle(self, *args, **options): | ||
csv_file = options['csv_file'] | ||
|
||
# Get all field names of the GRTSCells model | ||
model_fields = [field.name for field in GRTSCells._meta.get_fields()] | ||
|
||
with open(csv_file, 'r') as file: | ||
reader = csv.DictReader(file) | ||
total_rows = sum(1 for _ in reader) # Get total number of rows in the CSV | ||
file.seek(0) # Reset file pointer to start | ||
next(reader) # Skip header row | ||
counter = 0 # Initialize progress counter | ||
|
||
for row in reader: | ||
# Filter row dictionary to include only keys that exist in the model fields | ||
filtered_row = {key: row[key] for key in row if key in model_fields} | ||
|
||
for key, value in filtered_row.items(): | ||
if value == '': | ||
filtered_row[key] = None | ||
|
||
# Convert boolean fields from string to boolean values | ||
for boolean_field in ['priority_frame', 'priority_state', 'clipped']: | ||
if filtered_row.get(boolean_field): | ||
if filtered_row[boolean_field].lower() == 'true': | ||
filtered_row[boolean_field] = True | ||
elif filtered_row[boolean_field].lower() == 'false': | ||
filtered_row[boolean_field] = False | ||
else: | ||
raise ValidationError(f'Invalid boolean value for field {boolean_field}: {filtered_row[boolean_field]}') | ||
|
||
# Check if a record with all the data already exists | ||
if GRTSCells.objects.filter(**filtered_row).exists(): | ||
#self.stdout.write(f'Skipping row because it already exists: {filtered_row}') | ||
counter += 1 | ||
self.stdout.write(f'Processed {counter} of {total_rows} rows') | ||
continue | ||
|
||
try: | ||
GRTSCells.objects.create(**filtered_row) | ||
counter += 1 | ||
self.stdout.write(f'Processed {counter} of {total_rows} rows') | ||
except ValidationError as e: | ||
self.stderr.write(str(e)) | ||
continue |
48 changes: 48 additions & 0 deletions
48
bats_ai/core/migrations/0008_grtscells_recording_recorded_time.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# Generated by Django 4.1.13 on 2024-02-23 17:06 | ||
|
||
import django.contrib.gis.db.models.fields | ||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('core', '0007_temporalannotations'), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name='GRTSCells', | ||
fields=[ | ||
('id', models.IntegerField(primary_key=True, serialize=False)), | ||
('grts_cell_id', models.IntegerField()), | ||
('sample_frame_id', models.IntegerField(blank=True, null=True)), | ||
('grts_geom', django.contrib.gis.db.models.fields.GeometryField(blank=True, null=True, srid=4326)), | ||
('water_p', models.FloatField(blank=True, null=True)), | ||
('outside_p', models.FloatField(blank=True, null=True)), | ||
('location_1_type', models.CharField(blank=True, max_length=255, null=True)), | ||
('location_1_name', models.CharField(blank=True, max_length=255, null=True)), | ||
('location_1_p', models.FloatField(blank=True, null=True)), | ||
('location_2_type', models.CharField(blank=True, max_length=255, null=True)), | ||
('location_2_name', models.CharField(blank=True, max_length=255, null=True)), | ||
('location_2_p', models.FloatField(blank=True, null=True)), | ||
('sub_location_1_type', models.CharField(blank=True, max_length=255, null=True)), | ||
('sub_location_1_name', models.CharField(blank=True, max_length=255, null=True)), | ||
('sub_location_1_p', models.FloatField(blank=True, null=True)), | ||
('sub_location_2_type', models.CharField(blank=True, max_length=255, null=True)), | ||
('sub_location_2_name', models.CharField(blank=True, max_length=255, null=True)), | ||
('sub_location_2_p', models.FloatField(blank=True, null=True)), | ||
('own_1_name', models.CharField(blank=True, max_length=255, null=True)), | ||
('own_1_p', models.FloatField(blank=True, null=True)), | ||
('priority_frame', models.BooleanField(blank=True, null=True)), | ||
('priority_state', models.BooleanField(blank=True, null=True)), | ||
('geom_4326', django.contrib.gis.db.models.fields.GeometryField(srid=4326)), | ||
('clipped', models.BooleanField(blank=True, null=True)), | ||
], | ||
), | ||
migrations.AddField( | ||
model_name='recording', | ||
name='recorded_time', | ||
field=models.TimeField(blank=True, null=True), | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
from django.contrib.gis.db import models | ||
|
||
sample_frame_map = { | ||
12: 'Mexico', | ||
14: 'Contintental US', | ||
19: 'Canada', | ||
20: 'Alaska', | ||
21: 'Puerto Rico', | ||
15: 'Hawaii', | ||
22: 'Offshore Caribbean', | ||
23: 'Offshore AKCAN', | ||
24: 'Offshore CONUS', | ||
25: 'Offshore Hawaii', | ||
26: 'Offshore Mexico', | ||
} | ||
|
||
class GRTSCells(models.Model): | ||
id = models.IntegerField(primary_key=True) | ||
grts_cell_id = models.IntegerField() | ||
sample_frame_id = models.IntegerField(blank=True, null=True) | ||
grts_geom = models.GeometryField(blank=True, null=True) | ||
water_p = models.FloatField(blank=True, null=True) | ||
outside_p = models.FloatField(blank=True, null=True) | ||
location_1_type = models.CharField(max_length=255, blank=True, null=True) | ||
location_1_name = models.CharField(max_length=255, blank=True, null=True) | ||
location_1_p = models.FloatField(blank=True, null=True) | ||
location_2_type = models.CharField(max_length=255, blank=True, null=True) | ||
location_2_name = models.CharField(max_length=255, blank=True, null=True) | ||
location_2_p = models.FloatField(blank=True, null=True) | ||
sub_location_1_type = models.CharField(max_length=255, blank=True, null=True) | ||
sub_location_1_name = models.CharField(max_length=255, blank=True, null=True) | ||
sub_location_1_p = models.FloatField(blank=True, null=True) | ||
sub_location_2_type = models.CharField(max_length=255, blank=True, null=True) | ||
sub_location_2_name = models.CharField(max_length=255, blank=True, null=True) | ||
sub_location_2_p = models.FloatField(blank=True, null=True) | ||
own_1_name = models.CharField(max_length=255, blank=True, null=True) | ||
own_1_p = models.FloatField(blank=True, null=True) | ||
# continue defining all fields similarly | ||
priority_frame = models.BooleanField(blank=True, null=True) | ||
priority_state = models.BooleanField(blank=True, null=True) | ||
geom_4326 = models.GeometryField() | ||
clipped = models.BooleanField(blank=True, null=True) | ||
|
||
@property | ||
def sampleFrameMapping(self): | ||
return sample_frame_map[self.sample_frame_id] | ||
|
||
@staticmethod | ||
def sort_order(): | ||
return [ | ||
14, 20, 15, 24, 21, 19, 12, 22, 23, 25, 26 | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
from django.http import JsonResponse | ||
from bats_ai.core.models import GRTSCells | ||
from django.http import HttpRequest | ||
from ninja.pagination import RouterPaginated | ||
from django.contrib.gis.geos import Polygon | ||
|
||
from django.contrib.gis.geos import Point | ||
from django.contrib.gis.measure import D | ||
from ninja import Query | ||
|
||
router = RouterPaginated() | ||
|
||
@router.get('/grid_cell_id') | ||
def get_grid_cell_id(request: HttpRequest, latitude: float = Query(...), longitude: float = Query(...)): | ||
try: | ||
# Create a point object from the provided latitude and longitude | ||
point = Point(longitude, latitude, srid=4326) | ||
|
||
# Query the grid cell that contains the provided point | ||
cell = GRTSCells.objects.filter(geom_4326__contains=point).first() | ||
|
||
if cell: | ||
# Return the grid cell ID | ||
return JsonResponse({'grid_cell_id': cell.grts_cell_id}) | ||
else: | ||
return JsonResponse({'error': 'No grid cell found for the provided latitude and longitude'}, status=200) | ||
except Exception as e: | ||
return JsonResponse({'error': str(e)}, status=200) | ||
|
||
|
||
@router.get('/{id}') | ||
def get_cell_center(request: HttpRequest, id: int, quadrant: str = None): | ||
try: | ||
cells = GRTSCells.objects.filter(grts_cell_id=id) | ||
|
||
# Define a custom order for sample_frame_id | ||
custom_order = GRTSCells.sort_order() # Define your custom order here | ||
|
||
# Define a custom key function to sort cells based on the custom order | ||
def custom_sort_key(cell): | ||
return custom_order.index(cell.sample_frame_id) | ||
|
||
# Sort the cells queryset based on the custom order | ||
sorted_cells = sorted(cells, key=custom_sort_key) | ||
cell = sorted_cells[0] | ||
geom_4326 = cell.geom_4326 | ||
|
||
|
||
# Get the centroid of the entire cell polygon | ||
center = geom_4326.centroid | ||
|
||
if quadrant: | ||
# If quadrant is specified, divide the cell polygon into quadrants | ||
min_x, min_y, max_x, max_y = geom_4326.extent | ||
mid_x = (min_x + max_x) / 2 | ||
mid_y = (min_y + max_y) / 2 | ||
|
||
# Determine the bounding box coordinates of the specified quadrant | ||
if quadrant.upper() == 'NW': | ||
bbox = (min_x, mid_y, mid_x, max_y) | ||
elif quadrant.upper() == 'SE': | ||
bbox = (mid_x, min_y, max_x, mid_y) | ||
elif quadrant.upper() == 'SW': | ||
bbox = (min_x, min_y, mid_x, mid_y) | ||
elif quadrant.upper() == 'NE': | ||
bbox = (mid_x, mid_y, max_x, max_y) | ||
|
||
quadrant_polygon = Polygon.from_bbox(bbox) | ||
|
||
# Intersect the cell polygon with the specified quadrant's polygon | ||
quadrant_polygon = geom_4326.intersection(quadrant_polygon) | ||
|
||
# Get the centroid of the intersected polygon | ||
center = quadrant_polygon.centroid | ||
|
||
# Get the latitude and longitude of the centroid | ||
center_latitude = center.y | ||
center_longitude = center.x | ||
|
||
return JsonResponse({'latitude': center_latitude, 'longitude': center_longitude}) | ||
except GRTSCells.DoesNotExist: | ||
return JsonResponse({'error': f'Cell with cellId={id} does not exist'}, status=200) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.