Ramani API Framework for iOS

With the Ramani API Framework for iOS, you can add map data to your application. The API automatically handles access to the map servers, returns tiled-map displays (retina optimized), and provides a variety of charts returned as PNG-image or Scalable Vector-Graphics (SVG) for further client-side interactions.

Supported Platforms

With the Ramani API Framework for iOS, you can build apps that target native 32-bit or 64-bit devices running iOS 6.0 and later (up to 8.0).

Developing an application with the Ramani API Framework for iOS requires the following:

  • Xcode 5.0 or later.
  • iOS SDK 6.0 or later (up to 9.0).
  • Google Maps SDK 1.7 or later.

Obtaining the Ramani API Framework for iOS

The Ramani API Framework for iOS is distributed as a zip file containing a static framework.


Adding the Google Maps SDK for iOS to your project

Before you can add our map services to your application, you will need to add the Google Maps SDK to your project. You can follow these instructions to add the Google Maps SDK to your project


Adding the Ramani API Framework for iOS to your project

  1. Launch Xcode and either open an existing project, or create a new project.
  2. Drag the Ramani.framework bundle to the Frameworks group of your project. When prompted, select Copy items into destination group's folder.
  3. Add #import <Ramani/RSMapServices.h> to your header code.

The Ramani API Framework for iOS is designed as a superset of Google Maps SDK for iOS. You can use it as a drop in replacement for Google Maps SDK by following these steps:

  1. Add the Ramani API Framework for iOS to your project
  2. Replace any #import <GoogleMaps/GoogleMaps.h> with #import <Ramani/RSMapServices.h>


Obtaining the Ramani Example Application for iOS (optional)

To illustrate how the use our Maps-API, we provide an example application for iOS (v8.x) that demonstrates some of the API methods listed below.


Add your API-Key (apiKey)

You must provide the API-Key that you get from our client-area webpage before the API can access our map services. Please register here if you have not done already.



           [RSMapServices apiKey:@"API_KEY" userName:@"USERNAME"];

          

Note: Replace API_KEY with the string API_KEY that you created from client area.


Get a Map Layer (getMap)

With the Ramani API Framework for iOS, you can add a Map Layer to your application. The code below demonstrates how to add a map layer to an existing ViewController.


            #import "YourViewController.h"
            #import <Ramani/RSMapServices.h>

            @implementation YourViewController {
              GMSMapView *mapView_;
            }

            - (void)viewDidLoad {
              GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:-33.86
                                                                      longitude:151.20
                                                                           zoom:6];
              mapView_ = [GMSMapView mapWithFrame:CGRectZero camera:camera];
              mapView_.myLocationEnabled = YES;
              self.view = mapView_;
			  [RSMapServices apiKey:@"API_KEY" userName:@"USERNAME"];
              ///create map tile layer
              RSMapServices *tileLayer = [RSMapServices getMap:layerID];
              tileLayer.map = mapView_;
            }

            @end

          

Note: Replace layerID with the string name of the ID of a layer of your choice. A valid string consist of a layerID/param combination. You can obtain the layer ID/param-combination from the Layer Information-widget as part of our Stream Data Library (SDL).

Example: Once in the SDL-interface > select Layer entitled: Sentinel-3: Global Leaf-Area Index > leaf area index. Then from the Layer information-widget find the > Layer ID : simS3seriesLaiGlobal/lai


Get Location Info (getFeatureInfo)



            - (void) mapView:(GMSMapView *)mapView didTapAtCoordinate:(CLLocationCoordinate2D)coordinate {

                  NSString *featureInfo = [RSMapServices getFeatureInfo:coordinate layerID:layerID];

                  GMSMarker *marker = [GMSMarker markerWithPosition:coordinate];
                  marker.title = featureInfo;
                  marker.map = mapView_;
            }

          

Note: The getFeatureInfo operation is designed to provide clients with more information about a single location on a map.


Get a Vertical Profile (getVerticalProfile)



            UIImage *img = [RSMapServices getVerticalProfile:coordinate layerID:layerID];
            UIImageView * myImageView = [[UIImageView alloc] initWithImage:img];
            [self.view addSubview:myImageView];

          

Note: Same as Get Point Info (getFeatureInfo), but along a vertical dimension instead of a single point. Only works on layers that have a vertical dimension (explore the maps we have on offer in our SDL).

Example: For example, nitrates in the depth of the ocean.


Get a Time-series Profile (getTimeseriesProfile)



            UIImage *img = [RSMapServices getTimeseriesProfile:coordinate layerID:layerID];
            UIImageView * myImageView = [[UIImageView alloc] initWithImage:img];
            [self.view addSubview:myImageView];

          

Note: Same as Get Location Info (getFeatureInfo) but varying in time (along a temporal dimension). Only works on layers that have a temporal dimension (explore the maps we have on offer in our SDL).

Example: For example, LAI over the seasons of the year.


Get a Horizontal Profile (getTransect)



            UIImage *img = [RSMapServices getTransect:coordinatesArray layerID:layerID];
            UIImageView * myImageView = [[UIImageView alloc] initWithImage:img];
            [self.view addSubview:myImageView];

          

