Skip to content

Commit 0f2bc42

Browse files
committed
Towards cleaning up the geography module and seabed_tools
- Deleted projectAlongSeabed function since that has now moved to main project.py file - Deleted all of the old commented out code (that was used for plots in the 2023 shared anchor LCOE report) - Deleted the plot3d function because this is also outdated from the new project.plot3d - Still some more ideas to be addressed in merging in similar ideas from seabed_tools
1 parent 3e596e0 commit 0f2bc42

File tree

1 file changed

+0
-370
lines changed

1 file changed

+0
-370
lines changed

famodel/geography.py

Lines changed: 0 additions & 370 deletions
Original file line numberDiff line numberDiff line change
@@ -520,377 +520,7 @@ def getSoilGrid(centroid, latlong_crs, custom_crs, soil_file, nrows=100, ncols=1
520520

521521

522522

523-
def plot3d(lease_xs, lease_ys, bathymetryfilename, area_on_bath=False, args_bath={}, xbounds=None, ybounds=None, zbounds=None):
524-
'''Plot aspects of the Project object in matplotlib in 3D'''
525-
526-
# organize the bathymetry arguments
527-
if len(args_bath)==0:
528-
args_bath = {'zlim':[-3200,500], 'cmap':'gist_earth'}
529-
530-
fig = plt.figure(figsize=(6,4))
531-
ax = plt.axes(projection='3d')
532-
533-
if xbounds != None:
534-
ax.set_xlim(xbounds[0], xbounds[1])
535-
if ybounds != None:
536-
ax.set_ylim(ybounds[0], ybounds[1])
537-
if zbounds != None:
538-
ax.set_zlim(zbounds[0], zbounds[1])
539-
540-
# plot the lease area in a red color, if desired
541-
ax.plot(lease_xs, lease_ys, np.zeros(len(lease_xs)), color='r', zorder=100)
542-
543-
# plot the bathymetry in matplotlib using a plot_surface
544-
545-
# !!!! include option to plot entire bathymetry file or not
546-
547-
if isinstance(bathymetryfilename, str):
548-
bathGrid_Xs, bathGrid_Ys, bathGrid = sbt.readBathymetryFile(bathymetryfilename) # parse through the MoorDyn/MoorPy-formatted bathymetry file
549-
X, Y = np.meshgrid(bathGrid_Xs, bathGrid_Ys) # create a 2D mesh of the x and y values
550-
bath = ax.plot_surface(X, Y, -bathGrid, rstride=1, cstride=1,
551-
vmin=args_bath['zlim'][0], vmax=args_bath['zlim'][1],
552-
cmap=args_bath['cmap'])
553-
554-
'''
555-
# plot the project boundary
556-
if boundary:
557-
ax.plot(self.boundaryXs, self.boundaryYs, np.zeros(len(self.boundaryXs)), color='b', zorder=100, alpha=0.5)
558-
'''
559-
560-
# plot the projection of the lease area bounds on the seabed, if desired
561-
if area_on_bath:
562-
lease_zs = projectAlongSeabed(lease_xs, lease_ys, bathGrid_Xs, bathGrid_Ys, bathGrid)
563-
ax.plot(lease_xs, lease_ys, -lease_zs, color='tab:blue', zorder=10, alpha=0.5)
564-
565-
566-
set_axes_equal(ax)
567-
ax.axis('off')
568-
569-
return fig, ax
570-
571-
572-
573-
def projectAlongSeabed(x, y, bathXs, bathYs, bath_depths):
574-
'''Project a set of x-y coordinates along a seabed surface (grid),
575-
returning the corresponding z coordinates.'''
576-
577-
if len(x) == len(y):
578-
n = len(x)
579-
z = np.zeros(n) # z coordinate of each point [m]
580-
a = np.zeros(n) # could also do slope (dz/dh)
581-
for i in range(n):
582-
z[i], nvec = sbt.getDepthFromBathymetry(x[i], y[i], bathXs, bathYs, bath_depths)
583-
584-
else:
585-
z = np.zeros([len(y), len(x)])
586-
for i in range(len(y)):
587-
for j in range(len(x)):
588-
z[i,j], nvec = sbt.getDepthFromBathymetry(x[j], y[i], bathXs_mesh, bathYs_mesh, bath_depths)
589-
590-
return z
591-
592-
593-
594-
595-
596-
597-
598-
599-
600-
601-
602-
"""
603-
if self.lat0 != 0 and self.lon0 != 0:
604-
# set the centroid of the project and save in a GeoDataFrame
605-
self.centroid = (self.lon0, self.lat0)
606-
self.gdf = gpd.GeoDataFrame({'type':'centroid', 'geometry': [Point(self.centroid)]}, crs=self.latlong_crs)
607-
# set the target coordinate reference system (CRS) that will switch between regular lat/long system and "meters from centroid" system, based on centroid location
608-
information
609-
# extract the numeric code
610-
self. # save the target CRS (UTM 10N = 32610)
611-
612-
613-
gdf_leases = gpd.GeoDataFrame({'type': 'lease_area', 'geometry': lease_area.geometry}, crs=getLatLongCRS() )
614-
615-
gdf = add2geodataframe(gdf0, gdf_leases)
616-
617-
# convert lat/long boundary/lease area points to meters away from the centroid
618-
self.lease_xs, self.lease_ys = self.convertLatLong2Meters(self.area_longs, self.area_lats, self.centroid)
619-
620-
621-
if which_centroid=='lease_area':
622-
# make a blank copy of the gdf to switch to the target CRS to get the accurate centroid
623-
gdf_utm = self.gdf.copy().to_crs(self.target_crs)
624-
centroid_utm = (gdf_utm.geometry.centroid.values.x[0], gdf_utm.geometry.centroid.values.y[0])
625-
gdf_centroid = gpd.GeoDataFrame({'type':'centroid', 'geometry': [Point(centroid_utm)]}, crs=self.target_crs)
626-
else:
627-
# assuming the input centroid is in a long/lat pair
628-
gdf_centroid = gpd.GeoDataFrame({'type':'centroid', 'geometry': [Point(which_centroid)]}, crs=self.latlong_crs)
629-
gdf_centroid.to_crs(self.target_crs)
630-
631-
self.centroid_utm = (gdf_centroid.geometry.values.x[0], gdf_centroid.geometry.values.y[0])
632-
self.centroid = (gdf_centroid.to_crs(self.latlong_crs).geometry.values.x[0], gdf_centroid.to_crs(self.latlong_crs).geometry.values.y[0]) # assume centroid is focal point of Project
633-
634-
def initialize_geodataframe(crs, columns=['type','geometry']):
635-
636-
gdf = gpd.GeoDataFrame(columns=columns, geometry='initialization', crs=crs)
637-
638-
return gdf
639-
640-
def add2geodataframe(gdf_to_add_to, gdf_to_add):
641-
642-
# check to make sure they have the same columns and CRS
643-
644-
gdf_new = pd.concat([gdf_to_add_to, gdf_to_add])
645-
646-
return gdf_new
647-
648-
649-
650-
651-
652-
# TODO
653-
654-
# reference entire CA bathymetry file (maybe)
655-
# plot2d method and a plotGDF method (with bathymetry in the geodataframe using contours)
656-
657-
# add the coastline
658-
#xcoast, ycoast = sbt.getCoast(self.Xs, self.Ys, self.depths)
659-
#ax.plot(xcoast, ycoast, np.zeros(len(self.Ys)), color='k', zorder=100)
660-
661-
# need to fix up bounds
662-
#xbmin, xbmax = sbt.getPlotBounds(self.longs_bath, self.centroid, long=True)
663-
#ybmin, ybmax = sbt.getPlotBounds(self.lats_bath, self.centroid, long=False)
664-
665-
plt.show()
666-
667-
668-
669-
670-
671-
672-
673-
674-
# METHODS USED SPECIFICALLY FOR DEEPFARM LCOE ANALYSIS
675-
676-
def addMap2GDF(self, filename='', states=None):
677-
'''function to include a shapefile of a provided map'''
678-
679-
# read in the provided filename to add to the geodataframe
680-
usa = gpd.read_file(filename)
681-
# internal list of states, in order, to go with the default U.S. states shapefile
682-
statenamelist = ['Maryland','Iowa','Delaware','Ohio','Pennsylvania','Nebraska','Washington','Puerto Rico','Alabama','Arkansas','New Mexico', # 0-10
683-
'Texas','California','Kentucky','Georgia','Wisconsin','Oregon','Missouri','Virginia','Tennessee','Louisiana','New York', # 11-21
684-
'Michigan','Idaho','Florida','Alaska','Illinois','Montana','Minnesota','Indiana','Massachusetts','Kansas','Nevada','Vermont', # 22-33
685-
'Connecticut','New Jersey','Washington D.C.','North Carolina','Utah','North Dakota','South Carolina','Mississippi','Colorado', # 34-42
686-
'South Dakota','Oklahoma','Wyoming','West Virginia','Maine','Hawaii','New Hampshire','Arizona','Rhode Island'] # 43-51
687-
# insert names of the states into the new gdf
688-
usa.insert(0, 'type', statenamelist)
689-
# set the CRS of the USA pdf to the right CRS
690-
usa.set_crs(crs="EPSG:4326", inplace=True)
691-
self.usa = usa
692-
693-
for state in states:
694-
state_gs = usa.loc[usa['type']==state]
695-
self.gdf = pd.concat([self.gdf, state_gs])
696-
697-
698-
699-
def setFarmLayout(self, style='grid', nrows=10, ncols=10, turbine_spacing=2000, nOSS=2):
700-
701-
if style=='grid':
702-
# for now, this is very custom code specific to the DeepFarm project
703-
farmxspacing = (nrows-1)*turbine_spacing
704-
farmyspacing = (ncols-1)*turbine_spacing
705-
706-
turbine_distances_from_centroid = []
707-
oss_distances_from_centroid = []
708-
for j in reversed(range(ncols)):
709-
for i in range(nrows):
710-
xpos = -(farmxspacing/2)+(i*turbine_spacing)
711-
ypos = -(farmyspacing/2)+(j*turbine_spacing)
712-
turbine_distances_from_centroid.append((xpos, ypos))
713-
714-
# add positions of two offshore substations (OSSs)
715-
oss_distances_from_centroid.append((11000.0, 5000.0))
716-
oss_distances_from_centroid.append((11000.0, -5000.0))
717-
718-
if style=='shared':
719-
turbine_xspacing = np.sqrt(2000**2-1000**2)
720-
turbine_yspacing = 2000
721-
farmxspacing = turbine_xspacing*9
722-
farmyspacing = turbine_yspacing*9
723-
724-
turbine_distances_from_centroid = []
725-
oss_distances_from_centroid = []
726-
for j in reversed(range(ncols)):
727-
for i in range(nrows):
728-
xpos = -(farmxspacing/2)+(i*turbine_xspacing)
729-
ypos = -(farmyspacing/2)+(j*turbine_yspacing) - 1000*np.sin(np.radians(30)) + 1000*(i%2)
730-
turbine_distances_from_centroid.append((xpos, ypos))
731-
732-
# add positions of two offshore substations (OSSs)
733-
oss_distances_from_centroid.append((5.5*turbine_xspacing, 2.0*turbine_yspacing+1000*np.sin(np.radians(30))))
734-
oss_distances_from_centroid.append((5.5*turbine_xspacing, -2.5*turbine_yspacing-1000*np.sin(np.radians(30))))
735-
736-
if style=='small-shared':
737-
turbine_xspacing = np.sqrt(2000**2-1000**2)
738-
turbine_yspacing = 2000
739-
farmxspacing = turbine_xspacing*1
740-
farmyspacing = turbine_yspacing*2
741-
742-
turbine_distances_from_centroid = []
743-
oss_distances_from_centroid = []
744-
for j in reversed(range(3)):
745-
for i in range(2):
746-
xpos = -(farmxspacing/2)+(i*turbine_xspacing)
747-
ypos = -(farmyspacing/2)+(j*turbine_yspacing) - 1000*np.sin(np.radians(30)) + 1000*(i%2)
748-
turbine_distances_from_centroid.append((xpos, ypos))
749-
750-
# add positions of two offshore substations (OSSs)
751-
oss_distances_from_centroid.append((-0.5*turbine_xspacing, 2.0*turbine_yspacing-1000*np.sin(np.radians(30))))
752-
753-
754-
# create a copy of the global gdf and transform it into the easting/northing coordinate reference system
755-
gdf_utm = self.gdf.copy().to_crs(self.target_crs)
756-
xcentroid = gdf_utm.loc[gdf_utm['type']=='centroid'].centroid.x[0]
757-
ycentroid = gdf_utm.loc[gdf_utm['type']=='centroid'].centroid.y[0]
758-
759-
# create shapely Point objects of the turbine positions relative to the centroid, in the UTM CRS
760-
turbine_geoms = []
761-
for i,(x,y) in enumerate(turbine_distances_from_centroid):
762-
turbine_geoms.append( Point(xcentroid + x, ycentroid + y) )
763-
764-
oss_geoms = []
765-
for i,(x,y) in enumerate(oss_distances_from_centroid):
766-
oss_geoms.append( Point(xcentroid + x, ycentroid + y) )
767-
768-
# make a new gdf to put the turbine data together
769-
turbine_gdf = gpd.GeoDataFrame({'type': ['turbine']*len(turbine_geoms), 'geometry': turbine_geoms}, crs=self.target_crs)
770-
# make a new gdf to put the substation data together
771-
oss_gdf = gpd.GeoDataFrame({'type': 'substation', 'geometry': oss_geoms}, crs=self.target_crs)
772-
# merge these two geodataframes together into one (best way I can find to "add" rows to a dataframe; ignoring index makes all indices a different number)
773-
turbine_gdf = pd.concat([turbine_gdf, oss_gdf], ignore_index=True)
774-
775-
# convert the turbine/oss coordinates back to regular latitude/longitude (EPSG: 4326)
776-
turbine_gdf = turbine_gdf.to_crs('EPSG:4326')
777-
778-
# add the turbine gdf to the global gdf
779-
self.gdf = pd.concat([self.gdf, turbine_gdf], ignore_index=True)
780-
781-
# add local variables in this method to the turbine_gdf to be used later (but don't need for the global gdf)
782-
turbine_gdf.insert(2, 'easting_northing_geometry', turbine_geoms + oss_geoms)
783-
turbine_gdf.insert(3, 'meters_from_centroid', turbine_distances_from_centroid + oss_distances_from_centroid)
784-
785-
# save this new turbine_gdf for future use
786-
self.turbine_gdf = turbine_gdf
787-
788-
# make a layout CSV (used for WHaLE/WAVES)
789-
self.makeLayoutCSV()
790-
791-
792-
793-
def makeLayoutCSV(self, filename='layout_test.csv'):
794-
795-
turbine_longs = [point.coords[0][0] for point in self.turbine_gdf.geometry]
796-
turbine_lats = [point.coords[0][1] for point in self.turbine_gdf.geometry]
797-
798-
self.turbine_gdf.insert(2, 'longitude', turbine_longs)
799-
self.turbine_gdf.insert(3, 'latitude', turbine_lats)
800-
801-
turbine_eastings = [point.coords[0][0] for point in self.turbine_gdf['easting_northing_geometry']]
802-
turbine_northings = [point.coords[0][1] for point in self.turbine_gdf['easting_northing_geometry']]
803-
804-
#self.turbine_gdf.insert(5, 'easting', turbine_eastings)
805-
#self.turbine_gdf.insert(6, 'northing', turbine_northings)
806-
807-
turbine_x_from_centroid = [point[0] for point in self.turbine_gdf['meters_from_centroid']]
808-
turbine_y_from_centroid = [point[1] for point in self.turbine_gdf['meters_from_centroid']]
809-
810-
self.turbine_gdf.insert(5, 'easting', turbine_x_from_centroid)
811-
self.turbine_gdf.insert(6, 'northing', turbine_y_from_centroid)
812-
813-
self.turbine_gdf.insert(8, 'floris_x', turbine_x_from_centroid)
814-
self.turbine_gdf.insert(9, 'floris_y', turbine_y_from_centroid)
815-
816-
columns = ['type', 'longitude', 'latitude', 'easting', 'northing', 'floris_x', 'floris_y']
817-
df = pd.DataFrame(self.turbine_gdf)
818-
df.to_csv(filename, columns=columns)
819-
820-
821-
def plotGDF(self, kwargs):
822-
'''2D map-like plot'''
823-
824-
if 'centroid' in kwargs:
825-
centroid_settings = kwargs['centroid']
826-
if 'label' in centroid_settings:
827-
centroid_label = 'centroid'
828-
if 'map' in kwargs:
829-
map_settings = kwargs['map']
830-
if 'farm' in kwargs:
831-
farm_settings = kwargs['farm']
832-
833-
fig, ax = plt.subplots(1,1)
834-
835-
if 'centroid' in kwargs:
836-
self.gdf.loc[self.gdf['type']=='centroid'].plot(ax=ax, color=centroid_settings['color'], label=centroid_label)
837-
838-
if 'boundary' in kwargs:
839-
map_boundary = self.gdf.loc[self.gdf['type']=='California'].boundary
840-
map_boundary.plot(ax=ax, color=map_settings['color'])
841-
842-
if 'farm' in kwargs:
843-
self.gdf.loc[self.gdf['type']=='turbine'].plot(ax=ax, color=farm_settings['turbine']['color'], label='turbine')
844-
self.gdf.loc[self.gdf['type']=='substation'].plot(ax=ax, color=farm_settings['oss']['color'], label='substation')
845-
846-
ax.set_xlabel('Longitude')
847-
ax.set_ylabel('Latitude')
848-
ax.legend()
849-
850-
ax.set_xlim([-124.875, -124.55])
851-
ax.set_ylim([40.025, 40.25])
852-
853-
fig.tight_layout()
854-
855-
# Some GeoPandas Help
856-
# to plot just one entry of a geoseries: gdf.loc[[0],'geometry'].plot()
857-
# to get the columns of a gdf: gdf.columns
858-
# merging gdf's
859-
# adding columns to gdf's
860-
861-
return fig, ax
862-
863-
864-
865-
def addPoints(self, ax, pointlist=[], kwargs={}):
866-
867-
point_settings = kwargs['pointlist']
868-
869-
points = gpd.GeoDataFrame({'type':['nrel_channel','nrel_humboldt','nrel_crescent_city','hawaii'],
870-
'geometry': pointlist}, crs='EPSG:4326')
871-
872-
points.plot(ax=ax, color=point_settings['color'], marker=point_settings['marker'], label=point_settings['label'])
873-
874-
875-
def addState(self, ax, states=[], kwargs={}):
876-
877-
for state in states:
878-
state_settings=kwargs[state]
879-
880-
state_geom = self.usa.loc[self.usa['type']==state]
881-
if 'boundary' in state_settings:
882-
state_geom = state_geom.boundary
883-
884-
newstate = gpd.GeoDataFrame({'type':state, 'geometry':state_geom}, crs='EPSG:4326')
885-
886-
newstate.plot(ax=ax, color=state_settings['color'])
887-
888-
889-
890-
891-
892523

893-
"""
894524

895525

896526

0 commit comments

Comments
 (0)