All Projects → fosskers → mapalgebra

fosskers / mapalgebra

Licence: BSD-3-Clause license
Efficient, polymorphic Map Algebra in Haskell.

Programming Languages

haskell
3896 projects
scala
5932 projects
python
139335 projects - #7 most used programming language

Projects that are alternatives of or similar to mapalgebra

nyc-subway-station-locator
NYC Subway Station Locator Solution
Stars: ✭ 29 (-14.71%)
Mutual labels:  gis
topo
A Geometry library for Elixir that calculates spatial relationships between two geometries
Stars: ✭ 125 (+267.65%)
Mutual labels:  gis
GeoFuse
Thematic Engine for Dynamic CSV or Tab Delimited Data
Stars: ✭ 15 (-55.88%)
Mutual labels:  gis
localtileserver
🌐 dynamic tile server for visualizing rasters in Jupyter with ipyleaflet or folium
Stars: ✭ 190 (+458.82%)
Mutual labels:  gis
python-grass-addon
How to write a Python GRASS GIS 7 addon
Stars: ✭ 45 (+32.35%)
Mutual labels:  gis
geojson-to-sqlite
CLI tool for converting GeoJSON files to SQLite (with SpatiaLite)
Stars: ✭ 41 (+20.59%)
Mutual labels:  gis
CesiumJsFirstPersonCameraController
cesiumgis.com/
Stars: ✭ 20 (-41.18%)
Mutual labels:  gis
importer-exporter
3D City Database client for high-performance import and export of 3D city model data
Stars: ✭ 104 (+205.88%)
Mutual labels:  gis
spatialwidget
Utility package to convert R data into JSON for use in htmlwidget mapping libraries
Stars: ✭ 17 (-50%)
Mutual labels:  gis
awesome-geospatial-data-download-sites
This is the repo for open source geospatial data download sites.
Stars: ✭ 19 (-44.12%)
Mutual labels:  gis
mesh-api
Database for managing a mesh network
Stars: ✭ 14 (-58.82%)
Mutual labels:  gis
openSTARS
open source implementation of the STARS ArcGIS toolbox
Stars: ✭ 33 (-2.94%)
Mutual labels:  gis
osm4scala
Scala and Spark library focused on reading OpenStreetMap Pbf files.
Stars: ✭ 62 (+82.35%)
Mutual labels:  gis
lopocs
Migrated to: https://gitlab.com/Oslandia/lopocs
Stars: ✭ 78 (+129.41%)
Mutual labels:  gis
mini-map-maker
A tool for automatically generating 3D printable STLs from freely available lidar scan data.
Stars: ✭ 51 (+50%)
Mutual labels:  gis
deegree3
Official deegree repository providing geospatial core libraries, data access and advanced OGC web service implementations
Stars: ✭ 118 (+247.06%)
Mutual labels:  gis
gis-snippets
Some code snippets for GIS tasks
Stars: ✭ 45 (+32.35%)
Mutual labels:  gis
conrex
An Elixir implementation of the CONREC algorithm for topographic or isochrone maps.
Stars: ✭ 52 (+52.94%)
Mutual labels:  gis
30DayMapChallenge
The official website for #30DayMapChallenge, It is a daily mapping/cartography/data visualization challenge aimed at the spatial community. Code for map submissions.
Stars: ✭ 33 (-2.94%)
Mutual labels:  gis
pyGISS
📡 A lightweight GIS Software in less than 100 lines of code
Stars: ✭ 114 (+235.29%)
Mutual labels:  gis

mapalgebra

Efficient, polymorphic Map Algebra for Haskell.

This library is an implementation of Map Algebra as described in the book GIS and Cartographic Modeling by Dana Tomlin. The fundamental primitive is the Raster, a rectangular grid of data that usually describes some area on the earth.

mapalgebra is built on top of massiv, a powerful Parallel Array library by Alexey Kuleshevich.

Usage

Always compile with -threaded, -O2, and -with-rtsopts=-N for best performance.

The Raster Type

This library provides Rasters which are lazy, polymorphic, and typesafe. They can hold any kind of data, and are aware of their projection and dimensions at the type level. This means that imagery of different size or projection are considered completely different types, which prevents an entire class of bugs.

