def imageToPolygon(wcs, widthPix, heightPix, padRad=0.0): """Computes and returns a spherical convex polygon approximation to the region of the unit sphere covered by an image specified with a WCS and a width/height (pixels). The polygon is computed by connecting the world coordinates of the 4 image corners with great circles, and can optionally be padded by padRad radians. """ # Compute image corners cd = wcs.getCDMatrix() xpad = math.degrees(padRad) / math.sqrt(cd[0, 0]**2 + cd[0, 1]**2) ypad = math.degrees(padRad) / math.sqrt(cd[1, 0]**2 + cd[1, 1]**2) xmin, ymin = -0.5 - xpad, -0.5 - ypad xmax, ymax = widthPix + xpad - 0.5, heightPix + ypad - 0.5 # Produce a lsst.afw.coord.coordLib.Coord object for each vertex coords = [ wcs.pixelToSky(xmin, ymin), wcs.pixelToSky(xmax, ymin), wcs.pixelToSky(xmax, ymax), wcs.pixelToSky(xmin, ymax) ] # Map these to python tuples containing cartesian unit vectors verts = [] for c in coords: verts.append(tuple(c.getVector())) # and turn them into a spherical convex polygon convex, cc = geom.convex(verts) if not convex: raise RuntimeError('Image corners do not form a convex polygon: ' + cc) elif not cc: verts.reverse() return geom.SphericalConvexPolygon(verts)
def coordsToPolygon(coords): verts = [tuple(c.getVector()) for c in coords] convex, cc = geom.convex(verts) if not convex: raise RuntimeError('Image corners do not form a convex polygon: ' + cc) elif not cc: verts.reverse() return geom.SphericalConvexPolygon(verts)
def getGeometry(self, pixelId, fiducial=False): """Returns a spherical convex polygon corresponding to the fiducial or padded boundaries of the sky-pixel with the specified id. """ root, ix, iy = self.coords(pixelId) xl = 2.0 * float(ix) / float(self.resolution) - 1.0 xr = 2.0 * float(ix + 1) / float(self.resolution) - 1.0 yb = 2.0 * float(iy) / float(self.resolution) - 1.0 yt = 2.0 * float(iy + 1) / float(self.resolution) - 1.0 c, x, y = self.center[root], self.x[root], self.y[root] v = list( map(geom.normalize, [(c[0] + xl * x[0] + yb * y[0], c[1] + xl * x[1] + yb * y[1], c[2] + xl * x[2] + yb * y[2]), (c[0] + xr * x[0] + yb * y[0], c[1] + xr * x[1] + yb * y[1], c[2] + xr * x[2] + yb * y[2]), (c[0] + xr * x[0] + yt * y[0], c[1] + xr * x[1] + yt * y[1], c[2] + xr * x[2] + yt * y[2]), (c[0] + xl * x[0] + yt * y[0], c[1] + xl * x[1] + yt * y[1], c[2] + xl * x[2] + yt * y[2])])) if not fiducial and self.padding > 0.0: # Determine angles by which edge planes must be rotated outwards sp = math.sin(self.padding) theta = [ 0.5 * geom.cartesianAngularSep(x[0], x[1]) for x in ((v[0], v[3]), (v[1], v[0]), (v[2], v[1]), (v[3], v[2])) ] sina = [sp / math.cos(math.radians(x)) for x in theta] cosa = [math.sqrt(1.0 - x * x) for x in sina] # find plane equations of fiducial pixel boundaries xlp = self.xplane[root][ix][0] ybp = self.yplane[root][iy][0] xrp = self.xplane[root][ix + 1][0] ytp = self.yplane[root][iy + 1][0] # rotate edge planes outwards xlp = self.xrot[root](xlp, -sina[0], cosa[0]) ybp = self.yrot[root](ybp, -sina[1], cosa[1]) xrp = self.xrot[root](xrp, sina[2], cosa[2]) ytp = self.yrot[root](ytp, sina[3], cosa[3]) # intersect rotated planes to find vertices of padded sky-pixel v = list( map(geom.normalize, [ geom.cross(xlp, ybp), geom.cross(xrp, ybp), geom.cross(xrp, ytp), geom.cross(xlp, ytp) ])) return geom.SphericalConvexPolygon(v)