iOS 開発者ガイド for SDK

プラットフォームデータ拡張子

プラットフォームデータ拡張 (PDE) を使用 すると、 SDK for iOS からプラットフォームデータ拡張機能 API に簡単にアクセスできます。 この拡張機能を使用すると、さまざまな用途で後で使用できる幅広いデータにアクセスできます。 道路の高度、斜面、交通標識の表示などがあります。 使用例および PDE を介してアクセスできるデータのタイプの詳細については 、プラットフォーム Data Extension API 開発者ガイドを参照してください。

PDE 主題図レイヤ

PDE では、マップの内容が複数の主題図レイヤに分割されます。 各主題図データレイヤは特定のユースケースを提供し、道路高度など、そのレイヤに必要なデータのみを含みます。 PDE を使用するには、まずアプリに必要なデータを決定し、それに応じて PDE 主題図レイヤを選択する必要があります。 使用可能な主題図レイヤは、 PDE Layers API を介して見つけることができます。 その後、個 々の Layer API を使用して、対象の主題図レイヤを確認できます。 アプリで PDE を使用する前に、正しい主題図レイヤを選択して、使用するデータとその使用方法を決定する必要があります。 これは極めて重要なステップです。

注 : 小規模な道路でのルートの開始、より大きな道路への登坂、主要な部分の高速道路での滞在、目的地に近づいたときに小規模な道路に再び降りることが一般的です。 ルート全体の小さな道路に関するすべての情報を取得するに は、大量のデータが必要になるため、道路リンクに関連する主題図のレイヤーは、実際には 5 つのレイヤーに分割され、 HERE マップの機能的な道路クラスに対応します。 機能的なクラス 1 の道路は一般に高速道路ですが、機能的なクラス 5 の道路は目的地の近くでのみ使用される小さな道路です。 これらのレイヤーを使用するには、機能クラスのサフィックス "_FCx" を追加してタイルレイヤーを指定する必要があります。 x は 1 ~ 5 の数値です。 たとえば、 ROAD_GEOM_FC1です。 レイヤーが PSTLCB_GEN レイヤーなどの道路リンクに関連付けられていない場合は、サフィックス "_FCx" を追加してタイルレイヤーを指定する必要はありません。

PDE クラス

