Dit is een blogserie waarin functies voor het ontwikkelen van kaartapps met Flutter worden geïntroduceerd. Deze keer richten we ons op het weergeven van shapefiles. We implementeren een functie om shapefile-gegevens op de kaart te tonen. In dit artikel laten we zien hoe je deze functie implementeert met de Flutter-kaart SDK (ArcGIS Maps SDK for Flutter).
De voorbeeldcode is beschikbaar op GitHub, dus als je snel wilt beginnen, kun je die downloaden. Hoe je de app uitvoert staat beschreven in README. Om het voorbeeld uit te voeren heb je een API-sleutel verkrijgen (niet betaald) nodig. Voor het installeren van de kaart SDK en het weergeven van de kaart, zie het blogartikel “Laten we een kaartapp maken met Flutter!”. Dit artikel richt zich op de functie voor het weergeven van shapefiles.
Wat is een shapefile?
Een shapefile is een formaat voor GIS (Geografisch Informatiesysteem) data. Het kan vectorgegevens (punten, lijnen, polygonen) bevatten die locaties, vormen en attributen van objecten zoals doelen, wegen en gebouwen beschrijven. Shapefiles zijn een industrieel standaard vectorformaat in GIS en worden ondersteund door ArcGIS-producten en veel andere GIS-software.
Implementatie van de functie voor het weergeven van shapefiles
Om shapefiles weer te geven gebruik je de klasse ShapefileFeatureTable. Hiermee kun je shapefile-gegevens vanaf een opgegeven pad als laag op de kaart tonen. De shapefile die we gebruiken is te vinden hier. Deze bevat willekeurig geplaatste puntdata binnen de prefectuur Chiba.
1. Volg stap 6 in het blogartikel “Laten we een kaartapp maken met Flutter!” om te bevestigen dat je de gemaakte kaart kunt instellen in de MapView-controller en dat de kaart wordt weergegeven.
2. Download en pak het ZIP-bestand uit dat de shapefile bevat via deze linkから、シェープファイルを格納した ZIP ファイルをダウンロードして解凍します。shp
3. アプリケーションに配置したシェープファイルを追加するために pubspec.yaml の assets セクションを下記のように更新します。
assets:
- assets/shp/
4. デバイス内のパスの取得に path_provider パッケージを使用するため、pubspec.yaml の dependencies セクションにパッケージを追加します。
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.8
arcgis_maps: ^200.8.0+4672
# 追加
path_provider: ^2.1.5
5. lib/main.dart を開き、既に書かれているインポート行の後に、下記のコードを追加して、この後の処理に必要なパッケージをインポートします。
import 'package:path_provider/path_provider.dart';
import 'package:flutter/services.dart';
import 'dart:io';
6. ファイル操作等に await を使用するため _onMapViewReady() を async 関数に変更します。
// 変更前
void _onMapViewReady() {
// 変更後
Future<void> _onMapViewReady() async {
7. _onMapViewReady() async 関数の最後にコードを追加します。assets フォルダーにあるシェープファイルを読み込み、iOS/Android アプリケーションのドキュメント ディレクトリーに、新たにシェープファイルを作成します。
// マップビュー コントローラーに作成したマップを設定します。
_mapViewController.arcGISMap = map;
// 追加
// 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. 続いて、ドキュメント ディレクトリーに作成したシェープファイル (.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);
//Na wijziging
final initialPoint = ArcGISPoint(
x: 140.1111782,
y: 35.6130401,
spatialReference: SpatialReference.wgs84,
);
map.initialViewpoint = Viewpoint.fromCenter(initialPoint, scale: 100000);
17. Bouw en bekijk de shapefile. De puntgegevens worden weergegeven in drie kleuren: rood/blauw/geel.
Samenvatting
In dit artikel hebben we de functie voor het weergeven van shapefiles geïmplementeerd. Niet alleen het weergeven van gegevens, maar ook toegang tot de ShapefileFeatureTable om queries uit te voeren en bewerkingen zoals query's en bewerken (toevoegen/verwijderen/bijwerken) zijn mogelijk. We hebben deze keer shapefiles gebruikt, maar de SDK ondersteunt ook veel andere GIS-gegevens zoals geodatabases en GeoPackage, rasterdata enzovoort.
Gerelateerde links