def _run_binary(self, inter, radius, grid_size=20):
        """Runs binary on area

        Args:
            @inter: the projected polygon in which we are running
                    the binary attack algorithm
            @radius: the radius of the disk to perform the cuts
        """

        vb.vb_print(self.verbose, "Running Binary", "UDP", True)

        last_inter_area = float('inf')
        while (inter.area > self.BINARY_STOP_AREA and
               self.attack_queries < self.query_limit):

            vb.vb_print(self.verbose, "Estimating cut", "UDP", True)
            # find projected coordinates that cut inter in half
            proj_coords = cells.cut(inter, self.proj, radius, grid_size)
            circle = Point(proj_coords[0], proj_coords[1]).buffer(radius * 1000)

            self.json_out["DUDP"].append({"query": self.attack_queries,
                                          "disk": self._log_kml("disk",
                                                                circle),
                                          "active_area": self._log_kml("inter",
                                                                       inter),
                                         })

            # calculate the coordinates for the new cut query
            (query_lon, query_lat) = self.proj(proj_coords[0],
                                               proj_coords[1],
                                               inverse=True)

            self._place_at_coords(self.attacker,
                                  query_lat,
                                  query_lon,
                                  self.test_id)

            if self.oracle is None:
                raise SystemExit("oracle should not be None after coverage")

            oracle_rspn = [None, None]
            attempts = 0
            while oracle_rspn[0] is None:
                # ask the oracle if the victim is in proximity
                oracle_rspn = self.oracle.in_proximity(self.attacker,
                                                       self.victim,
                                                       self.test_id)
                # increase queries
                self.attack_queries += oracle_rspn[1]
                if oracle_rspn[0] is None and attempts > 5:
                    self._update_attacker()
                attempts += 1

            if oracle_rspn[0] is True:
                # if in proximity take the intersection
                inter_new = inter.intersection(circle)
            else:
                # else take the difference
                inter_new = inter.difference(circle)

            if inter_new.is_empty:
                print "\n\n\t ***WARNING!! EMPTY INTERSECTION***\n\n"
                inter = circle
            else:
                inter = inter_new

            # log kml
            self._log_kml("inter", inter)

            # if area is not reduced after intersection
            # break to avoid an infinite loop.
            area = inter.area
            if math.fabs(last_inter_area - area) < self.MIN_REDUCTION * area:
                vb.vb_print(self.verbose,
                            "Area not significantly reduced ..stopping",
                            "UDP",
                            True)
                break
            else:
                last_inter_area = inter.area

        est_location = cells.poly_centroid(inter, self.proj)
        vb.vb_print(self.verbose,
                    "Estimated Location: " + str(est_location),
                    "UDP",
                    True)

        real_est_distance = earth.distance_on_unit_sphere(self.victim.loc[0],
                                                          self.victim.loc[1],
                                                          est_location[0],
                                                          est_location[1])
        # convert to m
        real_est_distance *= 1000
        vb.vb_print(self.verbose,
                    "Distance from real loc: " + str(real_est_distance) + "m",
                    "UDP",
                    True)

        self.json_out["est_location"].append({"query": self.attack_queries,
                                              "area" : inter.area,
                                              "coords": [est_location[0],
                                                         est_location[1]]})
        self.json_out["real_location"].append({"query": -1,
                                               "coords": [self.victim.loc[0],
                                                          self.victim.loc[1]]})

        output_json = ''.join(os.getcwd() + "/" + self.JSON_DIR)
        output_json += self.service_name + "_UDP_"
        with open(output_json + str(self.test_id) + ".json", "w") as outfile:
            json.dump(self.json_out, outfile)

        return real_est_distance
    def _run_trilateration(self, rounding_classes):
        """Runs a variance of the trilateration attack on the search_area

        Args:
            rouding_classes: a list of intervals with the radiuses

        Returns:
            A polygon in projected coordinates containing the target
            """

        vb.vb_print(self.verbose,
                    "Running trilateration",
                    "UDP",
                    True)
        # get minimum radius in the rounding classes
        MIN_R = sorted([cl[0] for cl in rounding_classes])[0][0]

        #initially the intersection is the whole area
        inter = self.search_area
        # place the attacker in the center
        if self.attacker.loc is None or self.attacker.loc[0] is None:
            starting_loc = cells.poly_centroid(inter, self.proj)
            self._place_at_coords(self.attacker,
                                  starting_loc[0],
                                  starting_loc[1],
                                  self.test_id)

        if self.oracle is None:
            self.oracle = apo.RoundingProximityOracle(self.auditor,
                                                      rounding_classes,
                                                      self.verbose)

        # initially get a rough estimate with 3 queries from
        # three locations at a distance of 120 degrees.
        # Initiate intersection rings
        rings = []
        for i in range(3):
            # get a ring and check if we are switching to binary
            ring_response = self.__get_ring(MIN_R)
            if ring_response is None:
                raise SystemExit("victim not found")
            else:
                distance_range, ring = ring_response
            self._log_kml("ring", ring)
            rings.append(ring)

            #XXX no need to check for multipolygon in case of DUDP
            # as we are working inside a polygonal area
            inter_new = None
            if inter.geom_type == "MultiPolygon":
                for p in inter:
                    cut_inter = p.intersection(ring)
                    if inter_new is None:
                        inter_new = cut_inter
                    else:
                        inter_new = inter_new.union(cut_inter)
            else:
                inter_new = inter.intersection(ring)

            # update the intersection
            inter = ring if inter_new.is_empty else inter_new

            # log kml files
            self.json_out["RUDP"].append({"query": self.attack_queries,
                                          "ring": self._log_kml("ring", ring),
                                          "active_area": self._log_kml("inter",
                                                                       inter),
                                         })

            # update attacker location
            dist = float(distance_range[0] + distance_range[1]) / 2
            # calculate new location for the next query
            new_loc = earth.point_on_earth(self.attacker.loc[0],
                                           self.attacker.loc[1],
                                           dist,
                                           i * 120)

            self._place_at_coords(self.attacker,
                                  new_loc[0],
                                  new_loc[1],
                                  self.test_id)

        # switch to binary
        return inter