text: """lineset.py: LineSet element and geometry"""
  from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  from __future__ import unicode_literals
  
  import numpy as np
  import properties
  
  from .base import ProjectElement
  from .data import Int2Array, Vector3Array
  
  
  class LineSetElement(ProjectElement):
      """Contains line set spatial information and attributes"""
      vertices = properties.Instance(
          'Spatial coordinates of line vertices relative to line set origin',
          Vector3Array,
      )
      segments = properties.Instance(
          'Endpoint vertex indices of line segments',
          Int2Array,
      )
      subtype = properties.StringChoice(
          'Category of LineSet',
          choices=('line', 'borehole'),
          default='line',
      )
  
      _valid_locations = ('vertices', 'segments')
  
      def location_length(self, location):
          """Return correct data length based on location"""
          if location == 'segments':
              return self.num_cells
          return self.num_nodes
  
      @property
      def num_nodes(self):
          """Number of nodes (vertices)"""
          return len(self.vertices.array)
  
      @property
      def num_cells(self):
          """Number of cells (segments)"""
          return len(self.segments.array)
  
      @properties.validator
      def _validate_mesh(self):
          """Ensures segment indices are valid"""
          if np.min(self.segments.array) < 0:
              raise ValueError('Segments may only have positive integers')
          if np.max(self.segments.array) >= len(self.vertices.array):
              raise ValueError('Segments expects more vertices than provided')
          return True
  