def install_fixtures(self): session = self.db.session() PARIS_LAT_DEG = from_degrees(PARIS_LAT) PARIS_LON_DEG = from_degrees(PARIS_LON) qry = session.query(Cell) if qry.count() > 0: session.query(Cell).delete() lat = from_degrees(PARIS_LAT) lon = from_degrees(PARIS_LON) key = dict(mcc=FRANCE_MCC, mnc=2, lac=3) data = [ Cell(lat=lat, lon=lon, radio=2, cid=4, **key), Cell(lat=lat + 20000, lon=lon + 40000, radio=2, cid=5, **key), ] session.add_all(data) if session.query(Wifi).count() > 0: session.query(Wifi).delete() wifis = [ Wifi(key="A1", lat=PARIS_LAT_DEG, lon=PARIS_LON_DEG), Wifi(key="B2", lat=PARIS_LAT_DEG, lon=PARIS_LON_DEG), Wifi(key="C3", lat=PARIS_LAT_DEG, lon=PARIS_LON_DEG), Wifi(key="D4", lat=None, lon=None), ] session.add_all(wifis) session.commit()
def update_lac(self, radio, mcc, mnc, lac): with self.db_session() as session: # Select all the cells in this LAC that aren't the virtual # cell itself, and derive a bounding box for them. q = session.query(Cell).filter(Cell.radio == radio).filter( Cell.mcc == mcc).filter(Cell.mnc == mnc).filter( Cell.lac == lac).filter(Cell.cid != CELLID_LAC) cells = q.all() points = [(to_degrees(c.lat), to_degrees(c.lon)) for c in cells] min_lat = to_degrees(min([c.min_lat for c in cells])) min_lon = to_degrees(min([c.min_lon for c in cells])) max_lat = to_degrees(max([c.max_lat for c in cells])) max_lon = to_degrees(max([c.max_lon for c in cells])) bbox_points = [(min_lat, min_lon), (min_lat, max_lon), (max_lat, min_lon), (max_lat, max_lon)] ctr = centroid(points) rng = range_to_points(ctr, bbox_points) # switch units back to DB preferred centimicrodegres angle # and meters distance. ctr_lat = from_degrees(ctr[0]) ctr_lon = from_degrees(ctr[1]) rng = int(round(rng * 1000.0)) # Now create or update the LAC virtual cell q = session.query(Cell).filter(Cell.radio == radio).filter( Cell.mcc == mcc).filter(Cell.mnc == mnc).filter( Cell.lac == lac).filter(Cell.cid == CELLID_LAC) lac = q.first() if lac is None: lac = Cell(radio=radio, mcc=mcc, mnc=mnc, lac=lac, cid=CELLID_LAC, lat=ctr_lat, lon=ctr_lon, range=rng) else: lac.new_measures = 0 lac.lat = ctr_lat lac.lon = ctr_lon lac.range = rng session.commit()
def make_submission(**kw): measure = dict(radio='umts', lat=from_degrees(49.25), lon=from_degrees(123.10), accuracy=120, altitude=220, altitude_accuracy=10, time=time) cell = dict(mcc=302, mnc=220, lac=12345, cid=34567, psc=-1, asu=15, signal=-83, ta=5) for (k, v) in kw.items(): if k in measure: measure[k] = v else: cell[k] = v return (measure, cell)
def make_submission(**kw): measure = dict(radio='', lat=from_degrees(49.25), lon=from_degrees(123.10), accuracy=120, altitude=220, altitude_accuracy=10, time=time) wifi = dict(key="12:34:56:78:90:12", frequency=2442, channel=7, signal=-85) for (k, v) in kw.items(): if k in measure: measure[k] = v else: wifi[k] = v return (measure, wifi)
def update_lac(self, radio, mcc, mnc, lac): with self.db_session() as session: # Select all the cells in this LAC that aren't the virtual # cell itself, and derive a bounding box for them. q = session.query(Cell).filter( Cell.radio == radio).filter( Cell.mcc == mcc).filter( Cell.mnc == mnc).filter( Cell.lac == lac).filter( Cell.cid != CELLID_LAC).filter( Cell.new_measures == 0).filter( Cell.lat.isnot(None)).filter( Cell.lon.isnot(None)) cells = q.all() if len(cells) == 0: return points = [(to_degrees(c.lat), to_degrees(c.lon)) for c in cells] min_lat = to_degrees(min([c.min_lat for c in cells])) min_lon = to_degrees(min([c.min_lon for c in cells])) max_lat = to_degrees(max([c.max_lat for c in cells])) max_lon = to_degrees(max([c.max_lon for c in cells])) bbox_points = [(min_lat, min_lon), (min_lat, max_lon), (max_lat, min_lon), (max_lat, max_lon)] ctr = centroid(points) rng = range_to_points(ctr, bbox_points) # switch units back to DB preferred centimicrodegres angle # and meters distance. ctr_lat = from_degrees(ctr[0]) ctr_lon = from_degrees(ctr[1]) rng = int(round(rng * 1000.0)) # Now create or update the LAC virtual cell q = session.query(Cell).filter( Cell.radio == radio).filter( Cell.mcc == mcc).filter( Cell.mnc == mnc).filter( Cell.lac == lac).filter( Cell.cid == CELLID_LAC) lac = q.first() if lac is None: lac = Cell(radio=radio, mcc=mcc, mnc=mnc, lac=lac, cid=CELLID_LAC, lat=ctr_lat, lon=ctr_lon, range=rng) else: lac.new_measures = 0 lac.lat = ctr_lat lac.lon = ctr_lon lac.range = rng session.commit()
def test_normalize_cells(self): radio_pairs = [('gsm', 0), ('cdma', 1), ('umts', 2), ('wcdma', 2), ('lte', 3), ('wimax', -1), ('', -1), ('hspa', -1), ('n/a', -1)] valid_mccs = [1, 25, 999] invalid_mccs = [-10, 0, 1000, 3456] valid_mncs = [0, 542, 32767] invalid_mncs = [-10, -1, 32768, 93870] valid_lacs = [0, 763, 65535] invalid_lacs = [-1, -10, 65536, 987347] valid_cids = [0, 12345, 268435455] invalid_cids = [-10, -1, 268435456, 498169872] valid_pscs = [0, 120, 512] invalid_pscs = [-1, 513, 4456] valid_latitudes = [from_degrees(x) for x in [-90.0, -45.0, 0.0, 45.0, 90.0]] invalid_latitudes = [from_degrees(x) for x in [-100.0, -90.1, 90.1, 100.0]] valid_longitudes = [from_degrees(x) for x in [-180.0, -90.0, 0.0, 90.0, 180.0]] invalid_longitudes = [from_degrees(x) for x in [-190.0, -180.1, 180.1, 190]] valid_accuracies = [0, 1, 100, 10000] invalid_accuracies = [-10, -1, 5000000] valid_altitudes = [-100, -1, 0, 10, 100] invalid_altitudes = [-20000, 200000] valid_altitude_accuracies = [0, 1, 100, 1000] invalid_altitude_accuracies = [-10, -1, 500000] valid_asus = [0, 10, 31] invalid_asus = [-10, -1, 32, 100] valid_tas = [0, 15, 63] invalid_tas = [-10, -1, 64, 100] valid_signals = [-200, -100, -1] invalid_signals = [-300, -201, 0, 10] time = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S.%f') def make_submission(**kw): measure = dict(radio='umts', lat=from_degrees(49.25), lon=from_degrees(123.10), accuracy=120, altitude=220, altitude_accuracy=10, time=time) cell = dict(mcc=302, mnc=220, lac=12345, cid=34567, psc=-1, asu=15, signal=-83, ta=5) for (k, v) in kw.items(): if k in measure: measure[k] = v else: cell[k] = v return (measure, cell) # Try all radio values for (radio, v) in radio_pairs: (measure, cell) = make_submission(radio=radio) self.check_normalized_cell(measure, cell, dict(radio=v)) # Try all valid (mcc, mnc) pairs for mcc in valid_mccs: for mnc in valid_mncs: (measure, cell) = make_submission(mcc=mcc, mnc=mnc) self.check_normalized_cell(measure, cell, dict(mcc=mcc, mnc=mnc)) # Try all invalid mcc variants individually for mcc in invalid_mccs: (measure, cell) = make_submission(mcc=mcc) self.check_normalized_cell(measure, cell, None) # Try all invalid mnc variants individually for mnc in invalid_mncs: (measure, cell) = make_submission(mnc=mnc) self.check_normalized_cell(measure, cell, None) # Try all valid (lac, cid) pairs, with invalid pscs for lac in valid_lacs: for cid in valid_cids: for psc in invalid_pscs: (measure, cell) = make_submission(lac=lac, cid=cid, psc=psc) self.check_normalized_cell(measure, cell, dict(lac=lac, cid=cid, psc=-1)) # Try all invalid lacs, with an invalid psc for lac in invalid_lacs: for psc in invalid_pscs: (measure, cell) = make_submission(lac=lac, psc=psc) self.check_normalized_cell(measure, cell, None) # Try all invalid cids, with an invalid psc for cid in invalid_cids: for psc in invalid_pscs: (measure, cell) = make_submission(cid=cid, psc=psc) self.check_normalized_cell(measure, cell, None) # Try all invalid lacs, with a valid psc for lac in invalid_lacs: for psc in valid_pscs: (measure, cell) = make_submission(lac=lac, psc=psc) self.check_normalized_cell(measure, cell, dict(lac=-1, psc=psc)) # Try all invalid cids, with a valid psc for cid in invalid_cids: for psc in valid_pscs: (measure, cell) = make_submission(cid=cid, psc=psc) self.check_normalized_cell(measure, cell, dict(cid=-1, psc=psc)) # Try all valid (lat, lon) pairs for lat in valid_latitudes: for lon in valid_longitudes: (measure, cell) = make_submission(lat=lat, lon=lon) self.check_normalized_cell(measure, cell, dict(lat=lat, lon=lon)) # Try all invalid latitudes individually for lat in invalid_latitudes: (measure, cell) = make_submission(lat=lat) self.check_normalized_cell(measure, cell, None) # Try all invalid longitudes individually for lon in invalid_longitudes: (measure, cell) = make_submission(lon=lon) self.check_normalized_cell(measure, cell, None) # Try all 'nice to have' valid fields individually for (k, vs) in [('accuracy', valid_accuracies), ('altitude', valid_altitudes), ('altitude_accuracy', valid_altitude_accuracies), ('asu', valid_asus), ('ta', valid_tas), ('signal', valid_signals)]: for v in vs: (measure, cell) = make_submission(**{k: v}) self.check_normalized_cell(measure, cell, {k: v}) # Try all 'nice to have' invalid fields individually for (k, vs, x) in [('accuracy', invalid_accuracies, 0), ('altitude', invalid_altitudes, 0), ('altitude_accuracy', invalid_altitude_accuracies, 0), ('asu', invalid_asus, -1), ('ta', invalid_tas, 0), ('signal', invalid_signals, 0)]: for v in vs: (measure, cell) = make_submission(**{k: v}) self.check_normalized_cell(measure, cell, {k: x})