I have several shape files that define different levels of detail of UK postcodes. They are
Postcode Area (124 polygons)
Postcode District (2833 polygons)
Postcode Sector (9505 polygons)
If I load them into an InformationLayer then we start to get problems with speed especially on the Postcode Sectors. I have decided that probably the best approach is to use a Dynamic Layer, and then choose which of the polygons to show.
I have a couple of questions
1. Can I instantiate a MapShapeReader on its own without associating it with a layer, and if so, how do I then get the polygons?
2. Once I have the polygons, is there an easy way to work out which polygons should be displayed?
I am currently using the beta software with shp files, but I think the basic principal would work with kml files too
Thanks
Simon
Postcode Area (124 polygons)
Postcode District (2833 polygons)
Postcode Sector (9505 polygons)
If I load them into an InformationLayer then we start to get problems with speed especially on the Postcode Sectors. I have decided that probably the best approach is to use a Dynamic Layer, and then choose which of the polygons to show.
I have a couple of questions
1. Can I instantiate a MapShapeReader on its own without associating it with a layer, and if so, how do I then get the polygons?
2. Once I have the polygons, is there an easy way to work out which polygons should be displayed?
I am currently using the beta software with shp files, but I think the basic principal would work with kml files too
Thanks
Simon
11 Answers, 1 is accepted
0
Accepted
Hi Simon,
You can use the MapShapeReader to read shape-file the following way without associating it with a layer:
You can use the LocationRect.Intersect method to check if the polygon should be displayed. Also you should check that the polygon has not been added to the dynamic layer earlier.
Please see the following sample implementation of the dynamic source:
Sincerely yours,
Andrey Murzov
the Telerik team
You can use the MapShapeReader to read shape-file the following way without associating it with a layer:
private
List<FrameworkElement> areas;
private
void
ReadShapes()
{
var reader =
new
MapShapeReader();
reader.PreviewReadCompleted +=
new
PreviewReadShapesCompletedEventHandler(PreviewReadCompleted);
reader.Read(
new
Uri(
"shape-file path"
, UriKind.RelativeOrAbsolute),
new
Uri(
"dbf-file path"
, UriKind.RelativeOrAbsolute));
}
private
void
PreviewReadCompleted(
object
sender, PreviewReadShapesCompletedEventArgs eventArgs)
{
if
(eventArgs.Error ==
null
)
{
this
.areas = eventArgs.Items;
}
}
You can use the LocationRect.Intersect method to check if the polygon should be displayed. Also you should check that the polygon has not been added to the dynamic layer earlier.
Please see the following sample implementation of the dynamic source:
private
class
DynamicSource : IMapDynamicSource
{
private
MainWindow page;
public
DynamicSource(MainWindow examplePage)
{
this
.page = examplePage;
}
public
void
ItemsRequest(
object
sender, ItemsRequestEventArgs e)
{
var layer = sender
as
DynamicLayer;
double
minZoom = e.MinZoom;
Location upperLeft = e.UpperLeft;
Location lowerRight = e.LowerRight;
LocationRect rect =
new
LocationRect(upperLeft, lowerRight);
List<
object
> items =
new
List<
object
>();
if
(minZoom == 3)
{
// request areas
foreach
(FrameworkElement element
in
page.areas)
{
var shape = element
as
MapShape;
if
(shape !=
null
)
{
if
(
this
.ShouldBeAdded(rect, shape, layer))
{
items.Add(shape);
}
}
}
}
e.CompleteItemsRequest(items);
}
private
bool
ShouldBeAdded(LocationRect rect, MapShape shape, DynamicLayer layer)
{
return
!layer.Items.Contains(shape)
&& rect.Intersect(shape.GeographicalBounds);
}
}
Sincerely yours,
Andrey Murzov
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Simon
Top achievements
Rank 1
answered on 02 Nov 2010, 09:50 AM
Thanks for the example, it gives me what I need, However working with your shape files it sometimes does not process some of the shapes that I would expect, for example if I use the Europe.shp file, it will never display the united kingdom
I added the following to the xaml
and then set the DynamicSource of that layer to the DynamicSource object that you gave me
I then put some debugging into the ShouldBeAdded method and found that for some shapes the Intersect method returned False even when surrounding polygons returned True.
I then made ShouldBeAdded return True always, and still some shapes would not be rendered
Attached is a picture of what Europe looks like
Thanks again for all the help on this
Simon
I added the following to the xaml
<
telerik:DynamicLayer
x:Name
=
"ThematicLayer"
>
<
telerik:DynamicLayer.ZoomGridList
>
<
telerik:ZoomGrid
LatitudesCount
=
"2"
LongitudesCount
=
"2"
MinZoom
=
"3"
/>
<
telerik:ZoomGrid
LatitudesCount
=
"4"
LongitudesCount
=
"4"
MinZoom
=
"9"
/>
</
telerik:DynamicLayer.ZoomGridList
>
</
telerik:DynamicLayer
>
and then set the DynamicSource of that layer to the DynamicSource object that you gave me
ThematicLayer.DynamicSource =
new
DynamicSource(
this
);
I then put some debugging into the ShouldBeAdded method and found that for some shapes the Intersect method returned False even when surrounding polygons returned True.
I then made ShouldBeAdded return True always, and still some shapes would not be rendered
Attached is a picture of what Europe looks like
Thanks again for all the help on this
Simon
0
Accepted
Hi Simon,
Thank you for the information. Indeed, we had a couple problems with using of the map shape objects with DynamicLayer. We've fixed these problems and the fix will be available with 2010.Q3 official release.
Sincerely yours,
Andrey Murzov
the Telerik team
Thank you for the information. Indeed, we had a couple problems with using of the map shape objects with DynamicLayer. We've fixed these problems and the fix will be available with 2010.Q3 official release.
Sincerely yours,
Andrey Murzov
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Simon
Top achievements
Rank 1
answered on 05 Nov 2010, 04:46 PM
Brilliant, thanks for looking into this for me
Regards
Simon
Regards
Simon
0
Thomas
Top achievements
Rank 1
answered on 08 Dec 2010, 05:25 PM
Hi Andrey,
Is there a way to loop thru the dataSource [dbf file: this.StateLayer.Reader.DataSource = new Uri(string.Format(ShapeRelativeUriFormat, "usa_states.dbf"), UriKind.Relative); ] prior to it being displayed, I more interested in appending information to the names of state than modifying the names in the dbf file.
Also, is there a way to load a state map and its counties on startup?
Regards
Thomas
Is there a way to loop thru the dataSource [dbf file: this.StateLayer.Reader.DataSource = new Uri(string.Format(ShapeRelativeUriFormat, "usa_states.dbf"), UriKind.Relative); ] prior to it being displayed, I more interested in appending information to the names of state than modifying the names in the dbf file.
Also, is there a way to load a state map and its counties on startup?
Regards
Thomas
0
Hi Thomas,
When the shape reader reads the shape file (shp and dbf pair) then it creates the ExtendedData instance for each shape with a data from dbf file.
You can change values of properties the ExtendedData provides. Also you can add new property and then assign the value from any other source.
You can make it from a code for each read shape using the PreviewReadCompleted event. It occurs before the shapes are added to the information layer.
The sample code is below.
You can change the StateLayerReaderReadCompleted method of DrillDown example to start loading county information on startup:
Best wishes,
Andrey Murzov
the Telerik team
When the shape reader reads the shape file (shp and dbf pair) then it creates the ExtendedData instance for each shape with a data from dbf file.
You can change values of properties the ExtendedData provides. Also you can add new property and then assign the value from any other source.
You can make it from a code for each read shape using the PreviewReadCompleted event. It occurs before the shapes are added to the information layer.
The sample code is below.
private
const
string
NonDbfDataField =
"SampleDataField"
;
void
RadMap1_InitializeCompleted(
object
sender, EventArgs e)
{
if
(!
this
.initialized)
{
this
.initialized =
true
;
this
.StateLayer.Reader =
new
MapShapeReader();
this
.StateLayer.Reader.PreviewReadCompleted +=
new
PreviewReadShapesCompletedEventHandler(Reader_PreviewReadCompleted);
this
.StateLayer.Reader.Source =
new
Uri(
string
.Format(ShapeRelativeUriFormat,
"usa_states.shp"
), UriKind.Relative);
this
.StateLayer.Reader.DataSource =
new
Uri(
string
.Format(ShapeRelativeUriFormat,
"usa_states.dbf"
), UriKind.Relative);
}
}
private
void
Reader_PreviewReadCompleted(
object
sender, PreviewReadShapesCompletedEventArgs eventArgs)
{
if
(eventArgs.Error ==
null
)
{
foreach
(MapShape shape
in
eventArgs.Items)
{
this
.SetAdditionalData(shape);
}
}
}
private
void
SetAdditionalData(MapShape shape)
{
ExtendedData extendedData = shape.ExtendedData;
if
(extendedData !=
null
)
{
// add new property to ExtendedData
if
(!extendedData.PropertySet.ContainsKey(NonDbfDataField))
{
extendedData.PropertySet.RegisterProperty(NonDbfDataField,
""
,
typeof
(
string
),
""
);
}
string
stateName = (
string
)shape.ExtendedData.GetValue(
"STATE_NAME"
);
string
additionalFieldValue =
this
.GetDataByStateName(stateName);
// assign value to new property
shape.ExtendedData.SetValue(NonDbfDataField, additionalFieldValue);
// change existing property
shape.ExtendedData.SetValue(
"STATE_NAME"
,
"State name: "
+ (
string
)shape.ExtendedData.GetValue(
"STATE_NAME"
));
}
}
private
string
GetDataByStateName(
string
stateName)
{
// returns additional field value
}
You can change the StateLayerReaderReadCompleted method of DrillDown example to start loading county information on startup:
private
void
StateLayerReaderReadCompleted(
object
sender, ReadShapesCompletedEventArgs eventArgs)
{
foreach
(MapShape shape
in
this
.StateLayer.Items)
{
shape.MouseLeftButtonUp +=
this
.StateShapeMouseLeftButtonUp;
if
((
string
)shape.ExtendedData.GetValue(
"STATE_NAME"
) ==
"Texas"
)
{
// setup default state
this
.stateShape = shape;
}
}
if
(
this
.stateShape !=
null
)
{
// start loading county information using the MouseLeftButtonUp event handler
this
.StateShapeMouseLeftButtonUp(
this
.stateShape,
null
);
}
}
Best wishes,
Andrey Murzov
the Telerik team
Browse the videos here>> to help you get started with RadControls for WPF
0
Gaurav
Top achievements
Rank 1
answered on 28 May 2013, 12:41 PM
How Can I instantiate a MapShapeReader on its own without associating it with a layer in xml side only ??
Is it possible ?
Is it possible ?
0
Hi Gaurav,
Yes, it is possible. You can create new instance of the MapShapeReader in the code-behind and then use its Read method to read data without associating it to a layer.
The sample code is below.
Regards,
Andrey Murzov
Telerik
Yes, it is possible. You can create new instance of the MapShapeReader in the code-behind and then use its Read method to read data without associating it to a layer.
The sample code is below.
private
void
ReadShapes()
{
MapShapeReader reader =
new
MapShapeReader();
reader.PreviewReadCompleted +=
new
PreviewReadShapesCompletedEventHandler(PreviewReadCompleted);
reader.Read(
new
Uri(
"shape-file path"
, UriKind.RelativeOrAbsolute),
new
Uri(
"dbf-file path"
, UriKind.RelativeOrAbsolute));
}
private
void
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
}
}
Regards,
Andrey Murzov
Telerik
Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.
0
Gaurav
Top achievements
Rank 1
answered on 29 May 2013, 09:21 AM
Thanks for ur concern but i think u didn't get my question..
I want to do it on code behind... I want to specify datasource and source in the .xml side only.
BTW i have seen this answer in above post... this is not i want that's why i make a new entry in this thread.
I want to do it on code behind... I want to specify datasource and source in the .xml side only.
BTW i have seen this answer in above post... this is not i want that's why i make a new entry in this thread.
0
Hi Gaurav,
Unfortunately the MapShapeReader cannot be used within XAML code other way than the value of InformationLayer.Reader property. Also it cannot be used for the DynamicLayer in XAML code directly.
Regards,
Andrey Murzov
Telerik
Unfortunately the MapShapeReader cannot be used within XAML code other way than the value of InformationLayer.Reader property. Also it cannot be used for the DynamicLayer in XAML code directly.
Regards,
Andrey Murzov
Telerik
Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.
0
Gaurav
Top achievements
Rank 1
answered on 29 May 2013, 11:32 AM
Thanks for the quick reply..