Copyright | (c) Azavea, 2016 |
---|---|
License | Apache 2 |
Maintainer | Colin Woodbury <cwoodbury@azavea.com> |
Safe Haskell | None |
Language | Haskell2010 |
GIS Vector Tiles, as defined by Mapbox.
This library implements version 2.1 of the official Mapbox spec, as defined here: https://github.com/mapbox/vector-tile-spec/tree/master/2.1
Note that currently this library ignores top-level protobuf extensions, Value extensions, and UNKNOWN geometries.
The order in which to explore the modules of this library is as follows:
Usage
This library reads and writes strict ByteString
s. Given some legal
VectorTile file called roads.mvt
:
import qualified Data.ByteString as BS import Data.Text (Text) import Geography.VectorTile import qualified Geography.VectorTile.Raw as R -- | Read in raw protobuf data and decode it into a high-level type. roads :: IO (Either Text VectorTile) roads = do mvt <- BS.readFile "roads.mvt" pure $ R.decode mvt >>= tile
Or encode a VectorTile
back into a ByteString
:
roadsBytes :: VectorTile -> BS.ByteString roadsBytes = R.encode . untile
- newtype VectorTile = VectorTile {}
- data Layer = Layer {}
- data Feature g = Feature {
- _featureId :: Int
- _metadata :: Map Text Val
- _geometries :: Vector g
- data Val
- tile :: RawVectorTile -> Either Text VectorTile
- layer :: RawLayer -> Either Text Layer
- features :: [Text] -> [RawVal] -> [RawFeature] -> Either Text (Vector (Feature Point), Vector (Feature LineString), Vector (Feature Polygon))
- value :: RawVal -> Either Text Val
- untile :: VectorTile -> RawVectorTile
- unlayer :: Layer -> RawLayer
- unfeature :: Geom g => [Text] -> [Val] -> Feature g -> RawFeature
- unval :: Val -> RawVal
- layers :: Functor f => (Vector Layer -> f (Vector Layer)) -> VectorTile -> f VectorTile
- version :: Functor f => (Layer -> f Int) -> Layer -> f Layer
- name :: Functor f => (Layer -> f Text) -> Layer -> f Layer
- points :: Functor f => (Layer -> f (Vector (Feature Point))) -> Layer -> f Layer
- linestrings :: Functor f => (Layer -> f (Vector (Feature LineString))) -> Layer -> f Layer
- polygons :: Functor f => (Layer -> f (Vector (Feature Polygon))) -> Layer -> f Layer
- extent :: Functor f => (Layer -> f Int) -> Layer -> f Layer
- featureId :: Functor f => (Feature g -> f Int) -> Feature g -> f (Feature g)
- metadata :: Functor f => (Feature g -> f (Map Text Val)) -> Feature g -> f (Feature g)
- geometries :: Functor f => (Feature g -> f (Vector g)) -> Feature g -> f (Feature g)
Types
newtype VectorTile Source #
A layer, which could contain any number of Feature
s of any Geometry
type.
This codec only respects the canonical three Geometry
types, and we split
them here explicitely to allow for more fine-grained access to each type.
A geographic feature. Features are a set of geometries that share some common theme:
- Points: schools, gas station locations, etc.
- LineStrings: Roads, power lines, rivers, etc.
- Polygons: Buildings, water bodies, etc.
Where, for instance, all school locations may be stored as a single
Feature
, and no Point
within that Feature
would represent anything
else.
Note: Each Geometry
type and their Multi* counterpart are considered
the same thing, as a Vector
of that Geometry
.
Feature | |
|
Legal Metadata Value types. Note that S64
are Z-encoded automatically
by the underlying Data.ProtocolBuffers library.
Protobuf Conversions
From Protobuf
Generally the tile
function is the only one needed here. Usage:
import qualified Geography.VectorTile.Raw as R R.decode someBytes >>= tile
Note that since the Data.ProtocolBuffers library does not handle default values, we handle those specifically defined in vector_tile.proto explicitely here. See:
https://github.com/mapbox/vector-tile-spec/blob/master/2.1/vector_tile.proto
tile :: RawVectorTile -> Either Text VectorTile Source #
Convert a RawVectorTile
of parsed protobuf data into a useable
VectorTile
.
features :: [Text] -> [RawVal] -> [RawFeature] -> Either Text (Vector (Feature Point), Vector (Feature LineString), Vector (Feature Polygon)) Source #
Convert a list of RawFeature
s of parsed protobuf data into Vector
s
of each of the three legal Geometry
types.
The long type signature is due to two things:
Feature
s are polymorphic at the high level, but not at the parsed protobuf mid-level. In a[RawFeature]
, there are features of points, linestrings, and polygons all mixed together.RawLayer
s andRawFeature
s are strongly coupled at the protobuf level. In order to achieve higher compression ratios,RawLayer
s contain all metadata in key/value lists to be shared across theirRawFeature
s, while thoseRawFeature
s store only indices into those lists. As a result, this function needs to be passed those key/value lists from the parentRawLayer
, and a more isomorphic:
feature :: Geometry g => RawFeature -> Either Text (Feature g)
is not possible.
To Protobuf
To convert from high-level data back into a form that can be encoded into raw protobuf bytes, use:
import qualified Geography.VectorTile.Raw as R R.encode $ untile someTile
This is a pure process and will succeed every time.
untile :: VectorTile -> RawVectorTile Source #
Encode a high-level VectorTile
back into its mid-level
RawVectorTile
form.
unfeature :: Geom g => [Text] -> [Val] -> Feature g -> RawFeature Source #
Encode a high-level Feature
back into its mid-level RawFeature
form.
Lenses
This section can be safely ignored if one isn't concerned with lenses. Otherwise, see the following for a good primer on Haskell lenses: http://hackage.haskell.org/package/lens-tutorial-1.0.1/docs/Control-Lens-Tutorial.html
These lenses are written in a generic way to avoid taking a dependency on one of the lens libraries.
layers :: Functor f => (Vector Layer -> f (Vector Layer)) -> VectorTile -> f VectorTile Source #
Lens' VectorTile (Vector Layer)
points :: Functor f => (Layer -> f (Vector (Feature Point))) -> Layer -> f Layer Source #
Lens' Layer (Vector (Feature Point))
linestrings :: Functor f => (Layer -> f (Vector (Feature LineString))) -> Layer -> f Layer Source #
Lens' Layer (Vector (Feature LineString)))
polygons :: Functor f => (Layer -> f (Vector (Feature Polygon))) -> Layer -> f Layer Source #
Lens' Layer (Vector (Feature Polygon)))
featureId :: Functor f => (Feature g -> f Int) -> Feature g -> f (Feature g) Source #
Lens' (Feature g) Int