aboutsummaryrefslogtreecommitdiffstats
path: root/examples/Example04.elm
diff options
context:
space:
mode:
Diffstat (limited to 'examples/Example04.elm')
-rw-r--r--examples/Example04.elm180
1 files changed, 180 insertions, 0 deletions
diff --git a/examples/Example04.elm b/examples/Example04.elm
new file mode 100644
index 0000000..eb7b650
--- /dev/null
+++ b/examples/Example04.elm
@@ -0,0 +1,180 @@
+port module Example04 exposing (main)
+
+import Browser
+import Html exposing (div, text)
+import Html.Attributes exposing (style)
+import Html.Lazy exposing (lazy2)
+import Http
+import Json.Decode
+import Json.Encode
+import LngLat exposing (LngLat)
+import Map
+import MapCommands
+import Mapbox.Cmd.Option as Opt
+import Mapbox.Element exposing (..)
+import Mapbox.Expression as E exposing (false, float, int, str, true)
+import Mapbox.Layer as Layer
+import Mapbox.Source as Source
+import Mapbox.Style as Style exposing (Style(..), StyleDef)
+
+
+port elmMapboxIncoming : (Json.Encode.Value -> msg) -> Sub msg
+
+
+main =
+ Browser.document
+ { init = init
+ , view = view
+ , update = update
+ , subscriptions = subscriptions
+ }
+
+
+subscriptions : Model -> Sub Msg
+subscriptions _ =
+ elmMapboxIncoming MapCenter
+
+
+type alias Model =
+ { position : LngLat
+ , zoom : Float
+ , features : List Json.Encode.Value
+ , jsonMap : Maybe StyleDef
+ }
+
+
+init : () -> ( Model, Cmd Msg )
+init () =
+ ( { position = LngLat 0 0
+ , zoom = 13.8
+ , features = []
+ , jsonMap = Nothing
+ }
+ , fetchStyle "mapbox://styles/yourstile/ck0dvc9zq0g2v1cmw9xg18pu7" "pk.eyJ1Ijoi..."
+ )
+
+
+type Msg
+ = Hover EventData
+ | Click EventData
+ | MapCenter Json.Encode.Value
+ | LoadedStyle (Result Http.Error String)
+
+
+fetchStyle styleUrl token =
+ String.replace "mapbox://styles/" "https://api.mapbox.com/styles/v1/" styleUrl
+ ++ "?access_token="
+ ++ token
+ |> Http.getString
+ |> Http.send LoadedStyle
+
+
+update msg model =
+ case msg of
+ Hover { lngLat, renderedFeatures } ->
+ ( { model | position = lngLat, features = renderedFeatures }, Cmd.none )
+
+ Click { lngLat, renderedFeatures } ->
+ ( { model | position = lngLat, features = renderedFeatures }, MapCommands.fitBounds [ Opt.linear True, Opt.maxZoom 10 ] ( LngLat.map (\a -> a - 0.2) lngLat, LngLat.map (\a -> a + 0.2) lngLat ) )
+
+ MapCenter e ->
+ ( model, Cmd.none )
+
+ LoadedStyle (Ok style) ->
+ ( { model
+ | jsonMap =
+ case
+ ( Json.Decode.decodeString Style.decode style
+ , Json.Decode.decodeString Style.decodeMiscDef style
+ )
+ of
+ ( Ok mapbox, Ok misc ) ->
+ Just { mapbox | misc = Style.miscDefToList misc }
+
+ _ ->
+ Nothing
+ }
+ , Cmd.none
+ )
+
+ LoadedStyle (Err e) ->
+ ( model, Cmd.none )
+
+
+geojson : Json.Encode.Value
+geojson =
+ Json.Decode.decodeString Json.Decode.value """
+{
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "id": 1,
+ "properties": {
+ "name": "Bermuda Triangle",
+ "area": 1150180
+ },
+ "geometry": {
+ "type": "Polygon",
+ "coordinates": [
+ [
+ [-64.73, 32.31],
+ [-80.19, 25.76],
+ [-66.09, 18.43],
+ [-64.73, 32.31]
+ ]
+ ]
+ }
+ }
+ ]
+}
+""" |> Result.withDefault (Json.Encode.object [])
+
+
+hoveredFeatures : List Json.Encode.Value -> MapboxAttr msg
+hoveredFeatures =
+ List.map (\feat -> ( feat, [ ( "hover", Json.Encode.bool True ) ] ))
+ >> featureState
+
+
+showMap mapbox features =
+ case mapbox of
+ Just style ->
+ map
+ [ maxZoom 150
+ , onMouseMove Hover
+ , onClick Click
+ , id "my-map"
+ , eventFeaturesLayers [ "changes" ]
+ , hoveredFeatures features
+ ]
+ (Style
+ { style
+ | layers =
+ style.layers
+ ++ [ Layer.fill "changes"
+ "changes"
+ [ Layer.fillOpacity (E.ifElse (E.toBool (E.featureState (str "hover"))) (float 0.9) (float 0.1))
+ ]
+ ]
+ , sources =
+ style.sources
+ ++ [ Source.geoJSONFromValue "changes" [] geojson
+ ]
+ }
+ )
+
+ Nothing ->
+ Html.text "Nothing"
+
+
+view model =
+ { title = "Mapbox Example"
+ , body =
+ [ css
+ , div [ style "width" "100vw", style "height" "100vh" ]
+ [ lazy2 showMap model.jsonMap model.features
+ , div [ style "position" "absolute", style "bottom" "20px", style "left" "20px" ] [ text (LngLat.toString model.position) ]
+ ]
+ ]
+ }