# Map Tile Provider Customization

This topic guides you through the steps to set a custom tile provider in the Map control using the IMapTileProvider and IMapTile interfaces.

## Content

You can add and configure a Custom Tile Provider in the [Map](/activereportsnet/docs/v20.1/report-authors/report-controls/report-controls-page-rdl-report/map) control using the [IMapTileProvider](/activereportsnet/api/v20.1/MESCIUS.ActiveReports.Core.Rendering/GrapeCity.ActiveReports.Extensibility.Rendering.Components.Map.IMapTileProvider.html) and [IMapTile](/activereportsnet/api/v20.1/MESCIUS.ActiveReports.Core.Rendering/GrapeCity.ActiveReports.Extensibility.Rendering.Components.Map.IMapTile.html) interfaces.

The **IMapTileProvider** interface contains detailed settings that are required to communicate with the tile server, whereas the **IMapTile** interface represents a single tile of a Map's tile layer that fetches the tile image based on the configurations in the **IMapTileProvider** interface.

### Set a Custom Tile Provider

Adding a custom tile provider also requires making some modifications in the ActiveReports.config file. Follow these steps to learn how to set a custom tile provider:

1. Create a Class Library Project, for example **MyClassLib**, in Visual Studio.
2. Add a new **Class** to the project and name the class, for example, **MyTileProvider**. You may add functions and features to this class for getting the Tile images based on your tile server settings and details. This class serves as the interface between your Map control and your custom tile server. Replace the existing code with the following in the **MyTileProvider** class to implement the **IMapTileProvider** interface.
<br>
    To write the code in Visual Basic.NET

    ```vbnet
    Imports System
    Imports System.Collections.Specialized
    Imports GrapeCity.ActiveReports.Extensibility.Rendering.Components.Map
    ```

    ```vbnet
    Namespace MyClassLib
       Public Class MyTileProvider Implements IMapTileProvider
            ' Tile provider settings, like ApiKey, Language, Style and etc.
            Public Property Settings() As NameValueCollection
            ' Add your code here.
            End Property
            ' Get instance of tile by specifying tile coordinates and details.
            Public Sub GetTile(key As MapTileKey, success As Action(Of IMapTile), [error] As Action(Of Exception))
            ' Add your code here.
            End Sub
        End Class 
    End Namespace
    ```

    To write the code in C#

    ```csharp
    using System;
    using System.Collections.Specialized;
    using GrapeCity.ActiveReports.Extensibility.Rendering.Components.Map;
    ```

    ```csharp
    namespace MyClassLib
    {
        public Class MyTileProvider :IMapTileProvider
        {// Tile provider settings, like ApiKey, Language, Style and etc.
        public NameValueCollection Settings { get; private set;}
        // Get instance of tile by specifying tile coordinates and details.
        public void GetTile(MapTileKey key, Action<IMapTile> success, Action<Exception> error);
        // Add your code here.
        }
    }
    ```
3. Add a new **Class** to the project and name the class, for example, **MyMapTile**. Replace the existing code with the following in the **MyMapTile** class to implement the **IMapTile** interface.
<br>
    To write the code in Visual Basic.NET

    ```vbnet
    Imports System.IO
    Imports GrapeCity.ActiveReports.Extensibility.Rendering.Components.Map
    ```

    ```vbnet
    Namespace MyClassLib
       Public Class MyMapTile Implements IMapTile
           ' Gets the tile identifier 
           Public Property Id() As MapTileKey
           ' Add your code here
           End Property
           ' Gets the tile image stream.
           Public Property Image() As Stream
           ' Add your code here. 
           End Property     
       End Class
    End Namespace
    ```

    To write the code in C#

    ```csharp
    using System.IO;
    using GrapeCity.ActiveReports.Extensibility.Rendering.Components.Map;
    ```

    ```csharp
    namespace MyClassLib
       public class MyMapTile : IMapTile
       {   // Gets the tile identifier.
           public MapTileKey Id { get; private set; }
           // Gets the tile image stream.
           public Stream Image { get; private set; }  
           // Add your code here.     
        }
    }
    ```
