Back to Devexpress

How to: Implement a Custom Geocode Provider

wpf-118754-controls-and-libraries-map-control-examples-gis-data-geocoding-how-to-implement-a-custom-geocode-provider.md

latest7.7 KB
Original Source

How to: Implement a Custom Geocode Provider

  • Jun 07, 2019
  • 4 minutes to read

This example demonstrates how to create a custom geocode provider.

To do this, design a class inheriting the InformationDataProviderBase class and the IMouseClickRequestSender interface, and implement the CreateData and RequestByPoint methods in the class. Then, design a class inheriting the IInformationData interface and override its IInformationData.OnDataResponse event. Implement the CalculateAddress method to provide custom geocode logic.

vb
Imports DevExpress.Xpf.Map
Imports System
Imports System.Windows

Namespace CustomGeocodeProvider
    ''' <summary>
    ''' Interaction logic for MainWindow.xaml
    ''' </summary>
    Partial Public Class MainWindow
        Inherits Window

        Public Sub New()
            InitializeComponent()
            informationLayer.DataProvider = New GeocodeDataProvider()
        End Sub
    End Class
    Public Class GeocodeDataProvider
        Inherits InformationDataProviderBase
        Implements IMouseClickRequestSender

        Public Sub New()
            Me.ProcessMouseEvents = True
        End Sub
        Protected Shadows ReadOnly Property Data() As GeocodeData
            Get
                Return CType(MyBase.Data, GeocodeData)
            End Get
        End Property
        Public Sub RequestByPoint(ByVal geoPoint As GeoPoint, ByVal screenPoint As Point) Implements IMouseClickRequestSender.RequestByPoint
            Data.CalculateAddress(geoPoint)
        End Sub
        Protected Overrides Function CreateData() As IInformationData
            Return New GeocodeData()
        End Function
        Protected Overrides Function CreateObject() As MapDependencyObject
            Return New GeocodeDataProvider()

        End Function
        Public Overrides ReadOnly Property IsBusy() As Boolean
            Get
                Throw New NotImplementedException()
            End Get
        End Property
        Public Overrides Sub Cancel()
            Throw New NotImplementedException()
        End Sub

    End Class
    Public Class GeocodeData
        Implements IInformationData

        Private address_Renamed As New LocationInformation()
        Public Property Address() As LocationInformation
            Get
                Return address_Renamed
            End Get
            Set(ByVal value As LocationInformation)
                address_Renamed = value
            End Set
        End Property

        Public Event OnDataResponse As EventHandler(Of RequestCompletedEventArgs) Implements IInformationData.OnDataResponse

        Private Function CreateEventArgs() As RequestCompletedEventArgs
            Dim item As MapItem = New MapPushpin() With {.Location = address_Renamed.Location, .Information = address_Renamed.Address.FormattedAddress}
            Return New RequestCompletedEventArgs(New MapItem() {item}, Nothing, False, Nothing)
        End Function
        Protected Sub RaiseChanged()
            RaiseEvent OnDataResponse(Me, CreateEventArgs())
        End Sub
        Public Sub CalculateAddress(ByVal geoPoint As GeoPoint)
            'Implement your custom geocode logic here
            Dim info As New LocationInformation()
            info.Address = New Address("Address from your service here " & Environment.NewLine & "Coordinates: " & geoPoint.ToString())
            info.Location = New GeoPoint(geoPoint.Latitude, geoPoint.Longitude)
            Address = info
            '
            RaiseChanged()
        End Sub
    End Class
    Public Class Address
        Inherits AddressBase

        Public Sub New(ByVal address As String)
            Me.FormattedAddress = address
        End Sub

        Protected Overrides Function CreateObject() As MapDependencyObject
            Throw New NotImplementedException()
        End Function
    End Class
End Namespace
xaml
<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:CustomGeocodeProvider"
        xmlns:dxm="http://schemas.devexpress.com/winfx/2008/xaml/map" x:Class="CustomGeocodeProvider.MainWindow"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>

        <dxm:MapControl>
            <dxm:ImageLayer>
                <dxm:OpenStreetMapDataProvider/>
            </dxm:ImageLayer>
            <dxm:InformationLayer x:Name="informationLayer"/>
        </dxm:MapControl>

    </Grid>
</Window>
csharp
using DevExpress.Xpf.Map;
using System;
using System.Windows;

namespace CustomGeocodeProvider {
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window {
        public MainWindow() {
            InitializeComponent();
            informationLayer.DataProvider = new GeocodeDataProvider();
        }
    }
    public class GeocodeDataProvider : InformationDataProviderBase, IMouseClickRequestSender {
        public GeocodeDataProvider() {
            this.ProcessMouseEvents = true;
        }
        protected new GeocodeData Data { get { return (GeocodeData)base.Data; } }
        public void RequestByPoint(GeoPoint geoPoint, Point screenPoint) {
            Data.CalculateAddress(geoPoint);
        }
        protected override IInformationData CreateData() {
            return new GeocodeData();
        }
        protected override MapDependencyObject CreateObject() {
            return new GeocodeDataProvider();

        }
        public override bool IsBusy {
            get {
                throw new NotImplementedException();
            }
        }
        public override void Cancel() {
            throw new NotImplementedException();
        }
    }
    public class GeocodeData : IInformationData {

        LocationInformation address = new LocationInformation();
        public LocationInformation Address { get { return address; } set { address = value; } }

        public event EventHandler<RequestCompletedEventArgs> OnDataResponse;
        RequestCompletedEventArgs CreateEventArgs() {
            MapItem item = new MapPushpin() { Location = address.Location, Information = address.Address.FormattedAddress };
            return new RequestCompletedEventArgs(new MapItem[] { item }, null, false, null);
        }
        protected void RaiseChanged() {
            if (OnDataResponse != null)
                OnDataResponse(this, CreateEventArgs());
        }
        public void CalculateAddress(GeoPoint geoPoint) {
            //Implement your custom geocode logic here
            LocationInformation info = new LocationInformation();
            info.Address = new Address("Address from your service here " + Environment.NewLine + "Coordinates: " + geoPoint.ToString());
            info.Location = new GeoPoint(geoPoint.Latitude, geoPoint.Longitude);
            Address = info;
            //
            RaiseChanged();
        }
    }
    public class Address : AddressBase {
        public Address(string address) {
            this.FormattedAddress = address;
        }

        protected override MapDependencyObject CreateObject() {
            throw new NotImplementedException();
        }
    }
}