I'm trying to create an application in c#, WPF which will get data from a MongoDB. The basic quering against the MongoDB I get and I also get data out from the DB, but the geodata I'm trying to use is stored like this: "geo" : { "type" : "Point", "coordinates" : [ 59.28973919, 11.1446193 ] }
So I retrieve the data like this:
public static MongoDatabase GetDatabase(string searchText)
{
MongoServerSettings settings = new MongoServerSettings();
settings.Server = new MongoServerAddress("database.example.com", 27017);
MongoServer server = new MongoServer(settings);
MongoDatabase database = server.GetDatabase("tweet_database");
var collection = database.GetCollection<Tweets>("docs");
System.Console.WriteLine("5");
var query = Query.And(Query.Matches("text", searchText),
Query.NE("geo_enabled", false));
System.Console.WriteLine("6");
var cursor = collection.Find(query);
cursor.SetLimit(20);
System.Console.WriteLine("7");
//Puts the result from the last query into a list.
var resultList = cursor.ToList();
//Iterates over the previous mentioned list and inserts the content into the ObservableCollcetion created earlier.
foreach (var item in resultList)
TweetOC.Add(item);
System.Console.WriteLine(TweetOC.Count);
return database;
}
The data retrieved is stored in:
class Docs
{
//Create a new Observable collection.
private static ObservableCollection<Tweets> _TweetOC = new ObservableCollection<Tweets>();
public static ObservableCollection<Tweets> TweetOC
{
get { return _TweetOC; }
set
{
_TweetOC = value;
}
}
}
And the "datamodel" is is this
[BsonIgnoreExtraElements]
public class Tweets
{
// The fields here are the ones which are written out ot the datagrid in Mainwindow.xaml.
public string text { get; set; }
public geo geo { get; set; }
}
[BsonIgnoreExtraElements]
public class geo
{
public double[] coordinates { get; set; }
}
The XAML is like this:
<Window.Resources>
<DataTemplate x:Key="Maptemplate">
<m:Pushpin m:MapLayer.Position="{Binding geo}"
Tag="{Binding}"
Content="{Binding text}">
<m:Pushpin.DataContext>
<local:Tweets/>
</m:Pushpin.DataContext>
</m:Pushpin>
</DataTemplate>
</Window.Resources>
<m:Map x:Name="myMap" CredentialsProvider="API-Key" Mode="Road" Margin="1,0,0,0"
Center="58.1453,7.9571,0.0000" ZoomLevel="9.000" Grid.Column="1" Grid.Row="2" >
<m:Map.Children>
<m:MapItemsControl
ItemsSource="{Binding TweetOC}"
ItemTemplate="{StaticResource Maptemplate}" >
<m:MapItemsControl.DataContext>
<local:Docs/>
</m:MapItemsControl.DataContext>
</m:MapItemsControl>
<m:MapLayer x:Name="ContentPopupLayer">
<Grid x:Name="ContentPopup"
Visibility="Collapsed"
Background="White"
Opacity="0.85">
<StackPanel Margin="15">
<TextBlock x:Name="ContentPopupText"
FontSize="12"
FontWeight="Bold"/>
<TextBlock x:Name="ContentPopupDescription"
FontSize="12"/>
</StackPanel>
</Grid>
</m:MapLayer>
</m:Map.Children>
</m:Map>
A few things are obviously excluded because I didn't think they were relevant.
My question is: How can I use the geodata or the array that the geodata is stored in to autogenerate pushpins on the map? Right now I think the problem is the conversion between the array in the geo-class and the location type used by Bing maps. Based on this errormessage when I retrieve data: System.Windows.Data Error: 1 :
Cannot create default converter to perform 'one-way' conversions between types 'WpfApplication1.geo' and 'Microsoft.Maps.MapControl.WPF.Location'. Consider using Converter property of Binding. BindingExpression:Path=geo; DataItem='Tweets' (HashCode=7643053); target element is 'Pushpin' (Name=''); target property is 'Position' (type 'Location')
Either that or my solution is completely wrong. So can someone please point me in the right direction?
And I know a lot of the coding and structure is bad, but so far in the project, functionality > structure and best practice.
Thanks in advance.
Update
The custom converter i tried writing and using, note that the convert back is never going to be used so I just typed something in there to make it compile:
public class GeoConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
object geo = value;
double asDouble = System.Convert.ToDouble(value);
return asDouble;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
object geo = value;
double asDouble = System.Convert.ToDouble(value);
return asDouble;
}
}
When I try to use use this I get this error: Unable to cast object of type 'WpfApplication1.geo' to type 'System.IConvertible.