クラス 説明
NMAPlatformDataRequest 指定したレイヤーおよび NMAGeoBoundingBox オブジェクトを使用して PDE データリクエストを作成します。
NMAPlatformDataResult PDE データリクエストの後、このタイプのオブジェクトとして結果が返されます。 結果を NSDictionary オブジェクトに変換する抽出メソッドを提供します。
NMAPlatformDataItemCollection NMAPlatformDataItem オブジェクトの配列。 たとえば、結果が NMAPlatformDataResult タイプオブジェクトであると仮定すると、 ROAD_GEOM_FC1 レイヤーデータの NMAPlatformDataItemCollectionresult[@"ROAD_GEOM_FC1"] を使用してアクセスできます。 このクラスには、コレクションを NSArray オブジェクトに変換するための抽出メソッドも用意されています。
NMAPlatformDataItem PDE データリクエストの後、各レイヤーデータがこのクラスのオブジェクトとともに返されます。 たとえば、アイテムが ROAD_GEOM_FC1 レイヤーデータを含む NMAPlatformDataItem オブジェクトであると仮定すると、 name プロパティには item[@"NAME"] を使用してアクセスできます。 指定したプロパティが見つからない nil 場合は、が返されます。 item.linkId とのよう item[@LINK_ID"]に、いくつかのプロパティのショートカットを使用できます。 このクラスには、 PDE データを NSDictionary オブジェクトに変換するための抽出メソッドも用意されています。

例 : PDE データを要求しています

次の例は、 PDE データを使用して機能を実装する方法を示しています。 目標は、平均的な高さに基づいて各道路セグメントを色付けすることである。 この機能を使用するには、 ROAD_GEOM_FC1 レイヤーと BASIC_HEIGHT_FC1 レイヤーの PDE データが必要です。 現在、 PDE データを要求する唯一の方法では、で指定されたレイヤーが必要 NMAGeoBoundingBoxです。

注 : ROAD_GEOM_FC[number] レイヤーおよび BASIC_HEIGHT_FC[number] レイヤーは、データが複数のタイルに分割されるため、「タイル」レイヤーとも呼ばれます。 サーバーの制限により、一度に最大 15 のタイルを要求できます。 PDE では、非タイルレイヤーもサポートされています。

両方のレイヤーのデータを使用するに LINK_ID は、プロパティを使用して 2 つの主題図レイヤーを結合する必要があります。 これについては、次のセクションで説明します。

次に、 Layer 要求のサンプル結果を示します。

ROAD_GEOM_FC1 レイヤーの API 結果 :

{
  "description": "Ungeneralized road, ferry and rail ferry geometry (polylines).<br/>If a road link crosses a tile boundary, it will be written into each of the tiles, each including the full link geometry. This simplifies use cases other than pure display of all geometry within a rectangle.",
  "attributes": {
  "LINK_ID": "Permanent link ID. Positive 64 bit Integer that globally identifies the road, carto or building footprint link, also across map releases. Link IDs are never reused.",
  "LONG_HAUL": "This link or polygon or POI is of major importance. It should be displayed at high zoom lavels, and it should be included for routing in/through regions where no detailed routing is supported.",
  "NAME": "A name of this road line. Roads can have multiple names, in the same or multiple languages. This field contains any of those.",
  "NAMES": "List of all names for this object, in all languages [...]",
  "TUNNEL": "Is this navigable link or railroad a tunnel?",
  "BRIDGE": "Is this navigable link or railroad a bridge?",
  "LAT": "Latitude coordinates [10^-5 degree WGS84] along the polyline. ",
  "LON": "Longitude coordinates [10^-5 degree WGS84] along the polyline. ",
  "ZLEVEL": "(-4 ... 11) indicates the height of the point relative to another point on a grade separated crossing with any other line. Comma separated. If z-level is null then the value '0' is left out."
  },
  "referencedStaticContents": [],
  "tileRequestsLevel": 9,
  "tileX": 499,
  "tileY": 403,
  "isStaticContent": false
}

BASIC_HEIGHT_FC1 レイヤーの API 結果 :

{
  "description": "Link height values computed from a Digital Terrain Model, cleaned up for continuity along links, bridges and tunnels. Less accurate than ADAS link height values, but full coverage and sufficient for certain use cases.",
  "attributes": {
  "LINK_ID": "Permanent link ID. Positive 64 bit Integer that globally identifies the road, carto or buildin footprint link, also across map releases. Link IDs are never reused.",
  "DTM_MIN_HEIGHT": "The minimum height [cm above WGS84 ellipsoid] encountered along the link.",
  "DTM_MAX_HEIGHT": "The maximum height [cm above WGS84 ellipsoid] encountered along the link.",
  "DTM_AVG_HEIGHT": "The average height [cm above WGS84 ellipsoid] along the link.",
  "DTM_REF_ZCOORD": "Height [cm above WGS84 ellipsoid] at the reference node of the link.",
  "DTM_NONREF_ZCOORD": "Height [cm above WGS84 ellipsoid] at the non-reference node of the link."
  },
  "referencedStaticContents": [],
  "tileRequestsLevel": 9,
  "tileX": 496,
  "tileY": 358,
  "isStaticContent": false
}

PDE レイヤーの使用を開始するには NMAPlatformDataRequest 、次のタイプのリクエストオブジェクトを作成します。

NSSet<NSString *> *layers = [NSSet setWithObjects:@"ROAD_GEOM_FC1", @"BASIC_HEIGHT_FC1", nil];
NMAGeoBoundingBox *box = self.mapView.boundingBox;
NMAPlatformDataRequest *request = [[NMAPlatformDataRequest alloc] initWithLayers:layers geoBoundingBox:box];

リクエストが無効であると判断さ nil れた場合は、が返されます。 ブロックまたはリスナーを使用してリクエストを実行できます。

// Is the request valid?
if (request) {
  [request startWithBlock:^(NMAPlatformDataRequest *request, NMAPlatformDataResult *result, NSError *error) {

    if (error) {
      NSLog(@"Error occurred!\n"
           "Code: %ld\n"
           "Description: %@\n"
           "Failure reason: %@\n",
          (long)error.code,
          error.localizedDescription,
          error.localizedFailureReason];
    }
    else {
      // Retrieved the result successfully, now process it
      RoadElevationProcessor *processor =
        [[RoadElevationProcessor alloc] initWithResult:result
                         andMapContainer:self.mapContainer];

      [processor process:^void (BOOL result, NSString *msg) {
        if (result) {
          [self addElevationLegend];
        } else {
          NSLog(@"Elevation data processing failed!");
        }

        if (msg) {
          NSLog(msg);
        }
      }];
    }
  }];
}
else {
  NSLog(@"Invalid request!");
};

例 : PDE データを処理しています

データの結果が正常に取得された後、データを処理する必要があります。 上記の例では、マップ ビューバウンディング ボックスで制限されている ROAD_GEOM_FC1 BASIC_HEIGHT_FC1 データを要求しています。 チュートリアルでは、サンプルのデータプロセッサクラスを実装しまし PlatformDataProcessorた。このクラスは、レイヤーを結合するメソッドを提供し、結合されたデータを使用できるように拡張できます。 この例では、色付け機能を実装する必要があります。

のクラス宣言を次に示します PlatformDataProcessor

/**
 * Defines the code block that returns a string given a data item object.
 * It is used to index data item objects for quickly joining the data.
 */
typedef NSString* (^NMAPlatformDataProcessorIndexerBlock)(NMAPlatformDataItem*);

/**
 * Defines the code block that returns a string array given a data item
 * object. It is used to index data item objects for quickly joining
 * the data.
 */
typedef NSArray<NSString*>* (^NMAPlatformDataProcessorMultiIndexerBlock)(NMAPlatformDataItem*);

/**
 * Defines the code block that runs after join a operation.
 * The first argument sets the result and the other one sets the message
 * if available.
 */
typedef void (^NMAPlatformDataProcessorResultBlock)(BOOL, NSString*);

/**
 * \brief This class is for joining the PDE data coming from different
 *    layers using the passed indexers.
 */
@interface PlatformDataProcessor : NSObject

/**
 * This method joins two different layers data using the indexers and returns
 * a dictionary of items.
 *
 * \param mainLayer The layer data that will joined with the other layer data.
 *
 * \param mainIndexer The indexer for quickly joining the main layer data.
 *
 * \param otherLayer The other data that will joined with the main layer data.
 *
 * \param otherIndexer The indexer for quickly joining the other layer data.
 *
 * \return The dictionary of items that are joined where the key is the PDE data
 *     coming from the main layer data and the value is the PDE data coming
 *     from the other layer data.
 */
- (NSDictionary<NMAPlatformDataItem*, NMAPlatformDataItem*>*)
  joinLayer:(NMAPlatformDataItemCollection *)mainLayer
  usingIndexer:(NMAPlatformDataProcessorIndexerBlock)mainIndexer
  withOtherLayer:(NMAPlatformDataItemCollection *)otherLayer
  usingIndexer:(NMAPlatformDataProcessorIndexerBlock)otherIndexer;

/**
 * This method joins two different layers data using the indexers and returns
 * a dictionary of items.
 *
 * \param mainLayer The layer data that will joined with the other layer data.
 *
 * \param mainMultiIndexer The indexer for quickly joining the main layer data.
 *
 * \param otherLayer The other data that will joined with the main layer data.
 *
 * \param otherMultiIndexer The indexer for quickly joining the other layer data.
 *
 * \return The dictionary of items that are joined where the key is the PDE data
 *     coming from the main layer data and the value is the array of PDE data
 *     coming from the other layer data.
 */
- (NSDictionary<NMAPlatformDataItem*, NSArray<NMAPlatformDataItem*>*>*)
  joinLayer:(NMAPlatformDataItemCollection *)mainLayer
  usingMultiIndexer:(NMAPlatformDataProcessorMultiIndexerBlock)mainMultiIndexer
  withOtherLayer:(NMAPlatformDataItemCollection *)otherLayer
  usingMultiIndexer:(NMAPlatformDataProcessorMultiIndexerBlock)otherMultiIndexer;

/**
 * This method processes the data joined.
 *
 * \note The derived classes must implement this method.
 *
 * \param block The block that runs after the join operation. Note that its first argument brings
 *        the result and the other one brings a message if available.
 */
- (void)process:(NMAPlatformDataProcessorResultBlock)block;

[PlatformDataProcessor joinLayer:usingIndexer:withOtherLayer:usingIndexer] 複数のデータ項目を使用できるプロパティを使用して主題図レイヤを内部結合する方法を使用します。 たとえば TRAFFIC_SIGN_FCx 、主題図レイヤ LINK_IDS には、 LINK_ID最大 2 つのが含まれるプロパティがあります。

PlatformDataProcessor クラスの実装は次のとおりです。

@interface PlatformDataProcessor ()
{
}

- (NSDictionary<NSString*, NMAPlatformDataItem*>*)
  map:(NMAPlatformDataItemCollection *)collection
  withIndexer:(NMAPlatformDataProcessorIndexerBlock)indexer;

- (NSDictionary<NSString*, NSArray<NMAPlatformDataItem*>*>*)
  multiMap:(NMAPlatformDataItemCollection *)collection
  withMultiIndexer:(NMAPlatformDataProcessorMultiIndexerBlock)indexer;

@end

@implementation PlatformDataProcessor

#pragma mark - Public methods

- (NSDictionary<NMAPlatformDataItem*, NMAPlatformDataItem*>*)
  joinLayer:(NMAPlatformDataItemCollection *)mainLayer
  usingIndexer:(NMAPlatformDataProcessorIndexerBlock)mainIndexer
  withOtherLayer:(NMAPlatformDataItemCollection *)otherLayer
  usingIndexer:(NMAPlatformDataProcessorIndexerBlock)otherIndexer
{
  NSDictionary<NSString*, NMAPlatformDataItem*>* mappedItems =
    [self map:otherLayer withIndexer:otherIndexer];
  NSMutableDictionary<NMAPlatformDataItem*, NMAPlatformDataItem*>* dictionary =
    [[NSMutableDictionary alloc] init];

  for (NMAPlatformDataItem *item in mainLayer) {
    NSString *key = mainIndexer(item);
    NMAPlatformDataItem *matchedItem = mappedItems[key];

    if (matchedItem) {
      dictionary[item] = matchedItem;
    }
  }

  return dictionary;
}

- (NSDictionary<NMAPlatformDataItem*, NSArray<NMAPlatformDataItem*>*>*)
  joinLayer:(NMAPlatformDataItemCollection *)mainLayer
  usingMultiIndexer:(NMAPlatformDataProcessorMultiIndexerBlock)mainMultiIndexer
  withOtherLayer:(NMAPlatformDataItemCollection *)otherLayer
  usingMultiIndexer:(NMAPlatformDataProcessorMultiIndexerBlock)otherMultiIndexer
{
  NSDictionary<NSString*, NSArray<NMAPlatformDataItem*>*>* mappedItems =
    [self multiMap:otherLayer withMultiIndexer:otherMultiIndexer];
  NSMutableDictionary<NMAPlatformDataItem*, NSMutableArray<NMAPlatformDataItem*>*>* dictionary =
    [[NSMutableDictionary alloc] init];

  for (NMAPlatformDataItem *item in mainLayer) {
    NSArray<NSString*> *array = mainMultiIndexer(item);

    for (NSString *key in array) {
      NSArray<NMAPlatformDataItem*> *matchedItems = mappedItems[key];

      if (matchedItems) {
        NSMutableArray<NMAPlatformDataItem*> *entry = dictionary[item];

        if (!entry) {
          entry = [[NSMutableArray alloc] init];
          dictionary[item] = entry;
        }

        [entry addObjectsFromArray:matchedItems];
      }
    }
  }

  return dictionary;
}

- (void)process:(NMAPlatformDataProcessorResultBlock)block
{
  NSLog(@"Derived classes must implement [PlatformDataProcessor process:] method!");
  abort();
}

#pragma mark - Private methods

- (NSDictionary<NSString*, NMAPlatformDataItem*>*)
  map:(NMAPlatformDataItemCollection *)collection
  withIndexer:(NMAPlatformDataProcessorIndexerBlock)indexer
{
  NSMutableDictionary<NSString*, NMAPlatformDataItem*>* dictionary =
    [[NSMutableDictionary alloc] init];

  for (NMAPlatformDataItem* item in collection) {
    NSString* key = indexer(item);

    dictionary[key] = item;
  }

  return dictionary;
}

- (NSDictionary<NSString*, NSArray<NMAPlatformDataItem*>*>*)
  multiMap:(NMAPlatformDataItemCollection *)collection
  withMultiIndexer:(NMAPlatformDataProcessorMultiIndexerBlock)indexer
{
  NSMutableDictionary<NSString*, NSMutableArray<NMAPlatformDataItem*>*>* dictionary =
    [[NSMutableDictionary alloc] init];

  for (NMAPlatformDataItem* item in collection) {
    NSArray<NSString*>* array = indexer(item);

    for (NSString* key in array) {
      if (!dictionary[key]) {
        dictionary[key] = [[NSMutableArray  alloc] init];
      }

      [dictionary[key] addObject:item];
    }
  }

  return dictionary;
}

@end

次に、 RoadElevationProcessor create. RoadElevationProcessor class は、道路セグメントの平均高さに従って色分けするために PlatformDataProcessor 拡張されます。 このクラスには、結果と NMAMapPolyline 、そのオブジェクトを対象とした専用のマップコンテナが必要です。 提供 PlatformDataProcessor されているインデクサブロックに応じて、基本クラスが主題図レイヤデータの内部結合を実行することに注意 RoadElevationProcessor してください。クラスは、結合されたデータを使用して、目的の機能を実装します。

RoadElevationProcessor クラスの宣言を次に示します。

/**
 * \brief Extends the PlatformDataProcessor class for the road elevation
 *    handling.
 */
@interface RoadElevationProcessor : PlatformDataProcessor

/**
 * Creates a road elevation processor object.
 *
 * \param result The PDE road elevation data result to be processed.
 *
 * \param mapContainer The polylines that will be colored according to the average road
 *           segments will be inserted to this map container.
 *
 * \return If the parameters are valid, a RoadElevationProcessor object configured with
 *     the parameters and nil otherwise.
 */
- (instancetype)initWithResult:(NMAPlatformDataResult *)result
         andMapContainer:(NMAMapContainer *)mapContainer;

@end;

RoadElevationProcessor クラスの主なメソッドは、以下のプロセスメソッドです。

- (void)process:(NMAPlatformDataProcessorResultBlock)block
{
  BOOL result = FALSE;
  NSString *msg;
  NSDictionary<NMAPlatformDataItem*, NMAPlatformDataItem*>* joinedItems =
    [self joinLayer:_result[@"ROAD_GEOM_FC1"]
      usingIndexer:^NSString* (NMAPlatformDataItem *item) {
        return item.linkId;
      }
      withOtherLayer:_result[@"BASIC_HEIGHT_FC1"]
      usingIndexer:^NSString* (NMAPlatformDataItem *item) {
        return item.linkId;
      }];

  // Any joined data?
  if (joinedItems && joinedItems.count) {
    // Set the message
    msg = [NSString stringWithFormat:@"Joined elevation items count = %ld\n",
      (unsigned long)joinedItems.count];

    // One-by-one check the joined data
    for (NMAPlatformDataItem *roadGeometry in joinedItems) {
      // Filter out the road geometries having less than 2 coordinates
      // as they show nothing on the map
      if (roadGeometry.coordinates.count > 1) {
        NMAPlatformDataItem *height = joinedItems[roadGeometry];
        NMAMapPolyline *polyline =
          [NMAMapPolyline mapPolylineWithVertices:roadGeometry.coordinates];

        polyline.lineColor = [self getColorDependingOnHeight:height.averageHeightCm];
        polyline.lineWidth = 10;

        [_mapContainer addMapObject:polyline];
      }
    }

    result = TRUE;
  }

  // Done: pass the result along with the msg
  block(result, msg);
}

このメソッドの最初の処理は、 2 つの異なる主題図レイヤからのデータを " インデクサ " ブロックに結合することです。 HERE データは LINK_IDを介して結合されます linkId プロパティは NMAPlatformDataItem 、クラスのショートカットプロパティとして使用できます。 データを結合すると、各 ROAD_GEOM_FC1 データ項目が関連 BASIC_HEIGHT_FC1 するデータ項目と内部的に結合 NSDictionary<NMAPlatformDataItem*, NMAPlatformDataItem*>され、結合されたデータが実際の型があるディクショナリとして返されます。 各キーと値のペアは、この機能に必要なデータを提供します。 ROAD_GEOM_FC1 主題図のレイヤデータを表す NMAPlatformDataItem キーは、道路セグメントの座標などの道路のジオメトリを提供し、 BASIC_HEIGHT_FC1 主題図のレイヤデータを表す NMAPlatformDataItem タイプの値はその道路セグメントの平均高さを提供します。 結合されたデータは、目的の機能を実装するために必要なすべてのものを提供します。

を使用して結合されたデータ LINK_ID は、次のようになります。

{
  BRIDGE = N;
  LAT = "5246124,2";
  "LINK_ID" = 936938339;
  LON = "1342560,24";
  "LONG_HAUL" = Y;
  NAME = A100;
  NAMES = "GERBNTunnel BritzGERY\"tU|n@l \"brItsGERBNA100GERN\"?a: \"hUn|d6t;GERN\"?aU|to:|ba:n ?aIn|\"hUn|d6t;GERY\"?a: ?aIn|\"hUn|d6t;GERN\"?aU|to:|ba:n \"hUn|d6tGERBNStadtring BerlinGERY\"Stat|rIN bEr|\"li:n";
  TUNNEL = Y;
  ZLEVEL = ",";
} = {
  "DTM_AVG_HEIGHT" = 8500;
  "DTM_MAX_HEIGHT" = 8693;
  "DTM_MIN_HEIGHT" = 8099;
  "DTM_NONREF_ZCOORD" = 8500;
  "DTM_REF_ZCOORD" = 8500;
  "LINK_ID" = 936938339;
}

キーと値のペアが同じで LINK_IDあることに注意してください。