dart_crs 1.0.3 copy "dart_crs: ^1.0.3" to clipboard
dart_crs: ^1.0.3 copied to clipboard

This package extends proj4dart by embedding the EPSG Geodetic Parameter Dataset maintained by the Geodesy Subcommittee of the IOGP Geomatics Committee.

example/lib/main.dart

import 'package:dart_crs/dart_crs.dart';
import 'package:flutter/material.dart';
import 'package:proj4dart/proj4dart.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.teal),
        useMaterial3: true,
        elevatedButtonTheme: ElevatedButtonThemeData(
            style: ElevatedButton.styleFrom(
                backgroundColor: Colors.teal,
                textStyle:
                    const TextStyle(color: Colors.white, fontSize: 14.0))),
      ),
      home: const MyHomePage(title: 'Dart_Crs Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  CoordinateTransform? transform;
  TextEditingController xController = TextEditingController();
  TextEditingController yController = TextEditingController();
  TextEditingController xTransformController = TextEditingController();
  TextEditingController yTransformController = TextEditingController();
  TextEditingController sourceCRSController = TextEditingController();
  TextEditingController targetCRSController = TextEditingController();
  Point? sourcePoint;
  Point? targetPoint;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      resizeToAvoidBottomInset: false,
      appBar: PreferredSize(
        preferredSize: const Size.fromHeight(50.0),
        child: AppBar(
          centerTitle: true,
          backgroundColor: Theme.of(context).colorScheme.primary,
          title: Text(widget.title,
              style: const TextStyle(
                  fontSize: 22.0,
                  color: Colors.white,
                  fontWeight: FontWeight.bold)),
        ),
      ),
      body: Container(
        padding: const EdgeInsets.all(15.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          children: <Widget>[
            const SizedBox(height: 30),
            const Text('Coordinate Reference Systems',
                style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500)),
            const SizedBox(height: 20.0),
            Row(
              children: [
                Expanded(
                  child: TextField(
                    controller: sourceCRSController,
                    decoration: const InputDecoration(
                      label: Text('Source CRS',
                          style: TextStyle(
                              fontSize: 14.0, fontWeight: FontWeight.w500)),
                      contentPadding:
                          EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0),
                      border: OutlineInputBorder(),
                      hintText: 'EPSG:xxxx',
                      hintStyle: TextStyle(fontSize: 13),
                      enabled: true,
                    ),
                  ),
                ),
                const SizedBox(width: 15.0),
                Expanded(
                  child: TextField(
                    controller: targetCRSController,
                    decoration: const InputDecoration(
                      label: Text('Target CRS',
                          style: TextStyle(
                              fontSize: 14.0, fontWeight: FontWeight.w500)),
                      contentPadding:
                          EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0),
                      border: OutlineInputBorder(),
                      hintText: 'EPSG:xxxx',
                      hintStyle: TextStyle(fontSize: 13),
                    ),
                  ),
                ),
              ],
            ),
            const SizedBox(height: 30),
            const Text('Source Coordinates',
                style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500)),
            const SizedBox(height: 20.0),
            Row(
              children: [
                Expanded(
                  child: TextField(
                    controller: xController,
                    decoration: const InputDecoration(
                      label: Text('X (East) Coordinate',
                          style: TextStyle(
                              fontSize: 14.0, fontWeight: FontWeight.w500)),
                      contentPadding:
                          EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0),
                      border: OutlineInputBorder(),
                      hintText: 'Enter Coordinate',
                      hintStyle: TextStyle(fontSize: 13),
                      enabled: true,
                    ),
                  ),
                ),
                const SizedBox(width: 15.0),
                Expanded(
                  child: TextField(
                    controller: yController,
                    decoration: const InputDecoration(
                      label: Text('Y (North) Coordinate',
                          style: TextStyle(
                              fontSize: 14.0, fontWeight: FontWeight.w500)),
                      contentPadding:
                          EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0),
                      border: OutlineInputBorder(),
                      hintText: 'Enter Coordinate',
                      hintStyle: TextStyle(fontSize: 13),
                    ),
                  ),
                ),
              ],
            ),
            const SizedBox(height: 30),
            const Text('Transformed Coordinates',
                style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500)),
            const SizedBox(height: 20.0),
            Row(
              children: [
                Expanded(
                  child: TextField(
                    readOnly: true,
                    controller: xTransformController,
                    decoration: const InputDecoration(
                      label: Text('X (East) Coordinate',
                          style: TextStyle(
                              fontSize: 14.0, fontWeight: FontWeight.w500)),
                      contentPadding:
                          EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0),
                      border: OutlineInputBorder(),
                      // hintText: 'Enter Coordinate',
                      // hintStyle: TextStyle(fontSize: 13),
                      enabled: true,
                    ),
                  ),
                ),
                const SizedBox(width: 15.0),
                Expanded(
                  child: TextField(
                    controller: yTransformController,
                    decoration: const InputDecoration(
                      label: Text('Y (North) Coordinate',
                          style: TextStyle(
                              fontSize: 14.0, fontWeight: FontWeight.w500)),
                      contentPadding:
                          EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0),
                      border: OutlineInputBorder(),
                      // hintText: 'Enter Coordinate',
                      // hintStyle: TextStyle(fontSize: 13),
                    ),
                  ),
                ),
              ],
            ),
            const SizedBox(height: 40),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                ElevatedButton(
                  child: const Text('Forward',
                      style: TextStyle(color: Colors.white, fontSize: 14.0)),
                  onPressed: () async {
                    final sourceCRS = sourceCRSController.text.toUpperCase();
                    if (!validateCRS(sourceCRS)) {
                      FocusManager.instance.primaryFocus?.unfocus();
                      ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
                          content: Text('Invalid or missing source SRS')));
                      return;
                    }
                    final targetCRS = targetCRSController.text.toUpperCase();
                    if (!validateCRS(targetCRS)) {
                      FocusManager.instance.primaryFocus?.unfocus();
                      ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
                          content: Text('Invalid or missing target SRS')));
                      return;
                    }
                    try {
                      transform ??=
                          await CRSFactory.createCoordinateTransformFromCodes(
                              sourceCRS, targetCRS);
                      final x = double.parse(xController.value.text);
                      final y = double.parse(yController.value.text);
                      sourcePoint = Point(x: x, y: y);
                      targetPoint = transform!.transform(sourcePoint!);
                      setState(() {
                        if (targetPoint != null) {
                          xTransformController.text =
                              targetPoint!.x.toStringAsPrecision(11);
                          yTransformController.text =
                              targetPoint!.y.toStringAsPrecision(11);
                        }
                      });
                    } on InvalidArgumentException {
                      if (context.mounted) {
                        FocusManager.instance.primaryFocus?.unfocus();
                        ScaffoldMessenger.of(context).showSnackBar(
                            const SnackBar(
                                content:
                                    Text('Invalid or missing source or target SRS')));
                        return;
                      }
                    }
                  },
                ),
                const SizedBox(width: 30.0),
                ElevatedButton(
                  style: ButtonStyle(
                    shape: MaterialStateProperty.all<RoundedRectangleBorder>(
                        RoundedRectangleBorder(
                            borderRadius: BorderRadius.circular(24.0),
                            side: const BorderSide(color: Colors.teal))),
                  ),
                  child: const Text('Inverse',
                      style: TextStyle(color: Colors.white, fontSize: 16.0)),
                  onPressed: () async {
                    if (targetPoint != null) {
                      targetPoint = transform!.inverse(targetPoint!);
                      setState(() {
                        if (targetPoint != null) {
                          xTransformController.text =
                              targetPoint!.x.toStringAsPrecision(11);
                          yTransformController.text =
                              targetPoint!.y.toStringAsPrecision(11);
                        }
                      });
                    }
                  },
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }

  bool validateCRS(String crsCode) {
    final lc = crsCode.toLowerCase();
    return lc.startsWith("epsg:");
  }
}
1
likes
160
points
32
downloads

Publisher

verified publisherredfishresearch.com

Weekly Downloads

This package extends proj4dart by embedding the EPSG Geodetic Parameter Dataset maintained by the Geodesy Subcommittee of the IOGP Geomatics Committee.

Repository (GitHub)
View/report issues

Documentation

API reference

License

BSD-3-Clause (license)

Dependencies

flutter, path, proj4dart, sqflite

More

Packages that depend on dart_crs