应用程序:SharedCoordinateSystem
Revit平台:全部
Revit版本:2011.0
首次发布时间:9.1
编程语言:C#
技能水平:中等
类别:元素
类型:ExternalCommand(外部命令)
主题:获取和设置项目的地点、位置。
概述:
本示例演示了如何获取项目的位置和地点,并更改它们的值。
相关类:
Autodesk.Revit.UI.IExternalCommand
Autodesk.Revit.DB.Element
Autodesk.Revit.DB.GeometryElement
Autodesk.Revit.DB.Parameter
Autodesk.Revit.DB.GeometryObject
Autodesk.Revit.DB.Transform
Autodesk.Revit.DB.Structure.AnalyticalModel
Autodesk.Revit.DB.SiteLocation
Autodesk.Revit.DB.CitySet
项目文件:
Command.cs
该文件包含继承自“IExternalCommand”接口并实现“Execute”方法的“Command”类。
CoordinateSystemData.cs
该文件包含了一个名为“CoordinateSystemData”的类,用于处理位置信息,如“获取”、“更改”和“复制”位置。
CoordinateSystemDataForm.cs
该文件包含了一个名为“CoordinateSystemDataForm”的类,用于在具有两个选项卡“Locations”和“Place”的TabControl中显示和设置位置和地点信息。
DuplicateForm.cs
该文件包含了一个名为“DuplicateForm”的类,用于复制位置信息。
PlaceInfo.cs
该文件由以下组成:
一个名为“PlaceInfo”的类,用于存储所有城市的信息,包括其名称、纬度、经度和时区;
一个名为“CityInfo”的结构体,用于描述有关城市的信息;
一个名为“CityInfoString”的结构体,用于描述城市信息,其所有成员均为字符串类型。
UnitConversion.cs
该文件包含了一个名为“UnitConversion”的类,它是一个实用程序类,提供单位信息和一些单位转换函数,如将字符串转换为双精度浮点数。
描述:
本示例演示了以下功能:
- 获取当前文档的地点信息,并从地点信息中获取以下数据:
- 城市名称。
- 纬度。
- 经度。
- 时区。
- 获取当前文档的位置信息,并从位置信息中获取以下数据:
- 名称
- 转换(从此点到原点)
- 提供对话框以显示当前文档的地点和位置数据,并修改以下信息:
- 活动地点的纬度、经度和时区
- 活动文档的活动地点(城市名称、纬度和经度)到定义的磁盘上的AR-CITY.UNI文件
- 当前位置的转换
- 从定义的位置列表中获取当前位置
- 向列表中添加新位置。
实施:
- 可以使用“Document.ActiveProjectLocation”属性检索活动项目的位置。
- 可以使用“Document.SiteLocation”属性检索活动项目的地点。可以通过“Autodesk.Revit.Site.SiteLocation”类的“Latitude”、“Longitude”和“TimeZone”属性检索纬度、经度和时区信息。
说明:
1. 将项目文件夹中的“timezone.txt”文件复制到“SharedCoordinateSystem.dll”文件所在的同一文件夹目录中,然后运行命令。
2. 一个带有选项卡控件的对话框将被显示,用于显示有关地点和位置的信息,允许设置或更改位置和地点的值。
3. 此外,此示例类似于Revit“设置”下的菜单命令“管理地点和位置”,前者几乎可以执行后者可以执行的所有操作。
源代码:
完整的源代码请加入QQ群649037449,在群文件中下载RevitSDK.exe,解压后在文件夹中搜索本文中应用程序名称即可获得完整源码
CoordinateSystemData.cs
PlaceInfo.cs
//
// (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;
namespace Revit.SDK.Samples.SharedCoordinateSystem.CS
{
/// <summary>
/// a struct used to describe information about city
/// </summary>
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
/// <summary>
/// property used to get and set TimeZone
/// </summary>
public double TimeZone
{
get
{
return m_timeZone;
}
set
{
m_timeZone = value;
}
}
/// <summary>
/// property used to get and set Latitude
/// </summary>
public double Latitude
{
get
{
return m_latitude;
}
set
{
m_latitude = value;
}
}
/// <summary>
/// property used to get and set Longitude
/// </summary>
public double Longitude
{
get
{
return m_longitude;
}
set
{
m_longitude = value;
}
}
/// <summary>
/// property used to get and set city name
/// </summary>
public string CityName
{
get
{
return m_cityName;
}
set
{
m_cityName = value;
}
}
/// <summary>
/// class CityInfo's constructor
/// </summary>
/// <param name="latitude">latitude of city</param>
/// <param name="longitude">longitude of city</param>
public CityInfo(double latitude, double longitude)
{
m_latitude = latitude;
m_longitude = longitude;
m_timeZone = PlaceInfo.InvalidTimeZone;
m_cityName = null;
}
/// <summary>
/// class CityInfo's constructor
/// </summary>
/// <param name="latitude">latitude of city</param>
/// <param name="longitude">longitude of city</param>
/// <param name="timeZone">timezone of city</param>
/// <param name="cityName">city name</param>
public CityInfo(double latitude, double longitude, double timeZone, string cityName)
{
m_timeZone = timeZone;
m_latitude = latitude;
m_longitude = longitude;
m_cityName = cityName;
}
}
/// <summary>
/// a struct used to describe information about city
/// displayed in Form and it's members are string type
/// </summary>
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
/// <summary>
/// property used to get and set TimeZone
/// </summary>
public string TimeZone
{
get
{
return m_timeZone;
}
set
{
m_timeZone = value;
}
}
/// <summary>
/// property used to get and set Latitude
/// </summary>
public string Latitude
{
get
{
return m_latitude;
}
set
{
m_latitude = value;
}
}
/// <summary>
/// property used to get and set Longitude
/// </summary>
public string Longitude
{
get
{
return m_longitude;
}
set
{
m_longitude = value;
}
}
/// <summary>
/// class CityInfo's constructor
/// </summary>
/// <param name="latitude">latitude of city</param>
/// <param name="longitude">longitude of city</param>
public CityInfoString(string latitude, string longitude)
{
m_latitude = latitude;
m_longitude = longitude;
m_timeZone = null;
}
/// <summary>
/// class CityInfo's constructor
/// </summary>
/// <param name="latitude">latitude of city</param>
/// <param name="longitude">longitude of city</param>
/// <param name="timeZone">timezone of city</param>
public CityInfoString(string latitude, string longitude, string timeZone)
{
m_timeZone = timeZone;
m_latitude = latitude;
m_longitude = longitude;
}
}
/// <summary>
/// a class used to store information of all city
/// include it's name,Latitude,longitude,timezone
/// </summary>
public class PlaceInfo
{
private List<string> m_citiesName; //city's name
private List<CityInfo> m_citiesInfo; //information of all cities,such Latitude,longitude
private List<string> 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
/// <summary>
/// property used to get and set all cities' name
/// </summary>
public List<string> CitiesName
{
get
{
return m_citiesName;
}
set
{
m_citiesName = value;
}
}
/// <summary>
/// property used to get and set all timezone
/// </summary>
public List<string> TimeZones
{
get
{
return m_timeZones;
}
set
{
m_timeZones = value;
}
}
/// <summary>
/// property used to get Invalid timezone
/// </summary>
public static double InvalidTimeZone
{
get
{
return m_invalidTimeZone;
}
}
/// <summary>
/// class PlaceInfo's constructor
/// </summary>
/// <param name="cities"></param>
public PlaceInfo(CitySet cities)
{
Initialize(cities);
}
/// <summary>
/// initialize function
/// </summary>
/// <param name="cities">a set store all cities</param>
/// <returns></returns>
public bool Initialize(CitySet cities)
{
m_citiesInfo = new List<CityInfo>();
m_citiesName = new List<string>();
m_timeZones = new List<string>();
if (InitCities(cities) && InitTimeZone())
{
return true;
}
return false;
}
/// <summary>
/// Add a city info to city info List
/// </summary>
/// <param name="cityInfo">the city info need to add</param>
public void AddCityInfo(CityInfo cityInfo)
{
if (m_citiesInfo.Contains(cityInfo))
{
return;
}
m_citiesInfo.Add(cityInfo);
}
/// <summary>
/// try to get city name according to CityInfo
/// </summary>
/// <param name="cityInfo">store information about city</param>
/// <param name="cityName">city's name</param>
/// <param name="timeZone">city's timezone</param>
/// <returns>figure out whether this function successful</returns>
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;
}
/// <summary>
/// try to get city info according to city name
/// </summary>
/// <param name="cityName">city name</param>
/// <param name="cityInfo">city's information</param>
/// <returns>figure out whether this function successful</returns>
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;
}
/// <summary>
/// try to get city's timezone
/// </summary>
/// <param name="timeZoneNumber">time zone</param>
/// <returns>figure out whether this function successful</returns>
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;
}
/// <summary>
/// try to get TimeZone's number from a string
/// </summary>
/// <param name="timeZoneString">a string store TimeZone</param>
/// <returns>result Parse from string</returns>
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;
}
/// <summary>
/// initialize cities
/// </summary>
/// <param name="cities"></param>
/// <returns></returns>
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;
}
/// <summary>
/// initialize timezone
/// </summary>
/// <returns></returns>
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;
}
}
}
UnitConversion.cs
//
// (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.Globalization;
namespace Revit.SDK.Samples.SharedCoordinateSystem.CS
{
/// <summary>
/// define type of value
/// </summary>
public enum ValueType
{
/// <summary>
/// general value
/// </summary>
General = 0,
/// <summary>
/// angle value
/// </summary>
Angle
}
/// <summary>
/// a class used to deal with converting operation
/// </summary>
public class UnitConversion
{
private static readonly int DefaultPrecision = 3; //default precision
private static readonly double AngleRatio = 0.0174532925199433; //ratio of Angle
/// <summary>
/// convert CityInfo into CityInfoString
/// </summary>
/// <param name="cityInfo">CityInfo need to convert</param>
/// <returns>conversion result</returns>
public static CityInfoString ConvertFrom(CityInfo cityInfo)
{
CityInfoString cityInfoString = new CityInfoString();
cityInfoString.Latitude = DoubleToString(cityInfo.Latitude, ValueType.Angle);
cityInfoString.Longitude = DoubleToString(cityInfo.Longitude, ValueType.Angle);
return cityInfoString;
}
/// <summary>
/// convert CityInfoString into CityInfo
/// </summary>
/// <param name="cityInfoString">CityInfoString need to convert</param>
/// <returns>conversion result</returns>
public static CityInfo ConvertTo(CityInfoString cityInfoString)
{
CityInfo cityInfo = new CityInfo();
double temp;
//convert Latitude
if (StringToDouble(cityInfoString.Latitude, ValueType.Angle, out temp))
{
cityInfo.Latitude = temp;
}
else
{
cityInfo.Latitude = Double.NaN;
}
//convert Longitude
if (StringToDouble(cityInfoString.Longitude, ValueType.Angle, out temp))
{
cityInfo.Longitude = temp;
}
else
{
cityInfo.Longitude = Double.NaN;
}
return cityInfo;
}
/// <summary>
/// deal with value according to precision
/// </summary>
/// <param name="value">original value will be dealed</param>
/// <param name="precision">precision wanted to be set</param>
/// <returns>return the dealed value</returns>
public static double DealPrecision(double value, int precision)
{
//first make sure 0 =< precision <= 15
if (precision < 0 && precision > 15)
{
return value;
}
//if >1 or < -1,just use Math.Round to deal with
double newValue;
if (value >= 1 || value <= -1 || 0 == value)
{
//Math.Round: returns the number with the specified precision
//nearest the specified value.
newValue = Math.Round(value, precision);
return newValue;
}
//if -1 < value < 1,
//find first number which is not "0"
//compare it with precision, then select
//min of them as final precision
int firstNumberPos = 0;
double temp = Math.Abs(value);
for (firstNumberPos = 1; ; firstNumberPos++)
{
temp *= 10;
if (temp >= 1)
{
break;
}
}
//make sure firstNumberPos <= 15
if (firstNumberPos > 15)
{
firstNumberPos = 15;
}
//Math.Round: returns the number with the specified precision
//nearest the specified value.
newValue = Math.Round(value, firstNumberPos > precision ? firstNumberPos : precision);
return newValue;
}
/// <summary>
/// convert double into string
/// </summary>
/// <param name="value">double value need to convert</param>
/// <param name="valueType">value type</param>
/// <returns>conversion result</returns>
public static string DoubleToString(double value, ValueType valueType)
{
string displayText = null; // string included value and unit of parameter
double newValue;
ValueConversion(value, ValueType.Angle, true, out newValue);
value = newValue;
newValue = DealPrecision(value, DefaultPrecision);
//calculate the number after ".",if less than DecimalNumber
// add some "0" after it
displayText = DealDecimalNumber(newValue.ToString(), DefaultPrecision);
if(ValueType.Angle == valueType)
{
char degree = (char)0xb0;
displayText += degree;
}
return displayText;
}
/// <summary>
/// deal with decimal number
/// </summary>
/// <param name="value">string wanted to deal with</param>
/// <param name="number">number of decimal</param>
/// <returns>result dealing with</returns>
public static string DealDecimalNumber(string value, int number)
{
string newValue = value;
int dist;
if (newValue.Contains("."))
{
int index = newValue.IndexOf(".");
dist = newValue.Length - (index + 1);
}
else
{
dist = 0;
newValue += ".";
}
if (dist < number)
{
for (int i = 0; i < number - dist; i++)
{
newValue += "0";
}
}
return newValue;
}
/// <summary>
/// convert string into double
/// </summary>
/// <param name="value">string value need to convert</param>
/// <param name="valueType">value type</param>
/// <param name="newValue">conversion result</param>
/// <returns>if success, return true; otherwise, return false</returns>
public static bool StringToDouble(string value, ValueType valueType, out double newValue)
{
newValue = 0;
if (null == value)
{
return false;
}
//try to Parse double from string
double result;
if (ParseFromString(value, valueType, out result))
{
//deal with ratio
ValueConversion(result, valueType, false, out newValue);
return true;
}
return false;
}
/// <summary>
/// Parse double from string
/// </summary>
/// <param name="value">string value</param>
/// <param name="valueType">value type</param>
/// <param name="result">conversion result</param>
/// <returns>if success, return true; otherwise, return false</returns>
private static bool ParseFromString(string value, ValueType valueType, out double result)
{
string newValue = null;
string degree = ((char)0xb0).ToString();
//if nothing, set result = 0;
if (value.Length == 0)
{
result = 0;
return true;
}
else if (ValueType.General == valueType)
{
}
//check if contain degree symbol
else if (value.Contains(degree))
{
int index = value.IndexOf(degree);
newValue = value.Substring(0, index);
}
//check if have string" " ,for there is string" "
//between value and unit when show in PropertyGrid
else if (value.Contains(" "))
{
int index = value.IndexOf(" ");
newValue = value.Substring(0, index);
}
//finally if don't have unit name in it
//other situation, set newValue = value
else
{
newValue = value;
}
//double.TryParse's return value:
//true if s is converted successfully; otherwise, false.
if (double.TryParse(newValue, out result))
{
return true;
}
return false;
}
/// <summary>
/// deal with ratio
/// </summary>
/// <param name="value">value need to deal with</param>
/// <param name="valueType">value type</param>
/// <param name="isDoubleToString">
/// figure out whether be called by function "DoubleToString"
/// </param>
/// <param name="newValue"></param>
private static void ValueConversion(double value, ValueType valueType,
bool isDoubleToString, out double newValue)
{
//ValueType.General == valueType,do nothing and return
if (ValueType.General == valueType)
{
newValue = value;
return;
}
//otherwise,check whether be called by function "DoubleToString"
if (isDoubleToString)
{
newValue = value / AngleRatio;
}
else
{
newValue = value * AngleRatio;
}
}
}
}
版权所有 :无锡模信建筑科技有限公司 苏ICP备2021028830号-1 BIM建模|BIM技术应用|BIM软件开发
联系地址:江苏省无锡市新吴区龙山路4号B座705 手机:18761516598