-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | A library for working with geospatial data types.
--   
--   Naqsha is a library to work with geospatial data types like latitudes
--   and longitudes. It provides some basic operations like distance
--   calculations.
@package naqsha
@version 0.2.0.1


-- | The internal module that exposes the basic geometric types in naqsha.
--   This interface is subject to change and hence use with caution.
module Naqsha.Geometry.Internal

-- | An abstract angle. Internally, angles are represented as a 64-bit
--   integer with each unit contribute 1/2^64 fraction of a complete
--   circle. This means that angles are accurate up to a resolution of 2 π
--   / 2^64 radians. Angles form a group under the angular addition and the
--   fact that these are represented as integers means one can expect high
--   speed accurate angle arithmetic.
--   
--   When expressing angles one can use a more convenient notation:
--   
--   <pre>
--   myAngle   = degree 21.71167
--   yourAngle = degree 21 &lt;&gt; minute 42 &lt;&gt; second 42
--   </pre>
newtype Angle
Angle :: Int64 -> Angle
[unAngle] :: Angle -> Int64

-- | Express angle in degrees.
degree :: Rational -> Angle

-- | Express angle in minutes.
minute :: Rational -> Angle

-- | Express angle in seconds.
second :: Rational -> Angle

-- | Express angle in radians
radian :: Double -> Angle

-- | Measure angle in degrees. This conversion may lead to loss of
--   precision.
toDegree :: Fractional r => Angle -> r

-- | Measure angle in radians. This conversion may lead to loss of
--   precision.
toRadian :: Angle -> Double

-- | The latitude of a point. Positive denotes North of Equator where as
--   negative South.
newtype Latitude
Latitude :: Angle -> Latitude
[unLat] :: Latitude -> Angle

-- | The longitude of a point. Positive denotes East of the Greenwich
--   meridian where as negative denotes West.
newtype Longitude
Longitude :: Angle -> Longitude
[unLong] :: Longitude -> Angle

-- | Construct latitude out of an angle.
lat :: Angle -> Latitude

-- | Convert angles to longitude.
lon :: Angle -> Longitude
instance Data.Bits.Bits Naqsha.Geometry.Internal.Longitude
instance Data.Group.Group Naqsha.Geometry.Internal.Longitude
instance GHC.Base.Monoid Naqsha.Geometry.Internal.Longitude
instance GHC.Classes.Ord Naqsha.Geometry.Internal.Longitude
instance GHC.Enum.Bounded Naqsha.Geometry.Internal.Longitude
instance GHC.Classes.Eq Naqsha.Geometry.Internal.Longitude
instance Data.Bits.Bits Naqsha.Geometry.Internal.Latitude
instance GHC.Classes.Ord Naqsha.Geometry.Internal.Latitude
instance GHC.Classes.Eq Naqsha.Geometry.Internal.Latitude
instance Data.Bits.Bits Naqsha.Geometry.Internal.Angle
instance GHC.Read.Read Naqsha.Geometry.Internal.Angle
instance GHC.Show.Show Naqsha.Geometry.Internal.Angle
instance Data.Vector.Unboxed.Base.Unbox Naqsha.Geometry.Internal.Angle
instance GHC.Classes.Ord Naqsha.Geometry.Internal.Angle
instance GHC.Classes.Eq Naqsha.Geometry.Internal.Angle
instance GHC.Enum.Enum Naqsha.Geometry.Internal.Angle
instance GHC.Show.Show Naqsha.Geometry.Internal.Longitude
instance GHC.Read.Read Naqsha.Geometry.Internal.Longitude
instance Data.Vector.Generic.Mutable.Base.MVector Data.Vector.Unboxed.Base.MVector Naqsha.Geometry.Internal.Longitude
instance Data.Vector.Generic.Base.Vector Data.Vector.Unboxed.Base.Vector Naqsha.Geometry.Internal.Longitude
instance GHC.Show.Show Naqsha.Geometry.Internal.Latitude
instance GHC.Read.Read Naqsha.Geometry.Internal.Latitude
instance GHC.Enum.Bounded Naqsha.Geometry.Internal.Latitude
instance Data.Vector.Generic.Mutable.Base.MVector Data.Vector.Unboxed.Base.MVector Naqsha.Geometry.Internal.Latitude
instance Data.Vector.Generic.Base.Vector Data.Vector.Unboxed.Base.Vector Naqsha.Geometry.Internal.Latitude
instance GHC.Base.Monoid Naqsha.Geometry.Internal.Angle
instance Data.Group.Group Naqsha.Geometry.Internal.Angle
instance GHC.Enum.Bounded Naqsha.Geometry.Internal.Angle
instance Data.Vector.Generic.Mutable.Base.MVector Data.Vector.Unboxed.Base.MVector Naqsha.Geometry.Internal.Angle
instance Data.Vector.Generic.Base.Vector Data.Vector.Unboxed.Base.Vector Naqsha.Geometry.Internal.Angle


-- | This module implements the geohash encoding of geo-locations.
--   <a>https://en.wikipedia.org/wiki/Geohash</a>. To try out geohash
--   encoding on web visit <a>http://geohash.org</a>
module Naqsha.Geometry.Coordinate.GeoHash

