// // (C) Copyright 2003-2019 by Autodesk, Inc. // // Permission to use, copy, modify, and distribute this software in // object code form for any purpose and without fee is hereby granted, // provided that the above copyright notice appears in all copies and // that both that copyright notice and the limited warranty and // restricted rights notice below appear in all supporting // documentation. // // AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS. // AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF // MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC. // DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE // UNINTERRUPTED OR ERROR FREE. // // Use, duplication, or disclosure by the U.S. Government is subject to // restrictions set forth in FAR 52.227-19 (Commercial Computer // Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) // (Rights in Technical Data and Computer Software), as applicable. // using System; using System.Collections.Generic; using System.Text; using System.Collections; using System.IO; using System.Windows.Forms; using Autodesk.Revit; using Autodesk.Revit.DB; using Autodesk.Revit.UI; using TaskDialog = Autodesk.Revit.UI.TaskDialog; namespace Revit.SDK.Samples.SharedCoordinateSystem.CS { /// /// a struct used to describe information about city /// public struct CityInfo { double m_timeZone; //Timezone in which the city resides double m_latitude; //Latitude of the city double m_longitude; //Longitude of the city string m_cityName; //name of city /// /// property used to get and set TimeZone /// public double TimeZone { get { return m_timeZone; } set { m_timeZone = value; } } /// /// property used to get and set Latitude /// public double Latitude { get { return m_latitude; } set { m_latitude = value; } } /// /// property used to get and set Longitude /// public double Longitude { get { return m_longitude; } set { m_longitude = value; } } /// /// property used to get and set city name /// public string CityName { get { return m_cityName; } set { m_cityName = value; } } /// /// class CityInfo's constructor /// /// latitude of city /// longitude of city public CityInfo(double latitude, double longitude) { m_latitude = latitude; m_longitude = longitude; m_timeZone = PlaceInfo.InvalidTimeZone; m_cityName = null; } /// /// class CityInfo's constructor /// /// latitude of city /// longitude of city /// timezone of city /// city name public CityInfo(double latitude, double longitude, double timeZone, string cityName) { m_timeZone = timeZone; m_latitude = latitude; m_longitude = longitude; m_cityName = cityName; } } /// /// a struct used to describe information about city /// displayed in Form and it's members are string type /// public struct CityInfoString { string m_timeZone; //Timezone in which the city resides string m_latitude; //Latitde of the city string m_longitude; //Longitude of the city /// /// property used to get and set TimeZone /// public string TimeZone { get { return m_timeZone; } set { m_timeZone = value; } } /// /// property used to get and set Latitude /// public string Latitude { get { return m_latitude; } set { m_latitude = value; } } /// /// property used to get and set Longitude /// public string Longitude { get { return m_longitude; } set { m_longitude = value; } } /// /// class CityInfo's constructor /// /// latitude of city /// longitude of city public CityInfoString(string latitude, string longitude) { m_latitude = latitude; m_longitude = longitude; m_timeZone = null; } /// /// class CityInfo's constructor /// /// latitude of city /// longitude of city /// timezone of city public CityInfoString(string latitude, string longitude, string timeZone) { m_timeZone = timeZone; m_latitude = latitude; m_longitude = longitude; } } /// /// a class used to store information of all city /// include it's name,Latitude,longitude,timezone /// public class PlaceInfo { private List m_citiesName; //city's name private List m_citiesInfo; //information of all cities,such Latitude,longitude private List m_timeZones; //timezone information of all cities private bool m_isTimeZonesValid; //figure out whether can get timezone information private const double Diff = 0.0001; //used to check whether two double values are equal private static readonly double m_invalidTimeZone = -13; //value used when can't get timezone /// /// property used to get and set all cities' name /// public List CitiesName { get { return m_citiesName; } set { m_citiesName = value; } } /// /// property used to get and set all timezone /// public List TimeZones { get { return m_timeZones; } set { m_timeZones = value; } } /// /// property used to get Invalid timezone /// public static double InvalidTimeZone { get { return m_invalidTimeZone; } } /// /// class PlaceInfo's constructor /// /// public PlaceInfo(CitySet cities) { Initialize(cities); } /// /// initialize function /// /// a set store all cities /// public bool Initialize(CitySet cities) { m_citiesInfo = new List(); m_citiesName = new List(); m_timeZones = new List(); if (InitCities(cities) && InitTimeZone()) { return true; } return false; } /// /// Add a city info to city info List /// /// the city info need to add public void AddCityInfo(CityInfo cityInfo) { if (m_citiesInfo.Contains(cityInfo)) { return; } m_citiesInfo.Add(cityInfo); } /// /// try to get city name according to CityInfo /// /// store information about city /// city's name /// city's timezone /// figure out whether this function successful public bool TryGetCityNameTimeZone(CityInfo cityInfo, out string cityName, out double timeZone) { cityName = null; timeZone = m_invalidTimeZone; //loop to find cityinfo matched foreach (CityInfo temp in m_citiesInfo) { //compare Latitude and longitude,and if difference < Diff // the two CityInfo are equal if (Math.Abs(temp.Latitude - cityInfo.Latitude) < Diff && Math.Abs(temp.Longitude - cityInfo.Longitude) < Diff) { cityName = temp.CityName; timeZone = temp.TimeZone; return true; } } return false; } /// /// try to get city info according to city name /// /// city name /// city's information /// figure out whether this function successful public bool TryGetCityInfo(string cityName, out CityInfo cityInfo) { //compare cityName with element's CityName of m_citiesInfo //if they are equal, that element is matched foreach (CityInfo temp in m_citiesInfo) { if (cityName == temp.CityName) { cityInfo = temp; return true; } } cityInfo = new CityInfo(); return false; } /// /// try to get city's timezone /// /// time zone /// figure out whether this function successful public string TryGetTimeZoneString(double timeZoneNumber) { //if Initialize faied or timeZoneNumber is not in range -12 to 12, return null if (!m_isTimeZonesValid || timeZoneNumber > 13 || timeZoneNumber < -12) { return null; } string timeZoneString = null; string temp = null; //try to get a string like "(GMT+08:00)", //the number in string associate with timeZoneNumber //first if timeZoneNumber is 0 if (0 == timeZoneNumber) { temp = "(GMT)"; } else { //if timeZoneNumber > 0 if (timeZoneNumber > 0) { if (timeZoneNumber > 9) { temp = "(GMT+"; } else { temp = "(GMT+0"; } } //if timeZoneNumber < 0 else { if (timeZoneNumber < -9) { temp = "(GMT-"; } else { temp = "(GMT-0"; } } //if timeZoneNumber is not int, append ":30" to string int intNumber = (int)timeZoneNumber; if (0.5 == Math.Abs(timeZoneNumber - intNumber)) { temp += Math.Abs(intNumber) + ":30)"; } else { temp += Math.Abs(intNumber) + ":00)"; } } //try to find string in list m_timeZones contains string get above for (int i = 0; i < m_timeZones.Count; i++) { if (m_timeZones[i].Contains(temp)) { //here, use last member of list contains that string as result. timeZoneString = m_timeZones[i]; } } return timeZoneString; } /// /// try to get TimeZone's number from a string /// /// a string store TimeZone /// result Parse from string public double TryGetTimeZoneNumber(string timeZoneString) { bool isPlus; double result = 0; //check timezone is plus, zero or negative if (timeZoneString.Contains("+")) { isPlus = true; } else if (timeZoneString.Contains("-")) { isPlus = false; } else { return result; } //get int and decimal part of timezone string intString = timeZoneString.Substring(5, 2); string decimalString = timeZoneString.Substring(8, 1); double intNumber; double decimalNumber; //try to get double from string using method Double.TryParse if (Double.TryParse(intString, out intNumber) && Double.TryParse(decimalString, out decimalNumber)) { //if decimal part is not zero, add 0.5 after int part if (0 != decimalNumber) { result = intNumber + 0.5; } else { result = intNumber; } } //if timezone is negative, add minus if (!isPlus) { result *= -1; } return result; } /// /// initialize cities /// /// /// private bool InitCities(CitySet cities) { if (null == cities) { return false; } //add all element of CitySet cities to List m_cities CitySetIterator iter = cities.ForwardIterator(); iter.Reset(); for (; iter.MoveNext(); ) { City city = iter.Current as City; if (null == city) { continue; } m_citiesName.Add(city.Name); m_citiesInfo.Add(new CityInfo(city.Latitude, city.Longitude, city.TimeZone, city.Name)); } //sort list according to first char of element m_citiesName.Sort(); return true; } /// /// initialize timezone /// /// private bool InitTimeZone() { StreamReader streamReader = null; try { //open file store timezone string filepath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); if (!filepath.EndsWith("\\")) { filepath += "\\"; } filepath += "timezone.txt"; streamReader = File.OpenText(filepath); //add timezone to m_timeZones while (!streamReader.EndOfStream) { string text = streamReader.ReadLine(); if (null != text) { m_timeZones.Add(text); } } } catch (Exception e) { m_isTimeZonesValid = false; //show message to tell user that initialize failed TaskDialog.Show("Revit", e.Message); return false; } finally { //close file resource if (null != streamReader) { streamReader.Close(); } } m_isTimeZonesValid = true; return true; } } }