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


-- | GIS Vector Tiles, as defined by Mapbox.
--   
--   GIS Vector Tiles, as defined by Mapbox. This library implements
--   version 2.1 of the official Mapbox spec, as defined here:
--   <a>https://github.com/mapbox/vector-tile-spec/tree/master/2.1</a>
--   
--   Note that currently this library ignores top-level protobuf
--   extensions, <i>Value</i> extensions, and <i>UNKNOWN</i> geometries.
@package vectortiles
@version 1.3.0


-- | Raw Vector Tile data is stored as binary protobuf data. This module
--   reads and writes raw protobuf ByteStrings between a data type which
--   closely matches the current Mapbox vector tile spec defined here:
--   <a>https://github.com/mapbox/vector-tile-spec/blob/master/2.1/vector_tile.proto</a>
--   
--   As this raw version of the data is hard to work with, in practice we
--   convert to a more canonical Haskell type for further processing. See
--   <a>Geography.VectorTile</a> for the user-friendly version.
module Geography.VectorTile.Internal

-- | A family of data types which can associated with concrete underlying
--   Protobuf types.

-- | A type which can be converted to and from an underlying Protobuf type,
--   according to the <a>Protobuf</a> type family.
class Protobuffable a
fromProtobuf :: Protobuffable a => Protobuf a -> Either Text a
toProtobuf :: Protobuffable a => a -> Protobuf a

