Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize reading from iterable of coordinate values #131

Closed
navispatial opened this issue Jun 27, 2022 · 3 comments
Closed

Optimize reading from iterable of coordinate values #131

navispatial opened this issue Jun 27, 2022 · 3 comments
Labels
enhancement New feature or request 🌐 geobase Related to the code package "geobase" refactoring

Comments

@navispatial
Copy link
Member

For example Position has:

  /// Creates a position of [R] from [coords] given in order: x, y, z, m.
  ///
  /// The [coords] must contain at least two coordinate values (x and y)
  /// starting from [offset]. If [coords] contains three values, then 3rd item
  /// is z. If [coords] contains four values, then 4th item is m.
  ///
  /// A position instance is created using the factory function [to].
  static R createFromCoords<R extends Position>(
    Iterable<num> coords, {
    required CreatePosition<R> to,
    int offset = 0,
  }) {
    final len = coords.length - offset;
    if (len < 2) {
      throw const FormatException('Coords must contain at least two items');
    }
    return to.call(
      x: coords.elementAt(offset),
      y: coords.elementAt(offset + 1),
      z: len >= 3 ? coords.elementAt(offset + 2) : null,
      m: len >= 4 ? coords.elementAt(offset + 3) : null,
    );
  }

This could be optimized (in case iterable is not a list) by taking Iterator from coords and iterating available coordinate values.

@navispatial navispatial added enhancement New feature or request refactoring 🌐 geobase Related to the code package "geobase" labels Jun 27, 2022
@navispatial
Copy link
Member Author

Optimized

  /// Creates a position of [R] from [coords] given in order: x, y, z, m.
  ///
  /// The [coords] must contain at least two coordinate values (x and y)
  /// starting from [offset]. If [coords] contains three values, then 3rd item
  /// is z. If [coords] contains four values, then 4th item is m.
  ///
  /// A position instance is created using the factory function [to].
  static R createFromCoords<R extends Position>(
    Iterable<num> coords, {
    required CreatePosition<R> to,
    int offset = 0,
  }) {
    // resolve iterator for source coordinates
    final Iterator<num> iter;
    if (offset == 0) {
      iter = coords.iterator;
    } else if (coords.length >= offset + 2) {
      iter = coords.skip(offset).iterator;
    } else {
      throw invalidCoordinates;
    }

    // iterate at least to x and y + optionally z + m => then create position
    if (iter.moveNext()) {
      final x = iter.current;
      if (iter.moveNext()) {
        final y = iter.current;
        final optZ = iter.moveNext() ? iter.current : null;
        final optM = iter.moveNext() ? iter.current : null;
        return to.call(x: x, y: y, z: optZ, m: optM);
      }
    }
    throw invalidCoordinates;
  }

@navispatial
Copy link
Member Author

Other coordinate factory methods taking iterable input with similar impls.

@navispatial
Copy link
Member Author

Still other optimizations as commented above.

Implemented in geobase 0.3.0-dev.1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request 🌐 geobase Related to the code package "geobase" refactoring
Projects
None yet
Development

No branches or pull requests

1 participant