Loading autocnet/fileio/io_gdal.py +37 −41 Original line number Diff line number Diff line import pvl import os import warnings from pysal.cg.shapes import Polygon from autocnet.utils.utils import find_in_dict, find_nested_in_dict from autocnet.utils.utils import find_in_dict from osgeo import ogr import numpy as np import gdal import osr from autocnet.fileio import extract_metadata from pysal import cg gdal.UseExceptions() Loading @@ -34,6 +32,7 @@ for k, v in iter(NP2GDAL_CONVERSION.items()): GDAL2NP_CONVERSION[1] = 'int8' class GeoDataset(object): """ Geospatial dataset object that represents. Loading Loading @@ -124,6 +123,12 @@ class GeoDataset(object): no_data_value : float Special value used to indicate pixels that are not valid. metadata : dict A dictionary of available image metadata footprint : object An OGR footprint object """ def __init__(self, file_name): """ Loading Loading @@ -196,33 +201,43 @@ class GeoDataset(object): def latlon_extent(self): if not getattr(self, '_latlon_extent', None): try: # If we have a footprint, no need to compute pixel to latlon lowerlon, upperlon, lowerlat, upperlat = self.footprint.GetEnvelope() except: xy_extent = self.xy_extent lowerlat, lowerlon = self.pixel_to_latlon(xy_extent[0][0], xy_extent[0][1]) upperlat, upperlon = self.pixel_to_latlon(xy_extent[1][0], xy_extent[1][1]) self._latlon_extent = [(lowerlat, lowerlon), (upperlat, upperlon)] except: warnings.warn("Couldn't calculate a Latitude/Longitude extent") self._latlon_extent = None return self._latlon_extent @property def footprint_polygon(self): if not getattr(self, '_pvl_header', None): self._pvl_header = pvl.load(self.file_name) # Should be a member variable? polygon_pvl = find_in_dict(self._pvl_header, 'Polygon') def metadata(self): if not hasattr(self, '_metadata'): try: self._metadata = pvl.load(self.file_name) except: self._metadata = self.dataset.GetMetadata() return self._metadata @property def footprint(self): if not hasattr(self, '_footprint'): try: polygon_pvl = find_in_dict(self.metadata, 'Polygon') start_polygon_byte = find_in_dict(polygon_pvl, 'StartByte') num_polygon_bytes = find_in_dict(polygon_pvl, 'Bytes') # TODO: Do we really need to re-open the file here? self.dataset does not work f = open(self.file_name, 'r+') # I too dislike the additional open here. Not sure a good option with open(self.file_name, 'r+') as f: f.seek(start_polygon_byte - 1) wkt = f.read(num_polygon_bytes) polygon = ogr.CreateGeometryFromWkt(wkt) self._footprint_polygon = polygon f.close() return self._footprint_polygon # Sloppy unicode to string because GDAL pukes on unicode stream = str(f.read(num_polygon_bytes)) self._footprint = ogr.CreateGeometryFromWkt(stream) except: # Handle GDAL here self._footprint = None return self._footprint @property def xy_extent(self): Loading @@ -238,25 +253,6 @@ class GeoDataset(object): return self._xy_extent @property def bounding_box(self): """ A bounding box in lat/lon space Returns ------- """ if not getattr(self, '_bounding_box', None): try: latlons = self.latlon_extent # Will fail without geospatial data self._bounding_box = cg.standalone.get_bounding_box([cg.shapes.LineSegment(latlons[0], latlons[1])]) print(list(self._bounding_box)) except: envelope = self.footprint_polygon.GetEnvelope() self._bounding_box = [envelope[0], envelope[2], envelope[1], envelope[3]] # TODO: check me? print(self.bounding_box) return self._bounding_box @property def pixel_polygon(self): """ Loading autocnet/graph/network.py +22 −17 Original line number Diff line number Diff line import collections import itertools import os import dill as pickle Loading @@ -6,7 +8,6 @@ import numpy as np import pandas as pd from pysal import cg from autocnet.examples import get_path from autocnet.fileio.io_gdal import GeoDataset from autocnet.control.control import C from autocnet.fileio import io_json Loading Loading @@ -79,9 +80,9 @@ class CandidateGraph(nx.Graph): graph = pickle.load(f) return graph # TODO: Add ability to actually read this out of a file? @classmethod def from_filelist(cls, filelst): def from_filelist(cls, filelist): """ Instantiate the class using a filelist as a python list. An adjacency structure is calculated using the lat/lon information in the Loading @@ -89,7 +90,7 @@ class CandidateGraph(nx.Graph): Parameters ---------- filelst : list filelist : list A list containing the files (with full paths) to construct an adjacency graph from Returns Loading @@ -100,20 +101,24 @@ class CandidateGraph(nx.Graph): # TODO: Reject unsupported file formats + work with more file formats dataset_list = [] for file in filelst: dataset = GeoDataset(file) dataset_list.append(dataset) datasets = [GeoDataset(f) for f in filelist] # This is brute force for now, could swap to an RTree at some point. adjacency_dict = {} for data in dataset_list: adjacent_images = [] other_datasets = dataset_list.copy() other_datasets.remove(data) for other in other_datasets: if(cg.standalone.bbcommon(data.bounding_box, other.bounding_box)): adjacent_images.append(other.base_name) adjacency_dict[data.base_name] = adjacent_images for i, j in itertools.permutations(datasets,2): if not i.base_name in adjacency_dict.keys(): adjacency_dict[i.base_name] = [] if not j.base_name in adjacency_dict.keys(): adjacency_dict[j.base_name] = [] # Grab the footprints and test for intersection i_fp = i.footprint j_fp = j.footprint if i_fp.Intersects(j_fp): adjacency_dict[i.base_name].append(j.base_name) adjacency_dict[j.base_name].append(i.base_name) return cls(adjacency_dict) Loading autocnet/graph/tests/test_network.py +3 −0 Original line number Diff line number Diff line Loading @@ -78,6 +78,7 @@ class TestFromList(unittest.TestCase): self.assertEqual(self.graph.__len__(), 3) self.assertEqual(self.graph.number_of_nodes(), 3) ''' class TestFromListCubes(unittest.TestCase): @classmethod Loading @@ -90,6 +91,8 @@ class TestFromListCubes(unittest.TestCase): def test_graph_length(self): self.assertEqual(self.graph.number_of_nodes(), 3) self.assertEqual(self.graph.number_of_edges(), 3) ''' class TestEdge(unittest.TestCase): Loading Loading
autocnet/fileio/io_gdal.py +37 −41 Original line number Diff line number Diff line import pvl import os import warnings from pysal.cg.shapes import Polygon from autocnet.utils.utils import find_in_dict, find_nested_in_dict from autocnet.utils.utils import find_in_dict from osgeo import ogr import numpy as np import gdal import osr from autocnet.fileio import extract_metadata from pysal import cg gdal.UseExceptions() Loading @@ -34,6 +32,7 @@ for k, v in iter(NP2GDAL_CONVERSION.items()): GDAL2NP_CONVERSION[1] = 'int8' class GeoDataset(object): """ Geospatial dataset object that represents. Loading Loading @@ -124,6 +123,12 @@ class GeoDataset(object): no_data_value : float Special value used to indicate pixels that are not valid. metadata : dict A dictionary of available image metadata footprint : object An OGR footprint object """ def __init__(self, file_name): """ Loading Loading @@ -196,33 +201,43 @@ class GeoDataset(object): def latlon_extent(self): if not getattr(self, '_latlon_extent', None): try: # If we have a footprint, no need to compute pixel to latlon lowerlon, upperlon, lowerlat, upperlat = self.footprint.GetEnvelope() except: xy_extent = self.xy_extent lowerlat, lowerlon = self.pixel_to_latlon(xy_extent[0][0], xy_extent[0][1]) upperlat, upperlon = self.pixel_to_latlon(xy_extent[1][0], xy_extent[1][1]) self._latlon_extent = [(lowerlat, lowerlon), (upperlat, upperlon)] except: warnings.warn("Couldn't calculate a Latitude/Longitude extent") self._latlon_extent = None return self._latlon_extent @property def footprint_polygon(self): if not getattr(self, '_pvl_header', None): self._pvl_header = pvl.load(self.file_name) # Should be a member variable? polygon_pvl = find_in_dict(self._pvl_header, 'Polygon') def metadata(self): if not hasattr(self, '_metadata'): try: self._metadata = pvl.load(self.file_name) except: self._metadata = self.dataset.GetMetadata() return self._metadata @property def footprint(self): if not hasattr(self, '_footprint'): try: polygon_pvl = find_in_dict(self.metadata, 'Polygon') start_polygon_byte = find_in_dict(polygon_pvl, 'StartByte') num_polygon_bytes = find_in_dict(polygon_pvl, 'Bytes') # TODO: Do we really need to re-open the file here? self.dataset does not work f = open(self.file_name, 'r+') # I too dislike the additional open here. Not sure a good option with open(self.file_name, 'r+') as f: f.seek(start_polygon_byte - 1) wkt = f.read(num_polygon_bytes) polygon = ogr.CreateGeometryFromWkt(wkt) self._footprint_polygon = polygon f.close() return self._footprint_polygon # Sloppy unicode to string because GDAL pukes on unicode stream = str(f.read(num_polygon_bytes)) self._footprint = ogr.CreateGeometryFromWkt(stream) except: # Handle GDAL here self._footprint = None return self._footprint @property def xy_extent(self): Loading @@ -238,25 +253,6 @@ class GeoDataset(object): return self._xy_extent @property def bounding_box(self): """ A bounding box in lat/lon space Returns ------- """ if not getattr(self, '_bounding_box', None): try: latlons = self.latlon_extent # Will fail without geospatial data self._bounding_box = cg.standalone.get_bounding_box([cg.shapes.LineSegment(latlons[0], latlons[1])]) print(list(self._bounding_box)) except: envelope = self.footprint_polygon.GetEnvelope() self._bounding_box = [envelope[0], envelope[2], envelope[1], envelope[3]] # TODO: check me? print(self.bounding_box) return self._bounding_box @property def pixel_polygon(self): """ Loading
autocnet/graph/network.py +22 −17 Original line number Diff line number Diff line import collections import itertools import os import dill as pickle Loading @@ -6,7 +8,6 @@ import numpy as np import pandas as pd from pysal import cg from autocnet.examples import get_path from autocnet.fileio.io_gdal import GeoDataset from autocnet.control.control import C from autocnet.fileio import io_json Loading Loading @@ -79,9 +80,9 @@ class CandidateGraph(nx.Graph): graph = pickle.load(f) return graph # TODO: Add ability to actually read this out of a file? @classmethod def from_filelist(cls, filelst): def from_filelist(cls, filelist): """ Instantiate the class using a filelist as a python list. An adjacency structure is calculated using the lat/lon information in the Loading @@ -89,7 +90,7 @@ class CandidateGraph(nx.Graph): Parameters ---------- filelst : list filelist : list A list containing the files (with full paths) to construct an adjacency graph from Returns Loading @@ -100,20 +101,24 @@ class CandidateGraph(nx.Graph): # TODO: Reject unsupported file formats + work with more file formats dataset_list = [] for file in filelst: dataset = GeoDataset(file) dataset_list.append(dataset) datasets = [GeoDataset(f) for f in filelist] # This is brute force for now, could swap to an RTree at some point. adjacency_dict = {} for data in dataset_list: adjacent_images = [] other_datasets = dataset_list.copy() other_datasets.remove(data) for other in other_datasets: if(cg.standalone.bbcommon(data.bounding_box, other.bounding_box)): adjacent_images.append(other.base_name) adjacency_dict[data.base_name] = adjacent_images for i, j in itertools.permutations(datasets,2): if not i.base_name in adjacency_dict.keys(): adjacency_dict[i.base_name] = [] if not j.base_name in adjacency_dict.keys(): adjacency_dict[j.base_name] = [] # Grab the footprints and test for intersection i_fp = i.footprint j_fp = j.footprint if i_fp.Intersects(j_fp): adjacency_dict[i.base_name].append(j.base_name) adjacency_dict[j.base_name].append(i.base_name) return cls(adjacency_dict) Loading
autocnet/graph/tests/test_network.py +3 −0 Original line number Diff line number Diff line Loading @@ -78,6 +78,7 @@ class TestFromList(unittest.TestCase): self.assertEqual(self.graph.__len__(), 3) self.assertEqual(self.graph.number_of_nodes(), 3) ''' class TestFromListCubes(unittest.TestCase): @classmethod Loading @@ -90,6 +91,8 @@ class TestFromListCubes(unittest.TestCase): def test_graph_length(self): self.assertEqual(self.graph.number_of_nodes(), 3) self.assertEqual(self.graph.number_of_edges(), 3) ''' class TestEdge(unittest.TestCase): Loading