プラットフォームデータ拡張子
プラットフォームデータ拡張 (PDE) を使用 すると、 SDK for iOS からプラットフォームデータ拡張機能 API に簡単にアクセスできます。 この拡張機能を使用すると、さまざまな用途で後で使用できる幅広いデータにアクセスできます。 道路の高度、斜面、交通標識の表示などがあります。 使用例および PDE を介してアクセスできるデータのタイプの詳細については 、プラットフォーム Data Extension API 開発者ガイドを参照してください。
PDE 主題図レイヤ
PDE では、マップの内容が複数の主題図レイヤに分割されます。 各主題図データレイヤは特定のユースケースを提供し、道路高度など、そのレイヤに必要なデータのみを含みます。 PDE を使用するには、まずアプリに必要なデータを決定し、それに応じて PDE 主題図レイヤを選択する必要があります。 使用可能な主題図レイヤは、 PDE Layers API を介して見つけることができます。 その後、個 々の Layer API を使用して、対象の主題図レイヤを確認できます。 アプリで PDE を使用する前に、正しい主題図レイヤを選択して、使用するデータとその使用方法を決定する必要があります。 これは極めて重要なステップです。
_FCx
" を追加してタイルレイヤーを指定する必要があります。 x
は 1 ~ 5 の数値です。 たとえば、 ROAD_GEOM_FC1
です。 レイヤーが PSTLCB_GEN
レイヤーなどの道路リンクに関連付けられていない場合は、サフィックス "_FCx
" を追加してタイルレイヤーを指定する必要はありません。 PDE クラス
クラス | 説明 |
---|---|
NMAPlatformDataRequest | 指定したレイヤーおよび NMAGeoBoundingBox オブジェクトを使用して PDE データリクエストを作成します。 |
NMAPlatformDataResult | PDE データリクエストの後、このタイプのオブジェクトとして結果が返されます。 結果を NSDictionary オブジェクトに変換する抽出メソッドを提供します。 |
NMAPlatformDataItemCollection | NMAPlatformDataItem オブジェクトの配列。 たとえば、結果が NMAPlatformDataResult タイプオブジェクトであると仮定すると、 ROAD_GEOM_FC1 レイヤーデータの NMAPlatformDataItemCollection に result[@"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
あることに注意してください。