from dataclasses import dataclass
from typing import Optional, List, Union
from shapely.geometry import Point, LineString, Polygon, MultiPolygon
import pytz
import json
import geopandas as gpd
import pvlib
from energydatamodel import AbstractClass
[docs]
@dataclass(repr=False)
class GeoLocation(AbstractClass):
"""This is the docstring for Location."""
longitude: float
latitude: float
tz: Union[str, pytz.timezone] = "UTC"
altitude: Optional[float] = None
name: Optional[str] = None
def __post_init__(self):
self.point = Point(self.latitude, self.longitude)
if isinstance(self.tz, str):
self.tz = pytz.timezone(self.tz)
[docs]
@classmethod
def from_point(cls, point: Point):
return cls(longitude=point.x, latitude=point.y)
[docs]
def to_tuple(self):
return (self.latitude, self.longitude)
@property
def tuple(self):
return self.to_tuple()
[docs]
def to_pvlib(self):
return pvlib.location.Location(latitude=self.latitude, longitude=self.longitude, altitude=self.altitude, tz=self.tz)
Location = GeoLocation
[docs]
@dataclass
class GeoLine(AbstractClass, LineString):
"""This is the docstring for LineString."""
[docs]
@dataclass
class GeoPolygon(AbstractClass, Polygon):
"""This is the docstring for Polygon."""
name: Optional[str] = None
#TODO I think it would be nicer if GeoMultiPolygon was a subclass of MultiPolygon instead of composition.
[docs]
@dataclass
class GeoMultiPolygon(AbstractClass):
"""This is the docstring for Polygon."""
multipolygon: MultiPolygon = None
name: Optional[str] = None
[docs]
@classmethod
def from_geojson(cls, file: str):
multipolygon = gpd.read_file(file).loc[0, "geometry"]
return cls(multipolygon=multipolygon)
[docs]
def to_geojson(self):
return json.loads(json.dumps(self.multipolygon.__geo_interface__))
@property
def geojson(self):
return self.to_geojson()
[docs]
@dataclass
class GeoGraph(AbstractClass):
"""This is the docstring for GeoGraph."""
name: Optional[str] = None