def tileBoundsLonLat(zoom, x, y): corners = ((x, y), (x + 1, y + 1)) pixelCorners = [tileIndexToPixels(*corner) for corner in corners] mercatorCorners = [ transform.pixelsToMeters(*(pixels + (zoom, ))) for pixels in pixelCorners ] nw, se = [transform.metersToLatLon(c) for c in mercatorCorners] west, north = nw east, south = se return {'north': north, 'south': south, 'east': east, 'west': west}
def imageMapBounds(imageSize, tform): w, h = imageSize imageCorners = cornerPoints([0, 0, w, h]) mercatorCorners = [tform.forward(c) for c in imageCorners] latLonCorners = [transform.metersToLatLon(c) for c in mercatorCorners] bounds = Bounds(latLonCorners) return { 'west': bounds.xmin, 'south': bounds.ymin, 'east': bounds.xmax, 'north': bounds.ymax }
def parseManualEntryPointPairs(self, manualInfoDict): '''Unpack the inlier point pairs from an entry in the geocamTiePoint_overlay table''' imageInliers = [] gdcInliers = [] allPoints = manualInfoDict['points'] for point in allPoints: if (point[0] == None) or (point[1] == None) or (point[2] == None) or (point[3] == None): continue # Skip buggy entries! # The world coordinates in the manual table are stored in projected coordinates gdcCoord = transform.metersToLatLon((point[0], point[1])) gdcInliers.append(gdcCoord) imageInliers.append((point[2], point[3])) return (imageInliers, gdcInliers)
def getPixelToGdcTransform(imagePath, pixelToProjectedTransform=None): '''Returns a pixel to GDC transform. The input image must either be a nicely georegistered image from Earth Engine or a pixel to projected coordinates transform must be provided.''' if pixelToProjectedTransform: # Have image to projected transform, convert it to an image to GDC transform. # Use the simple file info call (the input file may not have geo information) (width, height) = IrgGeoFunctions.getImageSize(imagePath) imagePoints = [] gdcPoints = [] # Loop through a spaced out grid of pixels in the image pointPixelSpacing = (width + height) / 20 # Results in about 100 points for r in range(0, width, pointPixelSpacing): for c in range(0, height, pointPixelSpacing): # This pixel --> projected coords --> lonlat coord thisPixel = numpy.array([float(c), float(r)]) projectedCoordinate = pixelToProjectedTransform.forward( thisPixel) gdcCoordinate = transform.metersToLatLon(projectedCoordinate) imagePoints.append(thisPixel) gdcPoints.append(gdcCoordinate) # Solve for a transform with all of these point pairs pixelToGdcTransform = transform.getTransform( numpy.asarray(gdcPoints), numpy.asarray(imagePoints)) else: # Using a reference image from EE which will have nice bounds. # Use the more thorough file info call stats = IrgGeoFunctions.getImageGeoInfo(imagePath, False) (width, height) = stats['image_size'] (minLon, maxLon, minLat, maxLat) = stats['lonlat_bounds'] # Make a transform from ref pixel to GDC using metadata on disk xScale = (maxLon - minLon) / width yScale = (maxLat - minLat) / height transformMatrix = numpy.array([[xScale, 0, minLon], [0, -yScale, maxLat], [0, 0, 1]]) pixelToGdcTransform = transform.LinearTransform(transformMatrix) return pixelToGdcTransform
def generateGeotiffExport(self, exportName, metaJson, slug): """ This generates a geotiff from RPC. """ overlay = Overlay.objects.get(alignedQuadTree = self) imageSizeType = overlay.imageData.sizeType now = datetime.datetime.utcnow() timestamp = now.strftime('%Y-%m-%d-%H%M%S-UTC') # get image width and height imageWidth = overlay.imageData.width imageHeight = overlay.imageData.height # update the center point with current transform and use those values transformDict = overlay.extras.transform tform = transform.makeTransform(transformDict) center_meters = tform.forward([imageWidth / 2, imageHeight / 2]) clon, clat = transform.metersToLatLon(center_meters) # get the RPC values T_rpc = rpcModel.fitRpcToModel(self.reversePts, imageWidth, imageHeight, clon, clat) srs = gdalUtil.EPSG_4326 # get original image imgPath = overlay.getRawImageData().image.url.replace('/data/', settings.DATA_ROOT) # reproject and tar the output tiff geotiffExportName = exportName + ('-%s-geotiff_%s' % (imageSizeType, timestamp)) geotiffFolderPath = settings.DATA_ROOT + 'geocamTiePoint/export/' + geotiffExportName dosys('mkdir %s' % geotiffFolderPath) fullFilePath = geotiffFolderPath + '/' + geotiffExportName +'.tif' gdalUtil.reprojectWithRpcMetadata(imgPath, T_rpc.getVrtMetadata(), srs, fullFilePath) geotiff_writer = quadTree.TarWriter(geotiffExportName) arcName = geotiffExportName + '.tif' geotiff_writer.writeData('meta.json', dumps(metaJson)) geotiff_writer.addFile(fullFilePath, geotiffExportName + '/' + arcName) # double check this line (second arg may not be necessary) self.geotiffExportName = '%s.tar.gz' % geotiffExportName self.geotiffExport.save(self.geotiffExportName, ContentFile(geotiff_writer.getData()))
def convertTransformToGeo(imageToRefImageTransform, newImagePath, refImagePath, refImageGeoTransform=None): '''Converts an image-to-image homography to the ProjectiveTransform class used elsewhere in geocam. Either the reference image must be geo-registered, or the geo transform for it must be provided.''' # Convert the image-to-image transform parameters to a class temp = numpy.array([imageToRefImageTransform[0:3], imageToRefImageTransform[3:6], imageToRefImageTransform[6:9]] ) imageToRefTransform = transform.ProjectiveTransform(temp) newImageSize = IrgGeoFunctions.getImageSize(newImagePath) refImageSize = IrgGeoFunctions.getImageSize(refImagePath) # Get a pixel to GDC transform for the reference image refPixelToGdcTransform = registration_common.getPixelToGdcTransform( refImagePath, refImageGeoTransform) # Generate a list of point pairs imagePoints = [] projPoints = [] gdcPoints = [] print 'transform = \n' + str(imageToRefTransform.matrix) # Loop through an evenly spaced grid of pixels in the new image # - For each pixel, compute the desired output coordinate pointPixelSpacing = (newImageSize[0] + newImageSize[1]) / 20 # Results in about 100 points for r in range(0, newImageSize[0], pointPixelSpacing): for c in range(0, newImageSize[1], pointPixelSpacing): # Get pixel in new image and matching pixel in the reference image thisPixel = numpy.array([float(c), float(r)]) pixelInRefImage = imageToRefTransform.forward(thisPixel) # If any pixel transforms outside the reference image our transform # is probably invalid but continue on skipping this pixel. if ((not registration_common.isPixelValid(thisPixel, newImageSize)) or (not registration_common.isPixelValid(pixelInRefImage, refImageSize))): continue # Compute the location of this pixel in the projected coordinate system # used by the transform.py file. if (not refImageGeoTransform): # Use the geo information of the reference image gdcCoordinate = refPixelToGdcTransform.forward(pixelInRefImage) projectedCoordinate = transform.lonLatToMeters(gdcCoordinate) else: # Use the user-provided transform projectedCoordinate = refImageGeoTransform.forward(pixelInRefImage) gdcCoordinate = transform.metersToLatLon(projectedCoordinate) imagePoints.append(thisPixel) projPoints.append(projectedCoordinate) gdcPoints.append(gdcCoordinate) #print str(thisPixel) + ' --> ' + str(gdcCoordinate) + ' <--> ' + str(projectedCoordinate) # Compute a transform object that converts from the new image to projected coordinates #print 'Converting transform to world coordinates...' #testImageToProjectedTransform = transform.getTransform(numpy.asarray(worldPoints), # numpy.asarray(imagePoints)) testImageToProjectedTransform = transform.ProjectiveTransform.fit(numpy.asarray(projPoints), numpy.asarray(imagePoints)) testImageToGdcTransform = transform.ProjectiveTransform.fit(numpy.asarray(gdcPoints), numpy.asarray(imagePoints)) #print refPixelToGdcTransform #print testImageToProjectedTransform #for i, w in zip(imagePoints, worldPoints): # print str(i) + ' --> ' + str(w) + ' <--> ' + str(testImageToProjectedTransform.forward(i)) return (testImageToProjectedTransform, testImageToGdcTransform, refPixelToGdcTransform)