TUDelft-CNS-ATM / bluesky

The open source air traffic simulator
GNU General Public License v3.0
342 stars 239 forks source link

checkInside function of POLY gives ValueError when used on a single aircraft selected through the index #506

Open giulialeto opened 2 weeks ago

giulialeto commented 2 weeks ago

Hi,

In the areafilter.py, function checkInside for the Poly class, a ValueError arises when I am trying to check whether a specific aircraft (selected from an index) is inside a Poly. For example:

bs.traf.cre('KL001',actype="A320",acspd=AC_SPD)
ac_idx = bs.traf.id2idx('KL001')
bs.tools.areafilter.checkInside(poly_name, bs.traf.lat[ac_idx], bs.traf.lon[ac_idx], bs.traf.alt[ac_idx])

leads to ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (3,) + inhomogeneous part.

This is because multiple criteria are checked by np.all, see function below

def checkInside(self, lat, lon, alt):
  points = np.vstack((lat,lon)).T
  inside = np.all((self.border.contains_points(points), self.bottom <= alt, alt <= self.top), axis=0)
  return inside

While self.border.contains_points(points) always returns a bool array, self.bottom <= alt and alt <= self.top return a bool when the input has dimension 1. np.all expects compatible shapes.

A possible quick fix could be checking if the second or third criteria results in a np.ndarray or not, and making it an array if it doesn't, see code below

def checkInside(self, lat, lon, alt):
    points = np.vstack((lat,lon)).T
    # if only one aircraft was checked, converts boolean to np.array before checking np.all
    if type(self.bottom <= alt) == np.ndarray:
        inside = np.all((self.border.contains_points(points), self.bottom <= alt, alt <= self.top), axis=0)
    else:
        inside = np.all((self.border.contains_points(points), np.array([self.bottom <= alt]), np.array([alt <= self.top])), axis=0)
    return inside

Cheers!