def warp(self, target_bbox, target_size=None):
<EOL>if not target_size:<EOL><INDENT>px_per_unit = (float(self.image.size[<NUM_LIT:0>])/self.bbox.width, float(self.image.size[<NUM_LIT:1>])/self.bbox.height)<EOL>src_bbox = target_bbox.project(self.bbox.projection)<EOL>target_size = (int(round(src_bbox.width*px_per_unit[<NUM_LIT:0>])), int(round(src_bbox.height*px_per_unit[<NUM_LIT:1>])))<EOL><DEDENT>canvas_size = (<EOL>max(target_size[<NUM_LIT:0>], self.image.size[<NUM_LIT:0>]),<EOL>max(target_size[<NUM_LIT:1>], self.image.size[<NUM_LIT:1>])<EOL>)<EOL>if self.bbox == target_bbox and self.image.size == target_size:<EOL><INDENT>return self<EOL><DEDENT>elif self.bbox.projection.srs == target_bbox.projection.srs:<EOL><INDENT>to_source_image = world_to_image(self.bbox, self.image.size)<EOL>upper_left = to_source_image(*(target_bbox.xmin, target_bbox.ymax))<EOL>lower_right = to_source_image(*(target_bbox.xmax, target_bbox.ymin))<EOL>if canvas_size == self.image.size:<EOL><INDENT>im = self.image<EOL><DEDENT>else:<EOL><INDENT>im = Image.new("<STR_LIT>", canvas_size, (<NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>))<EOL>im.paste(self.image, (<NUM_LIT:0>, <NUM_LIT:0>))<EOL><DEDENT>new_image = im.transform(<EOL>target_size, Image.EXTENT, (upper_left[<NUM_LIT:0>], upper_left[<NUM_LIT:1>], lower_right[<NUM_LIT:0>], lower_right[<NUM_LIT:1>]),<EOL>Image.NEAREST<EOL>)<EOL><DEDENT>else:<EOL><INDENT>if canvas_size == self.image.size:<EOL><INDENT>im = self.image<EOL><DEDENT>else:<EOL><INDENT>im = Image.new("<STR_LIT>", canvas_size, (<NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>))<EOL>im.paste(self.image, (<NUM_LIT:0>, <NUM_LIT:0>))<EOL><DEDENT>new_image = im.transform(<EOL>target_size, Image.MESH, self._create_mesh(target_bbox, target_size), Image.NEAREST<EOL>)<EOL><DEDENT>return GeoImage(new_image, target_bbox)<EOL>
Returns a copy of this image warped to a target size and bounding box