{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} ------------------------------------------------------------------- -- | -- Module : Data.Geospatial.Internal.GeoFeature -- Copyright : (C) 2014-2018 HS-GeoJSON Project -- License : BSD-style (see the file LICENSE.md) -- Maintainer : Andrew Newman -- -- See Section 2.3 /Feature Collection Objects/ of the GeoJSON spec -- ------------------------------------------------------------------- module Data.Geospatial.Internal.GeoFeatureCollection ( -- * Types GeoFeatureCollection(..) -- * Lenses , boundingbox , geofeatures ) where import Data.Geospatial.Internal.BasicTypes import Data.Geospatial.Internal.GeoFeature import Data.Geospatial.Internal.Geometry.Aeson import Control.Applicative ((<$>), (<*>)) import Control.Lens (makeLenses) import Control.Monad (mzero) import Data.Aeson (FromJSON (..), ToJSON (..), Value (..), object, (.:), (.:?), (.=)) import Data.List ((++)) import Data.Maybe (Maybe (..)) import Data.Text (Text) import Prelude (Eq (..), Show, ($)) -- | See Section 2.3 /Feature Collection Objects/ of the GeoJSON spec -- data GeoFeatureCollection a = GeoFeatureCollection { _boundingbox :: Maybe BoundingBoxWithoutCRS , _geofeatures :: [GeoFeature a] } deriving (Show, Eq) makeLenses ''GeoFeatureCollection -- instances -- | Decode FeatureCollection objects from GeoJSON -- instance (FromJSON a) => FromJSON (GeoFeatureCollection a) where -- parseJSON :: Value -> Parse a parseJSON (Object obj) = do objType <- obj .: ("type" :: Text) if objType /= ("FeatureCollection" :: Text) then mzero else GeoFeatureCollection <$> obj .:? ("bbox" :: Text) <*> obj .: ("features" :: Text) parseJSON _ = mzero -- | Encode FeatureCollection objects to GeoJSON -- instance (ToJSON a) => ToJSON (GeoFeatureCollection a) where -- toJSON :: a -> Value toJSON (GeoFeatureCollection bbox' features) = object $ baseAttributes ++ optAttributes "bbox" bbox' where baseAttributes = ["type" .= ("FeatureCollection" :: Text), "features" .= features]