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

How to set SQLGeospatialDataReader programatically?

6 Answers 171 Views
Map
This is a migrated thread and some comments may be shown as answers.
Yan Moura
Top achievements
Rank 1
Veteran
Iron
Yan Moura asked on 02 Dec 2011, 09:16 PM
Hi,

I picked the Telerik sample at http://demos.telerik.com/silverlight/#Map/WktReader and I am trying (unsuccessfully) to implement the SqlGeospatialDataReader PROGRAMATICALLY instead in the XAML files.

Originally it is implemented in the XAML file this way:

<telerik:RadMap x:Name="RadMap1"
                        Center="33.7861647934865, -84.371616833534"
                        ZoomLevel="10"
                        MinZoomLevel="4">
            <telerik:InformationLayer x:Name="InformationLayer">
                <telerik:InformationLayer.Reader>
                    <telerik:SqlGeospatialDataReader Source="{Binding Source={StaticResource DataContext}, Path=WktDataCollection}"
                                                     GeospatialPropertyName="Geometry"
                                                     ToolTipFormat="Name">
                    </telerik:SqlGeospatialDataReader>
                </telerik:InformationLayer.Reader>
                <telerik:InformationLayer.ShapeFill>
                    <telerik:MapShapeFill Fill="#7FFFFFFF" Stroke="#5A636B" StrokeThickness="3" />
                </telerik:InformationLayer.ShapeFill>
                <telerik:InformationLayer.HighlightFill>
                    <telerik:MapShapeFill Fill="#B2FFFFFF" Stroke="#5A636B" StrokeThickness="3" />
                </telerik:InformationLayer.HighlightFill>
            </telerik:InformationLayer>
        </telerik:RadMap>

PS: I removed the PointTemplate section to make it simpler.

Then, I modified my XAML file to:

<telerik:RadMap x:Name="RadMap1"
                        Center="33.7861647934865, -84.371616833534"
                        ZoomLevel="10"
                        MinZoomLevel="4">
            <telerik:InformationLayer x:Name="InformationLayer" />
        </telerik:RadMap>

And modified my XAML.CS file to:

public MapShapeFill NFill = new MapShapeFill();
        public MapShapeFill HFill = new MapShapeFill();
        public SqlGeospatialDataReader SQLR = new SqlGeospatialDataReader();
 
        public MainPage()
        {
            InitializeComponent();
 
            // Configure Information Layer Shape Fill
            NFill.Fill = new SolidColorBrush(Colors.LightGray);
            NFill.Stroke = new SolidColorBrush(Colors.DarkGray);
            NFill.StrokeThickness = 3;
 
            // Configure Information Layer Highlight Shape Fill
            HFill.Fill = new SolidColorBrush(Colors.Cyan);
            HFill.Stroke = new SolidColorBrush(Colors.DarkGray);
            HFill.StrokeThickness = 3;
 
            InformationLayer.ShapeFill = NFill;
            InformationLayer.HighlightFill = HFill;
 
            SQLR.Source = "{Binding Source={StaticResource DataContext}, Path=WktDataCollection}";
            SQLR.GeospatialPropertyName = "Geometry";
            InformationLayer.Reader = SQLR;
 
            RadMap1.Provider = new BingMapProvider(MapMode.Aerial, true, "MyBingToken");
        }

Since I did things step by step, I know that it stopped to work when I implemented the SqlGeospatialDataReader part. The fill part worked nice. I suspect that the problem is in the Source, but I am not sure.

Any clues about what I am missing here?

Thanks!

6 Answers, 1 is accepted

Sort by
0
Yan Moura
Top achievements
Rank 1
Veteran
Iron
answered on 05 Dec 2011, 07:59 PM
Hey,

Never mind, I figured this out!

For whose may be interested, the problem was in the way I was setting the source, by simply attributing the source string to the Source property.

The right way is to create a new instance of the class that contains the collection and then attribute it to the Source property.

So, instead:

// Configure SQL Data Reader
SQLR.Source = "{Binding Source={StaticResource DataContext}, Path=WktDataCollection}";
SQLR.GeospatialPropertyName = "Geometry";

Do:

// Configure SQL Data Reader
WktDataViewModel mymodel = new WktDataViewModel();
SQLR.Source = mymodel.WktDataCollection;
SQLR.GeospatialPropertyName = "Geometry";

I hope this helps someone out there!

:)

The Telerik project (as well this programmatic implementation) are only for exemplification purposes since there is not a point on have a class with hard coded data.

Instead, you should completely delete the WktDataViewModel.cs class from your project and write a function that reads the data from database and then push this data into the collection, like this:

public partial class MyMainPage : UserControl
{
    public InformationLayer IL = new InformationLayer();
    public SqlGeospatialDataReader SQLR = new SqlGeospatialDataReader();
    public MapShapeFill NFill = new MapShapeFill();
    public MapShapeFill HFill = new MapShapeFill();
    public Collection<WktDataRow> MyCollection = new Collection<WktDataRow>();
     
