Log outage geometries to database #68

Merged
buckbanzai merged 6 commits from log-outage-location into main 2024-11-23 17:14:30 -08:00
2 changed files with 35 additions and 36 deletions
Showing only changes of commit 769e835411 - Show all commits

View file

@ -1,4 +1,5 @@
from shapely import MultiPolygon, Polygon
from shapely import MultiPolygon, Polygon, Geometry, to_wkb, from_wkb
from sqlalchemy.types import TypeDecorator, LargeBinary
def convert_outage_geometry(event) -> MultiPolygon:
@ -9,3 +10,21 @@ def convert_outage_geometry(event) -> MultiPolygon:
for ring in event["polygons"]["rings"]:
polygon_list.append(Polygon(ring))
return MultiPolygon(polygon_list)
class DBGeometry(TypeDecorator):
impl = LargeBinary
cache_ok = True
def process_bind_param(self, value, dialect):
if isinstance(value, Geometry):
value = to_wkb(value)
return value
def process_result_value(self, value, dialect):
if value is None:
return value
else:
if not isinstance(value, Geometry):
value = from_wkb(value)
return value

50
scl.py
View file

@ -5,17 +5,16 @@ from typing import Optional
import mastodon
import requests
import shapely
import sqlalchemy.types as types
import staticmap
import yaml
from mastodon import Mastodon
from PIL import Image, ImageDraw, ImageFont
from shapely import Geometry, MultiPolygon, Point, Polygon, from_wkb, to_wkb
from shapely import Geometry
from sqlalchemy import create_engine, select
from sqlalchemy.exc import NoResultFound
from sqlalchemy.orm import DeclarativeBase, Mapped, Session, mapped_column
from geospatial import convert_outage_geometry
from geospatial import DBGeometry, convert_outage_geometry
post_datetime_format = "%b %e %l:%M %p"
@ -118,16 +117,6 @@ def get_hashtag_string(event) -> str:
return hashtag_string
def convert_outage_geometry(event) -> MultiPolygon:
assert event["polygons"]["type"] == "polygon"
assert event["polygons"]["hasZ"] is False
assert event["polygons"]["hasM"] is False
polygon_list = []
for ring in event["polygons"]["rings"]:
polygon_list.append(Polygon(ring))
return MultiPolygon(polygon_list)
def do_initial_post(
event,
event_class,
@ -272,31 +261,21 @@ Cause: {}
)
)
post_result = mastodon_client.status_post(
status=post_text,
media_ids=map_media_post,
visibility="public",
language="en",
)
post_result = {"id": "0123"}
# post_result = mastodon_client.status_post(
# status=post_text,
# media_ids=map_media_post,
# visibility="public",
# language="en",
# )
post_id = post_result["id"]
return {"post_id": post_id, "map_media_post_id": map_media_post_id}
class GeometryWkb(types.TypeDecorator):
impl = types.LargeBinary
cache_ok = True
def process_bind_param(self, value, dialect):
return to_wkb(value)
def process_result_value(self, value, dialect):
return from_wkb(value)
class Base(DeclarativeBase):
type_annotation_map = {
Geometry: GeometryWkb,
Geometry: DBGeometry,
}
@ -317,10 +296,11 @@ class SclOutage(Base):
max_num_people: Mapped[int] = mapped_column()
neighborhood: Mapped[Optional[str]] = mapped_column()
city: Mapped[Optional[str]] = mapped_column()
outage_geometries: Mapped[Geometry] = mapped_column()
outage_geometries: Mapped[Optional[Geometry]] = mapped_column()
geometries_modified: Mapped[Optional[bool]] = mapped_column()
def __repr__(self) -> str:
return f"SclOutage(scl_outage_id={self.scl_outage_id!r}, most_recent_post_id={self.most_recent_post_id!r}, initial_post_id={self.initial_post_id!r}, map_media_post_id={self.map_media_post_id!r}, last_updated_time={self.last_updated_time!r}, no_longer_in_response_time={self.no_longer_in_response_time!r}, start_time={self.start_time!r}, num_people={self.num_people!r}, max_num_people={self.max_num_people!r}, neighborhood={self.neighborhood!r}, city={self.city!r}, outage_geometries={self.outage_geometries!r})"
return f"SclOutage(scl_outage_id={self.scl_outage_id!r}, most_recent_post_id={self.most_recent_post_id!r}, initial_post_id={self.initial_post_id!r}, map_media_post_id={self.map_media_post_id!r}, last_updated_time={self.last_updated_time!r}, no_longer_in_response_time={self.no_longer_in_response_time!r}, start_time={self.start_time!r}, num_people={self.num_people!r}, max_num_people={self.max_num_people!r}, neighborhood={self.neighborhood!r}, city={self.city!r}, outage_geometries={self.outage_geometries!r}, geometries_modified={self.geometries_modified!r})"
engine = create_engine("sqlite:///scl.db")
@ -393,9 +373,9 @@ with Session(engine) as session:
existing_record.max_num_people = event["numPeople"]
max_event_class = classify_event_size(existing_record.max_num_people)
if existing_record.outage_geometries != outage_geometries:
print("updating geometries")
print("Geometries modified")
existing_record.outage_geometries = outage_geometries
existing_record.geometries_modified = True
if updated_properties:
updated_properties.sort()