11 Answers, 1 is accepted
Thanks!
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
I would need exactly the same solution for Silverlight. I've noticed the method client.DownloadData doesnt exist for Silverlight. Any workaround?
Thank you
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.
From which radControls version are you talking about?
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.
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?
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"
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.
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
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.