Rasters have types signatures like this:

-- | A Raster of Ints backed by efficient byte-packed arrays, encoded
-- via the `Storable` typeclass. `P` (Prim), `U` (Unbox) and `B` (boxed) are also available.
--
-- This is either a freshly read image, or the result of evaluating a "delayed"
-- (`D` or `DW`) Raster.
Raster S LatLng 256 256 Int

-- | A "delayed" Raster of bytes. Likely the result of some Local Operation.
-- Waiting to be evaluated by the `strict` function.
Raster D WebMercator 512 512 Word8

-- | A "windowed" Raster of an ADT, the result of some Focal Operation.
-- Waiting to be evaluated by the `strict` function.
--
-- A generic `p` means we don't care about Projection here.
Raster DW p 1024 1024 (Maybe Double)

Reading Imagery

mapalgebra can currently read any image file of any value type, so long as it is grayscale (singleband) or RGBA. True multiband rasters (like from LandSat) are not yet supported.

To read a Raster:

-- | You must know the image dimensions ahead of time. If you don't care
-- about the projection, then `p` can be left generic.
getRaster :: IO (Raster S p 512 512 Word8)
getRaster = do
  erast <- fromGray "path/to/image.tif"
  case erast of
    Left err -> ... -- deal with the error.
    Right r  -> pure r

Colouring and Viewing Imagery

To quickly view a Raster you're working on, use the display function:

-- | Simplified type signature.
display :: Raster D p r c a -> IO ()

This will automatically colour gray, evaluate, and display your Raster using your OS's default image viewer.

To colour a Raster gray yourself, use grayscale:

grayscale :: Functor (Raster u p r c) => Raster u p r c a -> Raster u p r c (Pixel Y a)

True colouring is done with the classify function and colour ramps inspired by Gretchen N. Peterson's book Cartographer's Toolkit.

-- | Both `Raster D` and `Raster DW` are Functors, so this function works on
-- either of them. `Raster S`, etc., do not form Functors by design.
classify :: (Ord a, Functor f) => b -> Map a b -> f a -> f b

-- | An invisible pixel (alpha channel set to 0) to be passed
-- to `classify` as a default.
invisible :: Pixel RGBA Word8

-- | Given a list of "breaks", forms a colour ramp to be passed
-- to `classify`.
spectrum :: Ord k => [k] -> Map k (Pixel RGBA Word8)

We can generate the breaks via histogram and breaks (currently supports Word8 only):

-- | Input here is `Raster S`, meaning this image was freshly read,
-- or has already been fully computed with `strict`.
colourIt :: Raster S p r c Word8 -> Raster S p r c (Pixel RGBA Word8)
colourIt r = strict S . classify invisible cm $ lazy r
  where cm = spectrum . breaks $ histogram r

Before-and-after:

original image colour via spectrum ramp

Local Operations

All Local Operations defined in GIS and Cartographic Modeling are available. For the usual math ops, Raster D has a Num instance:

rast :: Raster D p 512 512 Int

squared :: Raster D p 512 512 Int
squared = rast * rast  -- Element-wise multiplication.

Focal Operations

Except for Focal Ranking and Focal Insularity, all Focal Operations of immedatiate neighbourhoods are provided:

rast :: Raster S p 512 512 Double

-- | `Raster DW` forms a Functor, so we can do simple unary transformations
-- (like colouring!) to it after Focal Ops.
averagedPlusAbit :: Raster S p 512 512 Double
averagedPlusAbit = strict S . fmap (+1) $ fmean rast

Typesafe NoData Handling

If it's known that your images have large areas of NoData, consider that Maybe has a Monoid instance:

import Data.Monoid (Sum(..))

nodatafsum :: Raster S p r c Word8 -> Raster DW p r c 512 Word8
nodatafsum = fmap (maybe 0 getSum) . fmonoid . strict B . fmap check . lazy
  where check 0 = Nothing
        check n = Just $ Sum n

In theory, one could construct special newtype wrappers with Monoid instances that handle any Focal scenario imaginable.

Future Work

  • Projection handling at IO time
  • Histogram generation for more data types
  • Reprojections
  • Extended neighbourhoods for Focal Ops
  • Upsampling and Downsampling
  • Improved NoData handling
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].