-- | Any classical type considered a GIS "geometry". These must be able to
--   convert between an encodable list of <a>Command</a>s.
class ProtobufGeom g
fromCommands :: ProtobufGeom g => Seq Command -> Either Text (Seq g)
toCommands :: ProtobufGeom g => Seq g -> Seq Command
data Tile
Tile :: !(Seq Layer) -> !(ExtField) -> Tile
data Layer
Layer :: !(Word32) -> !(Utf8) -> !(Seq Feature) -> !(Seq Utf8) -> !(Seq Value) -> !(Maybe Word32) -> !(ExtField) -> Layer
data Feature
Feature :: !(Maybe Word64) -> !(Seq Word32) -> !(Maybe GeomType) -> !(Seq Word32) -> Feature
[id] :: Feature -> !(Maybe Word64)
[tags] :: Feature -> !(Seq Word32)
[type'] :: Feature -> !(Maybe GeomType)
[geometry] :: Feature -> !(Seq Word32)
data Value
Value :: !(Maybe Utf8) -> !(Maybe Float) -> !(Maybe Double) -> !(Maybe Int64) -> !(Maybe Word64) -> !(Maybe Int64) -> !(Maybe Bool) -> !(ExtField) -> Value
[string_value] :: Value -> !(Maybe Utf8)
[float_value] :: Value -> !(Maybe Float)
[double_value] :: Value -> !(Maybe Double)
[int_value] :: Value -> !(Maybe Int64)
[uint_value] :: Value -> !(Maybe Word64)
[sint_value] :: Value -> !(Maybe Int64)
[bool_value] :: Value -> !(Maybe Bool)
[ext'field] :: Value -> !(ExtField)
data GeomType
UNKNOWN :: GeomType
POINT :: GeomType
LINESTRING :: GeomType
POLYGON :: GeomType

-- | The possible commands, and the values they hold.
data Command
MoveTo :: (Seq (Int, Int)) -> Command
LineTo :: (Seq (Int, Int)) -> Command
ClosePath :: Command

-- | Attempt to parse a list of Command/Parameter integers, as defined
--   here:
--   
--   
--   <a>https://github.com/mapbox/vector-tile-spec/tree/master/2.1#43-geometry-encoding</a>
commands :: Seq Word32 -> Either Text (Seq Command)

-- | Convert a list of parsed <a>Command</a>s back into their original
--   Command and Z-encoded Parameter integer forms.
uncommands :: Seq Command -> Seq Word32

-- | Z-encode a 64-bit Int.
zig :: Int -> Word32

-- | Decode a Z-encoded Word32 into a 64-bit Int.
unzig :: Word32 -> Int

-- | Convert a list of <tt>RawFeature</tt>s of parsed protobuf data into
--   <a>Vector</a>s of each of the three legal <a>ProtobufGeom</a> types.
--   
--   The long type signature is due to two things:
--   
--   <ol>
--   <li><tt>Feature</tt>s are polymorphic at the high level, but not at
--   the parsed protobuf mid-level. In a <tt>[RawFeature]</tt>, there are
--   features of points, linestrings, and polygons all mixed together.</li>
--   <li><tt>RawLayer</tt>s and <tt>RawFeature</tt>s are strongly coupled
--   at the protobuf level. In order to achieve higher compression ratios,
--   <tt>RawLayer</tt>s contain all metadata in key/value lists to be
--   shared across their <tt>RawFeature</tt>s, while those
--   <tt>RawFeature</tt>s store only indices into those lists. As a result,
--   this function needs to be passed those key/value lists from the parent
--   <tt>RawLayer</tt>, and a more isomorphic:</li>
--   </ol>
--   
--   <pre>
--   feature :: ProtobufGeom g =&gt; RawFeature -&gt; Either Text (Feature g)
--   </pre>
--   
--   is not possible.
feats :: Seq ByteString -> Seq Value -> Seq Feature -> Either Text (Seq (Feature Point), Seq (Feature LineString), Seq (Feature Polygon))

-- | Encode a high-level <tt>Feature</tt> back into its mid-level
--   <tt>RawFeature</tt> form.
unfeats :: ProtobufGeom g => HashMap ByteString Int -> HashMap Val Int -> GeomType -> Feature g -> Feature
instance GHC.Show.Show Geography.VectorTile.Internal.Command
instance GHC.Classes.Eq Geography.VectorTile.Internal.Command
instance Geography.VectorTile.Internal.ProtobufGeom Geography.VectorTile.Geometry.Point
instance Geography.VectorTile.Internal.ProtobufGeom Geography.VectorTile.Geometry.LineString
instance Geography.VectorTile.Internal.ProtobufGeom Geography.VectorTile.Geometry.Polygon
instance Geography.VectorTile.Internal.Protobuffable Geography.VectorTile.VectorTile.VectorTile
instance Geography.VectorTile.Internal.Protobuffable Geography.VectorTile.VectorTile.Layer
instance Geography.VectorTile.Internal.Protobuffable Geography.VectorTile.VectorTile.Val


-- | GIS Vector Tiles, as defined by Mapbox.
--   
--   This library implements version 2.1 of the official Mapbox spec, as
--   defined here:
--   <a>https://github.com/mapbox/vector-tile-spec/tree/master/2.1</a>
--   
--   Note that currently this library ignores top-level protobuf
--   extensions, <i>Value</i> extensions, and <i>UNKNOWN</i> geometries.
--   
--   <h2>Usage</h2>
--   
--   This library reads and writes strict <a>ByteString</a>s. Given some
--   legal VectorTile file called <tt>roads.mvt</tt>:
--   
--   <pre>
--   import qualified Data.ByteString as BS
--   import           Data.Text (Text)
--   import           Geography.VectorTile
--   
--   -- | Read in raw protobuf data and decode it into a high-level type.
--   roads :: IO (Either Text VectorTile)
--   roads = tile &lt;$&gt; BS.readFile "roads.mvt"
--   </pre>
--   
--   Likewise, use the <a>untile</a> function to convert a
--   <a>VectorTile</a> back into a <tt>ByteString</tt>.
module Geography.VectorTile

-- | A high-level representation of a Vector Tile. Implemented internally
--   as a <a>HashMap</a>, so that access to individual layers can be fast
--   if you know the layer names ahead of time.
--   
--   The layer name itself, a lazy <a>ByteString</a>, is guaranteed to be
--   UTF-8. If you wish to convert it to <a>Text</a>, consider
--   <a>decodeUtf8</a>.
newtype VectorTile
VectorTile :: HashMap ByteString Layer -> VectorTile
[_layers] :: VectorTile -> HashMap ByteString Layer

-- | Attempt to parse a <a>VectorTile</a> from a strict collection of
--   bytes.
tile :: ByteString -> Either Text VectorTile

-- | Convert a <a>VectorTile</a> back into bytes.
untile :: VectorTile -> ByteString

-- | Simple Lenses compatible with both lens and microlens.
type Lens' s a = forall f. Functor f => (a -> f a) -> s -> f s
layers :: Lens' VectorTile (HashMap ByteString Layer)

-- | A layer, which could contain any number of <a>Feature</a>s of any
--   <tt>Geometry</tt> type. This codec only respects the canonical three
--   <tt>Geometry</tt> types, and we split them here explicitely to allow
--   for more fine-grained access to each type.
data Layer
Layer :: Word -> ByteString -> Seq (Feature Point) -> Seq (Feature LineString) -> Seq (Feature Polygon) -> Word -> Layer

-- | The version of the spec we follow. Should always be 2.
[_version] :: Layer -> Word
[_name] :: Layer -> ByteString
[_points] :: Layer -> Seq (Feature Point)
[_linestrings] :: Layer -> Seq (Feature LineString)
[_polygons] :: Layer -> Seq (Feature Polygon)

-- | Default: 4096
[_extent] :: Layer -> Word
version :: Lens' Layer Word
name :: Lens' Layer ByteString
points :: Lens' Layer (Seq (Feature Point))
linestrings :: Lens' Layer (Seq (Feature LineString))
polygons :: Lens' Layer (Seq (Feature Polygon))
extent :: Lens' Layer Word

-- | A geographic feature. Features are a set of geometries that share some
--   common theme:
--   
--   <ul>
--   <li>Points: schools, gas station locations, etc.</li>
--   <li>LineStrings: Roads, power lines, rivers, etc.</li>
--   <li>Polygons: Buildings, water bodies, etc.</li>
--   </ul>
--   
--   Where, for instance, all school locations may be stored as a single
--   <a>Feature</a>, and no <a>Point</a> within that <a>Feature</a> would
--   represent anything else.
--   
--   Note: Each <tt>Geometry</tt> type and their <i>Multi*</i> counterpart
--   are considered the same thing, as a <a>Vector</a> of that
--   <tt>Geometry</tt>.
--   
--   Note: The keys to the metadata are <a>ByteString</a>, but are
--   guaranteed to be UTF-8.
data Feature g
Feature :: Word -> HashMap ByteString Val -> Seq g -> Feature g

-- | Default: 0
[_featureId] :: Feature g -> Word
[_metadata] :: Feature g -> HashMap ByteString Val
[_geometries] :: Feature g -> Seq g
featureId :: Lens' (Feature g) Word
metadata :: Lens' (Feature g) (HashMap ByteString Val)
geometries :: Lens' (Feature g) (Seq g)

-- | Legal Metadata <i>Value</i> types. Note that <a>S64</a> are Z-encoded
--   automatically by the underlying <a>Text.ProtocolBuffers</a> library.
data Val
St :: ByteString -> Val
Fl :: Float -> Val
Do :: Double -> Val
I64 :: Int64 -> Val
W64 :: Word64 -> Val
S64 :: Int64 -> Val
B :: Bool -> Val

-- | Points in space. Using "Record Pattern Synonyms" here allows us to
--   treat <a>Point</a> like a normal ADT, while its implementation remains
--   an unboxed <tt>(Int,Int)</tt>.
type Point = (Int, Int)
x :: (Int, Int) -> Int
y :: (Int, Int) -> Int

-- | <i>newtype</i> compiles away to expose only the <a>Vector</a> of
--   unboxed <a>Point</a>s at runtime.
newtype LineString
LineString :: Vector Point -> LineString
[lsPoints] :: LineString -> Vector Point

-- | A polygon aware of its interior rings.
--   
--   VectorTiles require that Polygon exteriors have clockwise winding
--   order, and that interior holes have counter-clockwise winding order.
--   These assume that the origin (0,0) is in the *top-left* corner.
data Polygon
Polygon :: Vector Point -> Seq Polygon -> Polygon
[polyPoints] :: Polygon -> Vector Point
[inner] :: Polygon -> Seq Polygon

-- | The area of a <a>Polygon</a> is the difference between the areas of
--   its outer ring and inner rings.
area :: Polygon -> Double

-- | The surveyor's formula for calculating the area of a <a>Polygon</a>.
--   If the value reported here is negative, then the <a>Polygon</a> should
--   be considered an Interior Ring.
--   
--   Assumption: The <a>Vector</a> given has at least 4 <a>Point</a>s.
surveyor :: Vector Point -> Double

-- | Euclidean distance.
distance :: Point -> Point -> Double