4. Add another **Class** to the project and name the class, for example, **WebRequestHelper**. Replace the existing code with the following in the **WebRequestHelper** class to implement the loading of raw website data into the System.IO.MemoryStream class.
<br>
    To write the code in Visual Basic.NET

    ```vbnet
    Imports System.IO
    Imports System.Net
    ```

    ```vbnet
    Namespace MyClassLib
        Module StringExtensions
            Public Sub CopyTo(ByVal input As Stream, ByVal output As Stream)
            'Add your code here    
            End Sub
            Private Function InlineAssignHelper(Of T)(ByRef target As T, value As T) As T
            'Add your code here    
            End Function
        End Module
        Friend NotInheritable Class WebRequestHelper
            Private Sub New()
            End Sub
            ' Load raw data into MemoryStream from specified Url.
            Public Shared Function DownloadData(url As String, timeoutMilliseconds As Integer) As Stream
            'Add your code here   
            End Function
            'Load raw data into MemoryStream from specified Url.
            Public Shared Sub DownloadDataAsync(url As String, timeoutMilliseconds As Integer, success As Action(Of MemoryStream), [error] As Action(Of Exception))
            'Add your code here   
            End Sub
            Private Shared Function InlineAssignHelper(Of T)(ByRef target As T, value As T) As T
            'Add your code here   
            End Function
        End Class
    End Namespace
    ```

    To write the code in C#

    ```csharp
    using System.IO;
    using System.Net;
    ```

    ```csharp
    namespace MyClassLib
    {  
        internal static class WebRequestHelper
        {   // Load raw data into MemoryStream from specified Url.
            public static Stream DownloadData(string url, int timeoutMilliseconds)        
            {//Add your code here  }       
            public static void DownloadDataAsync(string url, int timeoutMilliseconds, Action<MemoryStream> success, Action<Exception> error)
            {//Add your code here  }
            public static void CopyTo(this Stream input, Stream output)
            {//Add your code here  }
        }
    }
    ```
5. Save and build your class library project and locate the new .dll file in its **Bin>Debug** folder. This file has the same name as your class library project, with a .dll extension.
6. Create a Basic End User Designer in a new solution following the steps in [Creating a Basic End User Designer](https://github.com/activereports/Samples19/tree/main/DesignerPro/EndUserDesigner/C%23).
7. Run your Basic End User Designer project to create a EndUserDesigner.exe in your projects **Bin>Debug** folder.
8. Copy the ActiveReports.config file from the *C:\\Program Files (x86)\\MESCIUS\\ActiveReports 20\\* location and paste it into your End User Designer project's **Bin>Debug** folder.

    >type=warning
> **Caution**: ActiveReports.config file should always be placed inside the same folder as the EndUserDesigner.exe file for displaying a tile layer on a Map.
9. Right-click on the ActiveReports.config file and select **Include in this Project** to make changes in the config file.
10. Double-click to open the ActiveReports.config file and paste the following code between the **\<Configuration>** and **\</Configuration>** tags:

```auto
```xml
<!-- Register and configure custom tile provider. -->
<MapTileProvider Name="Custom" DisplayName="Custom Provider" type="YourTileProvider, AssemblyName, Version = x.x.x.x">
    <Settings>
      <add key="ApiKey" value="API Key" />
    </Settings>
</MapTileProvider>
```

> type=note
> **Note**: Replace **_YourTileProvider_** with fully qualified class name and **_AssemblyName_** with the name of the assembly created after implementing IMapTileProvider and IMapTile interfaces.
```

11. Add the Class Library project created in step 5 to your Basic End User Designer project.
12. Copy the *YourProjectName.dll* created in step 5 and paste it to the current project's **Bin > Debug** folder together with the EndUserDesigner.exe.
13. Save and Run the project.
14. Create a Report containing a Map control in the **Basic** **End User Designer**. See [Map Data Region](/activereportsnet/docs/v20.1/report-authors/design-reports/design-page-rdl-reports/tutorials-page-rdl/map-data-region-in-reports) for more information.
15. Add a Tile layer to the Map control. Right click the Tile layer and select **Edit** to view the custom tile provider added in the Provider drop-down. See [Tile Layer](/activereportsnet/docs/v20.1/report-authors/report-controls/report-controls-page-rdl-report/map/use-map-layers/tile-layer) for more information.

## See Also

#### Samples

[Custom Tile Provider](/activereportsnet/docs/v20.1/samples/samples-ar/advanced-sample/page-and-rdl-advanced/custom-tile-provider)