mirror of
https://github.com/DevExpress/netcore-winforms-demos.git
synced 2025-12-29 12:59:21 +00:00
195 lines
9.0 KiB
C#
195 lines
9.0 KiB
C#
namespace DevExpress.DevAV.Presenters {
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text.RegularExpressions;
|
|
using DevExpress.DevAV;
|
|
using DevExpress.DevAV.ViewModels;
|
|
using DevExpress.XtraMap;
|
|
using DevExpress.XtraMap.Services;
|
|
|
|
public abstract class RouteMapPresenter<TEntity, TViewModel> : BasePresenter<TViewModel>
|
|
where TEntity : class
|
|
where TViewModel : class, IRouteMapViewModel {
|
|
MapControl mapControlCore;
|
|
Action<TEntity> updateUIActionCore;
|
|
Action<List<RoutePoint>> updateRouteListActionCore;
|
|
public RouteMapPresenter(MapControl mapControl, TViewModel viewModel, Action<TEntity> updateUIAction, Action<List<RoutePoint>> updateRouteList)
|
|
: base(viewModel) {
|
|
this.mapControlCore = mapControl;
|
|
this.updateUIActionCore = updateUIAction;
|
|
this.updateRouteListActionCore = updateRouteList;
|
|
if(MapControl != null) {
|
|
BindMap();
|
|
SubscribeRouteProviderEvents();
|
|
}
|
|
SubscribeViewModelEvents();
|
|
}
|
|
protected override void OnDisposing() {
|
|
if(MapControl != null)
|
|
UnsubscribeRouteProviderEvents();
|
|
UnsubscribeViewModelEvents();
|
|
this.updateUIActionCore = null;
|
|
this.updateRouteListActionCore = null;
|
|
this.mapControlCore = null;
|
|
base.OnDisposing();
|
|
}
|
|
public MapControl MapControl {
|
|
get { return mapControlCore; }
|
|
}
|
|
protected ImageLayer TilesLayer {
|
|
get { return (ImageLayer)(MapControl.Layers[0]); }
|
|
}
|
|
protected InformationLayer GeoCodeLayer {
|
|
get { return (InformationLayer)(MapControl.Layers[1]); }
|
|
}
|
|
protected InformationLayer RouteLayer {
|
|
get { return (InformationLayer)(MapControl.Layers[3]); }
|
|
}
|
|
protected BingMapDataProvider TilesProvider {
|
|
get { return (BingMapDataProvider)TilesLayer.DataProvider; }
|
|
}
|
|
protected BingGeocodeDataProvider GeoCodeProvider {
|
|
get { return (BingGeocodeDataProvider)GeoCodeLayer.DataProvider; }
|
|
}
|
|
protected BingRouteDataProvider RouteProvider {
|
|
get { return (BingRouteDataProvider)RouteLayer.DataProvider; }
|
|
}
|
|
IZoomToRegionService zoomService;
|
|
void BindMap() {
|
|
TilesProvider.BingKey = MapViewModelBase.WinBingKey;
|
|
RouteProvider.BingKey = MapViewModelBase.WinBingKey;
|
|
GeoCodeProvider.BingKey = MapViewModelBase.WinBingKey;
|
|
//
|
|
this.zoomService = ((IServiceProvider)MapControl).GetService(typeof(IZoomToRegionService)) as IZoomToRegionService;
|
|
}
|
|
protected virtual void SubscribeRouteProviderEvents() {
|
|
GeoCodeProvider.LocationInformationReceived += GeoCodeProvider_LocationInformationReceived;
|
|
RouteProvider.RouteCalculated += RouteProvider_RouteCalculated;
|
|
RouteProvider.LayerItemsGenerating += RouteProvider_LayerItemsGenerating;
|
|
}
|
|
protected virtual void SubscribeViewModelEvents() {
|
|
ViewModel.UpdateRoute += ViewModel_UpdateRoute;
|
|
ViewModel.PointAChanged += ViewModel_PointAChanged;
|
|
ViewModel.PointBChanged += ViewModel_PointBChanged;
|
|
ViewModel.TravelModeChanged += ViewModel_TravelModeChanged;
|
|
}
|
|
protected virtual void UnsubscribeRouteProviderEvents() {
|
|
GeoCodeProvider.LocationInformationReceived -= GeoCodeProvider_LocationInformationReceived;
|
|
RouteProvider.RouteCalculated -= RouteProvider_RouteCalculated;
|
|
RouteProvider.LayerItemsGenerating -= RouteProvider_LayerItemsGenerating;
|
|
}
|
|
protected virtual void UnsubscribeViewModelEvents() {
|
|
ViewModel.UpdateRoute -= ViewModel_UpdateRoute;
|
|
ViewModel.PointAChanged -= ViewModel_PointAChanged;
|
|
ViewModel.PointBChanged -= ViewModel_PointBChanged;
|
|
ViewModel.TravelModeChanged -= ViewModel_TravelModeChanged;
|
|
}
|
|
void ViewModel_UpdateRoute(object sender, EventArgs e) {
|
|
UpdateUI(GetViewModelEntity());
|
|
}
|
|
protected void ViewModel_EntityChanged(object sender, System.EventArgs e) {
|
|
UpdateUI(GetViewModelEntity());
|
|
}
|
|
protected abstract TEntity GetViewModelEntity();
|
|
void ViewModel_TravelModeChanged(object sender, System.EventArgs e) {
|
|
RouteProvider.RouteOptions.Mode = ViewModel.TravelMode;
|
|
UpdateRoute();
|
|
}
|
|
MapPushpin PointAPin { get; set; }
|
|
void ViewModel_PointAChanged(object sender, System.EventArgs e) {
|
|
if(PointAPin == null)
|
|
PointAPin = new MapPushpin() { Text = "A" };
|
|
PointAPin.Location = ViewModel.PointA.ToGeoPoint();
|
|
}
|
|
MapPushpin PointBPin { get; set; }
|
|
void ViewModel_PointBChanged(object sender, System.EventArgs e) {
|
|
if(PointBPin == null)
|
|
PointBPin = new MapPushpin() { Text = "B" };
|
|
PointBPin.Location = ViewModel.PointB.ToGeoPoint();
|
|
}
|
|
void RouteProvider_RouteCalculated(object sender, BingRouteCalculatedEventArgs e) {
|
|
if(e.Error != null || e.Cancelled || e.CalculationResult == null || e.CalculationResult.ResultCode != RequestResultCode.Success)
|
|
return;
|
|
ProcessRouteResult(e.CalculationResult.RouteResults[0]);
|
|
}
|
|
void GeoCodeProvider_LocationInformationReceived(object sender, LocationInformationReceivedEventArgs e) {
|
|
if(e.Error != null || e.Cancelled || e.Result == null || e.Result.ResultCode != RequestResultCode.Success)
|
|
return;
|
|
LocationInformation[] locations = e.Result.Locations;
|
|
if(locations.Length > 0) {
|
|
LocationInformation loc = locations[0];
|
|
ViewModel.PointB = new Address()
|
|
{
|
|
Line = loc.Address.FormattedAddress,
|
|
Latitude = loc.Location.Latitude,
|
|
Longitude = loc.Location.Longitude,
|
|
};
|
|
}
|
|
}
|
|
void RouteProvider_LayerItemsGenerating(object sender, LayerItemsGeneratingEventArgs args) {
|
|
var items = args.Items;
|
|
for(int i = 0; i < items.Length; i++) {
|
|
MapPushpin pushpin = items[i] as MapPushpin;
|
|
if(pushpin != null)
|
|
pushpin.Visible = false;
|
|
}
|
|
AddRoutePoints();
|
|
}
|
|
void AddRoutePoints() {
|
|
RouteLayer.Data.Items.Clear();
|
|
RouteLayer.Data.Items.Add(PointAPin);
|
|
RouteLayer.Data.Items.Add(PointBPin);
|
|
}
|
|
void ProcessRouteResult(BingRouteResult routeResult) {
|
|
ViewModel.RouteDistance = routeResult.Distance;
|
|
ViewModel.RouteTime = routeResult.Time;
|
|
List<RoutePoint> routePoints = new List<RoutePoint>();
|
|
foreach(BingRouteLeg leg in routeResult.Legs)
|
|
foreach(BingItineraryItem item in leg.Itinerary)
|
|
routePoints.Add(new RoutePoint(item));
|
|
UpdateRouteList(routePoints);
|
|
zoomService.ZoomTo(ViewModel.PointA, ViewModel.PointB);
|
|
}
|
|
void UpdateRouteList(List<RoutePoint> routePoints) {
|
|
if(updateRouteListActionCore != null)
|
|
updateRouteListActionCore(routePoints);
|
|
}
|
|
void UpdateRoute() {
|
|
List<RouteWaypoint> points = new List<RouteWaypoint>();
|
|
points.Add(new RouteWaypoint("Point A", ViewModel.PointA.ToGeoPoint()));
|
|
points.Add(new RouteWaypoint("Point B", ViewModel.PointB.ToGeoPoint()));
|
|
RouteProvider.CalculateRoute(points);
|
|
}
|
|
void UpdateUI(TEntity entity) {
|
|
if(entity == null) return;
|
|
if(updateUIActionCore != null)
|
|
updateUIActionCore(entity);
|
|
MapControl.CenterPoint = ViewModel.PointA.ToGeoPoint();
|
|
AddRoutePoints();
|
|
UpdateRoute();
|
|
}
|
|
}
|
|
public sealed class RoutePoint {
|
|
static Regex removeTagRegex = new Regex(@"<[^>]*>", RegexOptions.Compiled);
|
|
BingItineraryItem item;
|
|
public RoutePoint(BingItineraryItem item) {
|
|
this.item = item;
|
|
ManeuverInstruction = removeTagRegex.Replace(item.ManeuverInstruction, string.Empty);
|
|
double itemDistance = item.Distance;
|
|
Distance = (itemDistance > 0.9) ?
|
|
String.Format("{0:0} mi", Math.Ceiling(itemDistance)) :
|
|
String.Format("{0:0} ft", Math.Ceiling(itemDistance * 52.8) * 100);
|
|
}
|
|
public BingManeuverType Maneuver {
|
|
get { return item.Maneuver; }
|
|
}
|
|
public string ManeuverInstruction {
|
|
get;
|
|
private set;
|
|
}
|
|
public string Distance {
|
|
get;
|
|
private set;
|
|
}
|
|
}
|
|
} |