-- | The encoding of geo-coordinates as a geohash string. Currently, the
--   encoding supports 24 base32 digits of geo hash value which means we
--   loose about 4-bits of accuracy w.r.t the representation of angles in
--   the library. However, this loss is rather theoretical as the angular
--   error that results from such loss is so insignificant that for all
--   practical purposes, this accuracy is good enough --- GPS devices will
--   have much greater errors. The quantity <a>accuracy</a> gives the
--   number of bits of precision supported by the geohash implementation
--   exposed here. As expected GeoHash implementations here will have
--   problems at regions close to the poles.
data GeoHash

-- | Encode a geo-location into its GeoHash string.
encode :: Geo -> GeoHash

-- | Decode the geo-location from its GeoHash string.
decode :: GeoHash -> Geo

-- | Precision of encoding measured in bits.
accuracy :: Int

-- | Convert the geo hash to bytestring.
toByteString :: GeoHash -> ByteString
instance GHC.Classes.Ord Naqsha.Geometry.Coordinate.GeoHash.GeoHash
instance GHC.Classes.Eq Naqsha.Geometry.Coordinate.GeoHash.GeoHash
instance GHC.Show.Show Naqsha.Geometry.Coordinate.GeoHash.GeoHash
instance Data.String.IsString Naqsha.Geometry.Coordinate.GeoHash.GeoHash


-- | Geometric operations on earth surface assuming that earth is a sphere
--   of radius 6371008 m.
--   
--   TODO: Port some calculations from
--   <a>http://www.movable-type.co.uk/scripts/latlong.html</a>
module Naqsha.Geometry.Spherical

-- | This combinator computes the distance (in meters) between two
--   geo-locations using the haversine distance between two points. For
--   <tt>Position</tt> which have an
distance :: Geo -> Geo -> Double

-- | A generalisation of <a>distance</a> that takes the radius as argument.
--   Will work on Mars for example once we set up a latitude longitude
--   system there. For this function units does not matter --- the computed
--   distance is in the same unit as the input radius. We have
--   
--   <pre>
--   distance = distance' rMean
--   </pre>
distance' :: Double -> Geo -> Geo -> Double

-- | Mean earth radius in meters. This is the radius used in the haversine
--   formula of <tt>dHvs</tt>.
rMean :: Double


-- | The geometric types and values exposed by naqsha.
module Naqsha.Geometry

-- | The coordinates of a point on the earth's surface.
data Geo
Geo :: {-# UNPACK #-} !Latitude -> {-# UNPACK #-} !Longitude -> Geo

-- | The North pole
northPole :: Geo

-- | The South pole
southPole :: Geo

-- | The latitude of a point. Positive denotes North of Equator where as
--   negative South.
data Latitude

-- | Construct latitude out of an angle.
lat :: Angle -> Latitude

-- | Convert an angle to a northern latitude
--   
--   <pre>
--   tropicOfCancer = north $ degree 23.5
--   </pre>
north :: Angle -> Latitude

-- | Convert an angle to a southern latitude.
--   
--   <pre>
--   tropicOfCapricon = south $ degree 23.5
--   </pre>
south :: Angle -> Latitude

-- | The latitude of equator.
equator :: Latitude

-- | The latitude corresponding to the Tropic of Cancer.
tropicOfCancer :: Latitude

-- | The latitude corresponding to the Tropic of Capricon
tropicOfCapricon :: Latitude

-- | The longitude of a point. Positive denotes East of the Greenwich
--   meridian where as negative denotes West.
data Longitude

-- | Convert angles to longitude.
lon :: Angle -> Longitude

-- | Convert angle to an eastern longitude.
--   
--   <pre>
--   kanpurLongitude = east $ degree 80.3461
--   </pre>
east :: Angle -> Longitude

-- | Convert angle to a western longitude
--   
--   <pre>
--   newyorkLongitude = west $ degree 74.0059
--   </pre>
west :: Angle -> Longitude

-- | The zero longitude.
greenwich :: Longitude

-- | An abstract angle. Internally, angles are represented as a 64-bit
--   integer with each unit contribute 1/2^64 fraction of a complete
--   circle. This means that angles are accurate up to a resolution of 2 π
--   / 2^64 radians. Angles form a group under the angular addition and the
--   fact that these are represented as integers means one can expect high
--   speed accurate angle arithmetic.
--   
--   When expressing angles one can use a more convenient notation:
--   
--   <pre>
--   myAngle   = degree 21.71167
--   yourAngle = degree 21 &lt;&gt; minute 42 &lt;&gt; second 42
--   </pre>
data Angle

-- | Express angle in degrees.
degree :: Rational -> Angle

-- | Express angle in minutes.
minute :: Rational -> Angle

-- | Express angle in seconds.
second :: Rational -> Angle

-- | Express angle in radians
radian :: Double -> Angle

-- | Measure angle in degrees. This conversion may lead to loss of
--   precision.
toDegree :: Fractional r => Angle -> r

-- | Measure angle in radians. This conversion may lead to loss of
--   precision.
toRadian :: Angle -> Double

-- | Angular quantities.
class Angular a
toAngle :: Angular a => a -> Angle


-- | Naqsha library version.
module Naqsha.Version

-- | The naqsha library version
version :: Version

-- | The version string associated with naqsha.
versionString :: String
