def testAntennaCoverForCircle(self): center = (10, 10) radius = 100 testCircle = circle.Circle(radius=radius, center=center) points_to_cover = [ tuple( map(operator.add, (r * math.cos(theta * math.pi / float(180)), r * math.sin(theta * math.pi / float(180))), center)) for theta in range(270, 360) for r in range(0, radius) ] points_to_cover = points_to_cover + [ tuple( map(operator.add, (r * math.cos(theta * math.pi / float(180)), r * math.sin(theta * math.pi / float(180))), center)) for theta in range(0, 90) for r in range(0, radius) ] pointCount = len(points_to_cover) #60 degrees antenna angle. antenna_angle = math.pi / 3 coverage_file = "DetectionCoverage_60deg.txt" detection_coverage = antennacover.read_detection_coverage( coverage_file) coverage = antennacover.find_antenna_overlay_for_points( points_to_cover, center, radius, detection_coverage, antenna_angle) printcover._testPrintAntennaCircleCover("AntennaCircleCover", testCircle, coverage, coverage_file, 60, points_to_cover) flag = True not_covered = 0 for point in points_to_cover: p = Point(point) found = False for i in range(len(coverage)): if coverage[i][2].contains(p): found = True break if not found: not_covered += 1 print "Not Covered ", not_covered # We tolerate a small miss rate in the points. self.assertTrue(not_covered < .01 * pointCount) coverage = float(not_covered) / float(pointCount) print "not covered fraction = ", coverage
def testAntennaCoverForCircle1(self): center = (20, 10) radius = 120 testCircle = circle.Circle(radius=radius, center=center) # Convert from polar to cartesian points in the sector of interest. points_to_cover = [ tuple( map(operator.add, (r * math.cos(theta * math.pi / float(180)), r * math.sin(theta * math.pi / float(180))), center)) for theta in range(95, 195) for r in range(0, radius) ] pointCount = len(points_to_cover) copy_of_points_to_cover = copy.copy(points_to_cover) #60 degrees antenna angle. coverage_file = "detection-coverage/ITMDetectionCoverage_60deg.json" detection_coverage = antennacover.read_detection_coverage( coverage_file) coverage = antennacover.find_antenna_overlay_for_points( points_to_cover, center, radius, detection_coverage) printcover._testPrintAntennaCircleCover("AntennaCircleCover1", testCircle, coverage, coverage_file, 60, points_to_cover) flag = True not_covered = 0 for point in copy_of_points_to_cover: p = Point(point) found = False for i in range(len(coverage)): if coverage[i][1].contains(p): found = True break if not found: not_covered += 1 print "Not Covered ", not_covered not_covered_fraction = not_covered / float( len(copy_of_points_to_cover)) print "Not covered fraction ", not_covered_fraction # We tolerate a small miss rate in the points. self.assertTrue(not_covered < .01 * len(copy_of_points_to_cover))
def __init__(self,bounding_polygon,detection_coverage_file,cover,steps = 0,tol=.005,coverage_units="km"): """ Parameters: bounding_polygon : A polygon that defines the area to be covered. possible_centers : An ordered set of points on the coastline that follows the intereference contour with the same restrictions as the interference contour. In general, because the coastline does not loop back on itself, these constraints can be naturally satisifed by just sampling the coastline. detection_coverage_file: A text file with the detection coverage of the antenna. See https://github.com/usnistgov/circle-cover/raw/master/figures/DetectionCoverage_90deg.png for example. cover : The cover generated by the antenna_cover_greedy algorithm tol: The max allowable tolerance of uncovered points. coverage_units: The coverage units to convert the detection_coverage curves to (this is assumed to be given to us in km). """ self.centers = [c[0] for c in cover ] self.indexes = [c[1] for c in cover ] self.state = [c[2] for c in cover ] # load the detection coverage file. self.detection_coverage = antennacover.read_detection_coverage(detection_coverage_file,coverage_units) # the polygons representing the antenna shapes (rotated and translated) self.cover_polygons = excessarea.generate_antenna_cover_polygons(self.indexes,self.state,self.centers,self.detection_coverage) # The bounding polygon consisting of the shore and the interference contour. self.bounding_polygon = bounding_polygon # Generate test points for computing area differences (polygon difference does not always work) self.generate_test_points() try: self.flag = False # BUGBUG -- this is to compensate for a bug in the data set. # Generate the test points to check for coverage. ratio = self.compute_uncovered_ratio(self.cover_polygons) except: # bounding polygon is not a simple polygon. Revert back to point counting. print "Exception -- fallback to slow routine" self.flag = True ratio = self.compute_uncovered_ratio1(self.cover_polygons) # allow ourselves at least the given tolerance. self.max_ratio = max(ratio,tol) # The counter that allows us to step through the array of polygons repeatedly self.index_count = 0 # The number of moves allowed. if steps == 0: self.steps = len(self.cover_polygons) * 50 else: self.steps = steps
def show_results_for_antenna_circle_cover(fileName) : plt.figure(dpi=90) # get the current axes. ax = plt.gca() f = open(fileName) result = json.load(f) coverage_filename = result["detection_coverage_file"] indexes = result["indexes"] angles = result["angles"] center = result["center"] points_to_cover = result["points_to_cover"] detection_coverage = antennacover.read_detection_coverage(coverage_filename) circ = None for k in range(0,len(indexes)): polygon = detection_coverage[indexes[k]][1] rotated_cover = antennacover.rotate(polygon,angles[k]) rotated_translated_cover = antennacover.translate(rotated_cover,center) if circ is None: circ = rotated_translated_cover else: circ = circ.union(rotated_translated_cover) p = PolygonPatch(rotated_translated_cover, fc=GRAY, ec=GRAY, alpha=0.5, zorder=2) ax.add_patch(p) for p in points_to_cover: plot_point(ax,p,RED) xmin = float(circ.bounds[0]) ymin = float(circ.bounds[1]) xmax = float(circ.bounds[2]) ymax = float(circ.bounds[3]) ax.set_xlim([xmin,xmax]) ax.set_ylim([ymin,ymax]) if os.path.dirname(fileName) != '': mpl.rcParams["savefig.directory"] = os.chdir(os.path.dirname(fileName)) else: mpl.rcParams["savefig.directory"] = os.chdir("./") plt.show()
def show_results_for_antenna_cover(fileName): plt.figure(dpi=90) # get the current axes. ax = plt.gca() with open(fileName) as f: result = json.load(f) ic_x = result["ic_x"] ic_y = result["ic_y"] interference_contour = zip(ic_x,ic_y) interference_linestring = LineString(interference_contour) plot_coords(ax,interference_contour,RED) plot_line(ax,interference_linestring,YELLOW) esc_loc_x = result["esc_loc_x"] esc_loc_y = result["esc_loc_y"] possible_centers = zip(esc_loc_x,esc_loc_y) antenna_loc_x = result["antenna_loc_x"] antenna_loc_y = result["antenna_loc_y"] cover_centers = zip(antenna_loc_x,antenna_loc_y) #centers_linestring = LineString(cover_centers) possible_centers_linestring = LineString(possible_centers) plot_coords(ax,cover_centers,GREEN) plot_line(ax,possible_centers_linestring,BLUE) angles = result['angles'] indexes = result['indexes'] # load the antenna pattern file. coverage_filename = result['detection_coverage_file'] detection_coverage = antennacover.read_detection_coverage(coverage_filename) print "plotting polygons .... " # Compute the bounds of the polygon cover for drawing. circ = interference_linestring circ = circ.union(possible_centers_linestring) for i in range(0,len(indexes)): polygon = detection_coverage[indexes[i]][1] rotated_cover = antennacover.rotate(polygon,angles[i]) rotated_translated_cover = antennacover.translate(rotated_cover,cover_centers[i]) circ = circ.union(rotated_translated_cover) p = PolygonPatch(rotated_translated_cover, fc=GRAY, ec=GRAY, alpha=0.5, zorder=2) ax.add_patch(p) xmin,ymin,xmax,ymax = circ.bounds delta = max(abs(xmax -xmin),abs(ymax-ymin)) ax.set_xlim([xmin,xmin+delta]) ax.set_ylim([ymin,ymin+delta]) coverage_file = result["detection_coverage_file"] sensor_count = result["sensor_count"] antenna_count = result["antenna_count"] print "computing excess area ... " sea_excess_area,land_excess_area,outage_area,coverage_area = excessarea.compute_excess_area_for_antenna_cover(indexes, angles, cover_centers, coverage_filename, possible_centers, interference_contour) title = "antenna_coverage_file = " + coverage_file +\ "\nland_excess_area = " + str(land_excess_area) + " sea_excess_area = " + str(sea_excess_area) +\ "\noutage_area = " + str(outage_area) + " coverage_area = " + str(coverage_area) +\ "\nsensor_count = " + str(sensor_count) + " antenna_count = " + str(antenna_count) plt.suptitle(title) plt.gcf().canvas.set_window_title(result["testName"] + "_" + coverage_file) if os.path.dirname(fileName) != '': mpl.rcParams["savefig.directory"] = os.chdir(os.path.dirname(fileName)) else: mpl.rcParams["savefig.directory"] = os.chdir("./") print "rendering ..." plt.show()
def compute_excess_area_for_antenna_cover(indexes, angles, centers, detection_coverage_file, possible_centers, protected_region, units="km"): """ Parameters: indexes - the selected contours from detection_coverage_file angles - the orientation of each antenna. centers : the centers of the sensors (ordered). interference_contour : The interference contour point set (ordered) detection_coverage_file: The detection coverage file. """ def point_covered_by_lobe(point, antenna_cover_lobes): for i in range(0, len(antenna_cover_lobes)): if antenna_cover_lobes[i].contains(point): return True return False # load the detection coverage file. detection_coverage = antennacover.read_detection_coverage( detection_coverage_file, coverage_units=units) # the bounding polygon representing the if-contour and the possible centers. This bounds the region that # needs to be covered. # Line string representing the interference contour. Add first and last point # of possible_centers to this. This is the interference contour that is on the sea. interference_contour_linestring = LineString(protected_region) protected_polygon = Polygon(protected_region) # Line string representing the possible sensor locations if len(possible_centers) > 1: possible_centers_linestring = LineString(possible_centers) else: possible_centers_linestring = Point(possible_centers[0]) # the polygons representing the antenna shapes (rotated and translated) antenna_cover_polygons = generate_antenna_cover_polygons( indexes, angles, centers, detection_coverage) # Take the union of these shapes cover_union = antenna_cover_polygons[0] for i in range(1, len(antenna_cover_polygons)): cover_union = cover_union.union(antenna_cover_polygons[i]) union = cover_union.union(interference_contour_linestring) minx, miny, maxx, maxy = union.bounds # Generate a point set and classify. ndivs = antennacover.NDIVISIONS deltax, deltay = float(maxx - minx) / ndivs, float(maxy - miny) / ndivs area_per_grid_point = deltax * deltay excess_sea_coverage_count = 0 excess_land_coverage_count = 0 outage_count = 0 polygon_area_count = 0 for i in range(0, ndivs): for j in range(0, ndivs): p = Point(minx + i * deltax, miny + j * deltay) if cover_union.contains(p) and not protected_polygon.contains(p): # The point p is now either on sea or land. d1 = interference_contour_linestring.distance(p) d2 = possible_centers_linestring.distance(p) if d1 < d2: excess_sea_coverage_count = excess_sea_coverage_count + 1 else: excess_land_coverage_count = excess_land_coverage_count + 1 if protected_polygon.contains(p): polygon_area_count = polygon_area_count + 1 if not cover_union.contains(p): outage_count = outage_count + 1 # BUGBUG -- this does not always work because of BUGS with the data set (self intersecting polygons) #outage = protected_polygon.difference(union).area ExcessArea = namedtuple( "ExcessArea", "excess_sea_coverage excess_land_coverage outage_area protected_region" ) return ExcessArea(round2(excess_sea_coverage_count * area_per_grid_point), round2(excess_land_coverage_count * area_per_grid_point), round2(outage_count * area_per_grid_point), round2(polygon_area_count * area_per_grid_point))
# Sort these in order of increasing antenna angle. sorted_detection_coverage_files = sorted( detection_coverage_file_list, key=lambda (t): t[0]) # Put the result in a list detection_coverage_files = [ s[1] for s in sorted_detection_coverage_files ] else: # We are given a single antenna cover file. detection_coverage_files = [detection_coverage_dir] print "Antenna Detection Coverage files ", detection_coverage_files min_cover_lobes = None for detection_coverage_file in detection_coverage_files: # Read the aperture angle from the file. antenna_cover_patterns = antennacover.read_detection_coverage( detection_coverage_file, coverage_units="m") cover = antennacover.min_antenna_area_cover_greedy( candidate_locs, dpa_polygon, detection_coverage_file, min_center_distance=0, tol=.005, coverage_units="m") cover_lobes = None for c in cover: center = c[0] index = c[1] angle = c[2] lobe = antennacover.translate_and_rotate( antenna_cover_patterns, center, index, angle) if cover_lobes is None: