Mini Kabibi Habibi
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Resources;
using System.Xml.Linq;
using DevExpress.Xpf.Map;
using System.Globalization;
using System.Runtime.Serialization;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Net;
using System.IO;
using System.Threading.Tasks;
using System.Runtime.Serialization.Json;
using System.Windows.Threading;
namespace MapDemo {
public enum TemperatureScale { Fahrenheit, Celsius };
public class DemoValuesProvider {
const string key = "AmSNFwVzMvaqFlCYQx9RRUfcAwSQCzi_Vcesric6JFQuBO9wZFXEsqzili-INaUA";
public string DevexpressBingKey { get { return key; } }
public IEnumerable<BingMapKind> BingMapKinds { get { return new BingMapKind[] { BingMapKind.Area, BingMapKind.Road, BingMapKind.Hybrid }; } }
public IEnumerable<string> ShapeMapTypes { get { return new string[] { "GDP", "Population", "Political" }; } }
public IEnumerable<string> ShapefileMapTypes { get { return new string[] { "World", "Africa", "South America", "North America", "Australia", "Eurasia" }; } }
public IEnumerable<TemperatureScale> TemperatureUnit { get { return new TemperatureScale[] { TemperatureScale.Celsius, TemperatureScale.Fahrenheit }; } }
}
public static class DataLoader {
public static XDocument LoadXmlFromResources(string fileName) {
try {
return XDocument.Load("/MapDemo;component" + fileName);
}
catch {
return null;
}
}
}
public class DoubleToTimeSpanConvert : IValueConverter {
#region IValueConvector implementation
public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) {
double doubleValue = 3600 * (double)value;
return new TimeSpan(0, 0, (int)Math.Ceiling(doubleValue));
}
public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) {
return null;
}
#endregion
}
public class RangeColor {
readonly int rangeMin;
readonly int rangeMax;
readonly Color fill;
public int RangeMin {
get { return rangeMin; }
}
public int RangeMax {
get { return rangeMax; }
}
public Color Fill {
get { return fill; }
}
public RangeColor(int rangeMin, int rangeMax, Color fill) {
this.rangeMin = rangeMin;
this.rangeMax = rangeMax;
this.fill = fill;
}
}
public class ViewTypeToBoolConverter : IValueConverter {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
if (targetType == typeof(bool) && value is ViewType && parameter is ViewType)
return (ViewType)value == (ViewType)parameter;
return false;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
if (value is bool)
if (targetType == typeof(ViewType)) {
return (bool)value ? ViewType.Gallery : ViewType.Map;
}
return null;
}
}
public class ShapefileWorldResources {
public Uri CountriesFileUri { get { return new Uri("/MapDemo;component/Data/Shapefiles/Maps/Countries.shp", UriKind.RelativeOrAbsolute); } }
public Uri AfricaFileUri { get { return new Uri("/MapDemo;component/Data/Shapefiles/Maps/Africa.shp", UriKind.RelativeOrAbsolute); } }
public Uri SouthAmericaFileUri { get { return new Uri("/MapDemo;component/Data/Shapefiles/Maps/SouthAmerica.shp", UriKind.RelativeOrAbsolute); } }
public Uri NorthAmericaFileUri { get { return new Uri("/MapDemo;component/Data/Shapefiles/Maps/NorthAmerica.shp", UriKind.RelativeOrAbsolute); } }
public Uri AustraliaFileUri { get { return new Uri("/MapDemo;component/Data/Shapefiles/Maps/Australia.shp", UriKind.RelativeOrAbsolute); } }
public Uri EurasiaFileUri { get { return new Uri("/MapDemo;component/Data/Shapefiles/Maps/Eurasia.shp", UriKind.RelativeOrAbsolute); } }
public ShapefileWorldResources() {
}
}
public class PhotoGalleryResources {
public BitmapImage CityInformationControlSource { get { return new BitmapImage(new Uri("/MapDemo;component/Images/PhotoGallery/CityInformationControl.png", UriKind.RelativeOrAbsolute)); } }
public BitmapImage LabelControlImageSource { get { return new BitmapImage(new Uri("/MapDemo;component/Images/PhotoGallery/Label.png", UriKind.RelativeOrAbsolute)); } }
public BitmapImage PlaceInfoControlPrevImageSource { get { return new BitmapImage(new Uri("/MapDemo;component/Images/PhotoGallery/PrevPlace.png", UriKind.RelativeOrAbsolute)); } }
public BitmapImage PlaceInfoControlNextImageSource { get { return new BitmapImage(new Uri("/MapDemo;component/Images/PhotoGallery/NextPlace.png", UriKind.RelativeOrAbsolute)); } }
public PhotoGalleryResources() {
}
}
public class CityWeather : INotifyPropertyChanged {
OpenWeatherMapService.CityWeatherInfo cityWeatherInfo;
string weatherIconPath;
Weather weather;
ObservableCollection<CityWeather> forecast;
List<WeatherDescription> weatherDescriptions;
string temperatureValueDataMember;
string temperatureString;
string crosshairLabelPattern;
public event PropertyChangedEventHandler PropertyChanged;
public DateTime DateTime { get { return GetTime(cityWeatherInfo.DateTime); } }
public int CityID { get { return cityWeatherInfo.Id; } }
public string City { get { return cityWeatherInfo.Name; } }
public double Longitude { get { return cityWeatherInfo.Coord.Longitude; } }
public double Latitude { get { return cityWeatherInfo.Coord.Latitude; } }
public Weather Weather { get { return weather; } }
public List<WeatherDescription> WeatherDescriptions { get { return weatherDescriptions; } }
public DateTime ForecastTime { get; set; }
public string WeatherIconPath {
get { return weatherIconPath; }
set {
if (weatherIconPath != value) {
weatherIconPath = value;
OnPropertyChanged("WeatherIconPath");
}
}
}
public ObservableCollection<CityWeather> Forecast {
get { return forecast; }
set {
if (forecast != value) {
forecast = value;
OnPropertyChanged("Forecast");
}
}
}
public string TemperatureValueDataMember {
get { return temperatureValueDataMember; }
set {
if (temperatureValueDataMember != value) {
temperatureValueDataMember = value;
OnPropertyChanged("TemperatureValueDataMember");
}
}
}
public string TemperatureString {
get { return temperatureString; }
set {
if (temperatureString != value) {
temperatureString = value;
OnPropertyChanged("TemperatureString");
}
}
}
public string CrosshairLabelPattern {
get { return crosshairLabelPattern; }
set {
if (crosshairLabelPattern != value) {
crosshairLabelPattern = value;
OnPropertyChanged("CrosshairLabelPattern");
}
}
}
public CityWeather(OpenWeatherMapService.CityWeatherInfo cityWeatherInfo) {
this.cityWeatherInfo = cityWeatherInfo;
this.weather = new Weather(cityWeatherInfo.Main);
this.weatherDescriptions = new List<WeatherDescription>();
foreach (OpenWeatherMapService.WeatherDescriptionInfo weatherDescription in cityWeatherInfo.Weather)
weatherDescriptions.Add(new WeatherDescription(weatherDescription));
}
void OnPropertyChanged(string name) {
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
DateTime GetTime(long seconds) {
DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0);
return dtDateTime.AddSeconds(seconds).ToLocalTime();
}
public void SetForecast(ObservableCollection<OpenWeatherMapService.CityWeatherInfo> forecast) {
ObservableCollection<CityWeather> cityWeatherList = new ObservableCollection<CityWeather>();
foreach (OpenWeatherMapService.CityWeatherInfo cityWeatherInfo in forecast)
cityWeatherList.Add(new CityWeather(cityWeatherInfo));
Forecast = cityWeatherList;
}
public void SetCurrentTemperatureType(TemperatureScale temperatureScale) {
switch (temperatureScale) {
case TemperatureScale.Fahrenheit:
TemperatureValueDataMember = "Weather.FahrenheitTemperature";
TemperatureString = Weather.FahrenheitTemperatureString;
CrosshairLabelPattern = "{A:g} : {V} °F";
break;
case TemperatureScale.Celsius:
TemperatureValueDataMember = "Weather.CelsiusTemperature";
TemperatureString = Weather.CelsiusTemperatureString;
CrosshairLabelPattern = "{A:g} : {V} °C";
break;
}
}
}
public class Weather {
OpenWeatherMapService.WeatherInfo weatherInfo;
public int CelsiusTemperature { get { return (int)(weatherInfo.Temp - 273.15); } }
public int FahrenheitTemperature { get { return (int)(weatherInfo.Temp - 273.15) * 9 / 5 + 32; } }
public int KelvinTemperature { get { return (int)weatherInfo.Temp; } }
public string CelsiusTemperatureString { get { return CelsiusTemperature.ToString("+#;-#;0") + " °C"; } }
public string FahrenheitTemperatureString { get { return FahrenheitTemperature.ToString("+#;-#;0") + " °F"; } }
public string KelvinTemperatureString { get { return weatherInfo.Temp.ToString("+#;-#;0") + " °K"; } }
public Weather(OpenWeatherMapService.WeatherInfo weatherInfo) {
this.weatherInfo = weatherInfo;
}
}
public class WeatherDescription {
OpenWeatherMapService.WeatherDescriptionInfo weatherDescriptionInfo;
public string IconName { get { return weatherDescriptionInfo.Icon; } }
public WeatherDescription(OpenWeatherMapService.WeatherDescriptionInfo weatherDescriptionInfo) {
this.weatherDescriptionInfo = weatherDescriptionInfo;
}
}
public class OpenWeatherMapService : INotifyPropertyChanged {
#region classes for JSON parsing
[DataContract]
public class ForecastInfo {
[DataMember]
public ObservableCollection<CityWeatherInfo> list;
}
[DataContract]
public class WorldWeatherInfo {
[DataMember]
public ObservableCollection<CityWeatherInfo> list;
}
[DataContract]
public class CityWeatherInfo {
[DataMember(Name = "id")]
public int Id { get; set; }
[DataMember(Name = "name")]
public string Name { get; set; }
[DataMember(Name = "coord")]
public Coordinates Coord { get; set; }
[DataMember(Name = "main")]
public WeatherInfo Main { get; set; }
[DataMember(Name = "weather")]
public List<WeatherDescriptionInfo> Weather { get; set; }
[DataMember(Name = "wind")]
public WindInfo Wind { get; set; }
[DataMember(Name = "dt")]
public long DateTime { get; set; }
}
[DataContract]
public class WeatherDescriptionInfo {
[DataMember(Name = "main")]
public string Main { get; set; }
[DataMember(Name = "description")]
public string Description { get; set; }
[DataMember(Name = "icon")]
public string Icon { get; set; }
}
[DataContract]
public class WindInfo {
[DataMember(Name = "speed")]
public double Speed { get; set; }
[DataMember(Name = "deg")]
public double Deg { get; set; }
}
[DataContract]
public class WeatherInfo {
[DataMember(Name = "temp")]
public double Temp { get; set; }
[DataMember(Name = "pressure")]
public double Pressure { get; set; }
[DataMember(Name = "humidity")]
public double Humidity { get; set; }
}
[DataContract]
public class Coordinates {
[DataMember(Name = "lon")]
public double Longitude { get; set; }
[DataMember(Name = "lat")]
public double Latitude { get; set; }
}
#endregion
TemperatureScale temperatureScale = TemperatureScale.Celsius;
object weatherLocker = new object();
ObservableCollection<CityWeather> weatherInCities;
List<string> capitals = new List<string>();
public event PropertyChangedEventHandler PropertyChanged;
public ObservableCollection<CityWeather> WeatherInCities {
get { return weatherInCities; }
set {
if (weatherInCities != value) {
weatherInCities = value;
OnPropertyChanged("WeatherInCities");
}
}
}
public ObservableCollection<CityWeather> Forecast { get; set; }
public OpenWeatherMapService() {
LoadCapitalsFromXML();
}
void weatherClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e) {
if (e.Error == null) {
Task.Factory.StartNew(() => {
DataContractJsonSerializer dc = new DataContractJsonSerializer(typeof(WorldWeatherInfo));
WorldWeatherInfo worldWeatherInfo = (WorldWeatherInfo)dc.ReadObject(e.Result);
ObservableCollection<CityWeather> tempWeatherInCities = new ObservableCollection<CityWeather>();
foreach (CityWeatherInfo weatherInfo in worldWeatherInfo.list) {
CityWeather cityWeather = new CityWeather(weatherInfo);
if (capitals.Contains(cityWeather.City)) {
if (cityWeather.WeatherDescriptions != null && cityWeather.WeatherDescriptions.Count > 0)
cityWeather.WeatherIconPath = "http://openweathermap.org/img/w/" + cityWeather.WeatherDescriptions[0].IconName + ".png";
tempWeatherInCities.Add(cityWeather);
}
}
lock (weatherLocker) {
WeatherInCities = tempWeatherInCities;
}
UpdateCurrentTemperatureType();
});
}
}
void forecastClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e) {
if (e.Error == null) {
((WebClient)sender).OpenReadCompleted -= forecastClient_OpenReadCompleted;
Stream stream = e.Result;
CityWeather cityWeatherInfo = (CityWeather)e.UserState;
Task.Factory.StartNew(() => {
DataContractJsonSerializer dc = new DataContractJsonSerializer(typeof(ForecastInfo));
ForecastInfo forecast = (ForecastInfo)dc.ReadObject(stream);
cityWeatherInfo.SetForecast(forecast.list);
});
}
}
void LoadCapitalsFromXML() {
XDocument document = DataLoader.LoadXmlFromResources("/Data/Capitals.xml");
if (document != null) {
foreach (XElement element in document.Element("Capitals").Elements())
capitals.Add(element.Value);
}
}
void OnPropertyChanged(string propertyName) {
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
void UpdateCurrentTemperatureType() {
lock (weatherLocker) {
if (WeatherInCities != null) {
foreach (CityWeather weather in WeatherInCities)
weather.SetCurrentTemperatureType(temperatureScale);
}
}
}
public void GetWeatherAsync() {
string link = "http://api.openweathermap.org/data/2.1/find/city?bbox=-180,-90,180,90";
WebClient weatherClient = new WebClient();
weatherClient.OpenReadCompleted += weatherClient_OpenReadCompleted;
weatherClient.OpenReadAsync(new Uri(link));
}
public void GetForecastForCityAsync(CityWeather cityWeather) {
string link = "http://api.openweathermap.org/data/2.1/forecast/city/" + cityWeather.CityID.ToString();
WebClient forecastClient = new WebClient();
forecastClient.OpenReadCompleted += forecastClient_OpenReadCompleted;
forecastClient.OpenReadAsync(new Uri(link), cityWeather);
}
public void SetCurrentTemperatureType(TemperatureScale temperatureScale) {
this.temperatureScale = temperatureScale;
UpdateCurrentTemperatureType();
}
}
}