    public MyMainPage()
    {
        // Initialize RadMap component
        InitializeComponent();
         
        // Load data into the collection
        // this is your function that supposed to get data
        // from SQL and load it into the MyCollection
        ReadDataFromSQL();
         
        // Configure SQL Data Reader
        SQLR.Source = MyCollection;
        SQLR.GeospatialPropertyName = "Geometry";
         
        // Configure Information Layer Shape Fill
        NFill.Fill = new SolidColorBrush(Colors.LightGray);
        NFill.Stroke = new SolidColorBrush(Colors.DarkGray);
        NFill.StrokeThickness = 3;
         
        // Configure Information Layer Highlight Shape Fill
        HFill.Fill = new SolidColorBrush(Colors.Cyan);
        HFill.Stroke = new SolidColorBrush(Colors.DarkGray);
        HFill.StrokeThickness = 3;
         
        // Add SQL Data Reader and Fills to Information Layer
        IL.Reader = SQLR;
        IL.ShapeFill = NFill;
        IL.HighlightFill = HFill;
         
        // Add Information Layer to Map
        RadMap1.Items.Add(IL);
    }
}

And finally your XAML file will be as simple as this:

<UserControl x:Class="YV_GIS.MainPage"
    xmlns:example="clr-namespace:YV_GIS"
    xmlns:telerikQuickStart="clr-namespace:Telerik.Windows.Controls.QuickStart;assembly=Telerik.Windows.Controls"
 
    <Grid x:Name="LayoutRoot">
        <telerik:RadMap x:Name="RadMap1"
                        Center="33.7861647934865, -84.371616833534"
                        ZoomLevel="10"
                        MinZoomLevel="4">
        </telerik:RadMap>
    </Grid>
</UserControl>

The big advantage on this approach is that you will have the minimum as possible declared in design time, and all the rest can be defined on-the-fly, giving too much more flexibility.

:)

Cheers!
0
Gonzalo
Top achievements
Rank 1
answered on 30 Apr 2013, 06:03 AM
Hello!

Thank you for your help, we are using this approach in our project :).
We would need something extra, we need to change fill color of each shape based on metric at runtime value and also we need to get an event when area is selected. How can we achieve this using this approach? Is there any way to access to MapPolygons, Mappaths, etc.... once SQLGeospatialDataReader has read all the shapes ? 

Thank you in advance.
0
Andrey
Telerik team
answered on 30 Apr 2013, 01:57 PM
Hello Gonzalo,

Yes, you can use the SqlGeospatialDataReader.PreviewReadCompleted event to get access to the generated shapes. Also you can access data of SQL table columns using the MapShape.ExtendedData property.
The sample code is below.
SQLR.PreviewReadCompleted += SQLR_PreviewReadCompleted;
SQLR.Source = MyCollection;
SQLR.GeospatialPropertyName = "Geometry";
 
private void SQLR_PreviewReadCompleted(object sender, PreviewReadShapesCompletedEventArgs e)
{
    if (e.Error != null)
    {
        MessageBox.Show(e.Error.Message);
    }
    else
    {
        // e.Items contains the list of objects which are created by SqlGeospatialDataReader
        foreach (object item in e.Items)
        {
            MapShape shape = item as MapShape;
            if (shape != null)
            {
                double myValue = (double)shape.ExtendedData.GetValue(SQLColumnName);
                if (myValue > 1)
                {
                    MapShapeFill fill = new MapShapeFill()
                    {
                        Fill = new SolidColorBrush(Colors.Orange),
                        Stroke = new SolidColorBrush(Colors.Blue),
                        StrokeThickness = 1
                    };
 
                    shape.ShapeFill = fill;
 
                    MapShapeFill highlight = new MapShapeFill()
                    {
                        Fill = new SolidColorBrush(Colors.Yellow),
                        Stroke = new SolidColorBrush(Colors.Blue),
                        StrokeThickness = 2
                    };
 
                    shape.HighlightFill = highlight;
                }
            }
        }
    }
}

Kind regards,
Andrey Murzov
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Gonzalo
Top achievements
Rank 1
answered on 30 Apr 2013, 07:13 PM
Thank you very much. I'll test the code with my team as soon as possible :)
0
Jenni
Top achievements
Rank 1
answered on 17 Jun 2013, 03:50 AM

I'm playing around with silverlight map control. All my data is in SQL server.  I have worked the entire weekend without success.

Will be possible to have published this complete project as example? Please. Thanks in advance

0
Andrey
Telerik team
answered on 17 Jun 2013, 10:02 AM
Hello Jenni,

I have attached an example which loads data via SqlGeospatialDataReader using WCF Data Service.
I hope this gets you started.

Regards,
Andrey Murzov
Telerik

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

Tags
Map
Asked by
Yan Moura
Top achievements
Rank 1
Veteran
Iron
Answers by
Yan Moura
Top achievements
Rank 1
Veteran
Iron
Gonzalo
Top achievements
Rank 1
Andrey
Telerik team
Jenni
Top achievements
Rank 1
Share this question
or