Как я могу рекурсивно прочитать и проанализировать файл XML во Flutter? - PullRequest
0 голосов
/ 28 февраля 2020

То, чего я в конечном итоге хочу достичь, - это чтобы пользователь мог нажать на кнопку, которая покажет панель, которая содержит список зданий и открывается с анимацией, которая извлекается из файла KML, размещенного в сети. сервер. Нажав на одно из этих зданий, вы добавите маркер в базовое приложение GoogleMap в месте расположения здания и путь к нему. Я хочу, чтобы этот KML-файл имел доступ с веб-сервера, поэтому при его обновлении мне не нужно будет обновлять приложение. Кроме того, этот KML-файл будет использоваться для отображения слоя карты для отображения кампуса.

Поскольку я ничего не знал о чтении KML-файлов с помощью Flutter, я начал создавать небольшое приложение для чтения локальных XML файла, но у меня есть несколько проблем.

Во-первых, файл KML / XML имеет подуровни, и мне трудно пройти через эти уровни.

Во-вторых, в файл с тем же именем и идентификатором. Мне сообщили, что это потому, что в одном месте есть несколько зданий. Как я могу добавить в список только отдельные элементы?

Вот мой файл main.dart

import 'package:flutter/material.dart';
import 'package:xml_test/buildings.dart';
import 'package:xml/xml.dart' as xml;

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  var appBar = AppBar();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'XML TEST',
      home: Scaffold(
        appBar: appBar,
        body: BuildPanel(),
      ),
    );
  }
}

class BuildPanel extends StatelessWidget {
//String _url =
  //    '**<URL TO REMOTE KML FILE>**';

  @override
  Widget build(BuildContext context) {
    return _panelLayout(context);
  }
}

Widget _panelLayout(BuildContext context) {
  return Align(
    alignment: Alignment.topLeft,
    child: LayoutBuilder(
        builder: (BuildContext context, BoxConstraints constraints) {
      return Column(
        children: <Widget>[
          DecoratedBox(
            decoration: BoxDecoration(
              gradient: LinearGradient(
                begin: Alignment.topLeft,
                end: Alignment.bottomRight,
                stops: [0.1, 1],
                colors: [Colors.black12, Colors.black],
              ),
            ),
          ),
          Container(
            width: MediaQuery.of(context).size.width * 0.85,
            height: (MediaQuery.of(context).size.height * 0.85),
            padding: EdgeInsets.fromLTRB(20.0, 0.0, 10.0, 0.0),
            child: FutureBuilder(
              future: getBuildingsfromXML(context),
              builder: (context, data) {
                if (data.hasData) {
                  List<Building> buildings = data.data;
                  return Container(
                    child: ListView.separated(
                        separatorBuilder: (context, index) =>
                            Divider(color: Colors.black),
                        itemCount: buildings.length,
                        itemBuilder: (context, index) {
                          return ListTile(
                            contentPadding: EdgeInsets.zero,
                            leading:
                                Icon(Icons.business, color: Colors.black12),
                            title: Text(
                              buildings[index].name,
                              style: TextStyle(
                                  fontSize: 16.0,
                                  fontWeight: FontWeight.normal),
                            ),
                          );
                        }),
                  );
                } else {
                  return Center(
                    child: CircularProgressIndicator(),
                  );
                }
              },
            ),
          ),
        ],
      );
    }),
  );
}

Future<List<Building>> getBuildingsfromXML(BuildContext context) async {
  String xmlString =
      await DefaultAssetBundle.of(context).loadString('assets/campus_map.kml');

  var raw = xml.parse(xmlString);
  var elements = raw.findAllElements("Placemark");

  return elements.map((element) {
    return Building(element.findElements("name").first.text);
  }).toList();
}

Вот файл building.dart. Это намеренно очень просто, чтобы я мог заставить все работать. Я буду добавлять другие элементы, такие как координаты позже.

class Building {
  String name;


  Building(this.name);

  factory Building.fromXML(Map<dynamic, dynamic> xml) {
    if (xml == null) {
      return null;
    } else {
      return Building(xml["name"]);
    }
  }
}

Вот пример файла KML

<Placemark id="375">
<styleUrl>#residenceStyle</styleUrl>
<name>Oak House</name>
<Polygon>
<outerBoundaryIs>
<LinearRing>
<coordinates>
-2.216519364122405,53.44279535518482,0 -2.216505282525077,53.44268392307145,0 -2.2171329194345617,53.44265836154188,0 -2.2171651059427404,53.44284048710456,0 -2.2180589520969534,53.44279495578707,0 -2.218079068664565,53.44314562555185,0 -2.2178919845857763,53.44314961949607,0 -2.2178571158685827,53.442909982179266,0 -2.217006185058608,53.442957110958325,0 -2.216976680759444,53.44276500094635,0
</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
<Placemark id="375">
<styleUrl>#residenceStyle</styleUrl>
<name>Oak House</name>
<Polygon>
<outerBoundaryIs>
<LinearRing>
<coordinates>
-2.2158689284362936,53.44303659072992,0 -2.215697937611594,53.44304098407979,0 -2.2156603866853857,53.44281452627149,0 -2.2156851971187734,53.442813328078806,0 -2.215669103864684,53.44266595012243,0 -2.216446273926749,53.44261682402337,0 -2.21645365000154,53.44272705811762,0 -2.2158347302713537,53.442761406363886,0
</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...