def testCodec(self): p = ConvexPolygon( [UnitVector3d.Z(), UnitVector3d.X(), UnitVector3d.Y()]) s = p.encode() self.assertEqual(ConvexPolygon.decode(s), p) self.assertEqual(Region.decode(s), p)
def find_intersecting_exposures(database, region): """Find exposures that intersect a spherical region. Parameters ---------- database : sqlite3.Connection or str A connection to (or filename of) a SQLite 3 database containing an exposure index. region : lsst.sphgeom.Region The spherical region of interest. Returns ------- A list of :class:`.ExposureInfo` objects corresponding to the exposures intersecting `region`. Their ``data_id`` attributes are data-id objects that can be passed to a butler to retrieve the corresponding exposure, and their ``boundary`` attributes are |polygon| objects. """ if isinstance(database, sqlite3.Connection): conn = database else: conn = sqlite3.connect(database) query = ("SELECT pickled_data_id, encoded_polygon\n" "FROM exposure JOIN exposure_rtree USING (rowid)\n" "WHERE x_min < ? AND x_max > ? AND\n" " y_min < ? AND y_max > ? AND\n" " z_min < ? AND z_max > ?") bbox = region.getBoundingBox3d() params = (bbox.x().getB(), bbox.x().getA(), bbox.y().getB(), bbox.y().getA(), bbox.z().getB(), bbox.z().getA()) results = [] for row in conn.execute(query, params): # Note that in Python 2, BLOB columns are mapped to Python buffer # objects, and so a conversion to str is necessary. In Python 3, # BLOBs are mapped to bytes directly, and the str() calls must # be removed. poly = ConvexPolygon.decode(str(row[1])) if region.relate(poly) != DISJOINT: results.append(ExposureInfo(pickle.loads(str(row[0])), poly)) return results
def process_result_value(self, value, dialect): if value is None: return None return ConvexPolygon.decode(super().process_result_value( value, dialect))
def testCodec(self): p = ConvexPolygon([UnitVector3d.Z(), UnitVector3d.X(), UnitVector3d.Y()]) s = p.encode() self.assertEqual(ConvexPolygon.decode(s), p) self.assertEqual(ConvexPolygon.cast(Region.decode(s)), p)
def store_exposure_info(database, allow_replace, exposure_info): """Store exposure data-ids and bounding polygons in the given database. The database is assumed to have been initialized via :func:`.create_exposure_tables`. Parameters ---------- database : sqlite3.Connection or str A connection to (or filename of) a SQLite 3 database. allow_replace : bool If ``True``, information for previously stored exposures with matching data-ids will be overwritten. exposure_info : iterable or lsst.daf.ingest.indexExposure.ExposureInfo One or more :class:`.ExposureInfo` objects to persist. Their ``data_id`` attributes must be pickled data-ids, and their ``boundary`` attributes must be |encoded| |polygon| objects. """ if isinstance(database, sqlite3.Connection): conn = database else: conn = sqlite3.connect(database) with conn: cursor = conn.cursor() if isinstance(exposure_info, ExposureInfo): exposure_info = (exposure_info,) # Insert or update information in database for info in exposure_info: if info is None: continue # In Python 2, the sqlite3 module maps between Python buffer # objects and BLOBs. When migrating to Python 3, the buffer() # calls should be removed (sqlite3 maps bytes objects to BLOBs). pickled_data_id = buffer(info.data_id) encoded_polygon = buffer(info.boundary) bbox = ConvexPolygon.decode(info.boundary).getBoundingBox3d() if allow_replace: # See if there is already an entry for the given data id. cursor.execute( 'SELECT rowid FROM exposure WHERE pickled_data_id = ?', (pickled_data_id,) ) results = cursor.fetchall() if len(results) > 0: # If so, update spatial information for the exposure. row_id = results[0][0] cursor.execute( 'UPDATE exposure\n' ' SET encoded_polygon = ?\n' ' WHERE rowid = ?', (encoded_polygon, row_id) ) cursor.execute( 'UPDATE exposure_rtree SET\n' ' x_min = ?, x_max = ?,\n' ' y_min = ?, y_max = ?,\n' ' z_min = ?, z_max = ?\n' 'WHERE rowid = ?', (bbox.x().getA(), bbox.x().getB(), bbox.y().getA(), bbox.y().getB(), bbox.z().getA(), bbox.z().getB(), row_id) ) return # Insert the data id and corresponding spatial information. cursor.execute( 'INSERT INTO exposure\n' ' (pickled_data_id, encoded_polygon)\n' ' VALUES (?, ?)', (pickled_data_id, encoded_polygon) ) row_id = cursor.lastrowid cursor.execute( 'INSERT INTO exposure_rtree\n' ' (rowid, x_min, x_max, y_min, y_max, z_min, z_max)\n' ' VALUES (?, ?, ?, ?, ?, ?, ?)', (row_id, bbox.x().getA(), bbox.x().getB(), bbox.y().getA(), bbox.y().getB(), bbox.z().getA(), bbox.z().getB()) )
def process_result_value(self, value: Optional[str], dialect: sqlalchemy.engine.Dialect ) -> Optional[ConvexPolygon]: if value is None: return None return ConvexPolygon.decode(super().process_result_value(value, dialect))
def process_result_value(self, value, dialect): return ConvexPolygon.decode( b64decode(value)) if value is not None else None