This is a migrated thread and some comments may be shown as answers.

ESRI Shapefile and non DBF DataSource

11 Answers 208 Views
Map
This is a migrated thread and some comments may be shown as answers.
James
Top achievements
Rank 1
James asked on 22 Nov 2010, 07:50 PM
Can I use a non dbf format DataSource (i.e. something external like a web service data source) with an ESRI shapefile?

11 Answers, 1 is accepted

Sort by
0
James
Top achievements
Rank 1
answered on 22 Nov 2010, 11:22 PM
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!
0
Accepted
Andrey
Telerik team
answered on 25 Nov 2010, 04:05 PM
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
0
Gonzalo
Top achievements
Rank 1
answered on 05 Mar 2013, 12:02 PM
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
0
Andrey
Telerik team
answered on 07 Mar 2013, 08:56 AM
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.

0
Gonzalo
Top achievements
Rank 1
answered on 07 Mar 2013, 10:54 AM
Thank you for your answer.
From which radControls version are you talking about?
0
Andrey
Telerik team
answered on 08 Mar 2013, 11:56 AM
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.

0
Gonzalo
Top achievements
Rank 1
answered on 08 Mar 2013, 12:35 PM
Thank you for your quick answer. In our proyect I have to do it programatically I hope i can do this as well :D
0
Gonzalo
Top achievements
Rank 1
answered on 01 Apr 2013, 09:19 AM
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?







0
Andrey
Telerik team
answered on 02 Apr 2013, 07:14 AM
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.

0
Gonzalo
Top achievements
Rank 1
answered on 23 Apr 2013, 10:53 PM
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
0
Andrey
Telerik team
answered on 24 Apr 2013, 11:13 AM
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.

Tags
Map
Asked by
James
Top achievements
Rank 1
Answers by
James
Top achievements
Rank 1
Andrey
Telerik team
Gonzalo
Top achievements
Rank 1
Share this question
or