-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create plot_extraction.md #9
Open
dhiraj-ms
wants to merge
18
commits into
main
Choose a base branch
from
plot_extraction
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
001e9dc
Create plot_extraction.md
dhiraj-ms 480db9f
Update mkdocs.yml
dhiraj-ms 27082ea
Merge branch 'main' into plot_extraction
dhiraj-ms eb45dd5
Update plot_extraction.md
dhiraj-ms 6489896
Merge branch 'plot_extraction' of https://github.com/danforthcenter/p…
dhiraj-ms 923e1f7
Update plot_extraction.md
dhiraj-ms c16d10e
Plot Extraction Algorithm
dhiraj-ms 2d4851d
Update __init__.py
dhiraj-ms b09b8cd
Update __init__.py
dhiraj-ms ea64527
Update __init__.py
dhiraj-ms f7dd749
Update pyproject.toml
dhiraj-ms 1ee6ee3
Update README.md
dhiraj-ms 0feb0d8
Update README.md
dhiraj-ms 7bbf0eb
Removed import "write_shapefile"
dhiraj-ms 64a67a0
Update __init__.py
dhiraj-ms 587eeff
Update plot_extraction.py
dhiraj-ms 174d732
Update plot_extraction.py
dhiraj-ms 300409e
Update plot_extraction.py
dhiraj-ms File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
## Create a rectangular shapefile to extract area of interest from agricultural research plots | ||
|
||
|
||
**plantcv.geospatial.extract_plot**(*input_filename, output_filename, ranges, columns, row_length, vertical_alley, horizontal_alley) | ||
|
||
**returns** [Multi-Polygon Shapefile] | ||
|
||
- **Parameters:** | ||
- input_filename - Filepath to input shapefile consiting four corners of the field | ||
- output_filename - Filepath to output shapefile containing individual rectangular ploygon corresponding to specific research plot | ||
- ranges - Number of ranges | ||
- columns - Number of columns | ||
- row_length - Row longth along column in meters | ||
- vertical_alley - Length of alley between ranges in meters | ||
- horziontal_alley - Length of alley between columns in meters | ||
|
||
- **Example use:** | ||
- below | ||
|
||
|
||
```python | ||
import plantcv.plantcv as pcv | ||
import plantcv.geospatial.extract_plot as gridcell | ||
|
||
# Path of input and output shapefile | ||
input_shapefile_path = '712_corner_points.shp' | ||
output_shapefile_path = '712_polygon.shp' | ||
output_shapefile = gridcell.write_shapefile(input_shapefile_path, output_shapefile_path, number_of_ranges=45, number_of_columns=12, | ||
row_length_along_column=2.4384, vertical_alley=0.9144, | ||
horizontal_alley=0.0) | ||
|
||
``` | ||
|
||
**Source Code:** [Here](https://github.com/danforthcenter/plantcv-geospatial/blob/main/plantcv/geospatial/plot_extract.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
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,82 @@ | ||
import math | ||
import fiona | ||
from shapely.geometry import mapping, Polygon, LineString | ||
|
||
|
||
def create_rectangle_from_points(shapefile_path): | ||
with fiona.open(shapefile_path, 'r') as shapefile: | ||
points = [shape['geometry']['coordinates'] for shape in shapefile] | ||
rectangle = Polygon(points) | ||
return rectangle | ||
|
||
|
||
def calculate_line_length_in_meters(line): | ||
total_length = 0 | ||
for i in range(len(line.coords)-1): | ||
x1, y1 = line.coords[i] | ||
x2, y2 = line.coords[i+1] | ||
segment_length = math.sqrt((x2 - x1)**2 + (y2 - y1)**2) | ||
total_length += segment_length | ||
return total_length | ||
|
||
|
||
def get_field_edges(rectangle): | ||
coords = list(rectangle.exterior.coords) | ||
edge1 = LineString([coords[0], coords[1]]) | ||
edge2 = LineString([coords[0], coords[3]]) | ||
return edge1, edge2 | ||
|
||
|
||
def create_grid(rectangle, edge1, edge2, columns, row_length_along_column, vertical_gap): | ||
edge1_length = calculate_line_length_in_meters(edge1) | ||
edge2_length = calculate_line_length_in_meters(edge2) | ||
horizontal_threshold = edge1_length/columns | ||
vertical_threshold = row_length_along_column | ||
divisions_along_edge1 = round(edge1_length / horizontal_threshold) | ||
divisions_along_edge2 = round((edge2_length - vertical_gap) / (vertical_threshold + vertical_gap)) + 1 | ||
edge1_start = edge1.coords[0] | ||
edge2_start = edge2.coords[0] | ||
|
||
edge1_dir = ((edge1.coords[1][0] - edge1_start[0]) / edge1.length, | ||
(edge1.coords[1][1] - edge1_start[1]) / edge1.length) | ||
edge2_dir = ((edge2.coords[1][0] - edge2_start[0]) / edge2.length, | ||
(edge2.coords[1][1] - edge2_start[1]) / edge2.length) | ||
|
||
grid_cells = [] | ||
|
||
for column_number in range(divisions_along_edge1): | ||
for row_number in range(divisions_along_edge2): | ||
start_x = edge1_start[0] + column_number * horizontal_threshold * edge1_dir[0] + row_number * (vertical_threshold + vertical_gap) * edge2_dir[0] | ||
start_y = edge1_start[1] + column_number * horizontal_threshold * edge1_dir[1] + row_number * (vertical_threshold + vertical_gap) * edge2_dir[1] | ||
bottom_left = (start_x, start_y) | ||
bottom_right = (bottom_left[0] + horizontal_threshold * edge1_dir[0], | ||
bottom_left[1] + horizontal_threshold * edge1_dir[1]) | ||
top_left = (bottom_left[0] + vertical_threshold * edge2_dir[0], | ||
bottom_left[1] + vertical_threshold * edge2_dir[1]) | ||
top_right = (bottom_right[0] + vertical_threshold * edge2_dir[0], | ||
bottom_right[1] + vertical_threshold * edge2_dir[1]) | ||
|
||
cell = Polygon([bottom_left, bottom_right, top_right, top_left, bottom_left]) | ||
if cell.intersects(rectangle): | ||
grid_cells.append({"polygon": cell, "row": row_number + 1, "column": column_number + 1}) | ||
|
||
return grid_cells | ||
|
||
|
||
def write_shapefile(number_of_columns, row_length_along_column, output_shapefile_path, input_shapefile_path, vertical_gap): | ||
rectangle = create_rectangle_from_points(input_shapefile_path) | ||
edge1, edge2 = get_field_edges(rectangle) | ||
grid_cells = create_grid(rectangle, edge1, edge2, number_of_columns, row_length_along_column, vertical_gap) | ||
|
||
with fiona.open(input_shapefile_path, 'r') as input_shapefile: | ||
driver = input_shapefile.driver | ||
crs = input_shapefile.crs | ||
schema = {'geometry': 'Polygon', 'properties': {'id': 'int', 'row': 'int', 'column': 'int', 'label': 'str'}} | ||
|
||
with fiona.open(output_shapefile_path, 'w', driver=driver, crs=crs, schema=schema) as output_shapefile: | ||
for idx, cell in enumerate(grid_cells): | ||
label = f"({cell['row']},{cell['column']})" | ||
output_shapefile.write({ | ||
'geometry': mapping(cell["polygon"]), | ||
'properties': {'id': idx, 'row': cell["row"], 'column': cell["column"], 'label': label}, | ||
}) |
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 @@ | ||
UTF-8 |
Binary file not shown.
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 @@ | ||
PROJCS["WGS_1984_UTM_Zone_15N",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-93.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]] |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is super minor, but having the filename closely matching the function name will make things more searchable as this repository gets larger in the future. Therefore, I suggest changing the filename to "extract_plot.md" here and the function file to "extract_plot.py".
Generally, this PR is adding a few functions all under the aim of plot extraction, but do we only expect an end user to call the function "write_shapefile"? If so, we can consider making the syntax of the other functions similar to that used in "helper functions" in the main namespace (e.g.
_calculate_grid
is a helper function ofauto_grid
insideroi_methods.py
).