Repository: azavea/raster-vision

Issue:
SemanticSegmentationRasterStore not saving for non-georeferenced imagery
```
root@122d4f0150f4:/opt/data/mar5# rastervision predict spacenet.zip example.jpg out.tif
/usr/local/lib/python3.5/dist-packages/pluginbase.py:439: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.
  fromlist, level)
2019-03-06 16:59:56.502396: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
/usr/local/lib/python3.5/dist-packages/rasterio/__init__.py:217: NotGeoreferencedWarning: Dataset has no geotransform set. The identity matrix may be returned.
  s = DatasetReader(path, driver=driver, **kwargs)
[0, 1, 2]
2019-03-06 16:59:56:rastervision.task.semantic_segmentation: INFO - Making predictions for scene
Traceback (most recent call last):
  File "/usr/lib/python3.5/runpy.py", line 184, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/lib/python3.5/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/opt/src/rastervision/__main__.py", line 17, in <module>
    rv.main()
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.5/dist-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/opt/src/rastervision/cli/main.py", line 241, in predict
    predictor.predict(image_uri, output_uri, export_config)
  File "/opt/src/rastervision/predictor.py", line 144, in predict
    scene.prediction_label_store.save(labels)
  File "/opt/src/rastervision/data/label_store/semantic_segmentation_raster_store.py", line 90, in save
    transform = self.crs_transformer.transform
AttributeError: 'IdentityCRSTransformer' object has no attribute 'transform'
```


Discussion:

Resolving patch:
diff --git a/rastervision/data/crs_transformer/crs_transformer.py b/rastervision/data/crs_transformer/crs_transformer.py
--- a/rastervision/data/crs_transformer/crs_transformer.py
+++ b/rastervision/data/crs_transformer/crs_transformer.py
@@ -3,9 +3,10 @@ class CRSTransformer(object):
 
     Each transformer is associated with a particular RasterSource."""
 
-    def __init__(self, image_crs=None, map_crs=None):
+    def __init__(self, image_crs=None, map_crs=None, transform=None):
         self.image_crs = image_crs
         self.map_crs = map_crs
+        self.transform = transform
 
     def map_to_pixel(self, map_point):
         """Transform point from map to pixel-based coordinates.
@@ -36,4 +37,4 @@ def get_map_crs(self):
         return self.map_crs
 
     def get_affine_transform(self):
-        raise NotImplementedError()
+        return self.transform
diff --git a/rastervision/data/crs_transformer/rasterio_crs_transformer.py b/rastervision/data/crs_transformer/rasterio_crs_transformer.py
--- a/rastervision/data/crs_transformer/rasterio_crs_transformer.py
+++ b/rastervision/data/crs_transformer/rasterio_crs_transformer.py
@@ -16,11 +16,10 @@ def __init__(self, transform, image_crs, map_crs='epsg:4326'):
             image_dataset: Rasterio DatasetReader
             map_crs: CRS code
         """
-        self.transform = transform
         self.map_proj = pyproj.Proj(init=map_crs)
         self.image_proj = pyproj.Proj(init=image_crs)
 
-        super().__init__(image_crs, map_crs)
+        super().__init__(image_crs, map_crs, transform)
 
     def map_to_pixel(self, map_point):
         """Transform point from map to pixel-based coordinates.
diff --git a/rastervision/data/label_store/semantic_segmentation_raster_store.py b/rastervision/data/label_store/semantic_segmentation_raster_store.py
--- a/rastervision/data/label_store/semantic_segmentation_raster_store.py
+++ b/rastervision/data/label_store/semantic_segmentation_raster_store.py
@@ -85,9 +85,7 @@ def save(self, labels):
         local_path = get_local_path(self.uri, self.tmp_dir)
         make_dir(local_path, use_dirname=True)
 
-        # TODO: this only works if crs_transformer is RasterioCRSTransformer.
-        # Need more general way of computing transform for the more general case.
-        transform = self.crs_transformer.transform
+        transform = self.crs_transformer.get_affine_transform()
         crs = self.crs_transformer.get_image_crs()
 
         band_count = 1


Test patch: