def __init__(self, *args, **kwargs):
        """
        Creates a NeomodelPoint.

        :param args: Positional arguments to emulate the behaviour of Shapely's Point (and specifically the copy
        constructor)
        :type args: list
        :param crs: Coordinate Reference System, must be one of ['cartesian', 'cartesian-3d', 'wgs-84', 'wgs-84-3d']
        :type crs: str
        :param x: x coordinate of point
        :type x: float
        :param y: y coordinate of point
        :type y: float
        :param z: z coordinate of point if the crs is cartesian-3d
        :type z: float
        :param latitude: Latitude of point
        :type latitude: float
        :param longitude: Longitude of point
        :type longitude: float
        :param height: Height of point if the crs is wgs-84-3d
        :type height: float
        :param kwargs: Dictionary of keyword arguments
        :type kwargs: dict
        """

        # Python2.7 Workaround for the order that the arguments get passed to the functions
        crs = kwargs.pop('crs', None)
        x = kwargs.pop('x', None)
        y = kwargs.pop('y', None)
        z = kwargs.pop('z', None)
        longitude = kwargs.pop('longitude', None)
        latitude = kwargs.pop('latitude', None)
        height = kwargs.pop('height', None)

        _x, _y, _z = None, None, None

        # CRS validity check is common to both types of constructors that follow
        if crs is not None and crs not in ACCEPTABLE_CRS:
            raise ValueError('Invalid CRS({}). Expected one of {}'.format(crs, ','.join(ACCEPTABLE_CRS)))
        self._crs = crs

        # If positional arguments have been supplied, then this is a possible call to the copy constructor or
        # initialisation by a coordinate iterable as per ShapelyPoint constructor.
        if len(args):
            # If a coordinate iterable was passed, emulate a call with x,y[,z] parameters
            if isinstance(args[0],(tuple, list)):
                # Check dimensionality of tuple
                if len(args[0]) < 2 or len(args[0]) > 3:
                    raise ValueError('Invalid vector dimensions. Expected 2 or 3, received {}'.format(len(args[0])))
                x = args[0][0]
                y = args[0][1]
                if len(args[0]) == 3:
                    z = args[0][2]
            # If another "Point" was passed, then this is a call to the copy constructor
            elif isinstance(args[0], ShapelyPoint):
                super(NeomodelPoint, self).__init__(args[0])
                # If the other Point was a NeomodelPoint then it bears the CRS that is used to
                # interpret the points and this has to be carried over.
                if isinstance(args[0], NeomodelPoint):
                    self._crs = args[0]._crs
                else:
                    # This allows NeomodelPoint((0,0),crs="wgs-84") which will interpret the tuple as
                    # (longitude,latitude) even though it was not specified as such with the named arguments.
                    #
                    # NOTE: Notice the indexing on the coordinates `args[0].coords[0]`. Coordinates are always an
                    # iterable which for Points has length of 1 but for other geometrical objects (e.g. boundaries)
                    # might be longer. This will come back to bite you, if you assume that `coords` is what it pretends
                    # to be (i.e. coords gives access to the actual coordinates NOT an iterable).
                    #
                    if len(args[0].coords[0]) == 2:
                        if crs is None:
                            self._crs = 'cartesian'
                    elif len(args[0].coords[0]) == 3:
                        if crs is None:
                            self._crs = 'cartesian-3d'
                    else:
                        raise ValueError('Invalid vector dimensions. '
                                         'Expected 2 or 3, received {}'.format(len(args[0].coords[0])))
                return
            else:
                raise TypeError('Invalid object passed to copy constructor. '
                                'Expected NeomodelPoint or shapely Point, received {}'.format(type(args[0])))

        # Initialisation is either via x,y[,z] XOR longitude,latitude[,height]. Specifying both leads to an error.
        if (x is not None or y is not None or z is not None) and \
                (latitude is not None or longitude is not None or height is not None):
            raise ValueError('Invalid instantiation via arguments. '
                             'A Point can be defined either by x,y,z coordinates OR latitude,longitude,height but not '
                             'a combination of these terms')

        # Specifying no initialisation argument at this point in the constructor is flagged as an error
        if x is None and y is None and z is None and longitude is None and latitude is None and height is None:
            raise ValueError('Invalid instantiation via no arguments. '
                             'A Point needs default values either in x,y,z or longitude, latitude, height coordinates')

        # Geographical Point Initialisation
        if latitude is not None and longitude is not None:
            if height is not None:
                if self._crs is None:
                    self._crs = 'wgs-84-3d'
                _z = height
            else:
                if self._crs is None:
                    self._crs = 'wgs-84'
            _x = longitude
            _y = latitude

        # Geometrical Point Initialisation
        if x is not None and y is not None:
            if z is not None:
                if self._crs is None:
                    self._crs = 'cartesian-3d'
                _z = z
            else:
                if self._crs is None:
                    self._crs = 'cartesian'
            _x = x
            _y = y

        if _z is None:
            if '-3d' not in self._crs:
                super(NeomodelPoint, self).__init__((float(_x),float(_y)), **kwargs)
            else:
                raise ValueError("Invalid vector dimensions(2) for given CRS({}).".format(self._crs))
        else:
            if '-3d' in self._crs:
                super(NeomodelPoint, self).__init__((float(_x), float(_y), float(_z)), **kwargs)
            else:
                raise ValueError("Invalid vector dimensions(3) for given CRS({}).".format(self._crs))
def __init__ ( self , * args , ** kwargs ) : crs = kwargs . pop ( 'crs' , None ) x = kwargs . pop ( 'x' , None ) y = kwargs . pop ( 'y' , None ) z = kwargs . pop ( 'z' , None ) longitude = kwargs . pop ( 'longitude' , None ) latitude = kwargs . pop ( 'latitude' , None ) height = kwargs . pop ( 'height' , None ) _x , _y , _z = None , None , None if crs is not None and crs not in ACCEPTABLE_CRS : raise ValueError ( 'Invalid CRS({}). Expected one of {}' . format ( crs , ',' . join ( ACCEPTABLE_CRS ) ) ) self . _crs = crs if len ( args ) : if isinstance ( args [ 0 ] , ( tuple , list ) ) : if len ( args [ 0 ] ) < 2 or len ( args [ 0 ] ) > 3 : raise ValueError ( 'Invalid vector dimensions. Expected 2 or 3, received {}' . format ( len ( args [ 0 ] ) ) ) x = args [ 0 ] [ 0 ] y = args [ 0 ] [ 1 ] if len ( args [ 0 ] ) == 3 : z = args [ 0 ] [ 2 ] elif isinstance ( args [ 0 ] , ShapelyPoint ) : super ( NeomodelPoint , self ) . __init__ ( args [ 0 ] ) if isinstance ( args [ 0 ] , NeomodelPoint ) : self . _crs = args [ 0 ] . _crs else : if len ( args [ 0 ] . coords [ 0 ] ) == 2 : if crs is None : self . _crs = 'cartesian' elif len ( args [ 0 ] . coords [ 0 ] ) == 3 : if crs is None : self . _crs = 'cartesian-3d' else : raise ValueError ( 'Invalid vector dimensions. ' 'Expected 2 or 3, received {}' . format ( len ( args [ 0 ] . coords [ 0 ] ) ) ) return else : raise TypeError ( 'Invalid object passed to copy constructor. ' 'Expected NeomodelPoint or shapely Point, received {}' . format ( type ( args [ 0 ] ) ) ) if ( x is not None or y is not None or z is not None ) and ( latitude is not None or longitude is not None or height is not None ) : raise ValueError ( 'Invalid instantiation via arguments. ' 'A Point can be defined either by x,y,z coordinates OR latitude,longitude,height but not ' 'a combination of these terms' ) if x is None and y is None and z is None and longitude is None and latitude is None and height is None : raise ValueError ( 'Invalid instantiation via no arguments. ' 'A Point needs default values either in x,y,z or longitude, latitude, height coordinates' ) if latitude is not None and longitude is not None : if height is not None : if self . _crs is None : self . _crs = 'wgs-84-3d' _z = height else : if self . _crs is None : self . _crs = 'wgs-84' _x = longitude _y = latitude if x is not None and y is not None : if z is not None : if self . _crs is None : self . _crs = 'cartesian-3d' _z = z else : if self . _crs is None : self . _crs = 'cartesian' _x = x _y = y if _z is None : if '-3d' not in self . _crs : super ( NeomodelPoint , self ) . __init__ ( ( float ( _x ) , float ( _y ) ) , ** kwargs ) else : raise ValueError ( "Invalid vector dimensions(2) for given CRS({})." . format ( self . _crs ) ) else : if '-3d' in self . _crs : super ( NeomodelPoint , self ) . __init__ ( ( float ( _x ) , float ( _y ) , float ( _z ) ) , ** kwargs ) else : raise ValueError ( "Invalid vector dimensions(3) for given CRS({})." . format ( self . _crs ) )
Creates a NeomodelPoint.

        :param args: Positional arguments to emulate the behaviour of Shapely's Point (and specifically the copy
        constructor)
        :type args: list
        :param crs: Coordinate Reference System, must be one of ['cartesian', 'cartesian-3d', 'wgs-84', 'wgs-84-3d']
        :type crs: str
        :param x: x coordinate of point
        :type x: float
        :param y: y coordinate of point
        :type y: float
        :param z: z coordinate of point if the crs is cartesian-3d
        :type z: float
        :param latitude: Latitude of point
        :type latitude: float
        :param longitude: Longitude of point
        :type longitude: float
        :param height: Height of point if the crs is wgs-84-3d
        :type height: float
        :param kwargs: Dictionary of keyword arguments
        :type kwargs: dict