Under the wing of an airplane sings about something


    If you carefully look at the image on the left, it is easy to determine the location of the author.
    It is enough to take the compass and atlas of Russia.
    Set the leg of the compass in Sasovo and draw a circle with a radius of 103 km.
    Then draw another circle (the center is in Sormovo) with a radius of 141 km.
    I will be at the intersection. Achtung! Fire!

    I’ll tell you how I wrote an altimeter application, interesting for air travelers. No ads. No money. Clean code.

    My friend, a careless rider, often flies Moscow-Geneva and back

    And he asked me to do him a favor. Make an iPhone application that reports on the current altitude. And something else informative.
    I guessed that the plane looked like my village beyond Krasnoyarsk. That is, the Internet is completely absent. I decided to cram directly into the application a list of legal airports in the world and lingerie galleries. What else to do on board an airplane, if not contemplation of the beautiful or the distant?

    GPS enable

    The modern iPhone GPS sensor stores planetary coordinates and altitude. The accuracy of the height measure depends on various factors, but is sometimes good enough - less than 6 yards. In this case, you can, by turning on the application, jump from the roof of a skyscraper and observe online a change in height. ️Warning! This may be hazardous to your health️.

    Turning on the GPS tracker in the application takes 7 lines
        CLLocationManager *locationManager; // это в заголовке класса типа ViewController
       // Do any additional setup after loading the view, typically from a nib.
        locationManager = [CLLocationManager new];
        [locationManager requestWhenInUseAuthorization];
        [locationManager requestAlwaysAuthorization];
        locationManager.delegate = self;
        locationManager.desiredAccuracy = kCLLocationAccuracyBest;
        [locationManager startUpdatingLocation];

    After that, two functions appear in your class that regularly receive messages from the GPS sensor.
    One function comes to life when the sensor is working, and the second - when the sensor is broken or does not see satellites.

    - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
        CLLocation *currentLocation = [locations objectAtIndex:0];
        NSLog(@"GPS Tracking   %f", currentLocation.verticalAccuracy);
        [playView updateHeight:currentLocation.altitude]; // это личное
    -(void) locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
        NSLog(@"GPS Error   %@, denied=%d", error.description, error.code==kCLErrorDenied);

    Do you think everything will work now? Nope

    For the application to work, the above was not enough. Nothing came into the didUpdateLocations function. And, in general, she was not called. And the didFailWithError function did not breathe.
    It turned out in the application settings, you need to enable two checkmarks, (we follow the hand, rraz) - Targets-> Capabilities-> Background modes->
    After these magical actions, the application worked, yo-ho-ho!
    How you will now process messages is a purely individual matter.

    App design

    I decided to show in portrait mode
    • Large numbers in height;
    • Small numbers indicate the accuracy of measurements;
    • A beautiful blue graph - every second height tracking;
    • A very beautiful burgundy schedule - every minute tracking height.

    Well, yes, the burgundy point is added to the chart 1 time per minute. There are 25 such points in total, so the old points are forgotten and not drawn when new ones appear. Is everything simple? Yes, and vividly so.

    Of course, in landscape mode, the big numbers go beautifully and a graph of the entire session appears.
    Added buttons to stop tracking and continue or start tracking again .
    These buttons are necessary because the tracking mode eats up the battery (I really didn’t notice this) and lights up an unpleasant blue background at the top of the screen when the application goes into sleep or inactive mode.

    Beautiful graphics

    To draw graphs, I applied the following trick. Started up
    pictures. I

    called segments between graph points with the UIImageView type.
    And transformed the segments according to the law of linear algebra, let its name be holy.
        for (int k=0;k<24-1;k++) {
            UIImageView *p1 = [pointsQ objectAtIndex:k];
            UIImageView *p2 = [pointsQ objectAtIndex:k+1];
            UIImageView *p = [linesQ objectAtIndex:k];
            float x1 = p1.center.x;
            float x2 = p2.center.x;
            float y1 = Y0 - (q2[k]-hmin)*dh;
            float y2 = Y0 - (q2[k+1]-hmin)*dh;
            float l2 = hypot((x2-x1),(y2-y1));
            float cDy = 1.0/l2;
            float a = -(x2-x1)*2.0/cellDy;
            float c = -(y2-y1)*cDy;
            float b = -(y2-y1)*2.0/cellDy;
            float d = (x2-x1)*cDy;
            float tx = 0.0;
            float ty = 0.0;
            p.alpha =  (q1[k]*q1[k+1]) ? 1.0 : 0.0;
            p.center = CGPointMake(0.5*(x1+x2), 0.5*(y1+y2));
            p.transform = CGAffineTransformMake(a, b, c, d, tx, ty);

    Here p1, p2 are the points between which it is necessary to draw a segment p, q1 [x] is the array of flags of the height value (0-no value), q2 [x] is the array of height values, cellDy is the image size in pixels. Y0 is the shift of the graph in height. Pervert, you say? Yes, I love such tricks, what to hide there, I remember the times of the games of the mind.
    The last three operators can be replaced with one, but this is homework.

    Homework answer
            p.transform =  (q1[k]*q1[k+1]) ? CGAffineTransformMake(a, b, c, d, 0.5*(x1+x2), 0.5*(y1+y2)) : CGAffineTransformMakeScale(0, 0);

    Here is such a flight. With a lot of data, I interpolate the elevation values ​​by 40 key points. I checked the work for 36 hours in a row, I think no one will surpass my record.

    List of airports

    The list of airports must be placed in the application so that it is available at any time, regardless of the availability of the Internet.
    I took the data about the airdromes from the first link from the request free airports list xml
    Packed the list in airports.sql file (less than 9000 units), added the file to the project, when I start the application, I read and load airports.sql into the Airport structure
    @interface Airport : NSObject
    @property (nonatomic) NSInteger db_id;
    @property (nonatomic) NSString *name;
    @property (nonatomic) NSString *city;
    @property (nonatomic) NSString *country;
    @property (nonatomic) NSString *iata;
    @property (nonatomic) NSString *icao;
    @property (nonatomic) double latitude;
    @property (nonatomic) double longitude;
    @property (nonatomic) double altitude;
    @property (nonatomic) int timezone;
    @property (nonatomic) NSString *dst;
    @property (nonatomic) NSString *timezone_name;
    @property (nonatomic, retain) CLLocation* location;
    @property (nonatomic,readonly) double distanceFromHere;
    - (id) initWithSQLStatement:(sqlite3_stmt *) selectstmt;
    - (double) distanceFromLocation:(CLLocation*)location;
    id integer, 
     name text, 
     city text, 
     country text, 
     iata text, 
     icao text, 
     latitude float, 
     longitude float, 
     altitude float, 
     timezone integer, 
     dst text, 
     timezone_name text
    */  это структура базы данных, если чо забыл

    The calculation of the distance from the current position to any airport was made by Apple long before me
    - (double) distanceFromLocation:(CLLocation*)location
        _distanceFromHere = [self.location distanceFromLocation:location];
        return _distanceFromHere;

    Then I add sorting and list the ten nearest airports (UITableViewController).
    I was surprised to find that the nearest airfield is not in Nizhny Novgorod, but in Sasovo, Ryazan province. Here are the miracles. I was in this Sasovo flight school in 1991. Nicolas D. and I made the YAK-52 simulator on the AT-286. 12 frames per second, assembler, I remember vaguely, Pascal, assembler again, Chassis-Royal cocktail .

    List of lingerie salons

    Initially, I wanted to stick photos and fake names of virtual courtesans of the largest cities in Europe. You’re flying, you see, but the list is being updated. But he didn’t dare - suddenly the Review Team is able to change the height, they will ban me for my bare boobs. Limited to beautiful linen.
    Added by the same algorithm as airfields.
    However, the quest turned out, the chip only works at a height above 9000 meters.

    Butting with the store


    The application was quickly made (as part of a useless event, 6 applications in 6 weeks ) and was approved for a long time in the store. A very long time, almost two months.
    The ambush was that the user should be warned with the following phrase

    Continued use of GPS running in the background can dramatically decrease battery life

    The first time the application slowed down - they said let's fix it.

    I inserted beautifully
    ️ Continued use of GPS running in the background can dramatically decrease battery life️

    And he turned out to be an idiot. These yellow special characters are prohibited.
    I had to wait another 10 days, and then another 10 ...
    And today they approved .

    Application check

    Yes, I had to fly. Not for me, of course, oats are expensive today. The problem became clear. In the aisle chairs, the application often does not work. GPS, a scoundrel, does not see satellites.
    I was comforted by the fact that there was a (wonderful?) Reason to get acquainted with a (beautiful?) Companion at the window.

    At the porthole, satellites and companions are visible wonderfully.

    Also popular now: