geojson 1.3.3 → 2.0.0
raw patch · 22 files changed
+706/−347 lines, 22 filesdep +deepseqdep ~basePVP ok
version bump matches the API change (PVP)
Dependencies added: deepseq
Dependency ranges changed: base
API changes (from Hackage documentation)
- Data.Geospatial: type BoundingBoxWithoutCRS = [Double]
- Data.Geospatial: type GeoPositionWithoutCRS = [Double]
- Data.Geospatial.Internal.BasicTypes: type BoundingBoxWithoutCRS = [Double]
- Data.Geospatial.Internal.BasicTypes: type GeoPositionWithoutCRS = [Double]
- Data.LineString: instance (Data.Aeson.Types.FromJSON.FromJSON a, GHC.Show.Show a) => Data.Aeson.Types.FromJSON.FromJSON (Data.LineString.LineString a)
- Data.LineString: instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Data.LineString.LineString a)
- Data.LineString: instance Data.Foldable.Foldable Data.LineString.LineString
- Data.LineString: instance Data.Traversable.Traversable Data.LineString.LineString
- Data.LineString: instance GHC.Base.Functor Data.LineString.LineString
- Data.LineString: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.LineString.LineString a)
- Data.LineString: instance GHC.Show.Show a => GHC.Show.Show (Data.LineString.LineString a)
- Data.LinearRing: instance (Data.Aeson.Types.FromJSON.FromJSON a, GHC.Show.Show a) => Data.Aeson.Types.FromJSON.FromJSON (Data.LinearRing.LinearRing a)
- Data.LinearRing: instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Data.LinearRing.LinearRing a)
- Data.LinearRing: instance Data.Foldable.Foldable Data.LinearRing.LinearRing
- Data.LinearRing: instance Data.Traversable.Traversable Data.LinearRing.LinearRing
- Data.LinearRing: instance GHC.Base.Functor Data.LinearRing.LinearRing
- Data.LinearRing: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.LinearRing.LinearRing a)
- Data.LinearRing: instance GHC.Show.Show a => GHC.Show.Show (Data.LinearRing.LinearRing a)
- Data.LinearRing: instance GHC.Show.Show a => GHC.Show.Show (Data.LinearRing.ListToLinearRingError a)
+ Data.Geospatial: GeoEmpty :: GeoPositionWithoutCRS
+ Data.Geospatial: GeoPointXY :: PointXY -> GeoPositionWithoutCRS
+ Data.Geospatial: GeoPointXYZ :: PointXYZ -> GeoPositionWithoutCRS
+ Data.Geospatial: GeoPointXYZM :: PointXYZM -> GeoPositionWithoutCRS
+ Data.Geospatial: PointXY :: !Double -> !Double -> PointXY
+ Data.Geospatial: PointXYZ :: !Double -> !Double -> !Double -> PointXYZ
+ Data.Geospatial: PointXYZM :: !Double -> !Double -> !Double -> !Double -> PointXYZM
+ Data.Geospatial: [_xyX] :: PointXY -> !Double
+ Data.Geospatial: [_xyY] :: PointXY -> !Double
+ Data.Geospatial: [_xyzX] :: PointXYZ -> !Double
+ Data.Geospatial: [_xyzY] :: PointXYZ -> !Double
+ Data.Geospatial: [_xyzZ] :: PointXYZ -> !Double
+ Data.Geospatial: [_xyzmM] :: PointXYZM -> !Double
+ Data.Geospatial: [_xyzmX] :: PointXYZM -> !Double
+ Data.Geospatial: [_xyzmY] :: PointXYZM -> !Double
+ Data.Geospatial: [_xyzmZ] :: PointXYZM -> !Double
+ Data.Geospatial: class HasGeoPositionWithoutCRS c_aotb
+ Data.Geospatial: data BoundingBoxWithoutCRS
+ Data.Geospatial: data GeoPositionWithoutCRS
+ Data.Geospatial: data PointXY
+ Data.Geospatial: data PointXYZ
+ Data.Geospatial: data PointXYZM
+ Data.Geospatial: geoPositionWithoutCRS :: HasGeoPositionWithoutCRS c_aotb => Lens' c_aotb GeoPositionWithoutCRS
+ Data.Geospatial: reWrapGeometry :: GeoFeature a -> GeospatialGeometry -> GeoFeature a
+ Data.Geospatial: retrieveXY :: GeoPositionWithoutCRS -> PointXY
+ Data.Geospatial: unBoundingBoxWithoutCrs :: BoundingBoxWithoutCRS -> Vector Double
+ Data.Geospatial.Internal.BasicTypes: BoundingBoxWithoutCRS :: Vector Double -> BoundingBoxWithoutCRS
+ Data.Geospatial.Internal.BasicTypes: DoubleArray :: [Double] -> DoubleArray
+ Data.Geospatial.Internal.BasicTypes: GeoEmpty :: GeoPositionWithoutCRS
+ Data.Geospatial.Internal.BasicTypes: GeoPointXY :: PointXY -> GeoPositionWithoutCRS
+ Data.Geospatial.Internal.BasicTypes: GeoPointXYZ :: PointXYZ -> GeoPositionWithoutCRS
+ Data.Geospatial.Internal.BasicTypes: GeoPointXYZM :: PointXYZM -> GeoPositionWithoutCRS
+ Data.Geospatial.Internal.BasicTypes: PointXY :: !Double -> !Double -> PointXY
+ Data.Geospatial.Internal.BasicTypes: PointXYZ :: !Double -> !Double -> !Double -> PointXYZ
+ Data.Geospatial.Internal.BasicTypes: PointXYZM :: !Double -> !Double -> !Double -> !Double -> PointXYZM
+ Data.Geospatial.Internal.BasicTypes: [_xyX] :: PointXY -> !Double
+ Data.Geospatial.Internal.BasicTypes: [_xyY] :: PointXY -> !Double
+ Data.Geospatial.Internal.BasicTypes: [_xyzX] :: PointXYZ -> !Double
+ Data.Geospatial.Internal.BasicTypes: [_xyzY] :: PointXYZ -> !Double
+ Data.Geospatial.Internal.BasicTypes: [_xyzZ] :: PointXYZ -> !Double
+ Data.Geospatial.Internal.BasicTypes: [_xyzmM] :: PointXYZM -> !Double
+ Data.Geospatial.Internal.BasicTypes: [_xyzmX] :: PointXYZM -> !Double
+ Data.Geospatial.Internal.BasicTypes: [_xyzmY] :: PointXYZM -> !Double
+ Data.Geospatial.Internal.BasicTypes: [_xyzmZ] :: PointXYZM -> !Double
+ Data.Geospatial.Internal.BasicTypes: [unBoundingBoxWithoutCrs] :: BoundingBoxWithoutCRS -> Vector Double
+ Data.Geospatial.Internal.BasicTypes: class HasGeoPositionWithoutCRS c_aotb
+ Data.Geospatial.Internal.BasicTypes: data GeoPositionWithoutCRS
+ Data.Geospatial.Internal.BasicTypes: data PointXY
+ Data.Geospatial.Internal.BasicTypes: data PointXYZ
+ Data.Geospatial.Internal.BasicTypes: data PointXYZM
+ Data.Geospatial.Internal.BasicTypes: geoPositionWithoutCRS :: HasGeoPositionWithoutCRS c_aotb => Lens' c_aotb GeoPositionWithoutCRS
+ Data.Geospatial.Internal.BasicTypes: instance Control.DeepSeq.NFData Data.Geospatial.Internal.BasicTypes.BoundingBoxWithoutCRS
+ Data.Geospatial.Internal.BasicTypes: instance Control.DeepSeq.NFData Data.Geospatial.Internal.BasicTypes.DoubleArray
+ Data.Geospatial.Internal.BasicTypes: instance Control.DeepSeq.NFData Data.Geospatial.Internal.BasicTypes.FeatureID
+ Data.Geospatial.Internal.BasicTypes: instance Control.DeepSeq.NFData Data.Geospatial.Internal.BasicTypes.GeoPositionWithoutCRS
+ Data.Geospatial.Internal.BasicTypes: instance Control.DeepSeq.NFData Data.Geospatial.Internal.BasicTypes.PointXY
+ Data.Geospatial.Internal.BasicTypes: instance Control.DeepSeq.NFData Data.Geospatial.Internal.BasicTypes.PointXYZ
+ Data.Geospatial.Internal.BasicTypes: instance Control.DeepSeq.NFData Data.Geospatial.Internal.BasicTypes.PointXYZM
+ Data.Geospatial.Internal.BasicTypes: instance Data.Aeson.Types.FromJSON.FromJSON Data.Geospatial.Internal.BasicTypes.BoundingBoxWithoutCRS
+ Data.Geospatial.Internal.BasicTypes: instance Data.Aeson.Types.FromJSON.FromJSON Data.Geospatial.Internal.BasicTypes.DoubleArray
+ Data.Geospatial.Internal.BasicTypes: instance Data.Aeson.Types.FromJSON.FromJSON Data.Geospatial.Internal.BasicTypes.GeoPositionWithoutCRS
+ Data.Geospatial.Internal.BasicTypes: instance Data.Aeson.Types.ToJSON.ToJSON Data.Geospatial.Internal.BasicTypes.BoundingBoxWithoutCRS
+ Data.Geospatial.Internal.BasicTypes: instance Data.Aeson.Types.ToJSON.ToJSON Data.Geospatial.Internal.BasicTypes.DoubleArray
+ Data.Geospatial.Internal.BasicTypes: instance Data.Aeson.Types.ToJSON.ToJSON Data.Geospatial.Internal.BasicTypes.GeoPositionWithoutCRS
+ Data.Geospatial.Internal.BasicTypes: instance Data.Geospatial.Internal.BasicTypes.HasGeoPositionWithoutCRS Data.Geospatial.Internal.BasicTypes.GeoPositionWithoutCRS
+ Data.Geospatial.Internal.BasicTypes: instance Foreign.Storable.Storable Data.Geospatial.Internal.BasicTypes.GeoPositionWithoutCRS
+ Data.Geospatial.Internal.BasicTypes: instance Foreign.Storable.Storable Data.Geospatial.Internal.BasicTypes.PointXY
+ Data.Geospatial.Internal.BasicTypes: instance GHC.Classes.Eq Data.Geospatial.Internal.BasicTypes.BoundingBoxWithoutCRS
+ Data.Geospatial.Internal.BasicTypes: instance GHC.Classes.Eq Data.Geospatial.Internal.BasicTypes.DoubleArray
+ Data.Geospatial.Internal.BasicTypes: instance GHC.Classes.Eq Data.Geospatial.Internal.BasicTypes.GeoPositionWithoutCRS
+ Data.Geospatial.Internal.BasicTypes: instance GHC.Classes.Eq Data.Geospatial.Internal.BasicTypes.PointXY
+ Data.Geospatial.Internal.BasicTypes: instance GHC.Classes.Eq Data.Geospatial.Internal.BasicTypes.PointXYZ
+ Data.Geospatial.Internal.BasicTypes: instance GHC.Classes.Eq Data.Geospatial.Internal.BasicTypes.PointXYZM
+ Data.Geospatial.Internal.BasicTypes: instance GHC.Generics.Generic Data.Geospatial.Internal.BasicTypes.BoundingBoxWithoutCRS
+ Data.Geospatial.Internal.BasicTypes: instance GHC.Generics.Generic Data.Geospatial.Internal.BasicTypes.DoubleArray
+ Data.Geospatial.Internal.BasicTypes: instance GHC.Generics.Generic Data.Geospatial.Internal.BasicTypes.FeatureID
+ Data.Geospatial.Internal.BasicTypes: instance GHC.Generics.Generic Data.Geospatial.Internal.BasicTypes.GeoPositionWithoutCRS
+ Data.Geospatial.Internal.BasicTypes: instance GHC.Generics.Generic Data.Geospatial.Internal.BasicTypes.PointXY
+ Data.Geospatial.Internal.BasicTypes: instance GHC.Generics.Generic Data.Geospatial.Internal.BasicTypes.PointXYZ
+ Data.Geospatial.Internal.BasicTypes: instance GHC.Generics.Generic Data.Geospatial.Internal.BasicTypes.PointXYZM
+ Data.Geospatial.Internal.BasicTypes: instance GHC.Show.Show Data.Geospatial.Internal.BasicTypes.BoundingBoxWithoutCRS
+ Data.Geospatial.Internal.BasicTypes: instance GHC.Show.Show Data.Geospatial.Internal.BasicTypes.DoubleArray
+ Data.Geospatial.Internal.BasicTypes: instance GHC.Show.Show Data.Geospatial.Internal.BasicTypes.GeoPositionWithoutCRS
+ Data.Geospatial.Internal.BasicTypes: instance GHC.Show.Show Data.Geospatial.Internal.BasicTypes.PointXY
+ Data.Geospatial.Internal.BasicTypes: instance GHC.Show.Show Data.Geospatial.Internal.BasicTypes.PointXYZ
+ Data.Geospatial.Internal.BasicTypes: instance GHC.Show.Show Data.Geospatial.Internal.BasicTypes.PointXYZM
+ Data.Geospatial.Internal.BasicTypes: newtype BoundingBoxWithoutCRS
+ Data.Geospatial.Internal.BasicTypes: newtype DoubleArray
+ Data.Geospatial.Internal.BasicTypes: retrieveXY :: GeoPositionWithoutCRS -> PointXY
+ Data.Geospatial.Internal.GeoFeature: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Geospatial.Internal.GeoFeature.GeoFeature a)
+ Data.Geospatial.Internal.GeoFeature: instance GHC.Generics.Generic (Data.Geospatial.Internal.GeoFeature.GeoFeature a)
+ Data.Geospatial.Internal.GeoFeature: reWrapGeometry :: GeoFeature a -> GeospatialGeometry -> GeoFeature a
+ Data.Geospatial.Internal.Geometry: instance Control.DeepSeq.NFData Data.Geospatial.Internal.Geometry.GeospatialGeometry
+ Data.Geospatial.Internal.Geometry: instance GHC.Generics.Generic Data.Geospatial.Internal.Geometry.GeospatialGeometry
+ Data.Geospatial.Internal.Geometry: retrieveXY :: GeoPositionWithoutCRS -> PointXY
+ Data.Geospatial.Internal.Geometry.GeoLine: instance Control.DeepSeq.NFData Data.Geospatial.Internal.Geometry.GeoLine.GeoLine
+ Data.Geospatial.Internal.Geometry.GeoLine: instance GHC.Generics.Generic Data.Geospatial.Internal.Geometry.GeoLine.GeoLine
+ Data.Geospatial.Internal.Geometry.GeoMultiLine: instance Control.DeepSeq.NFData Data.Geospatial.Internal.Geometry.GeoMultiLine.GeoMultiLine
+ Data.Geospatial.Internal.Geometry.GeoMultiLine: instance GHC.Generics.Generic Data.Geospatial.Internal.Geometry.GeoMultiLine.GeoMultiLine
+ Data.Geospatial.Internal.Geometry.GeoMultiPoint: instance Control.DeepSeq.NFData Data.Geospatial.Internal.Geometry.GeoMultiPoint.GeoMultiPoint
+ Data.Geospatial.Internal.Geometry.GeoMultiPoint: instance GHC.Generics.Generic Data.Geospatial.Internal.Geometry.GeoMultiPoint.GeoMultiPoint
+ Data.Geospatial.Internal.Geometry.GeoMultiPolygon: instance Control.DeepSeq.NFData Data.Geospatial.Internal.Geometry.GeoMultiPolygon.GeoMultiPolygon
+ Data.Geospatial.Internal.Geometry.GeoMultiPolygon: instance GHC.Generics.Generic Data.Geospatial.Internal.Geometry.GeoMultiPolygon.GeoMultiPolygon
+ Data.Geospatial.Internal.Geometry.GeoPoint: instance Control.DeepSeq.NFData Data.Geospatial.Internal.Geometry.GeoPoint.GeoPoint
+ Data.Geospatial.Internal.Geometry.GeoPoint: instance GHC.Generics.Generic Data.Geospatial.Internal.Geometry.GeoPoint.GeoPoint
+ Data.Geospatial.Internal.Geometry.GeoPoint: retrieveXY :: GeoPositionWithoutCRS -> PointXY
+ Data.Geospatial.Internal.Geometry.GeoPolygon: instance Control.DeepSeq.NFData Data.Geospatial.Internal.Geometry.GeoPolygon.GeoPolygon
+ Data.Geospatial.Internal.Geometry.GeoPolygon: instance GHC.Generics.Generic Data.Geospatial.Internal.Geometry.GeoPolygon.GeoPolygon
+ Data.LineString: SingletonVector :: VectorToLineStringError
+ Data.LineString: VectorEmpty :: VectorToLineStringError
+ Data.LineString: combineToVector :: (Storable a, Storable b) => (a -> a -> b) -> LineString a -> Vector b
+ Data.LineString: data VectorToLineStringError
+ Data.LineString: foldMap :: (Monoid m, Storable a) => (a -> m) -> LineString a -> m
+ Data.LineString: foldr :: (Storable a) => (a -> b -> b) -> b -> LineString a -> b
+ Data.LineString: fromVector :: (Validate v, Storable a) => Vector a -> v VectorToLineStringError (LineString a)
+ Data.LineString: instance (Data.Aeson.Types.FromJSON.FromJSON a, GHC.Show.Show a, Foreign.Storable.Storable a) => Data.Aeson.Types.FromJSON.FromJSON (Data.LineString.LineString a)
+ Data.LineString: instance (Data.Aeson.Types.ToJSON.ToJSON a, Foreign.Storable.Storable a) => Data.Aeson.Types.ToJSON.ToJSON (Data.LineString.LineString a)
+ Data.LineString: instance (Foreign.Storable.Storable a, GHC.Classes.Eq a) => GHC.Classes.Eq (Data.LineString.LineString a)
+ Data.LineString: instance (GHC.Show.Show a, Foreign.Storable.Storable a) => GHC.Show.Show (Data.LineString.LineString a)
+ Data.LineString: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.LineString.LineString a)
+ Data.LineString: instance GHC.Classes.Eq Data.LineString.VectorToLineStringError
+ Data.LineString: instance GHC.Generics.Generic (Data.LineString.LineString a)
+ Data.LineString: instance GHC.Show.Show Data.LineString.VectorToLineStringError
+ Data.LineString: map :: (Storable a, Storable b) => (a -> b) -> LineString a -> LineString b
+ Data.LineString: toVector :: (Storable a) => LineString a -> Vector a
+ Data.LinearRing: FirstNotEqualToLast :: a -> a -> VectorToLinearRingError a
+ Data.LinearRing: VectorTooShort :: Int -> VectorToLinearRingError a
+ Data.LinearRing: combineToVector :: (Storable a, Storable b) => (a -> a -> b) -> LinearRing a -> Vector b
+ Data.LinearRing: data VectorToLinearRingError a
+ Data.LinearRing: foldMap :: (Monoid m, Storable a) => (a -> m) -> LinearRing a -> m
+ Data.LinearRing: foldr :: Storable a => (a -> b -> b) -> b -> LinearRing a -> b
+ Data.LinearRing: fromVector :: (Eq a, Show a, Storable a, Validate v, Functor (v (NonEmpty (ListToLinearRingError a)))) => Vector a -> v (NonEmpty (VectorToLinearRingError a)) (LinearRing a)
+ Data.LinearRing: instance (Data.Aeson.Types.ToJSON.ToJSON a, Foreign.Storable.Storable a) => Data.Aeson.Types.ToJSON.ToJSON (Data.LinearRing.LinearRing a)
+ Data.LinearRing: instance (Foreign.Storable.Storable a, GHC.Classes.Eq a) => GHC.Classes.Eq (Data.LinearRing.LinearRing a)
+ Data.LinearRing: instance (Foreign.Storable.Storable a, GHC.Show.Show a) => GHC.Show.Show (Data.LinearRing.LinearRing a)
+ Data.LinearRing: instance (GHC.Classes.Eq a, Data.Aeson.Types.FromJSON.FromJSON a, GHC.Show.Show a, Foreign.Storable.Storable a) => Data.Aeson.Types.FromJSON.FromJSON (Data.LinearRing.LinearRing a)
+ Data.LinearRing: instance (GHC.Show.Show a, Foreign.Storable.Storable a) => GHC.Show.Show (Data.LinearRing.ListToLinearRingError a)
+ Data.LinearRing: instance (GHC.Show.Show a, Foreign.Storable.Storable a) => GHC.Show.Show (Data.LinearRing.VectorToLinearRingError a)
+ Data.LinearRing: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.LinearRing.LinearRing a)
+ Data.LinearRing: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.LinearRing.VectorToLinearRingError a)
+ Data.LinearRing: instance GHC.Generics.Generic (Data.LinearRing.LinearRing a)
+ Data.LinearRing: map :: (Storable a, Storable b) => (a -> b) -> LinearRing a -> LinearRing b
+ Data.LinearRing: toVector :: (Storable a) => LinearRing a -> Vector a
- Data.Geospatial: Collection :: [GeospatialGeometry] -> GeospatialGeometry
+ Data.Geospatial: Collection :: (Vector GeospatialGeometry) -> GeospatialGeometry
- Data.Geospatial: GeoFeatureCollection :: Maybe BoundingBoxWithoutCRS -> [GeoFeature a] -> GeoFeatureCollection a
+ Data.Geospatial: GeoFeatureCollection :: Maybe BoundingBoxWithoutCRS -> Vector (GeoFeature a) -> GeoFeatureCollection a
- Data.Geospatial: GeoMultiLine :: [LineString GeoPositionWithoutCRS] -> GeoMultiLine
+ Data.Geospatial: GeoMultiLine :: Vector (LineString GeoPositionWithoutCRS) -> GeoMultiLine
- Data.Geospatial: GeoMultiPoint :: [GeoPositionWithoutCRS] -> GeoMultiPoint
+ Data.Geospatial: GeoMultiPoint :: Vector GeoPositionWithoutCRS -> GeoMultiPoint
- Data.Geospatial: GeoMultiPolygon :: [[LinearRing GeoPositionWithoutCRS]] -> GeoMultiPolygon
+ Data.Geospatial: GeoMultiPolygon :: Vector (Vector (LinearRing GeoPositionWithoutCRS)) -> GeoMultiPolygon
- Data.Geospatial: GeoPolygon :: [LinearRing GeoPositionWithoutCRS] -> GeoPolygon
+ Data.Geospatial: GeoPolygon :: Vector (LinearRing GeoPositionWithoutCRS) -> GeoPolygon
- Data.Geospatial: [_geofeatures] :: GeoFeatureCollection a -> [GeoFeature a]
+ Data.Geospatial: [_geofeatures] :: GeoFeatureCollection a -> Vector (GeoFeature a)
- Data.Geospatial: [_unGeoMultiLine] :: GeoMultiLine -> [LineString GeoPositionWithoutCRS]
+ Data.Geospatial: [_unGeoMultiLine] :: GeoMultiLine -> Vector (LineString GeoPositionWithoutCRS)
- Data.Geospatial: [_unGeoMultiPoint] :: GeoMultiPoint -> [GeoPositionWithoutCRS]
+ Data.Geospatial: [_unGeoMultiPoint] :: GeoMultiPoint -> Vector GeoPositionWithoutCRS
- Data.Geospatial: [_unGeoMultiPolygon] :: GeoMultiPolygon -> [[LinearRing GeoPositionWithoutCRS]]
+ Data.Geospatial: [_unGeoMultiPolygon] :: GeoMultiPolygon -> Vector (Vector (LinearRing GeoPositionWithoutCRS))
- Data.Geospatial: [_unGeoPolygon] :: GeoPolygon -> [LinearRing GeoPositionWithoutCRS]
+ Data.Geospatial: [_unGeoPolygon] :: GeoPolygon -> Vector (LinearRing GeoPositionWithoutCRS)
- Data.Geospatial: _Collection :: Prism' GeospatialGeometry [GeospatialGeometry]
+ Data.Geospatial: _Collection :: Prism' GeospatialGeometry (Vector GeospatialGeometry)
- Data.Geospatial: bbox :: forall a_au3U. Lens' (GeoFeature a_au3U) (Maybe BoundingBoxWithoutCRS)
+ Data.Geospatial: bbox :: forall a_aLJe. Lens' (GeoFeature a_aLJe) (Maybe BoundingBoxWithoutCRS)
- Data.Geospatial: boundingbox :: forall a_avjj. Lens' (GeoFeatureCollection a_avjj) (Maybe BoundingBoxWithoutCRS)
+ Data.Geospatial: boundingbox :: forall a_aNkW. Lens' (GeoFeatureCollection a_aNkW) (Maybe BoundingBoxWithoutCRS)
- Data.Geospatial: featureId :: forall a_au3U. Lens' (GeoFeature a_au3U) (Maybe FeatureID)
+ Data.Geospatial: featureId :: forall a_aLJe. Lens' (GeoFeature a_aLJe) (Maybe FeatureID)
- Data.Geospatial: geofeatures :: forall a_avjj a_avlW. Lens (GeoFeatureCollection a_avjj) (GeoFeatureCollection a_avlW) [GeoFeature a_avjj] [GeoFeature a_avlW]
+ Data.Geospatial: geofeatures :: forall a_aNkW a_aNnB. Lens (GeoFeatureCollection a_aNkW) (GeoFeatureCollection a_aNnB) (Vector (GeoFeature a_aNkW)) (Vector (GeoFeature a_aNnB))
- Data.Geospatial: geometry :: forall a_au3U. Lens' (GeoFeature a_au3U) GeospatialGeometry
+ Data.Geospatial: geometry :: forall a_aLJe. Lens' (GeoFeature a_aLJe) GeospatialGeometry
- Data.Geospatial: mergeGeoLines :: [GeoLine] -> GeoMultiLine
+ Data.Geospatial: mergeGeoLines :: Vector GeoLine -> GeoMultiLine
- Data.Geospatial: mergeGeoPoints :: [GeoPoint] -> GeoMultiPoint
+ Data.Geospatial: mergeGeoPoints :: Vector GeoPoint -> GeoMultiPoint
- Data.Geospatial: mergeGeoPolygons :: [GeoPolygon] -> GeoMultiPolygon
+ Data.Geospatial: mergeGeoPolygons :: Vector GeoPolygon -> GeoMultiPolygon
- Data.Geospatial: properties :: forall a_au3U a_au7E. Lens (GeoFeature a_au3U) (GeoFeature a_au7E) a_au3U a_au7E
+ Data.Geospatial: properties :: forall a_aLJe a_aLQP. Lens (GeoFeature a_aLJe) (GeoFeature a_aLQP) a_aLJe a_aLQP
- Data.Geospatial: splitGeoMultiLine :: GeoMultiLine -> [GeoLine]
+ Data.Geospatial: splitGeoMultiLine :: GeoMultiLine -> Vector GeoLine
- Data.Geospatial: splitGeoMultiPoint :: GeoMultiPoint -> [GeoPoint]
+ Data.Geospatial: splitGeoMultiPoint :: GeoMultiPoint -> Vector GeoPoint
- Data.Geospatial: splitGeoMultiPolygon :: GeoMultiPolygon -> [GeoPolygon]
+ Data.Geospatial: splitGeoMultiPolygon :: GeoMultiPolygon -> Vector GeoPolygon
- Data.Geospatial: unGeoMultiLine :: Iso' GeoMultiLine [LineString GeoPositionWithoutCRS]
+ Data.Geospatial: unGeoMultiLine :: Iso' GeoMultiLine (Vector (LineString GeoPositionWithoutCRS))
- Data.Geospatial: unGeoMultiPoint :: Iso' GeoMultiPoint [GeoPositionWithoutCRS]
+ Data.Geospatial: unGeoMultiPoint :: Iso' GeoMultiPoint (Vector GeoPositionWithoutCRS)
- Data.Geospatial: unGeoMultiPolygon :: Iso' GeoMultiPolygon [[LinearRing GeoPositionWithoutCRS]]
+ Data.Geospatial: unGeoMultiPolygon :: Iso' GeoMultiPolygon (Vector (Vector (LinearRing GeoPositionWithoutCRS)))
- Data.Geospatial: unGeoPolygon :: Iso' GeoPolygon [LinearRing GeoPositionWithoutCRS]
+ Data.Geospatial: unGeoPolygon :: Iso' GeoPolygon (Vector (LinearRing GeoPositionWithoutCRS))
- Data.Geospatial.Internal.GeoFeature: bbox :: forall a_au3U. Lens' (GeoFeature a_au3U) (Maybe BoundingBoxWithoutCRS)
+ Data.Geospatial.Internal.GeoFeature: bbox :: forall a_aLJe. Lens' (GeoFeature a_aLJe) (Maybe BoundingBoxWithoutCRS)
- Data.Geospatial.Internal.GeoFeature: featureId :: forall a_au3U. Lens' (GeoFeature a_au3U) (Maybe FeatureID)
+ Data.Geospatial.Internal.GeoFeature: featureId :: forall a_aLJe. Lens' (GeoFeature a_aLJe) (Maybe FeatureID)
- Data.Geospatial.Internal.GeoFeature: geometry :: forall a_au3U. Lens' (GeoFeature a_au3U) GeospatialGeometry
+ Data.Geospatial.Internal.GeoFeature: geometry :: forall a_aLJe. Lens' (GeoFeature a_aLJe) GeospatialGeometry
- Data.Geospatial.Internal.GeoFeature: properties :: forall a_au3U a_au7E. Lens (GeoFeature a_au3U) (GeoFeature a_au7E) a_au3U a_au7E
+ Data.Geospatial.Internal.GeoFeature: properties :: forall a_aLJe a_aLQP. Lens (GeoFeature a_aLJe) (GeoFeature a_aLQP) a_aLJe a_aLQP
- Data.Geospatial.Internal.GeoFeatureCollection: GeoFeatureCollection :: Maybe BoundingBoxWithoutCRS -> [GeoFeature a] -> GeoFeatureCollection a
+ Data.Geospatial.Internal.GeoFeatureCollection: GeoFeatureCollection :: Maybe BoundingBoxWithoutCRS -> Vector (GeoFeature a) -> GeoFeatureCollection a
- Data.Geospatial.Internal.GeoFeatureCollection: [_geofeatures] :: GeoFeatureCollection a -> [GeoFeature a]
+ Data.Geospatial.Internal.GeoFeatureCollection: [_geofeatures] :: GeoFeatureCollection a -> Vector (GeoFeature a)
- Data.Geospatial.Internal.GeoFeatureCollection: boundingbox :: forall a_avjj. Lens' (GeoFeatureCollection a_avjj) (Maybe BoundingBoxWithoutCRS)
+ Data.Geospatial.Internal.GeoFeatureCollection: boundingbox :: forall a_aNkW. Lens' (GeoFeatureCollection a_aNkW) (Maybe BoundingBoxWithoutCRS)
- Data.Geospatial.Internal.GeoFeatureCollection: geofeatures :: forall a_avjj a_avlW. Lens (GeoFeatureCollection a_avjj) (GeoFeatureCollection a_avlW) [GeoFeature a_avjj] [GeoFeature a_avlW]
+ Data.Geospatial.Internal.GeoFeatureCollection: geofeatures :: forall a_aNkW a_aNnB. Lens (GeoFeatureCollection a_aNkW) (GeoFeatureCollection a_aNnB) (Vector (GeoFeature a_aNkW)) (Vector (GeoFeature a_aNnB))
- Data.Geospatial.Internal.Geometry: Collection :: [GeospatialGeometry] -> GeospatialGeometry
+ Data.Geospatial.Internal.Geometry: Collection :: (Vector GeospatialGeometry) -> GeospatialGeometry
- Data.Geospatial.Internal.Geometry: GeoMultiLine :: [LineString GeoPositionWithoutCRS] -> GeoMultiLine
+ Data.Geospatial.Internal.Geometry: GeoMultiLine :: Vector (LineString GeoPositionWithoutCRS) -> GeoMultiLine
- Data.Geospatial.Internal.Geometry: GeoMultiPoint :: [GeoPositionWithoutCRS] -> GeoMultiPoint
+ Data.Geospatial.Internal.Geometry: GeoMultiPoint :: Vector GeoPositionWithoutCRS -> GeoMultiPoint
- Data.Geospatial.Internal.Geometry: GeoMultiPolygon :: [[LinearRing GeoPositionWithoutCRS]] -> GeoMultiPolygon
+ Data.Geospatial.Internal.Geometry: GeoMultiPolygon :: Vector (Vector (LinearRing GeoPositionWithoutCRS)) -> GeoMultiPolygon
- Data.Geospatial.Internal.Geometry: GeoPolygon :: [LinearRing GeoPositionWithoutCRS] -> GeoPolygon
+ Data.Geospatial.Internal.Geometry: GeoPolygon :: Vector (LinearRing GeoPositionWithoutCRS) -> GeoPolygon
- Data.Geospatial.Internal.Geometry: [_unGeoMultiLine] :: GeoMultiLine -> [LineString GeoPositionWithoutCRS]
+ Data.Geospatial.Internal.Geometry: [_unGeoMultiLine] :: GeoMultiLine -> Vector (LineString GeoPositionWithoutCRS)
- Data.Geospatial.Internal.Geometry: [_unGeoMultiPoint] :: GeoMultiPoint -> [GeoPositionWithoutCRS]
+ Data.Geospatial.Internal.Geometry: [_unGeoMultiPoint] :: GeoMultiPoint -> Vector GeoPositionWithoutCRS
- Data.Geospatial.Internal.Geometry: [_unGeoMultiPolygon] :: GeoMultiPolygon -> [[LinearRing GeoPositionWithoutCRS]]
+ Data.Geospatial.Internal.Geometry: [_unGeoMultiPolygon] :: GeoMultiPolygon -> Vector (Vector (LinearRing GeoPositionWithoutCRS))
- Data.Geospatial.Internal.Geometry: [_unGeoPolygon] :: GeoPolygon -> [LinearRing GeoPositionWithoutCRS]
+ Data.Geospatial.Internal.Geometry: [_unGeoPolygon] :: GeoPolygon -> Vector (LinearRing GeoPositionWithoutCRS)
- Data.Geospatial.Internal.Geometry: _Collection :: Prism' GeospatialGeometry [GeospatialGeometry]
+ Data.Geospatial.Internal.Geometry: _Collection :: Prism' GeospatialGeometry (Vector GeospatialGeometry)
- Data.Geospatial.Internal.Geometry: mergeGeoLines :: [GeoLine] -> GeoMultiLine
+ Data.Geospatial.Internal.Geometry: mergeGeoLines :: Vector GeoLine -> GeoMultiLine
- Data.Geospatial.Internal.Geometry: mergeGeoPoints :: [GeoPoint] -> GeoMultiPoint
+ Data.Geospatial.Internal.Geometry: mergeGeoPoints :: Vector GeoPoint -> GeoMultiPoint
- Data.Geospatial.Internal.Geometry: mergeGeoPolygons :: [GeoPolygon] -> GeoMultiPolygon
+ Data.Geospatial.Internal.Geometry: mergeGeoPolygons :: Vector GeoPolygon -> GeoMultiPolygon
- Data.Geospatial.Internal.Geometry: splitGeoMultiLine :: GeoMultiLine -> [GeoLine]
+ Data.Geospatial.Internal.Geometry: splitGeoMultiLine :: GeoMultiLine -> Vector GeoLine
- Data.Geospatial.Internal.Geometry: splitGeoMultiPoint :: GeoMultiPoint -> [GeoPoint]
+ Data.Geospatial.Internal.Geometry: splitGeoMultiPoint :: GeoMultiPoint -> Vector GeoPoint
- Data.Geospatial.Internal.Geometry: splitGeoMultiPolygon :: GeoMultiPolygon -> [GeoPolygon]
+ Data.Geospatial.Internal.Geometry: splitGeoMultiPolygon :: GeoMultiPolygon -> Vector GeoPolygon
- Data.Geospatial.Internal.Geometry: unGeoMultiLine :: Iso' GeoMultiLine [LineString GeoPositionWithoutCRS]
+ Data.Geospatial.Internal.Geometry: unGeoMultiLine :: Iso' GeoMultiLine (Vector (LineString GeoPositionWithoutCRS))
- Data.Geospatial.Internal.Geometry: unGeoMultiPoint :: Iso' GeoMultiPoint [GeoPositionWithoutCRS]
+ Data.Geospatial.Internal.Geometry: unGeoMultiPoint :: Iso' GeoMultiPoint (Vector GeoPositionWithoutCRS)
- Data.Geospatial.Internal.Geometry: unGeoMultiPolygon :: Iso' GeoMultiPolygon [[LinearRing GeoPositionWithoutCRS]]
+ Data.Geospatial.Internal.Geometry: unGeoMultiPolygon :: Iso' GeoMultiPolygon (Vector (Vector (LinearRing GeoPositionWithoutCRS)))
- Data.Geospatial.Internal.Geometry: unGeoPolygon :: Iso' GeoPolygon [LinearRing GeoPositionWithoutCRS]
+ Data.Geospatial.Internal.Geometry: unGeoPolygon :: Iso' GeoPolygon (Vector (LinearRing GeoPositionWithoutCRS))
- Data.Geospatial.Internal.Geometry.GeoMultiLine: GeoMultiLine :: [LineString GeoPositionWithoutCRS] -> GeoMultiLine
+ Data.Geospatial.Internal.Geometry.GeoMultiLine: GeoMultiLine :: Vector (LineString GeoPositionWithoutCRS) -> GeoMultiLine
- Data.Geospatial.Internal.Geometry.GeoMultiLine: [_unGeoMultiLine] :: GeoMultiLine -> [LineString GeoPositionWithoutCRS]
+ Data.Geospatial.Internal.Geometry.GeoMultiLine: [_unGeoMultiLine] :: GeoMultiLine -> Vector (LineString GeoPositionWithoutCRS)
- Data.Geospatial.Internal.Geometry.GeoMultiLine: mergeGeoLines :: [GeoLine] -> GeoMultiLine
+ Data.Geospatial.Internal.Geometry.GeoMultiLine: mergeGeoLines :: Vector GeoLine -> GeoMultiLine
- Data.Geospatial.Internal.Geometry.GeoMultiLine: splitGeoMultiLine :: GeoMultiLine -> [GeoLine]
+ Data.Geospatial.Internal.Geometry.GeoMultiLine: splitGeoMultiLine :: GeoMultiLine -> Vector GeoLine
- Data.Geospatial.Internal.Geometry.GeoMultiLine: unGeoMultiLine :: Iso' GeoMultiLine [LineString GeoPositionWithoutCRS]
+ Data.Geospatial.Internal.Geometry.GeoMultiLine: unGeoMultiLine :: Iso' GeoMultiLine (Vector (LineString GeoPositionWithoutCRS))
- Data.Geospatial.Internal.Geometry.GeoMultiPoint: GeoMultiPoint :: [GeoPositionWithoutCRS] -> GeoMultiPoint
+ Data.Geospatial.Internal.Geometry.GeoMultiPoint: GeoMultiPoint :: Vector GeoPositionWithoutCRS -> GeoMultiPoint
- Data.Geospatial.Internal.Geometry.GeoMultiPoint: [_unGeoMultiPoint] :: GeoMultiPoint -> [GeoPositionWithoutCRS]
+ Data.Geospatial.Internal.Geometry.GeoMultiPoint: [_unGeoMultiPoint] :: GeoMultiPoint -> Vector GeoPositionWithoutCRS
- Data.Geospatial.Internal.Geometry.GeoMultiPoint: mergeGeoPoints :: [GeoPoint] -> GeoMultiPoint
+ Data.Geospatial.Internal.Geometry.GeoMultiPoint: mergeGeoPoints :: Vector GeoPoint -> GeoMultiPoint
- Data.Geospatial.Internal.Geometry.GeoMultiPoint: splitGeoMultiPoint :: GeoMultiPoint -> [GeoPoint]
+ Data.Geospatial.Internal.Geometry.GeoMultiPoint: splitGeoMultiPoint :: GeoMultiPoint -> Vector GeoPoint
- Data.Geospatial.Internal.Geometry.GeoMultiPoint: unGeoMultiPoint :: Iso' GeoMultiPoint [GeoPositionWithoutCRS]
+ Data.Geospatial.Internal.Geometry.GeoMultiPoint: unGeoMultiPoint :: Iso' GeoMultiPoint (Vector GeoPositionWithoutCRS)
- Data.Geospatial.Internal.Geometry.GeoMultiPolygon: GeoMultiPolygon :: [[LinearRing GeoPositionWithoutCRS]] -> GeoMultiPolygon
+ Data.Geospatial.Internal.Geometry.GeoMultiPolygon: GeoMultiPolygon :: Vector (Vector (LinearRing GeoPositionWithoutCRS)) -> GeoMultiPolygon
- Data.Geospatial.Internal.Geometry.GeoMultiPolygon: [_unGeoMultiPolygon] :: GeoMultiPolygon -> [[LinearRing GeoPositionWithoutCRS]]
+ Data.Geospatial.Internal.Geometry.GeoMultiPolygon: [_unGeoMultiPolygon] :: GeoMultiPolygon -> Vector (Vector (LinearRing GeoPositionWithoutCRS))
- Data.Geospatial.Internal.Geometry.GeoMultiPolygon: mergeGeoPolygons :: [GeoPolygon] -> GeoMultiPolygon
+ Data.Geospatial.Internal.Geometry.GeoMultiPolygon: mergeGeoPolygons :: Vector GeoPolygon -> GeoMultiPolygon
- Data.Geospatial.Internal.Geometry.GeoMultiPolygon: splitGeoMultiPolygon :: GeoMultiPolygon -> [GeoPolygon]
+ Data.Geospatial.Internal.Geometry.GeoMultiPolygon: splitGeoMultiPolygon :: GeoMultiPolygon -> Vector GeoPolygon
- Data.Geospatial.Internal.Geometry.GeoMultiPolygon: unGeoMultiPolygon :: Iso' GeoMultiPolygon [[LinearRing GeoPositionWithoutCRS]]
+ Data.Geospatial.Internal.Geometry.GeoMultiPolygon: unGeoMultiPolygon :: Iso' GeoMultiPolygon (Vector (Vector (LinearRing GeoPositionWithoutCRS)))
- Data.Geospatial.Internal.Geometry.GeoPolygon: GeoPolygon :: [LinearRing GeoPositionWithoutCRS] -> GeoPolygon
+ Data.Geospatial.Internal.Geometry.GeoPolygon: GeoPolygon :: Vector (LinearRing GeoPositionWithoutCRS) -> GeoPolygon
- Data.Geospatial.Internal.Geometry.GeoPolygon: [_unGeoPolygon] :: GeoPolygon -> [LinearRing GeoPositionWithoutCRS]
+ Data.Geospatial.Internal.Geometry.GeoPolygon: [_unGeoPolygon] :: GeoPolygon -> Vector (LinearRing GeoPositionWithoutCRS)
- Data.Geospatial.Internal.Geometry.GeoPolygon: unGeoPolygon :: Iso' GeoPolygon [LinearRing GeoPositionWithoutCRS]
+ Data.Geospatial.Internal.Geometry.GeoPolygon: unGeoPolygon :: Iso' GeoPolygon (Vector (LinearRing GeoPositionWithoutCRS))
- Data.LineString: fromLineString :: LineString a -> [a]
+ Data.LineString: fromLineString :: (Storable a) => LineString a -> [a]
- Data.LineString: fromList :: (Validate v) => [a] -> v ListToLineStringError (LineString a)
+ Data.LineString: fromList :: (Validate v, Storable a) => [a] -> v ListToLineStringError (LineString a)
- Data.LineString: lineStringLast :: LineString a -> a
+ Data.LineString: lineStringLast :: (Storable a) => LineString a -> a
- Data.LineString: lineStringLength :: LineString a -> Int
+ Data.LineString: lineStringLength :: (Storable a) => LineString a -> Int
- Data.LineString: makeLineString :: a -> a -> [a] -> LineString a
+ Data.LineString: makeLineString :: (Storable a) => a -> a -> Vector a -> LineString a
- Data.LinearRing: fromLinearRing :: LinearRing a -> [a]
+ Data.LinearRing: fromLinearRing :: (Storable a) => LinearRing a -> [a]
- Data.LinearRing: fromList :: (Validate v, Functor (v (NonEmpty (ListToLinearRingError a)))) => [a] -> v (NonEmpty (ListToLinearRingError a)) (LinearRing a)
+ Data.LinearRing: fromList :: (Eq a, Show a, Storable a, Validate v, Functor (v (NonEmpty (ListToLinearRingError a)))) => [a] -> v (NonEmpty (ListToLinearRingError a)) (LinearRing a)
- Data.LinearRing: fromListWithEqCheck :: (Eq a, Validate v, Applicative (v (NonEmpty (ListToLinearRingError a)))) => [a] -> v (NonEmpty (ListToLinearRingError a)) (LinearRing a)
+ Data.LinearRing: fromListWithEqCheck :: (Eq a, Show a, Storable a, Validate v, Applicative (v (NonEmpty (ListToLinearRingError a)))) => [a] -> v (NonEmpty (ListToLinearRingError a)) (LinearRing a)
- Data.LinearRing: makeLinearRing :: a -> a -> a -> [a] -> LinearRing a
+ Data.LinearRing: makeLinearRing :: (Eq a, Show a, Storable a) => a -> a -> a -> Vector a -> LinearRing a
- Data.LinearRing: ringLength :: LinearRing a -> Int
+ Data.LinearRing: ringLength :: (Storable a) => LinearRing a -> Int
Files
- CHANGELOG.md +12/−2
- README.md +1/−6
- geojson.cabal +8/−6
- src/Data/Geospatial.hs +19/−13
- src/Data/Geospatial/Internal/BasicTypes.hs +136/−21
- src/Data/Geospatial/Internal/GeoFeature.hs +10/−1
- src/Data/Geospatial/Internal/GeoFeatureCollection.hs +2/−1
- src/Data/Geospatial/Internal/GeoPosition.hs +10/−10
- src/Data/Geospatial/Internal/Geometry.hs +8/−3
- src/Data/Geospatial/Internal/Geometry/Aeson.hs +1/−0
- src/Data/Geospatial/Internal/Geometry/GeoLine.hs +5/−1
- src/Data/Geospatial/Internal/Geometry/GeoMultiLine.hs +11/−5
- src/Data/Geospatial/Internal/Geometry/GeoMultiPoint.hs +18/−16
- src/Data/Geospatial/Internal/Geometry/GeoMultiPolygon.hs +20/−17
- src/Data/Geospatial/Internal/Geometry/GeoPoint.hs +13/−11
- src/Data/Geospatial/Internal/Geometry/GeoPolygon.hs +18/−14
- src/Data/LineString.hs +111/−45
- src/Data/LinearRing.hs +120/−66
- test/Arbitrary.hs +11/−2
- test/Data/LineStringTests.hs +52/−22
- test/Data/LinearRingTests.hs +60/−24
- test/Fixture.hs +60/−61
CHANGELOG.md view
@@ -1,6 +1,16 @@-# 1.3.0+# 2.0.x -## 1.3.1->1.3.3+## 1.3.3 -> 2.0.0++- Switch to using `Data.Vector.Storable` instead of lists, +- `GeoPositionWithoutCRS` is now a sum type (Empty, XY, XYZ, or XYZM).+- New public methods on LineString and LinearRing+ - toVector, combineVector, fromVector+ - map, foldr, foldMap (as they are nolonger Foldable, Functor, or Traversable)++# 1.3.x++## 1.3.1 -> 1.3.3 - Fixed Validation dependency.
README.md view
@@ -1,4 +1,4 @@-# geojson [](https://travis-ci.org/newmana/hs-geojson) [Hackage](https://hackage.haskell.org/package/geojson)+# geojson [](https://travis-ci.org/indicatrix/hs-geojson) [Hackage](https://hackage.haskell.org/package/geojson) A thin GeoJSON Layer above the `aeson` library @@ -29,11 +29,6 @@ **After** running `cabal build`, you can run the unit tests with the command: cabal test--## Adding Unit tests--Currently only files in the `src/` directory are searched for tests, it is assumed that the code in `main/`-is a thin layer of code that uses modules from `src/`. ## Development: Cabal Dependency Hell?
geojson.cabal view
@@ -1,5 +1,5 @@ name: geojson-version: 1.3.3+version: 2.0.0 license: BSD3 license-file: LICENCE author: Dom De Re@@ -13,8 +13,8 @@ . <http://geojson.org/geojson-spec.html> -homepage: https://github.com/newmana/hs-geojson-bug-reports: https://github.com/newmana/hs-geojson/issues+homepage: https://github.com/indicatrix/hs-geojson+bug-reports: https://github.com/indicatrix/hs-geojson/issues cabal-version: >= 1.10 build-type: Simple extra-source-files: README.md,@@ -22,17 +22,18 @@ source-repository head type: git- location: https://github.com/newmana/hs-geojson.git+ location: https://github.com/indicatrix/hs-geojson.git source-repository this type: git- location: https://github.com/newmana/hs-geojson.git- tag: 1.3.3+ location: https://github.com/indicatrix/hs-geojson.git+ tag: 2.0.0 library hs-source-dirs: src build-depends: base < 5 && >= 4 , aeson >= 0.8+ , deepseq >= 1.4 , lens >= 4.11 , semigroups >= 0.16 , text >= 1.2@@ -72,6 +73,7 @@ , tasty-quickcheck , text >= 1.2 , validation >= 1+ , vector >= 0.10 other-modules: Arbitrary , Fixture , Data.LinearRingTests
src/Data/Geospatial.hs view
@@ -15,25 +15,28 @@ , Easting , Northing , Altitude- , FeatureID(..)- , GeoPositionWithoutCRS- , GeoPosition(..)- , GeoPoint(..)- , GeoMultiPoint(..), splitGeoMultiPoint, mergeGeoPoints- , GeoPolygon(..)- , GeoMultiPolygon(..), splitGeoMultiPolygon, mergeGeoPolygons- , GeoLine(..)- , GeoMultiLine(..), splitGeoMultiLine, mergeGeoLines- , GeospatialGeometry(..)+ , FeatureID (..)+ , GeoPositionWithoutCRS (..)+ , GeoPosition (..)+ , GeoPoint (..), retrieveXY+ , PointXY (..)+ , PointXYZ (..)+ , PointXYZM (..)+ , GeoMultiPoint (..), splitGeoMultiPoint, mergeGeoPoints+ , GeoPolygon (..)+ , GeoMultiPolygon (..), splitGeoMultiPolygon, mergeGeoPolygons+ , GeoLine (..)+ , GeoMultiLine (..), splitGeoMultiLine, mergeGeoLines+ , GeospatialGeometry (..) , Name , Code , Href , FormatString , ProjectionType- , CRSObject(..)+ , CRSObject (..) , BoundingBoxWithoutCRS- , GeoFeature(..)- , GeoFeatureCollection(..)+ , GeoFeature (..), reWrapGeometry+ , GeoFeatureCollection (..) -- * Functions , stripCRSFromPosition , defaultCRS@@ -45,6 +48,7 @@ , unGeoLine , unGeoMultiLine , unGeoMultiPolygon+ , unBoundingBoxWithoutCrs -- ** Feature Lenses , bbox , geometry@@ -53,6 +57,8 @@ , boundingbox , geofeatures -- * Prisms+ -- ** BasicTypes+ , HasGeoPositionWithoutCRS(..) -- ** Geometry , _NoGeometry , _Point
src/Data/Geospatial/Internal/BasicTypes.hs view
@@ -1,4 +1,7 @@+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TemplateHaskell #-} ------------------------------------------------------------------- -- |@@ -16,7 +19,13 @@ , Easting , Northing , Altitude- , GeoPositionWithoutCRS+ , GeoPositionWithoutCRS (..)+ , retrieveXY+ , PointXY (..)+ , PointXYZ (..)+ , PointXYZM (..)+ , DoubleArray (..)+ , HasGeoPositionWithoutCRS(..) -- * CRS Reference types , Name , Code@@ -24,13 +33,20 @@ , FormatString , ProjectionType -- * Feature Types- , BoundingBoxWithoutCRS+ , BoundingBoxWithoutCRS (..) , FeatureID (..) ) where -import Data.Aeson (FromJSON (..), ToJSON (..), Value (..))-import Data.Scientific (Scientific, toBoundedInteger)-import Data.Text (Text)+import Control.DeepSeq+import Control.Lens.TH (makeClassy)+import qualified Data.Aeson as Aeson+import qualified Data.Aeson.Types as AesonTypes+import qualified Data.Maybe as DataMaybe+import qualified Data.Scientific as Scientific+import qualified Data.Text as Text+import qualified Data.Vector.Storable as VectorStorable+import Foreign.Storable+import GHC.Generics type Latitude = Double type Longitude = Double@@ -38,37 +54,128 @@ type Northing = Double type Altitude = Double +newtype DoubleArray = DoubleArray [Double] deriving (Eq, Show, Generic, NFData, Aeson.FromJSON, Aeson.ToJSON)+ -- | (`GeoPositionWithoutCRS` is a catch all for indeterminate CRSs and for expression of positions -- before a CRS has been determined ---type GeoPositionWithoutCRS = [Double]+data PointXY = PointXY+ { _xyX :: !Double+ , _xyY :: !Double+ } deriving (Show, Eq, Generic, NFData) -type Name = Text+data PointXYZ = PointXYZ+ { _xyzX :: !Double+ , _xyzY :: !Double+ , _xyzZ :: !Double+ } deriving (Show, Eq, Generic, NFData)++data PointXYZM = PointXYZM+ { _xyzmX :: !Double+ , _xyzmY :: !Double+ , _xyzmZ :: !Double+ , _xyzmM :: !Double+ } deriving (Show, Eq, Generic, NFData)++data GeoPositionWithoutCRS = GeoEmpty | GeoPointXY PointXY | GeoPointXYZ PointXYZ | GeoPointXYZM PointXYZM deriving (Show, Eq, Generic, NFData)++makeClassy ''GeoPositionWithoutCRS++_toDoubleArray :: GeoPositionWithoutCRS -> [Double]+_toDoubleArray GeoEmpty = []+_toDoubleArray (GeoPointXY (PointXY x y)) = [x, y]+_toDoubleArray (GeoPointXYZ (PointXYZ x y z)) = [x, y, z]+_toDoubleArray (GeoPointXYZM (PointXYZM x y z m)) = [x, y, z, m]++_toGeoPoint :: DoubleArray -> Maybe GeoPositionWithoutCRS+_toGeoPoint (DoubleArray []) = Just GeoEmpty+_toGeoPoint (DoubleArray [x, y]) = Just $ GeoPointXY (PointXY x y)+_toGeoPoint (DoubleArray [x, y, z]) = Just $ GeoPointXYZ (PointXYZ x y z)+_toGeoPoint (DoubleArray [x, y, z, m]) = Just $ GeoPointXYZM (PointXYZM x y z m)+_toGeoPoint _ = Nothing++retrieveXY :: GeoPositionWithoutCRS -> PointXY+retrieveXY position =+ case position of+ GeoEmpty -> undefined -- TODO - Fix - represent this like WKB - NaN value+ (GeoPointXY p) -> p+ (GeoPointXYZ (PointXYZ pX pY _)) -> PointXY pX pY+ (GeoPointXYZM (PointXYZM pX pY _ _)) -> PointXY pX pY+{-# INLINE retrieveXY #-}++-- instances++instance Aeson.ToJSON GeoPositionWithoutCRS where+ -- toJSON :: a -> Value+ toJSON a = Aeson.toJSON $ _toDoubleArray a++instance Aeson.FromJSON GeoPositionWithoutCRS where+-- parseJSON :: Value -> Parser a+ parseJSON o = do+ x <- Aeson.parseJSON o+ DataMaybe.maybe (fail "Illegal coordinates") pure (_toGeoPoint x)++sizeOfDouble :: Int+sizeOfDouble = sizeOf (undefined :: Double)+{-# INLINE sizeOfDouble #-}++alignmentOfDouble :: Int+alignmentOfDouble = alignment (undefined :: Double)+{-# INLINE alignmentOfDouble #-}++instance VectorStorable.Storable PointXY where+ sizeOf _ = 2 * sizeOfDouble+ alignment _ = alignmentOfDouble+ {-# INLINE peek #-}+ peek p = PointXY <$> peekByteOff p 0 <*> peekByteOff p (1 * sizeOfDouble)+ {-# INLINE poke #-}+ poke p (PointXY x y) = pokeByteOff p 0 x *> pokeByteOff p (1 * sizeOfDouble) y++instance VectorStorable.Storable GeoPositionWithoutCRS where+ sizeOf _ = 5 * sizeOfDouble+ alignment _ = alignmentOfDouble+ {-# INLINE peek #-}+ peek p = do+ t <- peekByteOff p 0+ case (t :: Double) of+ 0 -> pure GeoEmpty+ 1 -> fmap GeoPointXY $ PointXY <$> peekByteOff p (1 * sizeOfDouble) <*> peekByteOff p (2 * sizeOfDouble)+ 2 -> fmap GeoPointXYZ $ PointXYZ <$> peekByteOff p (1 * sizeOfDouble) <*> peekByteOff p (2 * sizeOfDouble) <*> peekByteOff p (3 * sizeOfDouble)+ _ -> fmap GeoPointXYZM $ PointXYZM <$> peekByteOff p (1 * sizeOfDouble) <*> peekByteOff p (2 * sizeOfDouble) <*> peekByteOff p (3 * sizeOfDouble) <*> peekByteOff p (4 * sizeOfDouble)+ {-# INLINE poke #-}+ poke p val =+ case val of+ GeoEmpty -> pokeByteOff p 0 (0 :: Double) *> pokeByteOff p (1 * sizeOfDouble) (0 :: Double)+ (GeoPointXY (PointXY x y)) -> pokeByteOff p 0 (1 :: Double) *> pokeByteOff p (1 * sizeOfDouble) x *> pokeByteOff p (2 * sizeOfDouble) y+ (GeoPointXYZ (PointXYZ x y z)) -> pokeByteOff p 0 (2 :: Double) *> pokeByteOff p (1 * sizeOfDouble) x *> pokeByteOff p (2 * sizeOfDouble) y *> pokeByteOff p (3 * sizeOfDouble) z+ (GeoPointXYZM (PointXYZM x y z m)) -> pokeByteOff p 0 (3 :: Double) *> pokeByteOff p (1 * sizeOfDouble) x *> pokeByteOff p (2 * sizeOfDouble) y *> pokeByteOff p (3 * sizeOfDouble) z *> pokeByteOff p (4 * sizeOfDouble) m++type Name = Text.Text type Code = Int-type Href = Text-type FormatString = Text-type ProjectionType = Text+type Href = Text.Text+type FormatString = Text.Text+type ProjectionType = Text.Text -- Feature Types data FeatureID =- FeatureIDText Text- | FeatureIDNumber Int deriving (Show, Eq)+ FeatureIDText Text.Text+ | FeatureIDNumber Int deriving (Show, Eq, Generic, NFData) -instance FromJSON FeatureID where- parseJSON (Number nID) =+instance Aeson.FromJSON FeatureID where+ parseJSON (Aeson.Number nID) = case x of Nothing -> fail "Not an integer value" Just z -> pure $ FeatureIDNumber z where- x = toBoundedInteger nID :: Maybe Int- parseJSON (String sID) = pure $ FeatureIDText sID- parseJSON _ = fail "unknown id type"+ x = Scientific.toBoundedInteger nID :: Maybe Int+ parseJSON (Aeson.String sID) = pure $ FeatureIDText sID+ parseJSON _ = fail "unknown id type" -instance ToJSON FeatureID where- toJSON (FeatureIDText a) = String a- toJSON (FeatureIDNumber b) = Number (fromInteger $ toInteger b :: Scientific)+instance Aeson.ToJSON FeatureID where+ toJSON (FeatureIDText a) = Aeson.String a+ toJSON (FeatureIDNumber b) = Aeson.Number (fromInteger $ toInteger b :: Scientific.Scientific) -- | See Section 4 /Bounding Boxes/ of the GeoJSON spec,@@ -77,4 +184,12 @@ -- e.g for WGS84: minLongitude, minLatitude, maxLongitude, maxLatitude -- The spec mentions that it can be part of a geometry object too but doesnt give an example, -- This implementation will ignore bboxes on Geometry objects, they can be added if required.-type BoundingBoxWithoutCRS = [Double]+newtype BoundingBoxWithoutCRS = BoundingBoxWithoutCRS { unBoundingBoxWithoutCrs :: VectorStorable.Vector Double } deriving (Eq, Show, Generic, NFData)++instance Aeson.FromJSON BoundingBoxWithoutCRS where+ parseJSON obj = do+ doubles <- Aeson.parseJSON obj :: AesonTypes.Parser [Double]+ pure . BoundingBoxWithoutCRS $ VectorStorable.fromList doubles++instance Aeson.ToJSON BoundingBoxWithoutCRS where+ toJSON = Aeson.toJSON . VectorStorable.toList . unBoundingBoxWithoutCrs
src/Data/Geospatial/Internal/GeoFeature.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-}@@ -20,6 +22,8 @@ , geometry , properties , featureId+ -- * Utils+ , reWrapGeometry ) where import Data.Geospatial.Internal.BasicTypes@@ -27,6 +31,7 @@ import Data.Geospatial.Internal.Geometry.Aeson import Control.Applicative ((<$>), (<*>))+import Control.DeepSeq import Control.Lens (makeLenses) import Control.Monad (mzero) import Data.Aeson (FromJSON (..),@@ -36,6 +41,7 @@ import Data.List ((++)) import Data.Maybe (Maybe) import Data.Text (Text)+import GHC.Generics (Generic) import Prelude (Eq (..), Show, ($)) -- | See Section 2.2 /Feature Objects/ of the GeoJSON spec.@@ -44,7 +50,10 @@ _bbox :: Maybe BoundingBoxWithoutCRS, _geometry :: GeospatialGeometry, _properties :: a,- _featureId :: Maybe FeatureID } deriving (Show, Eq)+ _featureId :: Maybe FeatureID } deriving (Show, Eq, Generic, NFData)++reWrapGeometry :: GeoFeature a -> GeospatialGeometry -> GeoFeature a+reWrapGeometry (GeoFeature bbox _ props fId) geom = GeoFeature bbox geom props fId makeLenses ''GeoFeature
src/Data/Geospatial/Internal/GeoFeatureCollection.hs view
@@ -33,13 +33,14 @@ import Data.List ((++)) import Data.Maybe (Maybe (..)) import Data.Text (Text)+import qualified Data.Vector as Vector 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]+ , _geofeatures :: Vector.Vector (GeoFeature a) } deriving (Show, Eq) makeLenses ''GeoFeatureCollection
src/Data/Geospatial/Internal/GeoPosition.hs view
@@ -14,25 +14,25 @@ , stripCRSFromPosition ) where -import Data.Geospatial.Internal.BasicTypes+import qualified Data.Geospatial.Internal.BasicTypes as BasicTypes -- | see Section 2.1.1 /Position/ in the GeoJSON Spec, -- I make the assumption here that the only position types we will use will -- involve easting or northing (+ve or -ve Altitude) or lon or lat (+ve or -ve Altitude) data GeoPosition =- LonLat Longitude Latitude- | LonLatAlt Longitude Latitude Altitude- | EastingNorthing Easting Northing- | EastingNorthingAlt Easting Northing Altitude+ LonLat BasicTypes.Longitude BasicTypes.Latitude+ | LonLatAlt BasicTypes.Longitude BasicTypes.Latitude BasicTypes.Altitude+ | EastingNorthing BasicTypes.Easting BasicTypes.Northing+ | EastingNorthingAlt BasicTypes.Easting BasicTypes.Northing BasicTypes.Altitude -- | the `GeoPosition` is a bit special in that when you convert it to GeoJSON, -- it will lose the CRS info attached to it and cannot be read back in -- from the GeoJSON. Hence it is ineligible for the `FromJSON` type class, -- so this function will strip it down to a `GeoPositionWithoutCRS`, which is eligible-stripCRSFromPosition :: GeoPosition -> GeoPositionWithoutCRS-stripCRSFromPosition (LonLat lon lat) = [lon, lat]-stripCRSFromPosition (LonLatAlt lon lat alt) = [lon, lat, alt]-stripCRSFromPosition (EastingNorthing easting northing) = [easting, northing]-stripCRSFromPosition (EastingNorthingAlt easting northing alt) = [easting, northing, alt]+stripCRSFromPosition :: GeoPosition -> BasicTypes.GeoPositionWithoutCRS+stripCRSFromPosition (LonLat lon lat) = BasicTypes.GeoPointXY $ BasicTypes.PointXY lon lat+stripCRSFromPosition (LonLatAlt lon lat alt) = BasicTypes.GeoPointXYZ $ BasicTypes.PointXYZ lon lat alt+stripCRSFromPosition (EastingNorthing easting northing) = BasicTypes.GeoPointXY $ BasicTypes.PointXY easting northing+stripCRSFromPosition (EastingNorthingAlt easting northing alt) = BasicTypes.GeoPointXYZ $ BasicTypes.PointXYZ easting northing alt
src/Data/Geospatial/Internal/Geometry.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} -------------------------------------------------------------------@@ -12,7 +14,7 @@ ------------------------------------------------------------------- module Data.Geospatial.Internal.Geometry ( -- * Types- GeoPoint(..)+ GeoPoint(..), retrieveXY , GeoMultiPoint(..), splitGeoMultiPoint, mergeGeoPoints , GeoPolygon(..) , GeoMultiPolygon(..), splitGeoMultiPolygon, mergeGeoPolygons@@ -45,6 +47,7 @@ import Data.Geospatial.Internal.Geometry.GeoPolygon import Control.Applicative ((<$>))+import Control.DeepSeq import Control.Lens (makePrisms) import Control.Monad (mzero) import Data.Aeson (FromJSON (..),@@ -54,7 +57,10 @@ (.:), (.=)) import Data.Aeson.Types (Parser) import Data.Text (Text)+import qualified Data.Vector as Vector+import GHC.Generics (Generic) + -- | See section 2.1 /Geometry Objects/ in the GeoJSON Spec. data GeospatialGeometry = NoGeometry@@ -64,7 +70,7 @@ | MultiPolygon GeoMultiPolygon | Line GeoLine | MultiLine GeoMultiLine- | Collection [GeospatialGeometry] deriving (Show, Eq)+ | Collection (Vector.Vector GeospatialGeometry) deriving (Show, Eq, Generic, NFData) makePrisms ''GeospatialGeometry @@ -78,7 +84,6 @@ geometryFromAeson "GeometryCollection" (Object jsonObj) = Collection <$> (jsonObj .: ("geometries" :: Text)) geometryFromAeson "GeometryCollection" _ = mzero geometryFromAeson _ _ = mzero- -- | -- encodes Geometry Objects to GeoJSON
src/Data/Geospatial/Internal/Geometry/Aeson.hs view
@@ -25,6 +25,7 @@ import Data.Maybe (Maybe (..)) import Data.Text (Text) + -- | A generic function that can be used to read in the GeoJSON for: -- `GeoPoint`, `GeoMultiPoint`, `GeoLine`, `GeoMultiLine`, `GeoPolygon` and `GeoMultiPolygon` -- Takes in a String for the GeoJSON geometry type, the type constructor
src/Data/Geospatial/Internal/Geometry/GeoLine.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE TemplateHaskell #-} ------------------------------------------------------------------- -- |@@ -18,13 +20,15 @@ import Data.Geospatial.Internal.Geometry.Aeson import Data.LineString +import Control.DeepSeq import Control.Lens (makeLenses) import Control.Monad (mzero) import Data.Aeson (FromJSON (..), ToJSON (..), Value (..))+import GHC.Generics (Generic) -newtype GeoLine = GeoLine { _unGeoLine :: LineString GeoPositionWithoutCRS } deriving (Show, Eq)+newtype GeoLine = GeoLine { _unGeoLine :: LineString GeoPositionWithoutCRS } deriving (Show, Eq, Generic, NFData) makeLenses ''GeoLine
src/Data/Geospatial/Internal/Geometry/GeoMultiLine.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE TemplateHaskell #-} ------------------------------------------------------------------- -- |@@ -21,24 +23,28 @@ import Data.Geospatial.Internal.Geometry.GeoLine import Data.LineString +import Control.DeepSeq import Control.Lens (makeLenses) import Control.Monad (mzero) import Data.Aeson (FromJSON (..), ToJSON (..), Value (..))+import qualified Data.Vector as Vector+import GHC.Generics (Generic) -newtype GeoMultiLine = GeoMultiLine { _unGeoMultiLine :: [LineString GeoPositionWithoutCRS] } deriving (Show, Eq) +newtype GeoMultiLine = GeoMultiLine { _unGeoMultiLine :: Vector.Vector (LineString GeoPositionWithoutCRS) } deriving (Show, Eq, Generic, NFData)+ makeLenses ''GeoMultiLine -- | Split GeoMultiLine coordinates into multiple GeoLines-splitGeoMultiLine:: GeoMultiLine -> [GeoLine]-splitGeoMultiLine = map GeoLine . _unGeoMultiLine+splitGeoMultiLine:: GeoMultiLine -> Vector.Vector GeoLine+splitGeoMultiLine = Vector.map GeoLine . _unGeoMultiLine -- | Merge multiple GeoLines into one GeoMultiLine-mergeGeoLines :: [GeoLine] -> GeoMultiLine-mergeGeoLines = GeoMultiLine . map _unGeoLine+mergeGeoLines :: Vector.Vector GeoLine -> GeoMultiLine+mergeGeoLines = GeoMultiLine . Vector.map _unGeoLine -- instances
src/Data/Geospatial/Internal/Geometry/GeoMultiPoint.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE TemplateHaskell #-} ------------------------------------------------------------------- -- |@@ -20,32 +22,32 @@ import Data.Geospatial.Internal.Geometry.Aeson import Data.Geospatial.Internal.Geometry.GeoPoint +import Control.DeepSeq import Control.Lens (makeLenses) import Control.Monad (mzero)-import Data.Aeson (FromJSON (..),- ToJSON (..),- Value (..))+import qualified Data.Aeson as Aeson+import qualified Data.Vector as Vector+import GHC.Generics (Generic) -newtype GeoMultiPoint = GeoMultiPoint { _unGeoMultiPoint :: [GeoPositionWithoutCRS] } deriving (Show, Eq)+newtype GeoMultiPoint = GeoMultiPoint { _unGeoMultiPoint :: Vector.Vector GeoPositionWithoutCRS } deriving (Show, Eq, Generic, NFData) makeLenses ''GeoMultiPoint - -- | Split GeoMultiPoint coordinates into multiple GeoPoints-splitGeoMultiPoint:: GeoMultiPoint -> [GeoPoint]-splitGeoMultiPoint = map GeoPoint . _unGeoMultiPoint+splitGeoMultiPoint:: GeoMultiPoint -> Vector.Vector GeoPoint+splitGeoMultiPoint = Vector.map GeoPoint . _unGeoMultiPoint -- | Merge multiple GeoPoints into one GeoMultiPoint-mergeGeoPoints :: [GeoPoint] -> GeoMultiPoint-mergeGeoPoints = GeoMultiPoint . map _unGeoPoint+mergeGeoPoints :: Vector.Vector GeoPoint -> GeoMultiPoint+mergeGeoPoints = GeoMultiPoint . Vector.map _unGeoPoint -- instances -instance ToJSON GeoMultiPoint where--- toJSON :: a -> Value- toJSON = makeGeometryGeoAeson "MultiPoint" . _unGeoMultiPoint+instance Aeson.ToJSON GeoMultiPoint where+ -- toJSON :: a -> Value+ toJSON = makeGeometryGeoAeson "MultiPoint" . _unGeoMultiPoint -instance FromJSON GeoMultiPoint where--- parseJSON :: Value -> Parser a- parseJSON (Object o) = readGeometryGeoAeson "MultiPoint" GeoMultiPoint o- parseJSON _ = mzero+instance Aeson.FromJSON GeoMultiPoint where+ -- parseJSON :: Value -> Parser a+ parseJSON (Aeson.Object o) = readGeometryGeoAeson "MultiPoint" GeoMultiPoint o+ parseJSON _ = mzero
src/Data/Geospatial/Internal/Geometry/GeoMultiPolygon.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE TemplateHaskell #-} ------------------------------------------------------------------- -- |@@ -18,34 +20,35 @@ import Data.Geospatial.Internal.BasicTypes import Data.Geospatial.Internal.Geometry.Aeson-import Data.Geospatial.Internal.Geometry.GeoPolygon-import Data.LinearRing+import Data.Geospatial.Internal.Geometry.GeoPolygon as GeoPolygon+import qualified Data.LinearRing as LinearRing +import Control.DeepSeq import Control.Lens (makeLenses) import Control.Monad (mzero)-import Data.Aeson (FromJSON (..),- ToJSON (..),- Value (..))+import qualified Data.Aeson as Aeson+import qualified Data.Vector as Vector+import GHC.Generics (Generic) -newtype GeoMultiPolygon = GeoMultiPolygon { _unGeoMultiPolygon :: [[LinearRing GeoPositionWithoutCRS]] } deriving (Show, Eq)+newtype GeoMultiPolygon = GeoMultiPolygon { _unGeoMultiPolygon :: Vector.Vector (Vector.Vector (LinearRing.LinearRing GeoPositionWithoutCRS)) } deriving (Show, Eq, Generic, NFData) -- | Split GeoMultiPolygon coordinates into multiple GeoPolygons-splitGeoMultiPolygon :: GeoMultiPolygon -> [GeoPolygon]-splitGeoMultiPolygon = map GeoPolygon . _unGeoMultiPolygon+splitGeoMultiPolygon :: GeoMultiPolygon -> Vector.Vector GeoPolygon+splitGeoMultiPolygon = Vector.map GeoPolygon . _unGeoMultiPolygon -- | Merge multiple GeoPolygons into one GeoMultiPolygon-mergeGeoPolygons :: [GeoPolygon] -> GeoMultiPolygon-mergeGeoPolygons = GeoMultiPolygon . map _unGeoPolygon+mergeGeoPolygons :: Vector.Vector GeoPolygon -> GeoMultiPolygon+mergeGeoPolygons = GeoMultiPolygon . Vector.map GeoPolygon._unGeoPolygon makeLenses ''GeoMultiPolygon -- instances -instance ToJSON GeoMultiPolygon where--- toJSON :: a -> Value- toJSON = makeGeometryGeoAeson "MultiPolygon" . _unGeoMultiPolygon+instance Aeson.ToJSON GeoMultiPolygon where+ -- toJSON :: a -> Value+ toJSON = makeGeometryGeoAeson "MultiPolygon" . _unGeoMultiPolygon -instance FromJSON GeoMultiPolygon where--- parseJSON :: Value -> Parser a- parseJSON (Object o) = readGeometryGeoAeson "MultiPolygon" GeoMultiPolygon o- parseJSON _ = mzero+instance Aeson.FromJSON GeoMultiPolygon where+ -- parseJSON :: Value -> Parser a+ parseJSON (Aeson.Object o) = readGeometryGeoAeson "MultiPolygon" GeoMultiPolygon o+ parseJSON _ = mzero
src/Data/Geospatial/Internal/Geometry/GeoPoint.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE TemplateHaskell #-} ------------------------------------------------------------------- -- |@@ -10,30 +12,30 @@ module Data.Geospatial.Internal.Geometry.GeoPoint ( -- * Type GeoPoint(..)- -- * Lenses , unGeoPoint+ , retrieveXY ) where +import Control.DeepSeq+import Control.Lens (makeLenses)+import Control.Monad (mzero)+import qualified Data.Aeson as Aeson import Data.Geospatial.Internal.BasicTypes import Data.Geospatial.Internal.Geometry.Aeson+import GHC.Generics (Generic) -import Control.Lens (makeLenses)-import Control.Monad (mzero)-import Data.Aeson (FromJSON (..),- ToJSON (..),- Value (..)) -newtype GeoPoint = GeoPoint { _unGeoPoint :: GeoPositionWithoutCRS } deriving (Show, Eq)+newtype GeoPoint = GeoPoint { _unGeoPoint :: GeoPositionWithoutCRS } deriving (Show, Eq, Generic, NFData) makeLenses ''GeoPoint -- instances -instance ToJSON GeoPoint where+instance Aeson.ToJSON GeoPoint where -- toJSON :: a -> Value toJSON = makeGeometryGeoAeson "Point" . _unGeoPoint -instance FromJSON GeoPoint where+instance Aeson.FromJSON GeoPoint where -- parseJSON :: Value -> Parser a- parseJSON (Object o) = readGeometryGeoAeson "Point" GeoPoint o- parseJSON _ = mzero+ parseJSON (Aeson.Object o) = readGeometryGeoAeson "Point" GeoPoint o+ parseJSON _ = mzero
src/Data/Geospatial/Internal/Geometry/GeoPolygon.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE TemplateHaskell #-} ------------------------------------------------------------------- -- |@@ -14,27 +16,29 @@ , unGeoPolygon ) where +import Control.DeepSeq+import Control.Lens (makeLenses)+import Control.Monad (mzero)+import qualified Data.Aeson as Aeson import Data.Geospatial.Internal.BasicTypes import Data.Geospatial.Internal.Geometry.Aeson-import Data.LinearRing+import qualified Data.LinearRing as LinearRing+import qualified Data.Vector as Vector+import GHC.Generics (Generic) -import Control.Lens (makeLenses)-import Control.Monad (mzero)-import Data.Aeson (FromJSON (..),- ToJSON (..),- Value (..))+newtype GeoPolygon = GeoPolygon { _unGeoPolygon :: Vector.Vector (LinearRing.LinearRing GeoPositionWithoutCRS) } deriving (Show, Eq, Generic, NFData) -newtype GeoPolygon = GeoPolygon { _unGeoPolygon :: [LinearRing GeoPositionWithoutCRS] } deriving (Show, Eq)+-- Vector.Vector (LinearRing.LinearRing DoubleArray) makeLenses ''GeoPolygon -- instances -instance ToJSON GeoPolygon where--- toJSON :: a -> Value- toJSON = makeGeometryGeoAeson "Polygon" . _unGeoPolygon+instance Aeson.ToJSON GeoPolygon where+ -- toJSON :: a -> Value+ toJSON = makeGeometryGeoAeson "Polygon" . _unGeoPolygon -instance FromJSON GeoPolygon where--- parseJSON :: Value -> Parser a- parseJSON (Object o) = readGeometryGeoAeson "Polygon" GeoPolygon o- parseJSON _ = mzero+instance Aeson.FromJSON GeoPolygon where+ -- parseJSON :: Value -> Parser a+ parseJSON (Aeson.Object o) = readGeometryGeoAeson "Polygon" GeoPolygon o+ parseJSON _ = mzero
src/Data/LineString.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE NoImplicitPrelude #-} ------------------------------------------------------------------- -- |@@ -15,33 +17,39 @@ -- * Type LineString , ListToLineStringError(..)+ , VectorToLineStringError(..) -- * Functions+ , toVector+ , combineToVector+ , fromVector , fromLineString , fromList+ , Data.LineString.map+ , Data.LineString.foldr+ , Data.LineString.foldMap , makeLineString , lineStringHead , lineStringLast , lineStringLength ) where -import Prelude hiding (foldr)+import Prelude hiding (foldr) -import Control.Applicative (Applicative (..))-import Control.Lens (( # ), (^?))-import Control.Monad (mzero)-import Data.Aeson (FromJSON (..), ToJSON (..), Value)-import Data.Aeson.Types (Parser, typeMismatch)-import Data.Foldable (Foldable (..))-import Data.Functor ((<$>))-import Data.Maybe (fromMaybe)-import Data.Traversable (Traversable (..))-import Data.Validation (Validate (..), Validation, _Failure,- _Success)+import Control.Applicative (Applicative (..))+import Control.DeepSeq+import Control.Lens (( # ), (^?))+import Control.Monad (mzero)+import Data.Aeson (FromJSON (..), ToJSON (..), Value)+import Data.Aeson.Types (Parser, typeMismatch)+import Data.Maybe (fromMaybe)+import qualified Data.Validation as Validation+import qualified Data.Vector.Storable as VectorStorable+import GHC.Generics (Generic) -- | -- a LineString has at least 2 elements ---data LineString a = LineString a a [a] deriving (Eq)+data LineString a = LineString a a (VectorStorable.Vector a) deriving (Eq, Generic, NFData) -- | -- When converting a List to a LineString, here is a list of things that can go wrong:@@ -54,6 +62,17 @@ | SingletonList deriving (Eq) +-- |+-- When converting a Vector to a LineString, here is a list of things that can go wrong:+--+-- * The vector was empty+-- * The vector only had one element+--+data VectorToLineStringError =+ VectorEmpty+ | SingletonVector+ deriving (Eq)+ -- functions -- |@@ -65,85 +84,132 @@ -- | -- returns the last element in the string ---lineStringLast :: LineString a -> a+lineStringLast :: (VectorStorable.Storable a) => LineString a -> a lineStringLast (LineString _ x xs) = fromMaybe x (safeLast xs) -- | -- returns the number of elements in the list, including the replicated element at the end of the list. ---lineStringLength :: LineString a -> Int-lineStringLength (LineString _ _ xs) = 2 + length xs+lineStringLength :: (VectorStorable.Storable a) => LineString a -> Int+lineStringLength (LineString _ _ xs) = 2 + VectorStorable.length xs -- | -- This function converts it into a list and appends the given element to the end. ---fromLineString :: LineString a -> [a]-fromLineString (LineString x y zs) = x : y : zs+fromLineString :: (VectorStorable.Storable a) => LineString a -> [a]+fromLineString (LineString x y zs) = x : y : VectorStorable.toList zs -- | -- creates a LineString out of a list of elements, -- if there are enough elements (needs at least 2) elements ---fromList :: (Validate v) => [a] -> v ListToLineStringError (LineString a)-fromList [] = _Failure # ListEmpty-fromList [_] = _Failure # SingletonList-fromList (x:y:zs) = _Success # LineString x y zs+fromList :: (Validation.Validate v, VectorStorable.Storable a) => [a] -> v ListToLineStringError (LineString a)+fromList [] = Validation._Failure # ListEmpty+fromList [_] = Validation._Failure # SingletonList+fromList (x:y:zs) = Validation._Success # LineString x y (VectorStorable.fromList zs)+{-# INLINE fromList #-} -- |+-- create a vector from a LineString by combining values.+-- LineString 1 2 [3,4] (,) --> Vector [(1,2),(2,3),(3,4)]+--+combineToVector :: (VectorStorable.Storable a, VectorStorable.Storable b) => (a -> a -> b) -> LineString a -> VectorStorable.Vector b+combineToVector combine (LineString a b rest) = VectorStorable.cons (combine a b) combineRest+ where+ combineRest =+ if VectorStorable.null rest+ then+ VectorStorable.empty+ else+ (VectorStorable.zipWith combine <*> VectorStorable.tail) (VectorStorable.cons b rest)+{-# INLINE combineToVector #-}++-- |+-- create a vector from a LineString.+-- LineString 1 2 [3,4] --> Vector [1,2,3,4]+--+toVector :: (VectorStorable.Storable a) => LineString a -> VectorStorable.Vector a+toVector (LineString a b rest) = VectorStorable.cons a (VectorStorable.cons b rest)+{-# INLINE toVector #-}++-- |+-- creates a LineString out of a vector of elements,+-- if there are enough elements (needs at least 2) elements+--+fromVector :: (Validation.Validate v, VectorStorable.Storable a) => VectorStorable.Vector a -> v VectorToLineStringError (LineString a)+fromVector v =+ if VectorStorable.null v then+ Validation._Failure # VectorEmpty+ else+ fromVector' (VectorStorable.head v) (VectorStorable.tail v)+{-# INLINE fromVector #-}++fromVector' :: (Validation.Validate v, VectorStorable.Storable a) => a -> VectorStorable.Vector a -> v VectorToLineStringError (LineString a)+fromVector' first v =+ if VectorStorable.null v then+ Validation._Failure # SingletonVector+ else+ Validation._Success # LineString first (VectorStorable.head v) (VectorStorable.tail v)+{-# INLINE fromVector' #-}++-- | -- Creates a LineString -- @makeLineString x y zs@ creates a `LineString` homomorphic to the list @[x, y] ++ zs@ ---makeLineString- :: a -- ^ The first element- -> a -- ^ The second element- -> [a] -- ^ The rest of the optional elements+makeLineString :: (VectorStorable.Storable a) =>+ a -- ^ The first element+ -> a -- ^ The second element+ -> VectorStorable.Vector a -- ^ The rest of the optional elements -> LineString a makeLineString = LineString - -- instances instance Show ListToLineStringError where show ListEmpty = "List Empty" show SingletonList = "Singleton List" -instance (Show a) => Show (LineString a) where+instance Show VectorToLineStringError where+ show VectorEmpty = "Vector Empty"+ show SingletonVector = "Singleton Vector"++instance (Show a, VectorStorable.Storable a) => Show (LineString a) where show = show . fromLineString -instance Functor LineString where- fmap f (LineString x y zs) = LineString (f x) (f y) (fmap f zs)+map :: (VectorStorable.Storable a, VectorStorable.Storable b) => (a -> b) -> LineString a -> LineString b+map f (LineString x y zs) = LineString (f x) (f y) (VectorStorable.map f zs)+{-# INLINE map #-} --- | This instance of Foldable will run through the entire ring, closing the+-- | This will run through the entire ring, closing the -- loop by also passing the initial element in again at the end. ---instance Foldable LineString where--- foldr :: (a -> b -> b) -> b -> LineString a -> b- foldr f u (LineString x y zs) = f x (f y (foldr f u zs))+foldr :: (VectorStorable.Storable a) => (a -> b -> b) -> b -> LineString a -> b+foldr f u (LineString x y zs) = f x (f y (VectorStorable.foldr f u zs))+{-# INLINE foldr #-} -instance Traversable LineString where--- sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a)- sequenceA (LineString fx fy fzs) = LineString <$> fx <*> fy <*> sequenceA fzs+foldMap :: (Monoid m, VectorStorable.Storable a) => (a -> m) -> LineString a -> m+foldMap f = foldr (mappend . f) mempty+{-# INLINE foldMap #-} -instance (ToJSON a) => ToJSON (LineString a) where+instance (ToJSON a, VectorStorable.Storable a) => ToJSON (LineString a) where -- toJSON :: a -> Value toJSON = toJSON . fromLineString -instance (FromJSON a, Show a) => FromJSON (LineString a) where+instance (FromJSON a, Show a, VectorStorable.Storable a) => FromJSON (LineString a) where -- parseJSON :: Value -> Parser a parseJSON v = do xs <- parseJSON v let vxs = fromListValidated xs- maybe (parseError v (vxs ^? _Failure)) return (vxs ^? _Success)+ maybe (parseError v (vxs ^? Validation._Failure)) return (vxs ^? Validation._Success) -- helpers -fromListValidated :: [a] -> Validation ListToLineStringError (LineString a)+fromListValidated :: (VectorStorable.Storable a) => [a] -> Validation.Validation ListToLineStringError (LineString a) fromListValidated = fromList parseError :: Value -> Maybe ListToLineStringError -> Parser b parseError v = maybe mzero (\e -> typeMismatch (show e) v) -safeLast :: [a] -> Maybe a-safeLast [] = Nothing-safeLast [x] = Just x-safeLast (_:xs) = safeLast xs+safeLast :: (VectorStorable.Storable a) => VectorStorable.Vector a -> Maybe a+safeLast x = if VectorStorable.null x then Nothing else Just $ VectorStorable.last x+{-# INLINE safeLast #-}
src/Data/LinearRing.hs view
@@ -1,3 +1,6 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE NoImplicitPrelude #-} ------------------------------------------------------------------- -- |@@ -16,34 +19,45 @@ -- * Type LinearRing , ListToLinearRingError(..)+ , VectorToLinearRingError(..) -- * Functions+ , toVector+ , combineToVector+ , fromVector , fromLinearRing , fromList , fromListWithEqCheck , makeLinearRing+ , Data.LinearRing.map+ , Data.LinearRing.foldr+ , Data.LinearRing.foldMap , ringHead , ringLength ) where -import Prelude hiding (foldr)+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 800+import Prelude hiding (foldr)+#else+import Prelude+#endif -import Control.Applicative (Applicative (..))-import Control.Lens (( # ), (^?))-import Control.Monad (mzero)-import Data.Aeson (FromJSON (..), ToJSON (..), Value)-import Data.Aeson.Types (Parser, typeMismatch)-import Data.Foldable (Foldable (..))-import Data.Functor ((<$>))-import Data.List (intercalate)-import Data.List.NonEmpty as NL (NonEmpty, toList)-import Data.Traversable (Traversable (..))-import Data.Validation (Validate (..), Validation, _Failure,- _Success)+import Control.Applicative (Applicative (..))+import Control.DeepSeq+import Control.Lens (( # ), (^?))+import Control.Monad (mzero)+import Data.Aeson (FromJSON (..), ToJSON (..), Value)+import Data.Aeson.Types (Parser, typeMismatch)+import Data.Functor ((<$>))+import Data.List (intercalate)+import Data.List.NonEmpty as NL (NonEmpty, toList)+import qualified Data.Validation as Validation+import qualified Data.Vector.Storable as VectorStorable+import GHC.Generics (Generic) -- | -- a LinearRing has at least 3 (distinct) elements ---data LinearRing a = LinearRing a a a [a] deriving (Eq)+data LinearRing a = LinearRing a a a (VectorStorable.Vector a) deriving (Eq, Show, Generic, NFData) -- | -- When converting a List to a LinearRing there are some things that can go wrong@@ -57,6 +71,17 @@ | HeadNotEqualToLast a a deriving (Eq) +-- |+-- When converting a Vector to a LinearRing there are some things that can go wrong+--+-- * The vector can be too short+-- * The head may not be equal to the last element in the list+--+data VectorToLinearRingError a =+ VectorTooShort Int+ | FirstNotEqualToLast a a+ deriving (Eq)+ -- functions -- |@@ -68,14 +93,14 @@ -- | -- returns the number of elements in the list, including the replicated element at the end of the list. ---ringLength :: LinearRing a -> Int-ringLength (LinearRing _ _ _ xs) = 4 + length xs+ringLength :: (VectorStorable.Storable a) => LinearRing a -> Int+ringLength (LinearRing _ _ _ xs) = 4 + VectorStorable.length xs -- | -- This function converts it into a list and appends the given element to the end. ---fromLinearRing :: LinearRing a -> [a]-fromLinearRing (LinearRing x y z ws) = x : y : z : foldr (:) [x] ws+fromLinearRing :: (VectorStorable.Storable a) => LinearRing a -> [a]+fromLinearRing (LinearRing x y z ws) = x : y : z : VectorStorable.foldr (:) [x] ws -- | -- creates a LinearRing out of a list of elements,@@ -94,24 +119,60 @@ -- -- Unfortunately it doesn't check that the last element is the same as the first at the moment... ---fromList- :: (Validate v, Functor (v (NonEmpty (ListToLinearRingError a))))- => [a]- -> v (NonEmpty (ListToLinearRingError a)) (LinearRing a)-fromList (x:y:z:ws@(_:_)) = _Success # LinearRing x y z (foldrDropLast (:) [] ws)-fromList xs = _Failure # return (ListTooShort (length xs))+fromList :: (Eq a, Show a, VectorStorable.Storable a, Validation.Validate v, Functor (v (NonEmpty (ListToLinearRingError a)))) => [a] -> v (NonEmpty (ListToLinearRingError a)) (LinearRing a)+fromList (x:y:z:ws@(_:_)) = Validation._Success # LinearRing x y z (fromListDropLast ws)+fromList xs = Validation._Failure # pure (ListTooShort (length xs))+{-# INLINE fromList #-} -- | -- The expensive version of fromList that checks whether the head and last elements -- are equal. ---fromListWithEqCheck- :: (Eq a, Validate v, Applicative (v (NonEmpty (ListToLinearRingError a))))- => [a]- -> v (NonEmpty (ListToLinearRingError a)) (LinearRing a)+fromListWithEqCheck :: (Eq a, Show a, VectorStorable.Storable a, Validation.Validate v, Applicative (v (NonEmpty (ListToLinearRingError a)))) => [a] -> v (NonEmpty (ListToLinearRingError a)) (LinearRing a) fromListWithEqCheck xs = checkHeadAndLastEq xs *> fromList xs -- |+-- create a vector from a LinearRing by combining values.+-- LinearRing 1 2 3 [4,1] (,) --> Vector [(1,2),(2,3),(3,4),(4,1)]+--+combineToVector :: (VectorStorable.Storable a, VectorStorable.Storable b) => (a -> a -> b) -> LinearRing a -> VectorStorable.Vector b+combineToVector combine (LinearRing a b c rest) = VectorStorable.cons (combine a b) (VectorStorable.cons (combine b c) combineRest)+ where+ combineRest =+ if VectorStorable.null rest+ then+ VectorStorable.empty+ else+ (VectorStorable.zipWith combine <*> VectorStorable.tail) (VectorStorable.cons c rest)+{-# INLINE combineToVector #-}++-- |+-- create a vector from a LinearRing.+-- LinearRing 1 2 3 [4,1] --> Vector [1,2,3,4,1)]+--+toVector :: (VectorStorable.Storable a) => LinearRing a -> VectorStorable.Vector a+toVector (LinearRing a b c rest) = VectorStorable.cons a (VectorStorable.cons b (VectorStorable.cons c rest))+{-# INLINE toVector #-}++-- |+-- creates a LinearRing out of a vector of elements,+-- if there are enough elements (needs at least 3) elements+--+-- fromVector (x:y:z:ws@(_:_)) = _Success # LinearRing x y z (fromListDropLast ws)+-- fromList xs = _Failure # return (ListTooShort (length xs))++fromVector :: (Eq a, Show a, VectorStorable.Storable a, Validation.Validate v, Functor (v (NonEmpty (ListToLinearRingError a)))) => VectorStorable.Vector a -> v (NonEmpty (VectorToLinearRingError a)) (LinearRing a)+fromVector v =+ if VectorStorable.length v >= 3 then+ if VectorStorable.head v == VectorStorable.last v then+ Validation._Success # LinearRing (VectorStorable.unsafeIndex v 0) (VectorStorable.unsafeIndex v 1) (VectorStorable.unsafeIndex v 2) (VectorStorable.drop 3 v)+ else+ Validation._Failure # pure (FirstNotEqualToLast (VectorStorable.head v) (VectorStorable.last v))+ else+ Validation._Failure # pure (VectorTooShort (VectorStorable.length v))+{-# INLINE fromVector #-}++-- | -- Creates a LinearRing -- @makeLinearRing x y z xs@ creates a `LinearRing` homomorphic to the list @[x, y, z] ++ xs@ -- the list @xs@ should NOT contain the first element repeated, i.e the loop does not need to@@ -119,69 +180,65 @@ -- -- Repeating the first element is just redundant. ---makeLinearRing- :: a -- ^ The first element- -> a -- ^ The second element- -> a -- ^ The third element- -> [a] -- ^ The rest of the optional elements (WITHOUT the first element repeated at the end)+makeLinearRing :: (Eq a, Show a, VectorStorable.Storable a) =>+ a -- ^ The first element+ -> a -- ^ The second element+ -> a -- ^ The third element+ -> VectorStorable.Vector a -- ^ The rest of the optional elements (WITHOUT the first element repeated at the end) -> LinearRing a makeLinearRing = LinearRing - -- instances -instance (Show a) => Show (ListToLinearRingError a) where+instance (Show a, VectorStorable.Storable a) => Show (ListToLinearRingError a) where show (ListTooShort n) = "List too short: (length = " ++ show n ++ ")" show (HeadNotEqualToLast h l) = "head (" ++ show h ++ ") /= last(" ++ show l ++ ")" -instance (Show a) => Show (LinearRing a) where- show = show . fromLinearRing+instance (Show a, VectorStorable.Storable a) => Show (VectorToLinearRingError a) where+ show (VectorTooShort n) = "Vector too short: (length = " ++ show n ++ ")"+ show (FirstNotEqualToLast h l) = "head (" ++ show h ++ ") /= last(" ++ show l ++ ")" -instance Functor LinearRing where- fmap f (LinearRing x y z ws) = LinearRing (f x) (f y) (f z) (fmap f ws)+map :: (VectorStorable.Storable a, VectorStorable.Storable b) => (a -> b) -> LinearRing a -> LinearRing b+map f (LinearRing x y z ws) = LinearRing (f x) (f y) (f z) (VectorStorable.map f ws)+{-# INLINE map #-} --- | This instance of Foldable will run through the entire ring, closing the+-- | This will run through the entire ring, closing the -- loop by also passing the initial element in again at the end. ---instance Foldable LinearRing where--- foldr :: (a -> b -> b) -> b -> LinearRing a -> b- foldr f u (LinearRing x y z ws) = f x (f y (f z (foldr f (f x u) ws)))+foldr :: VectorStorable.Storable a => (a -> b -> b) -> b -> LinearRing a -> b+foldr f u (LinearRing x y z ws) = f x (f y (f z (VectorStorable.foldr f (f x u) ws)))+{-# INLINE foldr #-} --- |--- When traversing this Structure, the Applicative context--- of the last element will be appended to the end to close the loop----instance Traversable LinearRing where--- sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a)- sequenceA (LinearRing fx fy fz fws) = (LinearRing <$> fx <*> fy <*> fz <*> sequenceA fws) <* fx+foldMap :: (Monoid m, VectorStorable.Storable a) => (a -> m) -> LinearRing a -> m+foldMap f = foldr (mappend . f) mempty+{-# INLINE foldMap #-} -instance (ToJSON a) => ToJSON (LinearRing a) where+instance (ToJSON a, VectorStorable.Storable a) => ToJSON (LinearRing a) where -- toJSON :: a -> Value toJSON = toJSON . fromLinearRing -instance (FromJSON a, Show a) => FromJSON (LinearRing a) where+instance (Eq a, FromJSON a, Show a, VectorStorable.Storable a) => FromJSON (LinearRing a) where -- parseJSON :: Value -> Parser a parseJSON v = do xs <- parseJSON v let vxs = fromListAcc xs- maybe (parseError v (vxs ^? _Failure)) return (vxs ^? _Success)+ maybe (parseError v (vxs ^? Validation._Failure)) return (vxs ^? Validation._Success) -- helpers -fromListAcc :: [a] -> Validation (NonEmpty (ListToLinearRingError a)) (LinearRing a)+fromListAcc :: (Eq a, Show a, VectorStorable.Storable a) => [a] -> Validation.Validation (NonEmpty (ListToLinearRingError a)) (LinearRing a) fromListAcc = fromList -showErrors :: (Show a) => NonEmpty (ListToLinearRingError a) -> String+showErrors :: (Show a, VectorStorable.Storable a) => NonEmpty (ListToLinearRingError a) -> String showErrors = intercalate ", " . NL.toList . fmap show -parseError :: (Show a) => Value -> Maybe (NonEmpty (ListToLinearRingError a)) -> Parser b+parseError :: (Show a, VectorStorable.Storable a) => Value -> Maybe (NonEmpty (ListToLinearRingError a)) -> Parser b parseError v = maybe mzero (\e -> typeMismatch (showErrors e) v) -checkHeadAndLastEq- :: (Eq a, Validate v, Functor (v (NonEmpty (ListToLinearRingError a))))+checkHeadAndLastEq :: (Eq a, VectorStorable.Storable a, Validation.Validate v, Functor (v (NonEmpty (ListToLinearRingError a)))) => [a] -> v (NonEmpty (ListToLinearRingError a)) ()-checkHeadAndLastEq = maybe (_Failure # return (ListTooShort 0)) (\(h, l) -> if h == l then _Success # () else _Failure # return (HeadNotEqualToLast h l)) . mhl+checkHeadAndLastEq = maybe (Validation._Failure # pure (ListTooShort 0)) (\(h, l) -> if h == l then Validation._Success # () else Validation._Failure # pure (HeadNotEqualToLast h l)) . mhl where mhl ::[a] -> Maybe (a, a) mhl xs = (,) <$> safeHead xs <*> safeLast xs@@ -195,10 +252,7 @@ safeLast [x] = Just x safeLast (_:xs) = safeLast xs --- |--- Does a fold but ignores the last element of the list----foldrDropLast :: (a -> b -> b) -> b -> [a] -> b-foldrDropLast _ x [] = x-foldrDropLast _ x [_] = x-foldrDropLast f x (y:ys) = f y (foldrDropLast f x ys)+fromListDropLast :: (Eq a, VectorStorable.Storable a) => [a] -> VectorStorable.Vector a+fromListDropLast [] = VectorStorable.empty+fromListDropLast [_] = VectorStorable.empty+fromListDropLast x = VectorStorable.unsafeInit $ VectorStorable.fromList x
test/Arbitrary.hs view
@@ -2,14 +2,23 @@ module Arbitrary where +import qualified Data.Vector as Vector+import qualified Data.Vector.Storable as VectorStorable import Test.Tasty.QuickCheck (Arbitrary, arbitrary)+ -- Local import Data.LinearRing (LinearRing, makeLinearRing) import Data.LineString (LineString, makeLineString) -instance (Arbitrary a) => Arbitrary (LinearRing a) where+instance (Arbitrary a, Eq a, Show a, VectorStorable.Storable a) => Arbitrary (LinearRing a) where arbitrary = makeLinearRing <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary -instance (Arbitrary a) => Arbitrary (LineString a) where+instance (Arbitrary a, Eq a, Show a, VectorStorable.Storable a) => Arbitrary (LineString a) where arbitrary = makeLineString <$> arbitrary <*> arbitrary <*> arbitrary++instance (Arbitrary a, VectorStorable.Storable a) => Arbitrary (VectorStorable.Vector a) where+ arbitrary = fmap VectorStorable.fromList arbitrary++instance (Arbitrary a) => Arbitrary (Vector.Vector a) where+ arbitrary = fmap Vector.fromList arbitrary
test/Data/LineStringTests.hs view
@@ -1,16 +1,16 @@ module Data.LineStringTests where -import Data.Foldable (Foldable (..))-import Data.Validation (Validation (..))+import Data.Validation (Validation (..))+import qualified Data.Vector.Storable as VectorStorable import Test.Tasty-import Test.Tasty.Hspec (Spec, context, describe, it, shouldBe,- testSpec)-import Test.Tasty.QuickCheck (Property, property, testProperty)+import Test.Tasty.Hspec (Spec, context, describe,+ it, shouldBe, testSpec)+import Test.Tasty.QuickCheck (Property, property,+ testProperty) -- Local-import Arbitrary ()-import Data.LineString--+import Arbitrary ()+import qualified Data.Geospatial.Internal.BasicTypes as BasicTypes+import qualified Data.LineString as LineString -- Tests tests :: IO TestTree@@ -29,6 +29,9 @@ specTests = do specs <- sequence [ testSpec "Data.LineString.fromList" testFromList+ , testSpec "Data.LineString.fromVector" testFromVector+ , testSpec "Data.LineString.toVector" testToVector+ , testSpec "Data.LineString.combineToVector" testCombineToVector ] pure $ testGroup "Data.LineStringTests.Spec" specs @@ -36,20 +39,20 @@ -- (\xs -> lineStringLength xs == (length (fromLineString xs))) (xs :: LineString Int) ---testLineStringLength :: LineString Int -> Property-testLineStringLength xs = property $ lineStringLength xs == length (fromLineString xs)+testLineStringLength :: LineString.LineString Int -> Property+testLineStringLength xs = property $ LineString.lineStringLength xs == length (LineString.fromLineString xs) -- (\xs -> length (fromLineString xs) >= 4) (xs :: LineString Int) ---testFromLineString :: LineString Int -> Property-testFromLineString xs = property $ length (fromLineString xs) >= 2+testFromLineString :: LineString.LineString Int -> Property+testFromLineString xs = property $ length (LineString.fromLineString xs) >= 2 -- > (\xs -> (foldr (:) [] xs) == (fromLineString xs)) (xs :: LineString Int) ----- > (\xs -> (lineStringHead xs) == (foldr'' (\a -> const a) 0 xs)) (xs :: LineString Int)+-- > (\xs -> (lineStringHead xs) == (foldr (\a -> const a) 0 xs)) (xs :: LineString Int) ---testFoldable :: LineString Int -> Property-testFoldable xs = property $ (foldr (:) [] xs == fromLineString xs) && (lineStringHead xs == foldr' const 0 xs)+testFoldable :: LineString.LineString Int -> Property+testFoldable xs = property $ (LineString.foldr (:) [] xs == LineString.fromLineString xs) && (LineString.lineStringHead xs == LineString.foldr const 0 xs) -- Spec @@ -72,14 +75,41 @@ testFromList = describe "fromList" $ do it "creates a LineString out of a list of elements" $ do- fromList ([0, 1] :: [Int]) `shouldBe` Success (makeLineString 0 1 [])- fromList ([0, 1, 2] :: [Int]) `shouldBe` Success (makeLineString 0 1 [2])- fromList ([0, 1, 2, 4, 5, 0] :: [Int]) `shouldBe` Success (makeLineString 0 1 [2, 4, 5, 0])+ LineString.fromList ([0, 1] :: [Int]) `shouldBe` Success (LineString.makeLineString 0 1 VectorStorable.empty)+ LineString.fromList ([0, 1, 2] :: [Int]) `shouldBe` Success (LineString.makeLineString 0 1 (VectorStorable.fromList [2]))+ LineString.fromList ([0, 1, 2, 4, 5, 0] :: [Int]) `shouldBe` Success (LineString.makeLineString 0 1 (VectorStorable.fromList [2, 4, 5, 0])) context "when provided with invalid input" $ it "fails" $ do- fromList ([] :: [Int]) `shouldBe` Failure ListEmpty- fromList ([0] :: [Int]) `shouldBe` Failure SingletonList+ LineString.fromList ([] :: [Int]) `shouldBe` Failure LineString.ListEmpty+ LineString.fromList ([0] :: [Int]) `shouldBe` Failure LineString.SingletonList +testFromVector :: Spec+testFromVector =+ describe "fromVector" $ do+ it "creates a LineString out of a Vector of elements" $ do+ LineString.fromVector (VectorStorable.fromList [0, 1] :: (VectorStorable.Vector Int)) `shouldBe` Success (LineString.makeLineString 0 1 VectorStorable.empty)+ LineString.fromVector (VectorStorable.fromList [0, 1, 2] :: (VectorStorable.Vector Int)) `shouldBe` Success (LineString.makeLineString 0 1 (VectorStorable.fromList [2]))+ LineString.fromVector (VectorStorable.fromList [0, 1, 2, 4, 5, 0] :: (VectorStorable.Vector Int)) `shouldBe` Success (LineString.makeLineString 0 1 (VectorStorable.fromList [2, 4, 5, 0]))+ context "when provided with invalid input" $+ it "fails" $ do+ LineString.fromVector (VectorStorable.fromList [] :: (VectorStorable.Vector Int)) `shouldBe` Failure LineString.VectorEmpty+ LineString.fromVector (VectorStorable.fromList [0] :: (VectorStorable.Vector Int)) `shouldBe` Failure LineString.SingletonVector++testCombineToVector :: Spec+testCombineToVector =+ describe "combineToVector" $+ it "combine a LineString using PointXY" $ do+ LineString.combineToVector BasicTypes.PointXY (LineString.makeLineString 0 1 VectorStorable.empty) `shouldBe` VectorStorable.fromList [BasicTypes.PointXY 0 1]+ LineString.combineToVector BasicTypes.PointXY (LineString.makeLineString 0 1 (VectorStorable.fromList [2])) `shouldBe` VectorStorable.fromList [BasicTypes.PointXY 0 1, BasicTypes.PointXY 1 2]+ LineString.combineToVector BasicTypes.PointXY (LineString.makeLineString 0 1 (VectorStorable.fromList [2, 4, 5, 0])) `shouldBe` VectorStorable.fromList [BasicTypes.PointXY 0 1, BasicTypes.PointXY 1 2, BasicTypes.PointXY 2 4, BasicTypes.PointXY 4 5, BasicTypes.PointXY 5 0]++testToVector :: Spec+testToVector =+ describe "toVector" $+ it "from a LineString to a vector" $ do+ LineString.toVector (LineString.makeLineString 0 1 VectorStorable.empty) `shouldBe` VectorStorable.fromList ([0, 1] :: [Int])+ LineString.toVector (LineString.makeLineString 0 1 (VectorStorable.fromList [2])) `shouldBe` VectorStorable.fromList ([0, 1, 2] :: [Int])+ LineString.toVector (LineString.makeLineString 0 1 (VectorStorable.fromList [2, 4, 5, 0])) `shouldBe` VectorStorable.fromList ([0, 1, 2, 4, 5, 0] :: [Int])+ -- TODO -- (\xs -> safeLast (fromLineString xs) == Just (lineStringHead xs)) (xs :: LineString Int)---
test/Data/LinearRingTests.hs view
@@ -1,16 +1,17 @@ module Data.LinearRingTests where -import Data.Foldable (Foldable (..))-import Data.List.NonEmpty (NonEmpty (..))-import Data.Validation (Validation (..))+import qualified Data.List.NonEmpty as ListNonEmpty+import qualified Data.Validation as Validation+import qualified Data.Vector.Storable as VectorStorable import Test.Tasty-import Test.Tasty.Hspec (Spec, context, describe, it, shouldBe,- testSpec)-import Test.Tasty.QuickCheck (Property, property, testProperty)+import Test.Tasty.Hspec (Spec, context, describe,+ it, shouldBe, testSpec)+import Test.Tasty.QuickCheck (Property, property,+ testProperty) -- Local-import Arbitrary ()-import Data.LinearRing-+import Arbitrary ()+import qualified Data.Geospatial.Internal.BasicTypes as BasicTypes+import qualified Data.LinearRing as LinearRing -- Tests @@ -30,6 +31,9 @@ specTests = do specs <- sequence [ testSpec "Data.LinearRing.fromList" testFromList+ , testSpec "Data.LinearRing.fromVector" testFromVector+ , testSpec "Data.LinearRing.combineToVector" testCombineToVector+ , testSpec "Data.LinearRing.testToVector" testToVector ] pure $ testGroup "Data.LinearRingTests.Spec" specs @@ -37,20 +41,20 @@ -- > (\xs -> ringLength xs == (length (fromLinearRing xs))) (xs :: LinearRing Int) ---testRingLength :: LinearRing Int -> Property-testRingLength xs = property $ ringLength xs == length (fromLinearRing xs)+testRingLength :: LinearRing.LinearRing Int -> Property+testRingLength xs = property $ LinearRing.ringLength xs == length (LinearRing.fromLinearRing xs) -- > (\xs -> length (fromLinearRing xs) >= 4) (xs :: LinearRing Int) ---testFromLinearRing :: LinearRing Int -> Property-testFromLinearRing xs = property $ length (fromLinearRing xs) >= 4+testFromLinearRing :: LinearRing.LinearRing Int -> Property+testFromLinearRing xs = property $ length (LinearRing.fromLinearRing xs) >= 4 -- > (\xs -> (foldr (:) [] xs) == (fromLinearRing xs)) (xs :: LinearRing Int) ----- > (\xs -> (ringHead xs) == (foldr'' (\a -> const a) 0 xs)) (xs :: LinearRing Int)+-- > (\xs -> (ringHead xs) == (foldr (\a -> const a) 0 xs)) (xs :: LinearRing Int) ---testFoldable :: LinearRing Int -> Property-testFoldable xs = property $ (foldr (:) [] xs == fromLinearRing xs) && (ringHead xs == foldr' const 0 xs)+testFoldable :: LinearRing.LinearRing Int -> Property+testFoldable xs = property $ (LinearRing.foldr (:) [] xs == LinearRing.fromLinearRing xs) && (LinearRing.ringHead xs == LinearRing.foldr const 0 xs) -- Spec @@ -82,16 +86,48 @@ testFromList = describe "fromList" $ do it "creates a LinearRing out of a list of elements" $ do- fromList ([0, 1, 2, 3] :: [Int]) `shouldBe` Success (makeLinearRing 0 1 2 [])- fromList ([0, 1, 2, 4, 0] :: [Int]) `shouldBe` Success (makeLinearRing 0 1 2 [4])- fromList ([0, 1, 2, 4, 5, 0] :: [Int]) `shouldBe` Success (makeLinearRing 0 1 2 [4, 5])- fromList ([0, 1, 2, 4, 5, 6] :: [Int]) `shouldBe` Success (makeLinearRing 0 1 2 [4, 5])+ LinearRing.fromList ([0, 1, 2, 3] :: [Int]) `shouldBe` Validation.Success (LinearRing.makeLinearRing 0 1 2 VectorStorable.empty)+ LinearRing.fromList ([0, 1, 2, 4, 0] :: [Int]) `shouldBe` Validation.Success (LinearRing.makeLinearRing 0 1 2 (VectorStorable.fromList [4]))+ LinearRing.fromList ([0, 1, 2, 4, 5, 0] :: [Int]) `shouldBe` Validation.Success (LinearRing.makeLinearRing 0 1 2 (VectorStorable.fromList [4,5]))+ LinearRing.fromList ([0, 1, 2, 4, 5, 6] :: [Int]) `shouldBe` Validation.Success (LinearRing.makeLinearRing 0 1 2 (VectorStorable.fromList [4,5])) context "when provided with invalid input" $ it "fails" $ do- fromList [] `shouldBe` Failure (ListTooShort 0 :| [] :: NonEmpty (ListToLinearRingError Int))- fromList [0] `shouldBe` Failure (ListTooShort 1 :| [] :: NonEmpty (ListToLinearRingError Int))- fromList [0, 1] `shouldBe` Failure (ListTooShort 2 :| [] :: NonEmpty (ListToLinearRingError Int))- fromList [0, 1, 2] `shouldBe` Failure (ListTooShort 3 :| [] :: NonEmpty (ListToLinearRingError Int))+ LinearRing.fromList [] `shouldBe` Validation.Failure (LinearRing.ListTooShort 0 ListNonEmpty.:| [] :: ListNonEmpty.NonEmpty (LinearRing.ListToLinearRingError Int))+ LinearRing.fromList [0] `shouldBe` Validation.Failure (LinearRing.ListTooShort 1 ListNonEmpty.:| [] :: ListNonEmpty.NonEmpty (LinearRing.ListToLinearRingError Int))+ LinearRing.fromList [0, 1] `shouldBe` Validation.Failure (LinearRing.ListTooShort 2 ListNonEmpty.:| [] :: ListNonEmpty.NonEmpty (LinearRing.ListToLinearRingError Int))+ LinearRing.fromList [0, 1, 2] `shouldBe` Validation.Failure (LinearRing.ListTooShort 3 ListNonEmpty.:| [] :: ListNonEmpty.NonEmpty (LinearRing.ListToLinearRingError Int))++testFromVector :: Spec+testFromVector =+ describe "fromVector" $ do+ it "creates a LinearRing out of a vector of elements" $ do+ LinearRing.fromVector (VectorStorable.fromList ([0, 1, 0] :: [Int])) `shouldBe` Validation.Success (LinearRing.makeLinearRing 0 1 0 VectorStorable.empty)+ LinearRing.fromVector (VectorStorable.fromList ([0, 1, 2, 0] :: [Int])) `shouldBe` Validation.Success (LinearRing.makeLinearRing 0 1 2 (VectorStorable.fromList [0]))+ LinearRing.fromVector (VectorStorable.fromList ([0, 1, 2, 4, 0] :: [Int])) `shouldBe` Validation.Success (LinearRing.makeLinearRing 0 1 2 (VectorStorable.fromList [4, 0]))+ LinearRing.fromVector (VectorStorable.fromList ([0, 1, 2, 4, 5, 0]:: [Int])) `shouldBe` Validation.Success (LinearRing.makeLinearRing 0 1 2 (VectorStorable.fromList [4, 5, 0]))+ context "when provided with invalid input" $+ it "fails" $ do+ LinearRing.fromVector (VectorStorable.fromList []) `shouldBe` Validation.Failure (LinearRing.VectorTooShort 0 ListNonEmpty.:| [] :: ListNonEmpty.NonEmpty (LinearRing.VectorToLinearRingError Int))+ LinearRing.fromVector (VectorStorable.fromList [0]) `shouldBe` Validation.Failure (LinearRing.VectorTooShort 1 ListNonEmpty.:| [] :: ListNonEmpty.NonEmpty (LinearRing.VectorToLinearRingError Int))+ LinearRing.fromVector (VectorStorable.fromList [0, 1]) `shouldBe` Validation.Failure (LinearRing.VectorTooShort 2 ListNonEmpty.:| [] :: ListNonEmpty.NonEmpty (LinearRing.VectorToLinearRingError Int))+ LinearRing.fromVector (VectorStorable.fromList [0, 1, 2]) `shouldBe` Validation.Failure (LinearRing.FirstNotEqualToLast 0 2 ListNonEmpty.:| [] :: ListNonEmpty.NonEmpty (LinearRing.VectorToLinearRingError Int))++testCombineToVector :: Spec+testCombineToVector =+ describe "combineToVector" $+ it "combine a LinearRing using tuples" $ do+ LinearRing.combineToVector BasicTypes.PointXY (LinearRing.makeLinearRing 0 1 2 VectorStorable.empty) `shouldBe` VectorStorable.fromList [BasicTypes.PointXY 0 1, BasicTypes.PointXY 1 2]+ LinearRing.combineToVector BasicTypes.PointXY (LinearRing.makeLinearRing 0 1 2 (VectorStorable.fromList [4])) `shouldBe` VectorStorable.fromList [BasicTypes.PointXY 0 1, BasicTypes.PointXY 1 2, BasicTypes.PointXY 2 4]+ LinearRing.combineToVector BasicTypes.PointXY (LinearRing.makeLinearRing 0 1 2 (VectorStorable.fromList [4,5])) `shouldBe` VectorStorable.fromList [BasicTypes.PointXY 0 1, BasicTypes.PointXY 1 2, BasicTypes.PointXY 2 4, BasicTypes.PointXY 4 5]++testToVector :: Spec+testToVector =+ describe "toVector" $+ it "from a LinearRing to a vector" $ do+ LinearRing.toVector (LinearRing.makeLinearRing 0 1 0 VectorStorable.empty) `shouldBe` VectorStorable.fromList ([0, 1, 0] :: [Int])+ LinearRing.toVector (LinearRing.makeLinearRing 0 1 2 (VectorStorable.fromList [0])) `shouldBe` VectorStorable.fromList ([0, 1, 2, 0] :: [Int])+ LinearRing.toVector (LinearRing.makeLinearRing 0 1 2 (VectorStorable.fromList [4,0])) `shouldBe` VectorStorable.fromList ([0, 1, 2, 4, 0] :: [Int])+ -- TODO -- > (\xs -> safeLast (fromLinearRing xs) == Just (ringHead xs)) (xs :: LinearRing Int)
test/Fixture.hs view
@@ -2,13 +2,11 @@ module Fixture where -import qualified Data.Aeson as A+import qualified Data.Aeson as Aeson import qualified Data.ByteString.Lazy.Char8 as BS import qualified Data.Text as T -- Local-import Data.Geospatial.Internal.BasicTypes (BoundingBoxWithoutCRS,- FeatureID (..),- GeoPositionWithoutCRS)+import qualified Data.Geospatial.Internal.BasicTypes as BasicTypes import Data.Geospatial.Internal.CRS (CRSObject (..)) import Data.Geospatial.Internal.GeoFeature (GeoFeature (..)) import Data.Geospatial.Internal.GeoFeatureCollection (GeoFeatureCollection (..))@@ -18,10 +16,12 @@ mergeGeoLines) import Data.Geospatial.Internal.Geometry.GeoMultiPolygon (GeoMultiPolygon (..), mergeGeoPolygons)+import Data.Geospatial.Internal.Geometry.GeoPoint (GeoPoint (..)) import Data.Geospatial.Internal.Geometry.GeoPolygon (GeoPolygon (..))-import Data.LinearRing (LinearRing, makeLinearRing)-import Data.LineString (LineString, makeLineString)-+import qualified Data.LinearRing as LinearRing+import qualified Data.LineString as LineString+import qualified Data.Vector as Vector+import qualified Data.Vector.Storable as VectorStorable -- CRS Data @@ -43,31 +43,34 @@ testNamedCRS :: CRSObject testNamedCRS = NamedCRS "urn:ogc:def:crs:OGC:1.3:CRS84" +mkBoundingBox :: [Double] -> BasicTypes.BoundingBoxWithoutCRS+mkBoundingBox x = BasicTypes.BoundingBoxWithoutCRS $ VectorStorable.fromList x+ -- Bounding Box Data -lshapedPolyVertices :: [LinearRing GeoPositionWithoutCRS]-lshapedPolyVertices = [ makeLinearRing [120.0, -15.0] [127.0, -15.0] [127.0, -25.0] [[124.0, -25.0], [124.0, -18.0], [120.0, -18.0]] ]+mkGeoPoint :: Double -> Double -> BasicTypes.GeoPositionWithoutCRS+mkGeoPoint x y = BasicTypes.GeoPointXY $ BasicTypes.PointXY x y -lshapedPolyLineVertices :: LineString GeoPositionWithoutCRS-lshapedPolyLineVertices = makeLineString [120.0, -15.0] [127.0, -15.0] [[127.0, -25.0], [124.0, -25.0], [124.0, -18.0], [120.0, -18.0]]+lshapedPolyVertices :: Vector.Vector (LinearRing.LinearRing BasicTypes.GeoPositionWithoutCRS)+lshapedPolyVertices = Vector.fromList [LinearRing.makeLinearRing (mkGeoPoint 120.0 (-15.0)) (mkGeoPoint 127.0 (-15.0)) (mkGeoPoint 127.0 (-25.0)) (VectorStorable.fromList [mkGeoPoint 124.0 (-25.0), mkGeoPoint 124.0 (-18.0), mkGeoPoint 120.0 (-18.0)])] +lshapedPolyLineVertices :: LineString.LineString BasicTypes.GeoPositionWithoutCRS+lshapedPolyLineVertices = LineString.makeLineString (mkGeoPoint 120.0 (-15.0)) (mkGeoPoint 127.0 (-15.0)) (VectorStorable.fromList [mkGeoPoint 127.0 (-25.0), mkGeoPoint 124.0 (-25.0), mkGeoPoint 124.0 (-18.0), mkGeoPoint 120.0 (-18.0)]) -emptyVertices :: [LinearRing GeoPositionWithoutCRS]-emptyVertices = []+emptyVertices :: Vector.Vector (LinearRing.LinearRing BasicTypes.GeoPositionWithoutCRS)+emptyVertices = Vector.empty -emptyLineVertices :: [GeoPositionWithoutCRS]+emptyLineVertices :: [BasicTypes.GeoPositionWithoutCRS] emptyLineVertices = [] --testLatLonBBox :: BoundingBoxWithoutCRS-testLatLonBBox = [-32, 147.5, -29.5, 151.0]+testLatLonBBox :: BasicTypes.BoundingBoxWithoutCRS+testLatLonBBox = mkBoundingBox [-32, 147.5, -29.5, 151.0] testLatLonBBoxJSON :: BS.ByteString testLatLonBBoxJSON = "[-32,147.5,-29.5,151]" --testEmptyBBox :: BoundingBoxWithoutCRS-testEmptyBBox = []+testEmptyBBox :: BasicTypes.BoundingBoxWithoutCRS+testEmptyBBox = mkBoundingBox [] testEmptyBBoxJSON :: BS.ByteString testEmptyBBoxJSON = "[]"@@ -93,6 +96,16 @@ -- (124, -25) (127, -25) -- +-- Points+pointJSON :: BS.ByteString+pointJSON = "{\"coordinates\":[120,-15],\"type\":\"Polygon\"}"++geoPoint :: GeoPoint+geoPoint = GeoPoint point++point :: BasicTypes.GeoPositionWithoutCRS+point = BasicTypes.GeoPointXY $ BasicTypes.PointXY 120.0 (-15.0)+ -- Polys lShapedPolyJSON :: BS.ByteString lShapedPolyJSON = "{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],\"type\":\"Polygon\"}"@@ -118,27 +131,25 @@ emptyMultiPolyJSON = "{\"type\":\"MultiPolygon\",\"coordinates\":[]}" emptyMultiGeoPoly :: GeoMultiPolygon-emptyMultiGeoPoly = GeoMultiPolygon []+emptyMultiGeoPoly = GeoMultiPolygon Vector.empty emptyMultiPoly :: GeospatialGeometry emptyMultiPoly = MultiPolygon emptyMultiGeoPoly - singlePolyMultiPolyJSON :: BS.ByteString singlePolyMultiPolyJSON = "{\"type\":\"MultiPolygon\",\"coordinates\":[[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]]]}" singlePolyGeoMultiPoly :: GeoMultiPolygon-singlePolyGeoMultiPoly = mergeGeoPolygons [lShapedGeoPoly]+singlePolyGeoMultiPoly = mergeGeoPolygons (Vector.fromList [lShapedGeoPoly]) singlePolyMultiPoly :: GeospatialGeometry singlePolyMultiPoly = MultiPolygon singlePolyGeoMultiPoly - multiPolyJSON :: BS.ByteString multiPolyJSON = "{\"type\":\"MultiPolygon\",\"coordinates\":[[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]],[]]}" geoMultiPoly :: GeoMultiPolygon-geoMultiPoly = mergeGeoPolygons [lShapedGeoPoly, emptyGeoPoly]+geoMultiPoly = mergeGeoPolygons (Vector.fromList [lShapedGeoPoly, emptyGeoPoly]) multiPoly :: GeospatialGeometry multiPoly = MultiPolygon geoMultiPoly@@ -158,27 +169,25 @@ emptyMultiLineJSON = "{\"type\":\"MultiLineString\",\"coordinates\":[]}" emptyMultiGeoLine :: GeoMultiLine-emptyMultiGeoLine = GeoMultiLine []+emptyMultiGeoLine = GeoMultiLine Vector.empty emptyMultiLine :: GeospatialGeometry emptyMultiLine = MultiLine emptyMultiGeoLine - singleLineMultiLineJSON :: BS.ByteString singleLineMultiLineJSON = "{\"type\":\"MultiLineString\",\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]]}" singleLineGeoMultiLine :: GeoMultiLine-singleLineGeoMultiLine = mergeGeoLines [lShapedGeoLine]+singleLineGeoMultiLine = mergeGeoLines (Vector.fromList [lShapedGeoLine]) singleLineMultiLine :: GeospatialGeometry singleLineMultiLine = MultiLine singleLineGeoMultiLine - multiLineJSON :: BS.ByteString multiLineJSON = "{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]],[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]],\"type\":\"MultiLineString\"}" geoMultiLine :: GeoMultiLine-geoMultiLine = mergeGeoLines [lShapedGeoLine, lShapedGeoLine]+geoMultiLine = mergeGeoLines (Vector.fromList [lShapedGeoLine, lShapedGeoLine]) multiLine :: GeospatialGeometry multiLine = MultiLine geoMultiLine@@ -188,92 +197,82 @@ emptyCollectionJSON = "{\"type\":\"GeometryCollection\",\"geometries\":[]}" emptyCollection :: GeospatialGeometry-emptyCollection = Collection []-+emptyCollection = Collection Vector.empty bigassCollectionJSON :: BS.ByteString bigassCollectionJSON = "{\"geometries\":[{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]],\"type\":\"MultiLineString\"},{\"coordinates\":[],\"type\":\"MultiLineString\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]],[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]],\"type\":\"MultiLineString\"},{\"coordinates\":[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]],\"type\":\"LineString\"},{\"coordinates\":[[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],[]],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]]],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],\"type\":\"Polygon\"},{\"coordinates\":[],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],\"type\":\"Polygon\"}],\"type\":\"GeometryCollection\"}" bigassCollection :: GeospatialGeometry-bigassCollection = Collection [singleLineMultiLine, emptyMultiLine, multiLine, lShapedLine, multiPoly, singlePolyMultiPoly, lShapedPoly, emptyMultiPoly, lShapedPoly]+bigassCollection = Collection $ Vector.fromList [singleLineMultiLine, emptyMultiLine, multiLine, lShapedLine, multiPoly, singlePolyMultiPoly, lShapedPoly, emptyMultiPoly, lShapedPoly] -- Properties Data -testProperties :: A.Value-testProperties = A.object [T.pack "depth" A..= (5 :: Int), T.pack "comment" A..= T.pack "Bore run over by dump truck"]+testProperties :: Aeson.Value+testProperties = Aeson.object [T.pack "depth" Aeson..= (5 :: Int), T.pack "comment" Aeson..= T.pack "Bore run over by dump truck"] -- Feature Data -featureId :: Maybe FeatureID-featureId = Just $ FeatureIDText "GW001"+featureId :: Maybe BasicTypes.FeatureID+featureId = Just $ BasicTypes.FeatureIDText "GW001" -bbox :: Maybe BoundingBoxWithoutCRS+bbox :: Maybe BasicTypes.BoundingBoxWithoutCRS bbox = Just testLatLonBBox - bigFeatureJSON :: BS.ByteString bigFeatureJSON = "{\"bbox\":[-32,147.5,-29.5,151],\"geometry\":{\"geometries\":[{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]],\"type\":\"MultiLineString\"},{\"coordinates\":[],\"type\":\"MultiLineString\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]],[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]],\"type\":\"MultiLineString\"},{\"coordinates\":[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]],\"type\":\"LineString\"},{\"coordinates\":[[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],[]],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]]],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],\"type\":\"Polygon\"},{\"coordinates\":[],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],\"type\":\"Polygon\"}],\"type\":\"GeometryCollection\"},\"id\":\"GW001\",\"type\":\"Feature\",\"properties\":{\"depth\":5,\"comment\":\"Bore run over by dump truck\"}}" -bigFeature :: GeoFeature A.Value+bigFeature :: GeoFeature Aeson.Value bigFeature = GeoFeature bbox bigassCollection testProperties featureId - featureWithNoPropertiesJSON :: BS.ByteString featureWithNoPropertiesJSON = "{\"bbox\":[-32,147.5,-29.5,151],\"geometry\":{\"geometries\":[{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]],\"type\":\"MultiLineString\"},{\"coordinates\":[],\"type\":\"MultiLineString\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]],[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]],\"type\":\"MultiLineString\"},{\"coordinates\":[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]],\"type\":\"LineString\"},{\"coordinates\":[[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],[]],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]]],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],\"type\":\"Polygon\"},{\"coordinates\":[],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],\"type\":\"Polygon\"}],\"type\":\"GeometryCollection\"},\"id\":\"GW001\",\"type\":\"Feature\",\"properties\":null}" -featureWithNoProperties :: GeoFeature A.Value-featureWithNoProperties = GeoFeature bbox bigassCollection A.Null featureId-+featureWithNoProperties :: GeoFeature Aeson.Value+featureWithNoProperties = GeoFeature bbox bigassCollection Aeson.Null featureId featureWithNoGeometryJSON :: BS.ByteString featureWithNoGeometryJSON = "{\"type\":\"Feature\",\"properties\":{\"depth\":5,\"comment\":\"Bore run over by dump truck\"},\"geometry\":null,\"bbox\":[-32,147.5,-29.5,151],\"id\":\"GW001\"}" -featureWithNoGeometry :: GeoFeature A.Value+featureWithNoGeometry :: GeoFeature Aeson.Value featureWithNoGeometry = GeoFeature bbox NoGeometry testProperties featureId - featureWithNoIdJSON :: BS.ByteString featureWithNoIdJSON = "{\"bbox\":[-32,147.5,-29.5,151],\"geometry\":{\"geometries\":[{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]],\"type\":\"MultiLineString\"},{\"coordinates\":[],\"type\":\"MultiLineString\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]],[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]],\"type\":\"MultiLineString\"},{\"coordinates\":[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]],\"type\":\"LineString\"},{\"coordinates\":[[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],[]],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]]],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],\"type\":\"Polygon\"},{\"coordinates\":[],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],\"type\":\"Polygon\"}],\"type\":\"GeometryCollection\"},\"type\":\"Feature\",\"properties\":{\"depth\":5,\"comment\":\"Bore run over by dump truck\"}}" -featureWithNoId :: GeoFeature A.Value+featureWithNoId :: GeoFeature Aeson.Value featureWithNoId = GeoFeature bbox bigassCollection testProperties Nothing - featureWithNoBBoxJSON :: BS.ByteString featureWithNoBBoxJSON = "{\"geometry\":{\"geometries\":[{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]],\"type\":\"MultiLineString\"},{\"coordinates\":[],\"type\":\"MultiLineString\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]],[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]],\"type\":\"MultiLineString\"},{\"coordinates\":[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]],\"type\":\"LineString\"},{\"coordinates\":[[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],[]],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]]],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],\"type\":\"Polygon\"},{\"coordinates\":[],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],\"type\":\"Polygon\"}],\"type\":\"GeometryCollection\"},\"id\":\"GW001\",\"type\":\"Feature\",\"properties\":{\"depth\":5,\"comment\":\"Bore run over by dump truck\"}}" -featureWithNoBBox :: GeoFeature A.Value+featureWithNoBBox :: GeoFeature Aeson.Value featureWithNoBBox = GeoFeature Nothing bigassCollection testProperties featureId -- FeatureCollection Data -features :: [GeoFeature A.Value]-features = [featureWithNoBBox, featureWithNoGeometry, featureWithNoBBox, featureWithNoId, featureWithNoProperties, bigFeature]-+features :: Vector.Vector (GeoFeature Aeson.Value)+features = Vector.fromList [featureWithNoBBox, featureWithNoGeometry, featureWithNoBBox, featureWithNoId, featureWithNoProperties, bigFeature] bigAssFeatureCollectionJSON :: BS.ByteString bigAssFeatureCollectionJSON = "{\"bbox\":[-32,147.5,-29.5,151],\"features\":[{\"geometry\":{\"geometries\":[{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]],\"type\":\"MultiLineString\"},{\"coordinates\":[],\"type\":\"MultiLineString\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]],[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]],\"type\":\"MultiLineString\"},{\"coordinates\":[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]],\"type\":\"LineString\"},{\"coordinates\":[[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],[]],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]]],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],\"type\":\"Polygon\"},{\"coordinates\":[],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],\"type\":\"Polygon\"}],\"type\":\"GeometryCollection\"},\"id\":\"GW001\",\"type\":\"Feature\",\"properties\":{\"depth\":5,\"comment\":\"Bore run over by dump truck\"}},{\"bbox\":[-32,147.5,-29.5,151],\"geometry\":null,\"id\":\"GW001\",\"type\":\"Feature\",\"properties\":{\"depth\":5,\"comment\":\"Bore run over by dump truck\"}},{\"geometry\":{\"geometries\":[{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]],\"type\":\"MultiLineString\"},{\"coordinates\":[],\"type\":\"MultiLineString\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]],[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]],\"type\":\"MultiLineString\"},{\"coordinates\":[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]],\"type\":\"LineString\"},{\"coordinates\":[[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],[]],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]]],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],\"type\":\"Polygon\"},{\"coordinates\":[],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],\"type\":\"Polygon\"}],\"type\":\"GeometryCollection\"},\"id\":\"GW001\",\"type\":\"Feature\",\"properties\":{\"depth\":5,\"comment\":\"Bore run over by dump truck\"}},{\"bbox\":[-32,147.5,-29.5,151],\"geometry\":{\"geometries\":[{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]],\"type\":\"MultiLineString\"},{\"coordinates\":[],\"type\":\"MultiLineString\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]],[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]],\"type\":\"MultiLineString\"},{\"coordinates\":[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]],\"type\":\"LineString\"},{\"coordinates\":[[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],[]],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]]],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],\"type\":\"Polygon\"},{\"coordinates\":[],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],\"type\":\"Polygon\"}],\"type\":\"GeometryCollection\"},\"type\":\"Feature\",\"properties\":{\"depth\":5,\"comment\":\"Bore run over by dump truck\"}},{\"bbox\":[-32,147.5,-29.5,151],\"geometry\":{\"geometries\":[{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]],\"type\":\"MultiLineString\"},{\"coordinates\":[],\"type\":\"MultiLineString\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]],[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]],\"type\":\"MultiLineString\"},{\"coordinates\":[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]],\"type\":\"LineString\"},{\"coordinates\":[[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],[]],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]]],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],\"type\":\"Polygon\"},{\"coordinates\":[],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],\"type\":\"Polygon\"}],\"type\":\"GeometryCollection\"},\"id\":\"GW001\",\"type\":\"Feature\",\"properties\":null},{\"bbox\":[-32,147.5,-29.5,151],\"geometry\":{\"geometries\":[{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]],\"type\":\"MultiLineString\"},{\"coordinates\":[],\"type\":\"MultiLineString\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]],[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]],\"type\":\"MultiLineString\"},{\"coordinates\":[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]],\"type\":\"LineString\"},{\"coordinates\":[[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],[]],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]]],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],\"type\":\"Polygon\"},{\"coordinates\":[],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],\"type\":\"Polygon\"}],\"type\":\"GeometryCollection\"},\"id\":\"GW001\",\"type\":\"Feature\",\"properties\":{\"depth\":5,\"comment\":\"Bore run over by dump truck\"}}],\"type\":\"FeatureCollection\"}" -bigAssFeatureCollection :: GeoFeatureCollection A.Value+bigAssFeatureCollection :: GeoFeatureCollection Aeson.Value bigAssFeatureCollection = GeoFeatureCollection bbox features - bigAssFeatureCollectionWithNoBBoxJSON :: BS.ByteString bigAssFeatureCollectionWithNoBBoxJSON = "{\"features\":[{\"geometry\":{\"geometries\":[{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]],\"type\":\"MultiLineString\"},{\"coordinates\":[],\"type\":\"MultiLineString\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]],[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]],\"type\":\"MultiLineString\"},{\"coordinates\":[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]],\"type\":\"LineString\"},{\"coordinates\":[[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],[]],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]]],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],\"type\":\"Polygon\"},{\"coordinates\":[],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],\"type\":\"Polygon\"}],\"type\":\"GeometryCollection\"},\"id\":\"GW001\",\"type\":\"Feature\",\"properties\":{\"depth\":5,\"comment\":\"Bore run over by dump truck\"}},{\"bbox\":[-32,147.5,-29.5,151],\"geometry\":null,\"id\":\"GW001\",\"type\":\"Feature\",\"properties\":{\"depth\":5,\"comment\":\"Bore run over by dump truck\"}},{\"geometry\":{\"geometries\":[{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]],\"type\":\"MultiLineString\"},{\"coordinates\":[],\"type\":\"MultiLineString\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]],[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]],\"type\":\"MultiLineString\"},{\"coordinates\":[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]],\"type\":\"LineString\"},{\"coordinates\":[[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],[]],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]]],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],\"type\":\"Polygon\"},{\"coordinates\":[],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],\"type\":\"Polygon\"}],\"type\":\"GeometryCollection\"},\"id\":\"GW001\",\"type\":\"Feature\",\"properties\":{\"depth\":5,\"comment\":\"Bore run over by dump truck\"}},{\"bbox\":[-32,147.5,-29.5,151],\"geometry\":{\"geometries\":[{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]],\"type\":\"MultiLineString\"},{\"coordinates\":[],\"type\":\"MultiLineString\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]],[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]],\"type\":\"MultiLineString\"},{\"coordinates\":[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]],\"type\":\"LineString\"},{\"coordinates\":[[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],[]],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]]],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],\"type\":\"Polygon\"},{\"coordinates\":[],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],\"type\":\"Polygon\"}],\"type\":\"GeometryCollection\"},\"type\":\"Feature\",\"properties\":{\"depth\":5,\"comment\":\"Bore run over by dump truck\"}},{\"bbox\":[-32,147.5,-29.5,151],\"geometry\":{\"geometries\":[{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]],\"type\":\"MultiLineString\"},{\"coordinates\":[],\"type\":\"MultiLineString\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]],[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]],\"type\":\"MultiLineString\"},{\"coordinates\":[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]],\"type\":\"LineString\"},{\"coordinates\":[[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],[]],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]]],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],\"type\":\"Polygon\"},{\"coordinates\":[],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],\"type\":\"Polygon\"}],\"type\":\"GeometryCollection\"},\"id\":\"GW001\",\"type\":\"Feature\",\"properties\":null},{\"bbox\":[-32,147.5,-29.5,151],\"geometry\":{\"geometries\":[{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]],\"type\":\"MultiLineString\"},{\"coordinates\":[],\"type\":\"MultiLineString\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]],[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]]],\"type\":\"MultiLineString\"},{\"coordinates\":[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18]],\"type\":\"LineString\"},{\"coordinates\":[[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],[]],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]]],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],\"type\":\"Polygon\"},{\"coordinates\":[],\"type\":\"MultiPolygon\"},{\"coordinates\":[[[120,-15],[127,-15],[127,-25],[124,-25],[124,-18],[120,-18],[120,-15]]],\"type\":\"Polygon\"}],\"type\":\"GeometryCollection\"},\"id\":\"GW001\",\"type\":\"Feature\",\"properties\":{\"depth\":5,\"comment\":\"Bore run over by dump truck\"}}],\"type\":\"FeatureCollection\"}" -bigAssFeatureCollectionWithNoBBox :: GeoFeatureCollection A.Value+bigAssFeatureCollectionWithNoBBox :: GeoFeatureCollection Aeson.Value bigAssFeatureCollectionWithNoBBox = GeoFeatureCollection Nothing features - emptyFeatureCollectionJSON :: BS.ByteString emptyFeatureCollectionJSON = "{\"type\":\"FeatureCollection\",\"features\":[]}" -emptyFeatureCollection :: GeoFeatureCollection A.Value-emptyFeatureCollection = GeoFeatureCollection Nothing []-+emptyFeatureCollection :: GeoFeatureCollection Aeson.Value+emptyFeatureCollection = GeoFeatureCollection Nothing Vector.empty emptyFeatureCollectionWithBBoxJSON :: BS.ByteString emptyFeatureCollectionWithBBoxJSON = "{\"type\":\"FeatureCollection\",\"features\":[],\"bbox\":[-32,147.5,-29.5,151]}" -emptyFeatureCollectionWithBBox :: GeoFeatureCollection A.Value-emptyFeatureCollectionWithBBox = GeoFeatureCollection bbox []+emptyFeatureCollectionWithBBox :: GeoFeatureCollection Aeson.Value+emptyFeatureCollectionWithBBox = GeoFeatureCollection bbox Vector.empty