Note: Same as Get Location Info (getFeatureInfo), but along a horizontal dimension. coordinatesArray is NSMutableArray. The value of coordinatesArray consists of multiple (CLLocationCoordinate2D)coordinates.

Example: For example, atmospheric ozone along a line (single or multiple segments) crossing a city.


Get a Area Profile (getArea)



            [rect addCoordinate: CLLocationCoordinate2DMake(52.378953,5.927090)];
                [rect addCoordinate: CLLocationCoordinate2DMake(52.769540,6.196256)];
                [rect addCoordinate: CLLocationCoordinate2DMake(52.769540,7.113614)];
                [rect addCoordinate: CLLocationCoordinate2DMake(51.876492,6.998257)];
                [rect addCoordinate: CLLocationCoordinate2DMake(51.944266,6.295132)];
                [rect addCoordinate: CLLocationCoordinate2DMake(52.623061,6.690640)];

                GMSPolygon *polygon = [GMSPolygon polygonWithPath:rect];
                polygon.fillColor = [UIColor colorWithRed:0.25 green:0 blue:0 alpha:0.05];
                polygon.strokeColor = [UIColor blackColor];
                polygon.strokeWidth = 2;
                polygon.map = mapView_;

                dispatch_async(dispatch_get_main_queue(), ^{
                    UIImage *img = [RSMapServices getArea:rect layerID:layerID];
                    UIImageView * myImageView = [[UIImageView alloc] initWithImage:img];
                    [self.view addSubview:myImageView];
                });


          

Note: Same as Get a Horizontal Profile (getTransect), but for an area defined by addCoordinate, which must contain 3 or more elements to define a polygon.


Get Layer Attributes (getMetadata)


            NSDictionary *getMetadata = [RSMapServices getMetadata:layerID];
            NSLog(@"scaleRange :%@", getMetadata[@"scaleRange"]);
	   NSLog(@"TIME :%@", getMetadata[@"nearestTimeIso"]);
	    NSLog(@"ELEVATION :%@", getMetadata[@"zaxis"][@"values"]);
          

Note: Use this method to get Layer attributes aka metadata. For more information about which parameters you can get follow this link.

Example: To obtain the temporal range of a time-series required by getTimeseriesProfile use (TIME), or to get the extremes of a layer (Min) and (Max) to set the scaleRange parameter.

Get dates for timeseries and get return as RSS

          
            NSDictionary *params = @{@"item":@"dates", @"format":@"rss"};
            [RSMapServices setParams:params];

            NSDictionary *getMetadata = [RSMapServices getMetadata:layerID];

          
        

Example: click to see the example.

Get dates with ISO8601 format

          
            NSDictionary *params = @{@"item":@"dates"};
            [RSMapServices setParams:params];

            NSDictionary *getMetadata = [RSMapServices getMetadata:layerID];


            
          
        

Example: click to see the example.


Set Layer Attributes (setParams)


            NSDictionary *params = @{@"TIME":@"2010-02-04T00:00:00.000Z/2010-04-15T00:00:00.000Z"};
            [RSMapServices setParams:params];
            UIImage *img = [RSMapServices getTimeseriesProfile:coordinate layerID:layerID];
            UIImageView * myImageView = [[UIImageView alloc] initWithImage:img];
            [self.view addSubview:myImageView];

          

Note: Use this method to set Layer attributes. For more information about which parameters you can set follow this link.

Example: Use the param (TIME) to set the temporal range of a time-series.


Get an animated Map (getAnimation)

