ESRI Shapefile and non DBF DataSource

12 posts, 1 answers
  1. James
    James avatar
    30 posts
    Member since:
    Aug 2008

    Posted 22 Nov 2010 Link to this post

    Can I use a non dbf format DataSource (i.e. something external like a web service data source) with an ESRI shapefile?
  2. James
    James avatar
    30 posts
    Member since:
    Aug 2008

    Posted 22 Nov 2010 Link to this post

    I thought of another possible solution, but am away from my project right now. The issue I face is that the DBF data would need to refresh somewhat often, at least once per month in most cases. Does not sound like much, but it might be fairly large files - many of them for different KPI for the ESRI shapefile heatmaps. With normal packaging of the DBF files as resources, that would require a complete download of the whole app every time. My thought is using an HTTP or FTP Uri for the DBF path....will that work?? Yes, I'll take a hit on the load every time they change the KPI they want to look at (i.e. load a new DBF file for the shapefile), but each single one would not be large, there are just many of them. Each DBF fetch/load should not take too long (it's all Intranet as well...so that helps, too).

    Thanks!
  3. UI for WPF is Visual Studio 2017 Ready
  4. Answer
    Andrey
    Admin
    Andrey avatar
    1681 posts

    Posted 25 Nov 2010 Link to this post

    Hi James,

    Unfortunately the MapShapeReader does not support URIs which allows downloading resources from internet.
    I have created a PITS issue for this problem in future versions of map control.You can track it using the following link:
    http://www.telerik.com/support/pits.aspx#/public/silverlight/4127

    As workaround you can use the ShapeFileReader.Read method which allows reading shape-files from a stream. For example you can retrieve elements using HTTP protocol for downloading DBF-file the following way:

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Net;
    using System.Windows;
    using System.Windows.Documents;
    using System.Windows.Resources;
    using Telerik.Windows.Controls.Map;
      
    namespace DBFFromInternet
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            private bool initialized;
      
            public MainWindow()
            {
                InitializeComponent();
      
                this.radMap.InitializeCompleted += new EventHandler(radMap_InitializeCompleted);
            }
      
            private void radMap_InitializeCompleted(object sender, EventArgs e)
            {
                if (!this.initialized)
                {
                    this.initialized = true;
      
                    var shapeUri = new Uri("/DBFFromInternet;component/usa_states.shp", UriKind.Relative);
                    StreamResourceInfo shapeInfo = Application.GetResourceStream(shapeUri);
      
                    WebClient client = new WebClient();
                    byte[] data = client.DownloadData("http://demos.telerik.com/silverlight/DataSources/Geospatial/USA/usa_states.dbf");
                    Stream dbfStream = new MemoryStream(data);
      
                    List<FrameworkElement> elements = ShapeFileReader.Read(shapeInfo.Stream, dbfStream);
                    foreach (FrameworkElement element in elements)
                    {
                        var shape = element as IExtendedData;
                        if (shape != null)
                        {
                            element.ToolTip = shape.ExtendedData.GetValue("STATE_NAME");
                        }
      
                        this.informationLayer.Items.Add(element);
                    }
                }
            }
        }
    }

    Sincerely yours,
    Andrey Murzov
    the Telerik team

    Browse the videos here>> to help you get started with RadControls for WPF
  5. Gonzalo
    Gonzalo avatar
    9 posts
    Member since:
    Aug 2012

    Posted 05 Mar 2013 Link to this post

    Hello!

    I would need exactly the same solution for Silverlight. I've noticed the method client.DownloadData doesnt exist for Silverlight. Any workaround?

    Thank you
  6. Andrey
    Admin
    Andrey avatar
    1681 posts

    Posted 07 Mar 2013 Link to this post

    Hi Gonzalo,

    Currently the MapShapeReader supports URIs for resources from internet. So, you don't need to use that workaround.
    You can just use the MapShapeReader like the sample code below.
    <telerik:RadMap x:Name="radMap">
        <telerik:RadMap.Provider>
            <telerik:OpenStreetMapProvider />
        </telerik:RadMap.Provider>
        <telerik:InformationLayer x:Name="informationLayer">
            <telerik:InformationLayer.Reader>
                <telerik:MapShapeReader DataSource="http://demos.telerik.com/silverlight/DataSources/Geospatial/USA/usa_states.dbf"
                    Source="/DBFFromInternet;component/usa_states.shp"
                    ToolTipFormat="STATE_NAME" />
            </telerik:InformationLayer.Reader>
        </telerik:InformationLayer>
    </telerik:RadMap>

    Regards,
    Andrey Murzov
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

  7. Gonzalo
    Gonzalo avatar
    9 posts
    Member since:
    Aug 2012

    Posted 07 Mar 2013 Link to this post

    Thank you for your answer.
    From which radControls version are you talking about?
  8. Andrey
    Admin
    Andrey avatar
    1681 posts

    Posted 08 Mar 2013 Link to this post

    Hello Gonzalo,

    The issue has been fixed at end of 2010. I think you can use any version of RadControls since the Q1 2011. I have checked this solution with version 2011.1.315.1040. It works correctly.

    Kind regards,
    Andrey Murzov
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

  9. Gonzalo
    Gonzalo avatar
    9 posts
    Member since:
    Aug 2012

    Posted 08 Mar 2013 Link to this post

    Thank you for your quick answer. In our proyect I have to do it programatically I hope i can do this as well :D
  10. Gonzalo
    Gonzalo avatar
    9 posts
    Member since:
    Aug 2012

    Posted 01 Apr 2013 Link to this post

    Hello again!

    Here is my code:

    StreamResourceInfo dbfResourceInfo;
                            StreamResourceInfo shpResourceInfo;
                            List<FrameworkElement> shapes;
                            try
                            {
                                 
                                dbfResourceInfo = Application.GetResourceStream(new Uri(mapItem.DbfFileUri, UriKind.RelativeOrAbsolute));
                                shpResourceInfo = Application.GetResourceStream(new Uri(mapItem.ShpFileUri, UriKind.RelativeOrAbsolute));
                                shapes = ShapeFileReader.Read(shpResourceInfo.Stream, dbfResourceInfo.Stream);
                                 
                            }catch(Exception ex){
                                throw new Exception(CommonTranslations.msgErrorInvalidDBForSHPFileUri);
                            }                       
     
                            // For each shape create a mapAreaDTO and initializate it.
                            foreach (MapPolygon shape in shapes)
                            {
                                MapAreaDTO mapAreaDTO = new MapAreaDTO();                           
                                mapAreaDTO.Polygon = shape;
                                mapAreaDTO.PolygonAreaId = (string)shape.ExtendedData.GetValue(mapItem.DbfColumnName);
                                // add shape in shapesCollectionInShp
                                shapesCollectionInShp.Add(mapAreaDTO);
                            }

    Using this method limits my .shp access to relative-to-project URIs but it works. Now I would like to access these files (shp and dbf) using URI like http://myserver.com/shapefiles/myshapes
    .shp and http://myserver.com/shapefiles/myshapes.dbf
    For that purpose I've used MapShapeReader with read method but keeps on saying that absolute uri was found and it must be relative.


    On the other hand I havent been able to retrieve the shape list from a MapShapeReader (variable in code "reader") so i can loop the MapPolygons which are needed below.

    Any solutions to these 2 questions?







  11. Andrey
    Admin
    Andrey avatar
    1681 posts

    Posted 02 Apr 2013 Link to this post

    Hello Gonzalo,

    You can use the MapShapeReader for reading your shape-file. It allows to get access to the read objects using the MapShapeReader.PreviewReadCompleted event.
    The sample code is below.
    <telerik:RadMap x:Name="radMap">
        <telerik:RadMap.Provider>
            <telerik:OpenStreetMapProvider />
        </telerik:RadMap.Provider>
        <telerik:InformationLayer x:Name="informationLayer">
            <telerik:InformationLayer.Reader>
                <telerik:MapShapeReader DataSource="http://myserver.com/shapefiles/myshapes.dbf"
                    Source="http://myserver.com/shapefiles/myshapes.shp"
                    PreviewReadCompleted="MapShapeReader_PreviewReadCompleted"/>
            </telerik:InformationLayer.Reader>
        </telerik:InformationLayer>
    </telerik:RadMap>
    private void MapShapeReader_PreviewReadCompleted(object sender, PreviewReadShapesCompletedEventArgs eventArgs)
    {
        if (eventArgs.Error != null)
        {
            MessageBox.Show(eventArgs.Error.Message);
        }
        else
        {
            // eventArgs.Items contains the list of objects which are created by MapShapeReader
     
            foreach (MapPolygon shape in eventArgs.Items)
            {
                MapAreaDTO mapAreaDTO = new MapAreaDTO();                          
                mapAreaDTO.Polygon = shape;
                mapAreaDTO.PolygonAreaId = (string)shape.ExtendedData.GetValue(mapItem.DbfColumnName);
                // add shape in shapesCollectionInShp
                shapesCollectionInShp.Add(mapAreaDTO);
            }
        }
    }

    All the best,
    Andrey Murzov
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

  12. Gonzalo
    Gonzalo avatar
    9 posts
    Member since:
    Aug 2012

    Posted 23 Apr 2013 Link to this post

    Thank you for your help :)

    Just a few newbie questions 

    The URL of *.SHP and *.DBF is dynamic, that is to say there is an XML retrieved from server where URL is given. Is it possible to bind this URL to an attribute ? When I should do it before or after initialize() (UserControl) method? In case of twoway binding if i set this URL shapes will be loaded at that moment?

    We need to fill the color of the shapes among other properties when data comes XXXOnComplete Event. How can i access these shapes after being loaded?

    Thank you in advance
  13. Andrey
    Admin
    Andrey avatar
    1681 posts

    Posted 24 Apr 2013 Link to this post

    Hi Gonzalo,

    Yes, it is possible to use databinding for the MapShapeReader.Source and  for the MapShapeReader.DataSource properties.
    I have attached a sample solution which implements databinding of these properties from the viewmodel.
    I hope it helps.

    You shouldn't use TwoWay mode for databinding, because these properties are never changed by the MapShapeReader. The MapShapeReader loads the shape-file asynchronously. You should use the MapShapeReader.PreviewReadCompleted event in order to get access to the loaded shapes. It occurs when the shape-file is already loaded and the shapes are generated. Also the event arguments contains a list of generated shapes. So, you can use it to fill the color of the shapes.

    Regards,
    Andrey Murzov
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

Back to Top
UI for WPF is Visual Studio 2017 Ready