Toto je blogový článek představující funkce použitelné při vývoji mapových aplikací ve Flutteru v sérii. Tentokrát se zaměříme na zobrazení shapefile. Implementujeme funkci pro zobrazení dat shapefile na mapě. V tomto článku ukážeme, jak tuto funkci implementovat pomocí mapového SDK pro Flutter (ArcGIS Maps SDK for Flutter).
Ukázkový kód je zveřejněn na GitHubu, takže pokud chcete ihned vyzkoušet, stáhněte si ho. Návod k spuštění aplikace najdete v README. Pro spuštění ukázky je potřeba získat API klíč (zdarma). Postup od zavedení mapového SDK až po zobrazení mapy najdete v blogovém článku „Vytvořme si mapovou aplikaci ve Flutteru!“. Tento článek se zaměřuje na funkci zobrazení shapefile.
Co je shapefile?
Shapefile je jeden z formátů GIS (geografický informační systém) dat. Umožňuje ukládat vektorová data (body, čáry, polygony) s informacemi o poloze, tvaru a atributech objektů jako jsou cílové objekty, silnice nebo budovy. Shapefile je průmyslový standard vektorového formátu GIS a je podporován nejen produkty ArcGIS, ale i mnoha dalšími GIS softwary.
Implementace funkce zobrazení shapefile
Pro zobrazení shapefile použijeme třídu ShapefileFeatureTable クラスを使用します。指定したパスにあるシェープファイルのデータをレイヤーとして、マップ上に表示できます。今回使用するシェープファイルは、こちら に配置しています。シェープファイルには、千葉県内にランダムに配置したポイント データが格納されています。
1. 「Flutter で地図アプリを作成してみよう!」のブログ記事の手順 6 で、マップビュー コントローラーに作成したマップを設定してマップの表示までできることを確認します。
2. Stáhněte ZIP soubor obsahující shapefile z odkazu „こちら“ a rozbalte ho.shp složku umístěte do složky <název_aplikace>/asset. Složku asset vytvořte sami. 3. Pro přidání shapefile do aplikace aktualizujte sekci assets v souboru pubspec.yaml následovně:
assets:
- assets/shp/
4. Pro získání cesty v zařízení použijeme balíček path_provider, proto přidejte tento balíček do sekce dependencies v pubspec.yaml.dependencies:
flutter:
sdk: flutter
# Přidání Cupertino Icons fontu pro iOS ikony.
cupertino_icons: ^1.0.8
arcgis_maps: ^200.8.0+4672 # Přidáno path_provider: ^2.1.55. Otevřete lib/main.dart a za existující importy přidejte následující řádky pro import potřebných balíčků:import 'package:path_provider/path_provider.dart';import 'package:flutter/services.dart';
import 'dart:io';
6. Pro použití await u operací se soubory změňte funkci _onMapViewReady() na asynchronní:
// Před změnou
void _onMapViewReady() {
// Po změně
Future<void> _onMapViewReady() async {
7. Na konec asynchronní funkce _onMapViewReady() přidejte kód, který načte shapefile ze složky assets a vytvoří nový shapefile v dokumentové složce iOS/Android aplikace.
// Nastavení vytvořené mapy do ovladače MapView.
_mapViewController.arcGISMap = map;
// Přidáno
// Vytvoření nového shapefile v dokumentové složce z shapefile ve složce assets.
final assetManifest = await AssetManifest.loadFromAssetBundle(rootBundle);final fileAssetsList = assetManifest.listAssets().where((string) => string.startsWith("assets/shp/")).toList();for (int i = 0; i < fileAssetsList.length; i++) {
String filePath = fileAssetsList[i];
final byteData = await rootBundle.load(filePath);
final file = File('${(await getApplicationDocumentsDirectory()).path}/$filePath');
await file.create(recursive: true);
await file.writeAsBytes(byteData.buffer.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));
} 8. Dále vytvořte objekt File ze cesty k nově vytvořenému shapefile (.shp) v dokumentové složce.
final shapefile = File(
'${(await getApplicationDocumentsDirectory()).path}/assets/shp/random_points.shp',
);
9. Vytvořte ShapefileFeatureTable pomocí File.uri jako argumentu a poté vytvořte FeatureLayer ze ShapefileFeatureTable.
ShapefileFeatureTable umožňuje přístup k datům uloženým ve shapefile (vyhledávání a úpravy), zatímco FeatureLayer spravuje jejich zobrazení na mapě.
// Vytvoření ShapefileFeatureTable ze cesty k shapefile v dokumentové složce.final shapefileFeatureTable = ShapefileFeatureTable.withFileUri(shapefile.uri);await shapefileFeatureTable.load();
final shapefileFeatureLayer = FeatureLayer.withFeatureTable(shapefileFeatureTable);
await shapefileFeatureLayer.load();
10. Přidejte vytvořený FeatureLayer do operationalLayers objektu ArcGISMap.
_mapViewController.arcGISMap!.operationalLayers.add(shapefileFeatureLayer);
11. Sestavte projekt a přesuňte mapu do prefektury Chiba pro zobrazení shapefile. Protože není nastaven styl zobrazení, bodová data se zobrazují jako černé tečky.
.toList();
for (int i = 0; i < fileAssetsList.length; i++) {
String filePath = fileAssetsList[i];
final byteData = await rootBundle.load(filePath);
final file =
File('${(await getApplicationDocumentsDirectory()).path}/$filePath');
await file.create(recursive: true);
await file.writeAsBytes(byteData.buffer
.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));
}
8. 続いて、ドキュメント ディレクトリーに作成したシェープファイル (.shp) のパスから File オブジェクトを作成します。
final shapefile = File(
'${(await getApplicationDocumentsDirectory()).path}/assets/shp/random_points.shp',
);
9. File.uri を引数に指定して ShapefileFeatureTable を作成し、作成した ShapefileFeatureTable から FeatureLayer を作成します。ShapefileFeatureTable はシェープファイルに格納されているデータにアクセス (検索や編集) でき、FeatureLayer はマップ上での表示を管理します。
// ドキュメントディレクトリーにあるシェープファイルのパスから ShapefileFeatureTable を作成します。
final shapefileFeatureTable =
ShapefileFeatureTable.withFileUri(shapefile.uri);
await shapefileFeatureTable.load();
final shapefileFeatureLayer =
FeatureLayer.withFeatureTable(shapefileFeatureTable);
await shapefileFeatureLayer.load();
10. 作成した FeatureLayer を ArcGISMap オブジェクトの operationalLayers に追加します。
_mapViewController.arcGISMap!.operationalLayers.add(shapefileFeatureLayer);
11. この状態でビルドします。マップを千葉県に移動して、シェープファイルを表示します。表示スタイルを設定していないため、ポイント データが黒い点で表示されています。
属性に応じた色分け表示機能の実装
12. 今回は、シェープファイルの属性情報に応じて、色分け表示する機能を実装してみます。手順4の FeatureLayer を ArcGISMap の operationalLayers に追加するコードの前に、下記のコードを追加します。シェープファイルのポイント データには、name 属性フィールドに a, b, c のいずれかの属性値がランダムに格納されています。属性値が a のときは赤色の丸で、b のときは青色の丸で、c のときは黄色の丸で、それ以外の場合は黒色の丸で表示するために、それぞれのシンボル (SimpleMarkerSymbol) を作成します。
// 各属性値用のシンボルを作成します。
final redMarkerSymbol = SimpleMarkerSymbol(
style: SimpleMarkerSymbolStyle.circle,
color: Colors.red,
size: 10,
);
final blueMarkerSymbol = SimpleMarkerSymbol(
style: SimpleMarkerSymbolStyle.circle,
color: Colors.blue,
size: 10,
);
final yellowMarkerSymbol = SimpleMarkerSymbol(
style: SimpleMarkerSymbolStyle.circle,
color: Colors.yellow,
size: 10,
);
final defaultMarkerSymbol = SimpleMarkerSymbol(
style: SimpleMarkerSymbolStyle.circle,
color: Colors.black,
size: 10,
);
13. 続いて、レイヤーの表示ルールを定義するレンダラーを作成します。各ポイントの属性値に応じて表示スタイルを定義することができるレンダラーである UniqueValueRenderer を使用します。UniqueValueRenderer オブジェクトの uniqueValues プロパティには、a, b, c の属性値とそれに対応するシンボルから作成した UniqueValue オブジェクトの配列を設定します。
// name フィールドの属性値に応じて色分け表示(a は赤色、b は青色、c は黄色)するための、UniqueValueRenderer を作成します。
final aValue = UniqueValue(
description: 'name is a',
label: 'a',
symbol: redMarkerSymbol,
values: ['a'],
);
final bValue = UniqueValue(
description: 'name is b',
label: 'b',
symbol: blueMarkerSymbol,
values: ['b'],
);
final cValue = UniqueValue(
description: 'name is c',
label: 'c',
symbol: yellowMarkerSymbol,
values: ['c'],
);
final uniqueValueRenderer = UniqueValueRenderer(
fieldNames: ['name'],
uniqueValues: [
aValue,
bValue,
cValue,
],
defaultLabel: 'Other',
defaultSymbol: defaultMarkerSymbol,
);
14. 作成した UniqueValueRenderer をシェープファイル表示用の FeatureLayer の renderer プロパティに設定します。
shapefileFeatureLayer.renderer = uniqueValueRenderer;
15. シェープファイルのポイント データのシンボルが目立つように暗色のベースマップに変更します。
//変更前
final basemap =
Basemap.withStyle(BasemapStyle.arcGISStreets, parameters: bsp);
//変更後
final basemap =
Basemap.withStyle(BasemapStyle.arcGISDarkGray, parameters: bsp);
16. 最後にマップの初期表示座標とスケールを調整します。
//変更前
final initialPoint = ArcGISPoint(
x: 139.745461,
y: 35.65856,
spatialReference: SpatialReference.wgs84,
);
map.initialViewpoint = Viewpoint.fromCenter(initialPoint, scale: 10000);
//Po změně
final initialPoint = ArcGISPoint(
x: 140.1111782,
y: 35.6130401,
spatialReference: SpatialReference.wgs84,
);
map.initialViewpoint = Viewpoint.fromCenter(initialPoint, scale: 100000);
17. Sestavte a zobrazte shapefile. Bodová data jsou zobrazena ve třech barvách: červená/modrá/žlutá.
Shrnutí
V tomto článku jsme implementovali funkci zobrazení shapefile. Kromě samotného zobrazení dat je možné také přistupovat k ShapefileFeatureTable a provádět dotazy na data (query) a úpravy (přidání/odstranění/aktualizace). Tentokrát jsme použili shapefile, ale SDK podporuje i mnoho dalších GIS dat, jako jsou geodatabáze a GeoPackage, rastery a další.
Související odkazy