0

Please comment, how to get the latitude and longitude in the center of map (Xamarin.Forms.Maps) when region changed? In C#, retrieve the property "Map.VisibleRegion"(https://learn.microsoft.com/en-us/dotnet/api/xamarin.forms.maps.map.visibleregion?view=xamarin-forms) and find a related property "MapSpan.Center". However, it isn't same as F# with fabulous, I don't know how to retrieve property from view.map. Thank you.

let view (model : Model) dispatch =
    let paris = Position(48.8566, 2.3522)
    let london = Position(51.5074, -0.1278)
    let calais = Position(50.9513, 1.8587)

    let map =
        View.Map
            (hasZoomEnabled = true, hasScrollEnabled = true,
             pins = [ View.Pin(paris, label = "Paris", pinType = PinType.Place)
                      View.Pin(london, label = "London", pinType = PinType.Place) ],
             requestedRegion = MapSpan.FromCenterAndRadius(calais, Distance.FromKilometers(300.0)))
    // View
    View.ContentPage(content = map)
    -- e.g map.visibleRegion
madeinQuant
  • 1,721
  • 1
  • 18
  • 29
  • Hi , you can have a look at this sample(http://alejandroruizvarela.blogspot.com/2015/07/map-center-position-xamarinforms.html) . – Junior Jiang Dec 05 '19 at 09:58
  • Hi, @JuniorJiang-MSFT, Thank you for your help. I have seen this sample. Since my application is using fabulous UI to implement a simple Model-View-Update (MVU) application pattern, similar to the Elm architecture. It is quite complicated to apply this sample into my application. – madeinQuant Dec 05 '19 at 10:51
  • Add a `SelectedRegion` to your model. Add a new `SelectRegion` message to your list of messages. Then in your `update` function, make the `SelectRegion` message change the model. Next you'll need a region selector in your UI that fires off a message to update the model `dispatch (SelectRegion model.regions.calais)` or similar, although I'm guessing you wouldn't want to hardcode regions like this. Then all you'd need to do is replace the hardcoded `calais` in your view function above with `model.SelectedRegion`. – drkmtr Dec 06 '19 at 08:29
  • 1
    @drkmtr. Thank for you help. The hardcoded 'calais' is used to simplify the question. I can't find a method(callback or property) to update the model with the center position(latitude & longitude) of map when the position is changed by user(e.g. zoom, drag or pitch). – madeinQuant Dec 06 '19 at 14:59
  • Apologies, I had completely misunderstood the question ha. – drkmtr Dec 10 '19 at 19:02
  • @drkmtr That was greatly appreciated. Thank you. – madeinQuant Dec 11 '19 at 00:37

1 Answers1

0

Base on the comment (https://github.com/fsprojects/Fabulous/issues/635) from Tim Lariviere, the problem has been resolved. Thank you.

let mapRef = ViewRef<Map>()

......
let tryGetCameraPosition() =
        match mapRef.TryValue with 
                          | None -> Some (0.0, 0.0) |> Option.map (fun l -> CameraPositionRetrieved(l))
                          | Some obj -> 
                                let map = obj :?> Xamarin.Forms.Maps.Map
                                let c = map.VisibleRegion.Center
                                Some (c.Latitude, c.Longitude) |> Option.map (fun l -> CameraPositionRetrieved(l))
......
let update msg model =
    match msg with
    | UpdateCameraPosition  -> 
        let msg = tryGetCameraPosition()
        model, Cmd.ofMsgOption msg
    | CameraPositionRetrieved location -> { model with CameraPosition = Some location }, Cmd.none

......
let view (model : Model) dispatch =
......
View.Map(hasZoomEnabled = true, hasScrollEnabled = true, ref = mapRef,
madeinQuant
  • 1,721
  • 1
  • 18
  • 29