Loading autocnet/__init__.py +1 −1 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ try: with open(os.environ['autocnet_config'], 'r') as f: config = yaml.safe_load(f) except: warnings.warn('No autocnet_config environment variable set. Defaulting to an en empty configuration.') warnings.warn('No autocnet_config environment variable set. Defaulting to an empty configuration.') config = {} if 'dem' in config['spatial']: Loading autocnet/spatial/overlap.py +15 −54 Original line number Diff line number Diff line Loading @@ -10,7 +10,6 @@ from plio.io.io_gdal import GeoDataset from autocnet import config, dem from autocnet.cg import cg as compgeom from autocnet.io.db.model import Images, Measures, Overlay, Points from autocnet.matcher.subpixel import iterative_phase from autocnet.spatial import isis from plurmy import Slurm Loading Loading @@ -39,14 +38,11 @@ INSERT INTO overlay(intersections, geom) SELECT row.intersections, row.geom FROM """ def place_points_in_overlaps(nodes, size_threshold=0.0007, iterative_phase_kwargs={'size':71}, distribute_points_kwargs={}, cam_type='csm'): """ Place points in all of the overlap geometries by back-projecing using sensor models. The DEM specified in the config file will be used to calculate point elevations. Parameters ---------- nodes : dict-link Loading @@ -57,9 +53,6 @@ def place_points_in_overlaps(nodes, size_threshold=0.0007, size_threshold : float overlaps with area <= this threshold are ignored iterative_phase_kwargs : dict Dictionary of keyword arguments for the iterative phase matcher function """ points = [] for o in Overlay.overlapping_larger_than(size_threshold): Loading @@ -67,14 +60,12 @@ def place_points_in_overlaps(nodes, size_threshold=0.0007, if overlaps == None: continue overlapnodes = [nodes[id]['data'] for id in overlaps] points.extend(place_points_in_overlap(overlapnodes, o.geom, dem=dem, cam_type=cam_type, iterative_phase_kwargs=iterative_phase_kwargs, overlapnodes = [nodes[id]["data"] for id in overlaps] points.extend(place_points_in_overlap(overlapnodes, o.geom, cam_type=cam_type, distribute_points_kwargs=distribute_points_kwargs)) Points.bulkadd(points) def cluster_place_points_in_overlaps(size_threshold=0.0007, iterative_phase_kwargs={'size':71}, distribute_points_kwargs={}, walltime='00:10:00', cam_type="csm"): """ Loading @@ -82,16 +73,11 @@ def cluster_place_points_in_overlaps(size_threshold=0.0007, sensor models. This method uses the cluster to process all of the overlaps in parallel. See place_points_in_overlap and acn_overlaps. The DEM specified in the config file will be used to calculate point elevations. Parameters ---------- size_threshold : float overlaps with area <= this threshold are ignored iterative_phase_kwargs : dict Dictionary of keyword arguments for the iterative phase matcher function walltime : str Cluster job wall time as a string HH:MM:SS Loading @@ -111,7 +97,6 @@ def cluster_place_points_in_overlaps(size_threshold=0.0007, queuename = config['redis']['processing_queue'] for overlap in overlaps: msg = {'id' : overlap.id, 'iterative_phase_kwargs' : iterative_phase_kwargs, 'distribute_points_kwargs' : distribute_points_kwargs, 'walltime' : walltime, 'cam_type': cam_type} Loading @@ -127,11 +112,11 @@ def cluster_place_points_in_overlaps(size_threshold=0.0007, submitter.submit(array='1-{}'.format(job_counter)) return job_counter def place_points_in_overlap(nodes, geom, dem=dem, cam_type="csm", iterative_phase_kwargs={'size':71}, def place_points_in_overlap(nodes, geom, cam_type="csm", distribute_points_kwargs={}): """ Place points into an overlap geometry by back-projecing using sensor models. The DEM specified in the config file will be used to calculate point elevations. Parameters ---------- Loading @@ -141,13 +126,6 @@ def place_points_in_overlap(nodes, geom, dem=dem, cam_type="csm", geom : geometry The geometry of the overlap region dem : GeoDataset The DEM used to compute point elevations. An elevation of 0 is used if no DEM is passed in. iterative_phase_kwargs : dict Dictionary of keyword arguments for the iterative phase matcher function cam_type : str options: {"csm", "isis"} Pick what kind of camera model implementation to use Loading @@ -172,9 +150,6 @@ def place_points_in_overlap(nodes, geom, dem=dem, cam_type="csm", warnings.warn('Failed to distribute points in overlap') return [] # Grab the source image. This is just the node with the lowest ID, nothing smart. source = nodes[0] nodes.remove(source) for v in valid: lon = v[0] lat = v[1] Loading @@ -185,42 +160,28 @@ def place_points_in_overlap(nodes, geom, dem=dem, cam_type="csm", else: px, py = dem.latlon_to_pixel(lat, lon) height = dem.read_array(1, [px, py, 1, 1])[0][0] # Get the BCEF coordinate from the lon, lat x, y, z = pyproj.transform(lla, ecef, lon, lat, height) geom = shapely.geometry.Point(x, y, z) point = Points(apriori=geom, adjusted=geom, pointtype=2) # Would be 3 or 4 for ground if cam_type == "csm": gnd = csmapi.EcefCoord(x, y, z) sic = source.camera.groundToImage(gnd) ssample, sline = sic.samp, sic.line for node in nodes: if cam_type == "csm": image_coord = node.camera.groundToImage(gnd) sample, line = image_coord.samp, image_coord.line if cam_type == "isis": sline, ssample = isis.ground_to_image(source["image_path"], lat ,lon) line, sample = isis.ground_to_image(node["image_path"], lat ,lon) point.measures.append(Measures(sample=ssample, line=sline, imageid=source['node_id'], serial=source.isis_serial, point.measures.append(Measures(sample=sample, line=line, imageid=node['node_id'], serial=node.isis_serial, measuretype=3)) for i, dest in enumerate(nodes): if cam_type == "csm": dic = dest.camera.groundToImage(gnd) dline, dsample = dic.line, dic.samp if cam_type == "isis": dline, dsample = isis.ground_to_image(dest["image_path"], lat, lon) dx, dy, _ = iterative_phase(ssample, sline, dsample, dline, source.geodata, dest.geodata, **iterative_phase_kwargs) if dx is not None or dy is not None: point.measures.append(Measures(sample=dx, line=dy, imageid=dest['node_id'], serial=dest.isis_serial, measuretype=3)) if len(point.measures) >= 2: points.append(point) return points autocnet/spatial/tests/test_overlap_points.py +6 −22 Original line number Diff line number Diff line Loading @@ -6,9 +6,8 @@ from autocnet.graph.node import Node import csmapi @patch('autocnet.spatial.overlap.iterative_phase', return_value=(0, 1, 2)) @patch('autocnet.cg.cg.distribute_points_in_geom', return_value=[(0, 0), (5, 5), (10, 10)]) def test_place_points_in_overlap(point_distributer, phase_matcher): def test_place_points_in_overlap(point_distributer): # Mock setup first_node = MagicMock() first_node.camera = MagicMock() Loading @@ -30,13 +29,10 @@ def test_place_points_in_overlap(point_distributer, phase_matcher): fourth_node.camera.groundToImage.return_value = csmapi.ImageCoord(0.0, 0.0) fourth_node.isis_serial = '4' fourth_node.__getitem__.return_value = 4 dem = MagicMock() dem.latlon_to_pixel.return_value = (1.0, 1.0) dem.read_array.return_value = [[0.0]] # Actual function being tested points = place_points_in_overlap([first_node, second_node, third_node, fourth_node], Polygon([(0, 0), (0, 10), (10, 10), (10, 0)]), dem) Polygon([(0, 0), (0, 10), (10, 10), (10, 0)])) # Check the function output assert len(points) == 3 Loading @@ -48,18 +44,10 @@ def test_place_points_in_overlap(point_distributer, phase_matcher): # Check the mocks point_distributer.assert_called_with(Polygon([(0, 0), (0, 10), (10, 10), (10, 0)])) dem.latlon_to_pixel.assert_called() dem.read_array.assert_called() first_node.camera.groundToImage.assert_called() second_node.camera.groundToImage.assert_called() third_node.camera.groundToImage.assert_called() fourth_node.camera.groundToImage.assert_called() phase_matcher.assert_any_call(0.0, 1.0, 1.0, 1.0, first_node.geodata, second_node.geodata, size=71) phase_matcher.assert_any_call(0.0, 1.0, 1.0, 0.0, first_node.geodata, third_node.geodata, size=71) phase_matcher.assert_any_call(0.0, 1.0, 0.0, 0.0, first_node.geodata, fourth_node.geodata, size=71) class MockOverlap(): intersections = [0,1] Loading @@ -68,19 +56,15 @@ class MockOverlap(): @patch('autocnet.io.db.model.Overlay.overlapping_larger_than', return_value=[MockOverlap()]*3) @patch('autocnet.dem', return_value=None) @patch('autocnet.io.db.model.Points.bulkadd') @pytest.mark.parametrize("iterativekwargs, distributekwargs",[ ({'iterative_phase_kwargs':{'size':15}}, {'distribute_points_kwargs':{'ewpts_func':lambda:True}}) @pytest.mark.parametrize("distributekwargs",[ ({'distribute_points_kwargs':{'ewpts_func':lambda:True}}) ]) def test_place_points_in_overlaps(overlapper, dem, adder,iterativekwargs, distributekwargs): def test_place_points_in_overlaps(overlapper, adder, distributekwargs): nodes = [{"id": 0, "data": Node()}, {"id": 1, "data": Node()}] with patch('autocnet.spatial.overlap.place_points_in_overlap', return_value=[1,2,3]) as ppio: place_points_in_overlaps(nodes, iterative_phase_kwargs=iterativekwargs,distribute_points_kwargs=distributekwargs) place_points_in_overlaps(nodes,distribute_points_kwargs=distributekwargs) ppio.assert_called_with([Node(), Node()], Polygon([(0,0),(0,5),(5,5),(5,0),(0,0)]), dem=None, iterative_phase_kwargs=iterativekwargs, distribute_points_kwargs=distributekwargs, cam_type='csm') bin/acn_overlaps +2 −10 Original line number Diff line number Diff line Loading @@ -12,9 +12,7 @@ from autocnet.io.db.redis_queue import pop_computetime_push, finalize from autocnet.io.db.model import Overlay, Images, Points from autocnet.spatial.overlap import place_points_in_overlap from autocnet.graph.node import NetworkNode from autocnet import Session, dem from plio.io.io_gdal import GeoDataset from autocnet import Session #Load the config file try: Loading @@ -40,18 +38,12 @@ def main(msg, config): session.close() print('Placing points in overlap', id) points = place_points_in_overlap(nodes, overlap.geom, dem, msg["cam_type"], msg['iterative_phase_kwargs'], points = place_points_in_overlap(nodes, overlap.geom, msg["cam_type"], msg['distribute_points_kwargs']) session.add_all(points) session.commit() session.close() print('Placing points in overlap', id) points = place_points_in_overlap(nodes, overlap.geom, dem, msg["cam_type"], msg['iterative_phase_kwargs'], msg['distribute_points_kwargs']) print('Adding {} points to the database.'.format(len(points))) Points.bulkadd(points) Loading Loading
autocnet/__init__.py +1 −1 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ try: with open(os.environ['autocnet_config'], 'r') as f: config = yaml.safe_load(f) except: warnings.warn('No autocnet_config environment variable set. Defaulting to an en empty configuration.') warnings.warn('No autocnet_config environment variable set. Defaulting to an empty configuration.') config = {} if 'dem' in config['spatial']: Loading
autocnet/spatial/overlap.py +15 −54 Original line number Diff line number Diff line Loading @@ -10,7 +10,6 @@ from plio.io.io_gdal import GeoDataset from autocnet import config, dem from autocnet.cg import cg as compgeom from autocnet.io.db.model import Images, Measures, Overlay, Points from autocnet.matcher.subpixel import iterative_phase from autocnet.spatial import isis from plurmy import Slurm Loading Loading @@ -39,14 +38,11 @@ INSERT INTO overlay(intersections, geom) SELECT row.intersections, row.geom FROM """ def place_points_in_overlaps(nodes, size_threshold=0.0007, iterative_phase_kwargs={'size':71}, distribute_points_kwargs={}, cam_type='csm'): """ Place points in all of the overlap geometries by back-projecing using sensor models. The DEM specified in the config file will be used to calculate point elevations. Parameters ---------- nodes : dict-link Loading @@ -57,9 +53,6 @@ def place_points_in_overlaps(nodes, size_threshold=0.0007, size_threshold : float overlaps with area <= this threshold are ignored iterative_phase_kwargs : dict Dictionary of keyword arguments for the iterative phase matcher function """ points = [] for o in Overlay.overlapping_larger_than(size_threshold): Loading @@ -67,14 +60,12 @@ def place_points_in_overlaps(nodes, size_threshold=0.0007, if overlaps == None: continue overlapnodes = [nodes[id]['data'] for id in overlaps] points.extend(place_points_in_overlap(overlapnodes, o.geom, dem=dem, cam_type=cam_type, iterative_phase_kwargs=iterative_phase_kwargs, overlapnodes = [nodes[id]["data"] for id in overlaps] points.extend(place_points_in_overlap(overlapnodes, o.geom, cam_type=cam_type, distribute_points_kwargs=distribute_points_kwargs)) Points.bulkadd(points) def cluster_place_points_in_overlaps(size_threshold=0.0007, iterative_phase_kwargs={'size':71}, distribute_points_kwargs={}, walltime='00:10:00', cam_type="csm"): """ Loading @@ -82,16 +73,11 @@ def cluster_place_points_in_overlaps(size_threshold=0.0007, sensor models. This method uses the cluster to process all of the overlaps in parallel. See place_points_in_overlap and acn_overlaps. The DEM specified in the config file will be used to calculate point elevations. Parameters ---------- size_threshold : float overlaps with area <= this threshold are ignored iterative_phase_kwargs : dict Dictionary of keyword arguments for the iterative phase matcher function walltime : str Cluster job wall time as a string HH:MM:SS Loading @@ -111,7 +97,6 @@ def cluster_place_points_in_overlaps(size_threshold=0.0007, queuename = config['redis']['processing_queue'] for overlap in overlaps: msg = {'id' : overlap.id, 'iterative_phase_kwargs' : iterative_phase_kwargs, 'distribute_points_kwargs' : distribute_points_kwargs, 'walltime' : walltime, 'cam_type': cam_type} Loading @@ -127,11 +112,11 @@ def cluster_place_points_in_overlaps(size_threshold=0.0007, submitter.submit(array='1-{}'.format(job_counter)) return job_counter def place_points_in_overlap(nodes, geom, dem=dem, cam_type="csm", iterative_phase_kwargs={'size':71}, def place_points_in_overlap(nodes, geom, cam_type="csm", distribute_points_kwargs={}): """ Place points into an overlap geometry by back-projecing using sensor models. The DEM specified in the config file will be used to calculate point elevations. Parameters ---------- Loading @@ -141,13 +126,6 @@ def place_points_in_overlap(nodes, geom, dem=dem, cam_type="csm", geom : geometry The geometry of the overlap region dem : GeoDataset The DEM used to compute point elevations. An elevation of 0 is used if no DEM is passed in. iterative_phase_kwargs : dict Dictionary of keyword arguments for the iterative phase matcher function cam_type : str options: {"csm", "isis"} Pick what kind of camera model implementation to use Loading @@ -172,9 +150,6 @@ def place_points_in_overlap(nodes, geom, dem=dem, cam_type="csm", warnings.warn('Failed to distribute points in overlap') return [] # Grab the source image. This is just the node with the lowest ID, nothing smart. source = nodes[0] nodes.remove(source) for v in valid: lon = v[0] lat = v[1] Loading @@ -185,42 +160,28 @@ def place_points_in_overlap(nodes, geom, dem=dem, cam_type="csm", else: px, py = dem.latlon_to_pixel(lat, lon) height = dem.read_array(1, [px, py, 1, 1])[0][0] # Get the BCEF coordinate from the lon, lat x, y, z = pyproj.transform(lla, ecef, lon, lat, height) geom = shapely.geometry.Point(x, y, z) point = Points(apriori=geom, adjusted=geom, pointtype=2) # Would be 3 or 4 for ground if cam_type == "csm": gnd = csmapi.EcefCoord(x, y, z) sic = source.camera.groundToImage(gnd) ssample, sline = sic.samp, sic.line for node in nodes: if cam_type == "csm": image_coord = node.camera.groundToImage(gnd) sample, line = image_coord.samp, image_coord.line if cam_type == "isis": sline, ssample = isis.ground_to_image(source["image_path"], lat ,lon) line, sample = isis.ground_to_image(node["image_path"], lat ,lon) point.measures.append(Measures(sample=ssample, line=sline, imageid=source['node_id'], serial=source.isis_serial, point.measures.append(Measures(sample=sample, line=line, imageid=node['node_id'], serial=node.isis_serial, measuretype=3)) for i, dest in enumerate(nodes): if cam_type == "csm": dic = dest.camera.groundToImage(gnd) dline, dsample = dic.line, dic.samp if cam_type == "isis": dline, dsample = isis.ground_to_image(dest["image_path"], lat, lon) dx, dy, _ = iterative_phase(ssample, sline, dsample, dline, source.geodata, dest.geodata, **iterative_phase_kwargs) if dx is not None or dy is not None: point.measures.append(Measures(sample=dx, line=dy, imageid=dest['node_id'], serial=dest.isis_serial, measuretype=3)) if len(point.measures) >= 2: points.append(point) return points
autocnet/spatial/tests/test_overlap_points.py +6 −22 Original line number Diff line number Diff line Loading @@ -6,9 +6,8 @@ from autocnet.graph.node import Node import csmapi @patch('autocnet.spatial.overlap.iterative_phase', return_value=(0, 1, 2)) @patch('autocnet.cg.cg.distribute_points_in_geom', return_value=[(0, 0), (5, 5), (10, 10)]) def test_place_points_in_overlap(point_distributer, phase_matcher): def test_place_points_in_overlap(point_distributer): # Mock setup first_node = MagicMock() first_node.camera = MagicMock() Loading @@ -30,13 +29,10 @@ def test_place_points_in_overlap(point_distributer, phase_matcher): fourth_node.camera.groundToImage.return_value = csmapi.ImageCoord(0.0, 0.0) fourth_node.isis_serial = '4' fourth_node.__getitem__.return_value = 4 dem = MagicMock() dem.latlon_to_pixel.return_value = (1.0, 1.0) dem.read_array.return_value = [[0.0]] # Actual function being tested points = place_points_in_overlap([first_node, second_node, third_node, fourth_node], Polygon([(0, 0), (0, 10), (10, 10), (10, 0)]), dem) Polygon([(0, 0), (0, 10), (10, 10), (10, 0)])) # Check the function output assert len(points) == 3 Loading @@ -48,18 +44,10 @@ def test_place_points_in_overlap(point_distributer, phase_matcher): # Check the mocks point_distributer.assert_called_with(Polygon([(0, 0), (0, 10), (10, 10), (10, 0)])) dem.latlon_to_pixel.assert_called() dem.read_array.assert_called() first_node.camera.groundToImage.assert_called() second_node.camera.groundToImage.assert_called() third_node.camera.groundToImage.assert_called() fourth_node.camera.groundToImage.assert_called() phase_matcher.assert_any_call(0.0, 1.0, 1.0, 1.0, first_node.geodata, second_node.geodata, size=71) phase_matcher.assert_any_call(0.0, 1.0, 1.0, 0.0, first_node.geodata, third_node.geodata, size=71) phase_matcher.assert_any_call(0.0, 1.0, 0.0, 0.0, first_node.geodata, fourth_node.geodata, size=71) class MockOverlap(): intersections = [0,1] Loading @@ -68,19 +56,15 @@ class MockOverlap(): @patch('autocnet.io.db.model.Overlay.overlapping_larger_than', return_value=[MockOverlap()]*3) @patch('autocnet.dem', return_value=None) @patch('autocnet.io.db.model.Points.bulkadd') @pytest.mark.parametrize("iterativekwargs, distributekwargs",[ ({'iterative_phase_kwargs':{'size':15}}, {'distribute_points_kwargs':{'ewpts_func':lambda:True}}) @pytest.mark.parametrize("distributekwargs",[ ({'distribute_points_kwargs':{'ewpts_func':lambda:True}}) ]) def test_place_points_in_overlaps(overlapper, dem, adder,iterativekwargs, distributekwargs): def test_place_points_in_overlaps(overlapper, adder, distributekwargs): nodes = [{"id": 0, "data": Node()}, {"id": 1, "data": Node()}] with patch('autocnet.spatial.overlap.place_points_in_overlap', return_value=[1,2,3]) as ppio: place_points_in_overlaps(nodes, iterative_phase_kwargs=iterativekwargs,distribute_points_kwargs=distributekwargs) place_points_in_overlaps(nodes,distribute_points_kwargs=distributekwargs) ppio.assert_called_with([Node(), Node()], Polygon([(0,0),(0,5),(5,5),(5,0),(0,0)]), dem=None, iterative_phase_kwargs=iterativekwargs, distribute_points_kwargs=distributekwargs, cam_type='csm')
bin/acn_overlaps +2 −10 Original line number Diff line number Diff line Loading @@ -12,9 +12,7 @@ from autocnet.io.db.redis_queue import pop_computetime_push, finalize from autocnet.io.db.model import Overlay, Images, Points from autocnet.spatial.overlap import place_points_in_overlap from autocnet.graph.node import NetworkNode from autocnet import Session, dem from plio.io.io_gdal import GeoDataset from autocnet import Session #Load the config file try: Loading @@ -40,18 +38,12 @@ def main(msg, config): session.close() print('Placing points in overlap', id) points = place_points_in_overlap(nodes, overlap.geom, dem, msg["cam_type"], msg['iterative_phase_kwargs'], points = place_points_in_overlap(nodes, overlap.geom, msg["cam_type"], msg['distribute_points_kwargs']) session.add_all(points) session.commit() session.close() print('Placing points in overlap', id) points = place_points_in_overlap(nodes, overlap.geom, dem, msg["cam_type"], msg['iterative_phase_kwargs'], msg['distribute_points_kwargs']) print('Adding {} points to the database.'.format(len(points))) Points.bulkadd(points) Loading