With the Ramani API Framework for iOS, you can create animated map layers (provided the dataset of interest has a temporal dimension). The code below demonstrates how to add an animated map layer to an existing ViewController.


            #import "YourViewController.h"
            #import <Ramani/RSMapServices.h>

            @implementation YourViewController {
              GMSMapView *mapView_;
            }

            - (void)viewDidLoad {
              GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:-33.86
                                                                      longitude:151.20
                                                                           zoom:6];
              mapView_ = [GMSMapView mapWithFrame:CGRectZero camera:camera];
              mapView_.myLocationEnabled = YES;
              self.view = mapView_;

               NSArray *timeStep = @[
                      @"2010-09-08T00:00:00.000Z",
                      @"2010-09-15T00:00:00.000Z",
                      @"2010-09-27T00:00:00.000Z",
                      @"2010-10-04T00:00:00.000Z",
                      @"2010-10-14T00:00:00.000Z",
                      @"2010-10-26T00:00:00.000Z",
                      @"2010-11-05T00:00:00.000Z",
                      @"2010-11-12T00:00:00.000Z",
                      @"2010-11-19T00:00:00.000Z",
                      @"2010-11-22T00:00:00.000Z",
                      @"2010-11-24T00:00:00.000Z",
                      @"2010-11-29T00:00:00.000Z"
                      ];

		    overlayArray = [RSMapServices getAnimation:layerID timeStep:timeStep];

		    [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(createAnimation:) userInfo:nil repeats: YES];

            }

            -(void) createAnimation:(id)selector{
			    UIImage *img = [overlayArray objectAtIndex:[currentLayerIndex intValue]];

			    for(GMSGroundOverlay *gO in overlayObjectArray){
			        gO.map = nil;
			        [overlayObjectArray removeObject: gO];
			    }

			    NSDictionary *getMetadata = [RSMapServices getMetadata:layerID];
			    double bb0 = [getMetadata[@"bbox"][0] doubleValue];
			    double bb1 = [getMetadata[@"bbox"][1] doubleValue];
			    double bb2 = [getMetadata[@"bbox"][2] doubleValue];
			    double bb3 = [getMetadata[@"bbox"][3] doubleValue];

			    CLLocationCoordinate2D southWest = CLLocationCoordinate2DMake( bb1, bb0);
			    CLLocationCoordinate2D northEast = CLLocationCoordinate2DMake(bb3, bb2);
			    GMSCoordinateBounds *overlayBounds = [[GMSCoordinateBounds alloc] initWithCoordinate:southWest
			                                                                              coordinate:northEast];
			    GMSGroundOverlay *overlay = [GMSGroundOverlay groundOverlayWithBounds:overlayBounds icon:img];
			    overlay.bearing = 0;
			    overlay.zIndex = 5  * ([currentLayerIndex intValue] + 1);
			    overlay.map = mapView_;

			    [overlayObjectArray addObject: overlay];

			    if([currentLayerIndex intValue] < [overlayArray count] - 1){
			        currentLayerIndex = @([currentLayerIndex intValue] + 1);
			    }else{
			        currentLayerIndex = @0;
			    }
			}

            @end

          

Note: you can set the timeStep to compose the animation from the image sequence (timeseries).


Search using Elasticsearch (search)

Search data inside a vector layer and show it on the map.


            		NSDictionary *_keyword = @{@"field_name" : @"value"};
            		NSDictionary * result = [RSMapServices search:mapView_ layerID:layerID keyword:_keyword showOnMap:true];

          

Note: All you have to do before calling this method is selecting the corresponding layer in the Ramani Cloud Admin and click the “Index in Elasticsearch” button. Ramani Cloud will first map the table schema to an Elasticsearch type and then pipe the tabular data as GeoJSON to Elasticsearch.


Manipulate data of a vector map (sqlAPI)

The first example shows you how to search for a feature in a layer and show it on the map, the second shows you how to instert a new point (i.e. GPS-location).


          	/*example to get a feature point from table */
          	NSString *query = @"SELECT * FROM [schemaName].[layerID] WHERE round(ST_Distance(ST_Transform(\"the_geom\",3857),
          	'ST_GeomFromText('POINT(551569.5961058318 6701998.640044251)',3857))) < 6114.9622628
          	ORDER BY round(ST_Distance(ST_Transform(\"the_geom\",3857),
          	ST_GeomFromText('POINT(551569.5961058318 6701998.640044251)',3857)))LIMIT 5";

          	[RSMapServices sqlAPI:query];



          	/*other example for insert*/
          	NSString *insertQuery = @"INSERT INTO [schemaName].[layerID] (the_geom ,time, longitude, latitude, accelx, accely,
          	accelz, orientx, orienty, orientz, magneticx, magneticy, magneticz, bearing, speed, gpsaccuracy, entropy, annotation_observe,
          	status, rpqs, annotation_predict) VALUES (ST_GeomFromText('POINT(110.597145 -7.002776666666667)',4326),
          	1434159945524,110.597145,-7.002776666666667, 4.338,3.217,4.616,2.2945807,-53.003002,1.0712337,
          	-2.5,41.25,-15.0,0.0,0.0,6.8,0.9999999999999998,null,
          	null,null,null);";

          	[RSMapServices sqlAPI:insertQuery];
          

Store Point (storePoint)

Store a new or modified point feature on Ramani Cloud (currently only support for private layers):


            NSDictionary *fields = @{@"id" : @"100",
            						 @"time" : @"1434159945524",
            						 @"accelx" : @"4.338"
            						};
    		[RSMapServices storePoint:layerID fields:fields coordinate:coordinate];
          
Note: Allows the user to define series of points of interest and store these for repeated usage on different requests.


Store Polygon (storePolygon)

Store a (multi)polygon feature on Ramani Cloud (currently only support for private layers):


            NSDictionary *fields = @{@"id" : @"100",
            						 @"time" : @"1434159945524",
            						 @"accelx" : @"4.338"
            						};
            [RSMapServices storePolygon:_coordinates layerID:layerID fields:fields];
          

Note: This function can be used to retrieve a pre-defined area for future usage..


Store Line (storeLine)

Store your (multi)line feature on Ramani Cloud (currently only support for private layers):


            NSDictionary *fields = @{@"id" : @"100",
            						 @"time" : @"1434159945524",
            						 @"accelx" : @"4.338"
            						};
            [RSMapServices storeLine:_coordinates layerID:layerID fields:fields];
          

Note: Useful to keep a line stored for future usage, e.g. for obtaining a Horizontal Profile (with getTransect) for the same region over different days..