屋内地図を統合します
HERE Indoor Map には、マップ上でプライベート施設 を読み込んで表示し、操作する機能があります。 HERE Indoor Map の詳細については、『HERE Indoor Map ガイド』を参照してください。
カスタマイズされたフロアスイッチャーを備えた空港の施設 。 現在、 HERE SDK は プライベート 施設 のみをサポートしているため、施設 データはアプリ にのみ表示されます。デフォルトでは、地図に施設 は表示されません。 各施設 には、 HERE SDK 資格情報 に関連付けられた一意の施設 ID が割り当てられます。
VenueEngine を初期化します
HERE Indoor Map API の使用を開始する前 VenueEngine
に、インスタンスを作成して開始する必要があります。 これは、マップの初期化後に行うことができますが、を作成する最適なタイミングは VenueEngine
、マップがシーンをロードした後です。
class MyApp extends StatelessWidget {
final VenueEngineState _venueEngineState = VenueEngineState();
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'HERE SDK for Flutter - Venues',
home: Scaffold(
appBar: AppBar(
title: const Text('HERE SDK for Flutter - Venues'),
),
body: Column(children: [
Expanded(
child: Stack(children: <Widget>[
HereMap(onMapCreated: _onMapCreated),
VenueEngineWidget(state: _venueEngineState)
]),
),
]),
),
);
}
void _onMapCreated(HereMapController hereMapController) {
hereMapController.mapScene.loadSceneForMapScheme(MapScheme.normalDay,
(MapError error) {
if (error != null) {
print('Map scene not loaded. MapError: ${error.toString()}');
return;
}
hereMapController.mapScene.disableFeatures([MapFeatures.extrudedBuildings]);
var venueEngine;
try {
venueEngine = VenueEngine(_onVenueEngineCreated);
_venueEngineState.set(hereMapController, venueEngine, _geometryInfoState);
} on InstantiationException catch(e){
print('error caught: $e');
}
});
}
void _onVenueEngineCreated() {
_venueEngineState.onVenueEngineCreated();
}
}
VenueEngine
が初期化されると、コールバック が呼び出されます。 この時点から VenueService
、との両方にアクセスできます VenueMap
。 は VenueService
施設 の読み込みに使用 VenueMap
され、はマップ上の施設 を制御します。 コールバック 内では、必要なすべてのリスナーを追加してから VenueEngine
、を開始する必要があります。 プラットフォーム マップカタログ HRN
は、一度 VenueEngine
開始すると設定されます。
注
HERE リソースネーム の設定は任意です。 ユーザーが HERE リソースネーム を設定していない場合は、デフォルトのコレクション HERE リソースネーム が自動的に選択されます。 ユーザーが他のコレクションを使用する場合は、それぞれの HERE リソースネーム を設定できます。 HERE リソースネーム 値が見つからないか、または無効であることを示すエラーログが生成されます。 プロジェクトで有効な HERE リソースネーム文字列を受け取る方法の詳細については、『HERE Indoor Map ガイド』を参照してください。
class VenueEngineWidget extends StatefulWidget {
final VenueEngineState state;
VenueEngineWidget({required this.state});
@override
VenueEngineState createState() => state;
}
class VenueEngineState extends State<VenueEngineWidget> {
late VenueServiceListener _serviceListener;
void onVenueEngineCreated() {
var venueMap = venueEngine!.venueMap;
_serviceListener = VenueServiceListenerImpl();
_venueEngine!.venueService.addServiceListener(_serviceListener);
venueEngine!.start(_onAuthCallback);
if(HRN != "") {
venueEngine!.venueService.setHrn(HRN);
}
}
}
VenueEngine
が開始されると、現在の資格情報 を使用して認証され、が開始 VenueService
されます。 VenueService
が初期化されると VenueServiceListener.onInitializationCompleted()
、メソッドが呼び出されます。
class VenueServiceListenerImpl extends VenueServiceListener {
@override
onInitializationCompleted(VenueServiceInitStatus result) {
if (result != VenueServiceInitStatus.onlineSuccess) {
print("VenueService failed to initialize!");
}
}
@override
onVenueServiceStopped() {}
}
トークン を使用して VenueEngine を起動します
は VenueEngine
、有効な HERE 屋内プラットフォーム プロジェクトトークン を使用して開始できます。 HERE platform プロジェクト管理およびプロジェクトワークフローの詳細については 、「 HERE platform プロジェクト管理」を参照してください
class VenueEngineWidget extends StatefulWidget {
final VenueEngineState state;
VenueEngineWidget({required this.state});
@override
VenueEngineState createState() => state;
}
class VenueEngineState extends State<VenueEngineWidget> {
late VenueServiceListener _serviceListener;
void onVenueEngineCreated() {
var venueMap = venueEngine!.venueMap;
_serviceListener = VenueServiceListenerImpl();
_venueEngine!.venueService.addServiceListener(_serviceListener);
venueEngine!.startWithToken("TOKEN_GOES_HERE");
}
}
すべての屋内地図を一覧表示します
HERE Indoor Maps API では、アカウントおよび選択したコレクションでアクセス可能なすべてのプライベート施設 を一覧表示できます。 VenueMap
VenueInfo
施設 識別子、施設 ID 、および施設 名を含む要素を保持するリストが含まれています。
List<VenueInfo> venueInfo = _venueEngine!.venueMap.getVenueInfoList();
for (int i = 0; i < venueInfo.length; i++) {
int venueId = venueInfo[i].venueId;
print("Venue Identifier: " + venueInfo[i].venueIdentifier + " Venue Id: $venueId" + " Venue Name: "+venueInfo[i].venueName);
}
施設をロードして表示します
HERE Indoor Map API を使用すると、 ID によって施設 をロードおよび表示できます。現在の資格情報 セットの会場 ID を知っている必要があります。 施設 をロードして表示する方法はいくつかあります。 で VenueService
、新しい施設 ロードキューを開始する方法があります。
_venueEngine.venueService.startLoading();
既存のロードキューに施設 ID を追加することもできます。
_venueEngine.venueService.addVenueToLoad();
A VenueMap
には、施設 をマップに追加するための 2 つの方法があります。 selectVenueAsync()
および addVenueAsync()
。 どちらの方法も getVenueService().addVenueToLoad()
、 ID で施設 を読み込み、それをマップに追加するために使用します。 このメソッドで selectVenueAsync()
は、施設 も選択されます。
_venueEngine.venueMap.selectVenueAsync();
_venueEngine.venueMap.addVenueAsync();
施設 ID を指定して施設 を選択することもできます。
Container(
padding: EdgeInsets.only(left: 8, right: 8),
child: TextField(
decoration: InputDecoration(
border: InputBorder.none, hintText: 'Enter a venue ID'),
onSubmitted: (text) {
try {
int venueId = int.parse(text);
_venueEngineState.selectVenue(venueId);
} on FormatException catch (_) {
print("Venue ID should be a number!");
}
}),
),
施設 が正常にロードされると addVenueAsync()
、メソッドを使用している場合 VenueLifecycleDelegate.onVenueAdded()
は、メソッドのみがトリガーされます。 selectVenueAsync()
メソッドを使用している場合 VenueSelectionDelegate.onSelectedVenueChanged()
は、メソッドもトリガーされます。
class VenueSelectionListenerImpl extends VenueSelectionListener {
late VenueEngineState _venueEngineState;
VenueSelectionListenerImpl(VenueEngineState venueEngineState) {
_venueEngineState = venueEngineState;
}
@override
onSelectedVenueChanged(Venue? deselectedVenue, Venue? selectedVenue) {
_venueEngineState.onVenueSelectionChanged(selectedVenue);
}
}
Venue
からを削除することもでき VenueMap
ます。この場合 VenueLifecycleListener.onVenueRemoved()
、メソッドがトリガーされます。
_venueEngine.venueMap.removeVenue(venue);
ラベルテキストの設定
施設 のデフォルトのラベルテキスト設定を上書きできます。
VenueEngine
が初期化されると、コールバック が呼び出されます。 この時点から、へのアクセス権があり VenueService
ます。 setLabeltextPreference()
オプションのメソッドを呼び出して、レンダリング時のラベルテキストの設定を指定できます。 既定のスタイルラベルのテキスト設定を上書きすると、次のオプションを並べ替え順によって設定が定義される一覧として設定できます。
- " 占有者の名前 "
- "space_name"
- "internal_address"
- "space_type_name"
- "space_category_name"
これらは任意の順序で設定できます。 たとえば、ラベルテキストの環境設定に「占有者の名前」が含まれていない場合、リストの順序に基づいて「 space_name 」などに切り替わります。 設定が見つからない場合は、何も表示されません。
class VenueEngineWidget extends StatefulWidget {
final VenueEngineState state;
VenueEngineWidget({required this.state});
@override
VenueEngineState createState() => state;
}
class VenueEngineState extends State<VenueEngineWidget> {
late VenueServiceListener _serviceListener;
void onVenueEngineCreated() {
var venueMap = venueEngine!.venueMap;
_serviceListener = VenueServiceListenerImpl();
_venueEngine!.venueService.addServiceListener(_serviceListener);
venueEngine!.start(_onAuthCallback);
if(HRN != "") {
venueEngine!.venueService.setHrn(HRN);
}
venueEngine!.venueService.setLabeltextPreference(LabelPref);
}
}
施設図面とレベルを選択します
Venue
オブジェクトを使用すると、施設 の状態を制御できます。
このプロパティ selectedDrawing
を使用すると、地図に表示される図面を取得および設定できます。 新しい図面を選択すると VenueDrawingSelectionListener.onDrawingSelected()
、メソッドがトリガーされます。
でアイテムをクリックしたときに図面を選択する方法の例を次に示し ListView
ます。
Widget _drawingItemBuilder(BuildContext context, VenueDrawing drawing) {
bool isSelectedDrawing = drawing.identifier == _selectedDrawing!.identifier;
Property? nameProp = drawing.properties["name"];
return TextButton(
style: TextButton.styleFrom(
foregroundColor: isSelectedDrawing ? Colors.blue : Colors.white,
padding: EdgeInsets.zero
),
child: Text(
nameProp != null ? nameProp.asString : "",
textAlign: TextAlign.center,
style: TextStyle(
color: isSelectedDrawing ? Colors.white : Colors.black,
fontWeight: isSelectedDrawing ? FontWeight.bold : FontWeight.normal,
),
),
onPressed: () {
_isOpen = false;
_selectedVenue!.selectedDrawing = drawing;
},
);
}
プロパティ selectedLevel
および selectedLevelIndex
を使用すると、選択したレベルを取得および設定できます。 新しいレベルを選択する VenueLevelSelectionListener.onLevelSelected()
と、メソッドがトリガーされます。
次の例では、でアイテムがクリックされたときにレベルを選択する方法を示し ListView
ます。
Widget _levelItemBuilder(BuildContext context, VenueLevel level) {
bool isSelectedLevel = level.identifier == _selectedLevel!.identifier;
return TextButton(
style: TextButton.styleFrom(
foregroundColor: isSelectedLevel ? Colors.blue : Colors.white,
padding: EdgeInsets.zero
),
child: Text(
level.shortName,
textAlign: TextAlign.center,
style: TextStyle(
color: isSelectedLevel ? Colors.white : Colors.black,
fontWeight: isSelectedLevel ? FontWeight.bold : FontWeight.normal,
),
),
onPressed: () {
_selectedVenue!.selectedLevel = level;
},
);
}
図面およびレベルを制御する UI スイッチャーの完全な例については、GitHub で利用可能な indoor_map_app サンプルアプリを参照してください。
施設のスタイルをカスタマイズします
VenueGeometry
オブジェクトの表示スタイルを変更できます。 ジオメトリスタイルオブジェクトまたはラベルスタイルオブジェクト、またはそのいずれかを作成し Venue.setCustomStyle()
、メソッドに提供する必要があります。
final VenueGeometryStyle _geometryStyle =
VenueGeometryStyle(Color.fromARGB(255, 72, 187, 245), Color.fromARGB(255, 30, 170, 235), 1);
final VenueLabelStyle _labelStyle =
VenueLabelStyle(Color.fromARGB(255, 255, 255, 255), Color.fromARGB(255, 0, 130, 195), 1, 28);
_selectedVenue.setCustomStyle([geometry], _geometryStyle, _labelStyle);
識別子でスペースを選択します
スペース、レベル、および図面の ID は、 getIdentifier()
スペース呼び出しの場合などに、を使用して抽出できます。spaces.getIdentifier()
。 次に、これらの ID 値を使用するため getGeometryById(String id)
に、レベルまたはを使用して図面で特定のスペースを検索できます。
List<String> geometriesID = [];
List<VenueGeometry> geometries = [];
geometriesID.forEach((id) {
VenueGeometry? geometry = venue.selectedDrawing.getGeometryByIdentifier(id);
geometries.add(geometry!);
});
final VenueGeometryStyle _geometryStyle =
VenueGeometryStyle(Color.fromARGB(255, 72, 187, 245), Color.fromARGB(255, 30, 170, 235), 1);
final VenueLabelStyle _labelStyle =
VenueLabelStyle(Color.fromARGB(255, 255, 255, 255), Color.fromARGB(255, 0, 130, 195), 1, 28);
_selectedVenue.setCustomStyle(geometries, _geometryStyle, _labelStyle);
施設でタップジェスチャを処理します
施設 オブジェクトをタップして選択できます。 まず、選択 MapMarker
した形状の上にを置くタップリスナーサブクラスを作成します。
class VenueTapController extends TapListener {
final HereMapController hereMapController;
final VenueMap venueMap;
MapImage? _markerImage;
MapMarker? _marker;
VenueTapController(
{required this.hereMapController,
required this.venueMap}) {
hereMapController.gestures.tapListener = this;
_loadFileAsUint8List('poi.png').then((imagePixelData) => _markerImage =
MapImage.withPixelDataAndImageFormat(imagePixelData, ImageFormat.png));
}
Future<Uint8List> _loadFileAsUint8List(String fileName) async {
ByteData fileData = await rootBundle.load('assets/' + fileName);
return Uint8List.view(fileData.buffer);
}
}
TAP リスナー内では、メソッド VenueMap.getGeometry()
および VenueMap.getVenue()
メソッドのパラメーターとしてタップされた地理座標を使用できます。
@override
onTap(Point2D origin) {
deselectGeometry();
GeoCoordinates? position = hereMapController!.viewToGeoCoordinates(origin);
if (position == null) {
return;
}
VenueGeometry? geometry = venueMap.getGeometry(position);
if (geometry != null) {
_addPOIMapMarker(position);
} else {
Venue? venue = venueMap.getVenue(position);
if (venue != null) {
venueMap.selectedVenue = venue;
}
}
}
void deselectGeometry() {
if (_marker != null) {
hereMapController!.mapScene.removeMapMarker(_marker!);
_marker = null;
}
}
void _addPOIMapMarker(GeoCoordinates geoCoordinates) {
if (_markerImage == null) {
return;
}
Anchor2D anchor2D = Anchor2D.withHorizontalAndVertical(0.5, 1);
_marker = MapMarker.withAnchor(geoCoordinates, _markerImage!, anchor2D);
hereMapController!.mapScene.addMapMarker(_marker!);
}
施設 でのマップタップイベントの使用例については 、GitHub で利用可能な屋内の _map_app サンプルアプリ を参照してください。