public override IWorkspace Open(LocalConn conn) { IWorkspace workspace = null; switch (conn.Type) { case Base.Common.EnumDataSourceType.SHAPEFILE: workspace = WorkspaceUtil.OpenShapeFileWorkspace(conn.Path); break; case Base.Common.EnumDataSourceType.COVERAGE: workspace = WorkspaceUtil.OpenCoverageWorkspace(conn.Path); break; case Base.Common.EnumDataSourceType.PERSONAL_GEODATABASE: workspace = WorkspaceUtil.OpenMdbWorspace(conn.Path); break; case Base.Common.EnumDataSourceType.FILE_GEODATABASE: workspace = WorkspaceUtil.OpenFileGdbWorkspace(conn.Path); break; case Base.Common.EnumDataSourceType.TIN: workspace = WorkspaceUtil.OpenTinWorkspace(conn.Path); break; case Base.Common.EnumDataSourceType.CAD: workspace = WorkspaceUtil.OpenCadWorkspace(conn.Path); break; default: throw new Exception($"不支持当前本地文件格式[{conn.Path}]"); } return(workspace); }
/// <summary> /// 获取topo下的geometry union的数据 /// </summary> /// <param name="featureClass">源要素类</param> /// <param name="queryClause">查询条件</param> /// <param name="queryGeometry">指定范围下</param> /// <param name="spatialRelType">空间参考类型</param> /// <param name="topoUnionGeometry">输出topo union后的geometry</param> /// <param name="oidList">输出OID集合</param> /// <param name="geometryField">geometry字段名称,默认为Shape</param> public static void GetTopounionGeometryByQuery(IFeatureClass featureClass, String queryClause, IGeometry queryGeometry, esriSpatialRelEnum spatialRelType, out IGeometry topoUnionGeometry, out IList <string> oidList, string geometryField = "Shape") { List <IFeature> featureList = new List <IFeature>(); topoUnionGeometry = null; oidList = new List <string>(); try { ISpatialFilter spatialFilter = new SpatialFilter(); if (!string.IsNullOrEmpty(queryClause)) { spatialFilter.WhereClause = queryClause; } if (!string.IsNullOrEmpty(geometryField)) { spatialFilter.GeometryField = geometryField; } if (queryGeometry != null) { spatialFilter.Geometry = queryGeometry; spatialFilter.SpatialRel = spatialRelType; } ITopologicalOperator topologicalOperator = null; IFeatureCursor featureCursor = featureClass.Search(spatialFilter, false); IFeature feature = featureCursor.NextFeature(); IGeometry geometryTemp; while (feature != null) { geometryTemp = feature.Shape; // feature.ShapeCopy; if (topologicalOperator == null) { topologicalOperator = geometryTemp as ITopologicalOperator; } else { topologicalOperator = topologicalOperator.Union(geometryTemp) as ITopologicalOperator; } oidList.Add(feature.OID.ToString()); featureList.Add(feature); feature = featureCursor.NextFeature(); } topoUnionGeometry = topologicalOperator as IGeometry; WorkspaceUtil.ReleaseComObject(featureCursor); } catch (Exception e) { LOG.Error(e, $"{nameof(GetTopounionGeometryByQuery)}抛异常"); } }
public override void Init(IDictionary <string, Property> parameters) { if (!parameters.ContainsKey(nameof(this.FeatureClass_Source_First))) { throw new Exception("没有找到输入参数【总规用地图层】"); } if (!parameters.ContainsKey(nameof(this.Yddm_First))) { throw new Exception("没有找到输入参数【总规用地代码属性】"); } if (!parameters.ContainsKey(nameof(this.FeatureClass_Source_Second))) { throw new Exception("没有找到输入参数【控规用地图层】"); } if (!parameters.ContainsKey(nameof(this.Yddm_Second))) { throw new Exception("没有找到输入参数【控规用地代码属性】"); } if (!parameters.ContainsKey(nameof(this.ResultGDBPath))) { LOG.Info("没有指定新的输出路径,现在使用默认路径"); this.ResultGDBPath = base.OutputParametersMeta[nameof(this.ResultGDBPath)].DefaultValue.ToString(); } else { LOG.Info("使用新的输出路径"); this.ResultGDBPath = parameters[nameof(this.ResultGDBPath)].ToString(); } this.FeatureClass_Source_First = parameters[nameof(this.FeatureClass_Source_First)].ToString(); WorkspaceUtil.OpenFeatureClass(this.FeatureClass_Source_First, SEPARATOR_FEATURE_PATH, out this.m_localWorkspace_first, out this.m_featureClass_first); if (this.m_featureClass_first.FeatureDataset != null) { // 注意有要素集情况下的路径格式 this.sourceLayerFirstFullPath = this.FeatureClass_Source_First.Split(SEPARATOR_FEATURE_PATH)[0] + "/" + this.m_featureClass_first.FeatureDataset.Name + "/" + this.FeatureClass_Source_First.Split(SEPARATOR_FEATURE_PATH)[1]; } else { this.sourceLayerFirstFullPath = this.FeatureClass_Source_First.Split(SEPARATOR_FEATURE_PATH)[0] + "/" + this.FeatureClass_Source_First.Split(SEPARATOR_FEATURE_PATH)[1]; } this.FeatureClass_Source_Second = parameters[nameof(this.FeatureClass_Source_Second)].ToString(); WorkspaceUtil.OpenFeatureClass(this.FeatureClass_Source_Second, SEPARATOR_FEATURE_PATH, out this.m_localWorkspace_second, out this.m_featureClass_second); if (this.m_featureClass_second.FeatureDataset != null) { this.sourceLayerSecondFullPath = this.FeatureClass_Source_Second.Split(SEPARATOR_FEATURE_PATH)[0] + "/" + this.m_featureClass_second.FeatureDataset.Name + "/" + this.FeatureClass_Source_Second.Split(SEPARATOR_FEATURE_PATH)[1]; } else { this.sourceLayerSecondFullPath = this.FeatureClass_Source_Second.Split(SEPARATOR_FEATURE_PATH)[0] + "/" + this.FeatureClass_Source_Second.Split(SEPARATOR_FEATURE_PATH)[1]; } this.Yddm_First = parameters[nameof(this.Yddm_First)].ToString(); this.Yddm_Second = parameters[nameof(this.Yddm_Second)].ToString(); }
public override Result Execute() { string resultGDBPath = this.ResultGDBPath; try { if (!Directory.Exists(this.ResultGDBPath)) { DirectoryInfo dirInfo = Directory.CreateDirectory(this.ResultGDBPath); } resultGDBPath = Path.Combine(this.ResultGDBPath, string.Format("result_{0}.gdb", DateUtil.CurrentTimeMillis)); string pTempletMDBFile = AppDomain.CurrentDomain.BaseDirectory + GlobalSystemConfig.PATH_TEMPLATE_FGDB;// "template/fgdb.gdb"; long beginMillisecond = DateUtil.CurrentTimeMillis; // 创建一份gdb DirectFileUtil.CopyDirectInfo(pTempletMDBFile, resultGDBPath); IWorkspace resultWorkspace = WorkspaceUtil.OpenFileGdbWorkspace(resultGDBPath); LOG.Info("创建GDB消耗时间:[" + (DateUtil.CurrentTimeMillis - beginMillisecond) + "] 毫秒"); // 拷贝源对比图层 beginMillisecond = DateUtil.CurrentTimeMillis; //if (!WorkspaceServices.CopyLayer(new string[] { this.sourceLayerFirstFullPath, this.sourceLayerSecondFullPath }, resultGDBPath)) //{ // LOG.Error("拷贝图层失败,中止计算"); // return new Result(STATUS.ERROR, "拷贝图层失败", SysStatusCode.DME3000, false); //} //LOG.Info("拷贝源对比图层消耗时间:[" + (DateUtil.CurrentTimeMillis() - beginMillisecond) + "] 毫秒"); // 图层融合(union) UnionTool unionTool = new UnionTool { InputFeatures = new String[] { this.sourceLayerFirstFullPath, this.sourceLayerSecondFullPath }, OutputFeature = resultGDBPath + "/" + this.ReulstLayerName }; object result = unionTool.Excute(); if (null == result) { return(new Result(EnumSystemStatusCode.DME_ERROR, "图层联合分析失败", EnumSystemStatusCode.DME_ERROR, false)); } // 对输出图层进行规则计算 // TODO return(new Result(EnumSystemStatusCode.DME_SUCCESS, "差异分析完成", EnumSystemStatusCode.DME_SUCCESS, true)); } catch (Exception ex) { LOG.Error("差异分析失败,详情:" + ex.Message); return(new Result(EnumSystemStatusCode.DME_ERROR, "差异分析失败,详情:" + ex.Message, EnumSystemStatusCode.DME_ERROR, false)); } }
/// <summary> /// 两个要素类进行擦除操作 /// </summary> /// <param name="sourceFeatureClass">源要素类</param> /// <param name="eraseFeatureClass">用于擦除的要素类,必须是个面要素类</param> public static void Erase(IFeatureClass sourceFeatureClass, IFeatureClass eraseFeatureClass) { if (eraseFeatureClass.ShapeType != esriGeometryType.esriGeometryPolygon) { throw new Exception("EraseFeatureClass不是个面要素类"); } if (esriGeometryType.esriGeometryPoint == sourceFeatureClass.ShapeType) { throw new Exception("SourceFeatureClass不能是个点要素类"); } // 先要临时复制一个要素类 // 遍历用于擦除的要素 IFeatureCursor eraseFeatureCursor = eraseFeatureClass.Search(null, false); IFeature eraseFeature = null; while ((eraseFeature = eraseFeatureCursor.NextFeature()) != null) { ISpatialFilter spatialFilter = new SpatialFilterClass { Geometry = eraseFeature.Shape, SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects }; IFeatureCursor sourceFeatureCursor = sourceFeatureClass.Update(spatialFilter, false); IFeature sourceFeature = null; while ((sourceFeature = sourceFeatureCursor.NextFeature()) != null) { IGeometry geometry = sourceFeature.ShapeCopy; ITopologicalOperator topoOper = geometry as ITopologicalOperator; IGeometry geoDifference = topoOper.Difference(eraseFeature.Shape); sourceFeature.Shape = geoDifference; sourceFeatureCursor.UpdateFeature(sourceFeature); } // 释放游标 WorkspaceUtil.ReleaseComObject(sourceFeatureCursor); } }
public async Task GetSourceAsync( IExecutionContext executionContext, ServiceEndpoint endpoint, CancellationToken cancellationToken) { Trace.Entering(); // Validate args. ArgUtil.NotNull(executionContext, nameof(executionContext)); ArgUtil.NotNull(endpoint, nameof(endpoint)); #if OS_WINDOWS // Validate .NET Framework 4.6 or higher is installed. var netFrameworkUtil = HostContext.GetService <INetFrameworkUtil>(); if (!netFrameworkUtil.Test(new Version(4, 6))) { throw new Exception(StringUtil.Loc("MinimumNetFramework46")); } #endif // Create the tf command manager. var tf = HostContext.CreateService <ITfsVCCommandManager>(); tf.CancellationToken = cancellationToken; tf.Endpoint = endpoint; tf.ExecutionContext = executionContext; // Setup proxy. var agentProxy = HostContext.GetService <IVstsAgentWebProxy>(); if (!string.IsNullOrEmpty(executionContext.Variables.Agent_ProxyUrl) && !agentProxy.IsBypassed(endpoint.Url)) { executionContext.Debug($"Configure '{tf.FilePath}' to work through proxy server '{executionContext.Variables.Agent_ProxyUrl}'."); tf.SetupProxy(executionContext.Variables.Agent_ProxyUrl, executionContext.Variables.Agent_ProxyUsername, executionContext.Variables.Agent_ProxyPassword); } // Add TF to the PATH. string tfPath = tf.FilePath; ArgUtil.File(tfPath, nameof(tfPath)); var varUtil = HostContext.GetService <IVarUtil>(); executionContext.Output(StringUtil.Loc("Prepending0WithDirectoryContaining1", Constants.PathVariable, Path.GetFileName(tfPath))); varUtil.PrependPath(Path.GetDirectoryName(tfPath)); executionContext.Debug($"{Constants.PathVariable}: '{Environment.GetEnvironmentVariable(Constants.PathVariable)}'"); #if OS_WINDOWS // Set TFVC_BUILDAGENT_POLICYPATH string policyDllPath = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.ServerOM), "Microsoft.TeamFoundation.VersionControl.Controls.dll"); ArgUtil.File(policyDllPath, nameof(policyDllPath)); const string policyPathEnvKey = "TFVC_BUILDAGENT_POLICYPATH"; executionContext.Output(StringUtil.Loc("SetEnvVar", policyPathEnvKey)); Environment.SetEnvironmentVariable(policyPathEnvKey, policyDllPath); #endif // Check if the administrator accepted the license terms of the TEE EULA when configuring the agent. AgentSettings settings = HostContext.GetService <IConfigurationStore>().GetSettings(); if (tf.Features.HasFlag(TfsVCFeatures.Eula) && settings.AcceptTeeEula) { // Check if the "tf eula -accept" command needs to be run for the current user. bool skipEula = false; try { skipEula = tf.TestEulaAccepted(); } catch (Exception ex) { executionContext.Debug("Unexpected exception while testing whether the TEE EULA has been accepted for the current user."); executionContext.Debug(ex.ToString()); } if (!skipEula) { // Run the command "tf eula -accept". try { await tf.EulaAsync(); } catch (Exception ex) { executionContext.Debug(ex.ToString()); executionContext.Warning(ex.Message); } } } // Get the workspaces. executionContext.Output(StringUtil.Loc("QueryingWorkspaceInfo")); ITfsVCWorkspace[] tfWorkspaces = await tf.WorkspacesAsync(); // Determine the workspace name. string buildDirectory = executionContext.Variables.Agent_BuildDirectory; ArgUtil.NotNullOrEmpty(buildDirectory, nameof(buildDirectory)); string workspaceName = $"ws_{Path.GetFileName(buildDirectory)}_{settings.AgentId}"; executionContext.Variables.Set(Constants.Variables.Build.RepoTfvcWorkspace, workspaceName); // Get the definition mappings. DefinitionWorkspaceMapping[] definitionMappings = JsonConvert.DeserializeObject <DefinitionWorkspaceMappings>(endpoint.Data[WellKnownEndpointData.TfvcWorkspaceMapping])?.Mappings; // Determine the sources directory. string sourcesDirectory = GetEndpointData(endpoint, Constants.EndpointData.SourcesDirectory); ArgUtil.NotNullOrEmpty(sourcesDirectory, nameof(sourcesDirectory)); // Attempt to re-use an existing workspace if the command manager supports scorch // or if clean is not specified. ITfsVCWorkspace existingTFWorkspace = null; bool clean = endpoint.Data.ContainsKey(WellKnownEndpointData.Clean) && StringUtil.ConvertToBoolean(endpoint.Data[WellKnownEndpointData.Clean], defaultValue: false); if (tf.Features.HasFlag(TfsVCFeatures.Scorch) || !clean) { existingTFWorkspace = WorkspaceUtil.MatchExactWorkspace( executionContext: executionContext, tfWorkspaces: tfWorkspaces, name: workspaceName, definitionMappings: definitionMappings, sourcesDirectory: sourcesDirectory); if (existingTFWorkspace != null) { if (tf.Features.HasFlag(TfsVCFeatures.GetFromUnmappedRoot)) { // Undo pending changes. ITfsVCStatus tfStatus = await tf.StatusAsync(localPath : sourcesDirectory); if (tfStatus?.HasPendingChanges ?? false) { await tf.UndoAsync(localPath : sourcesDirectory); // Cleanup remaining files/directories from pend adds. tfStatus.AllAdds .OrderByDescending(x => x.LocalItem) // Sort descending so nested items are deleted before their parent is deleted. .ToList() .ForEach(x => { executionContext.Output(StringUtil.Loc("Deleting", x.LocalItem)); IOUtil.Delete(x.LocalItem, cancellationToken); }); } } else { // Perform "undo" for each map. foreach (DefinitionWorkspaceMapping definitionMapping in definitionMappings ?? new DefinitionWorkspaceMapping[0]) { if (definitionMapping.MappingType == DefinitionMappingType.Map) { // Check the status. string localPath = definitionMapping.GetRootedLocalPath(sourcesDirectory); ITfsVCStatus tfStatus = await tf.StatusAsync(localPath : localPath); if (tfStatus?.HasPendingChanges ?? false) { // Undo. await tf.UndoAsync(localPath : localPath); // Cleanup remaining files/directories from pend adds. tfStatus.AllAdds .OrderByDescending(x => x.LocalItem) // Sort descending so nested items are deleted before their parent is deleted. .ToList() .ForEach(x => { executionContext.Output(StringUtil.Loc("Deleting", x.LocalItem)); IOUtil.Delete(x.LocalItem, cancellationToken); }); } } } } // Scorch. if (clean) { // Try to scorch. try { await tf.ScorchAsync(); } catch (ProcessExitCodeException ex) { // Scorch failed. // Warn, drop the folder, and re-clone. executionContext.Warning(ex.Message); existingTFWorkspace = null; } } } } // Create a new workspace. if (existingTFWorkspace == null) { // Remove any conflicting workspaces. await RemoveConflictingWorkspacesAsync( tf : tf, tfWorkspaces : tfWorkspaces, name : workspaceName, directory : sourcesDirectory); // Remove any conflicting workspace from a different computer. // This is primarily a hosted scenario where a registered hosted // agent can land on a different computer each time. tfWorkspaces = await tf.WorkspacesAsync(matchWorkspaceNameOnAnyComputer : true); foreach (ITfsVCWorkspace tfWorkspace in tfWorkspaces ?? new ITfsVCWorkspace[0]) { await tf.WorkspaceDeleteAsync(tfWorkspace); } // Recreate the sources directory. executionContext.Debug($"Deleting: '{sourcesDirectory}'."); IOUtil.DeleteDirectory(sourcesDirectory, cancellationToken); Directory.CreateDirectory(sourcesDirectory); // Create the workspace. await tf.WorkspaceNewAsync(); // Remove the default mapping. if (tf.Features.HasFlag(TfsVCFeatures.DefaultWorkfoldMap)) { await tf.WorkfoldUnmapAsync("$/"); } // Sort the definition mappings. definitionMappings = (definitionMappings ?? new DefinitionWorkspaceMapping[0]) .OrderBy(x => x.NormalizedServerPath?.Length ?? 0) // By server path length. .ToArray() ?? new DefinitionWorkspaceMapping[0]; // Add the definition mappings to the workspace. foreach (DefinitionWorkspaceMapping definitionMapping in definitionMappings) { switch (definitionMapping.MappingType) { case DefinitionMappingType.Cloak: // Add the cloak. await tf.WorkfoldCloakAsync(serverPath : definitionMapping.ServerPath); break; case DefinitionMappingType.Map: // Add the mapping. await tf.WorkfoldMapAsync( serverPath : definitionMapping.ServerPath, localPath : definitionMapping.GetRootedLocalPath(sourcesDirectory)); break; default: throw new NotSupportedException(); } } } if (tf.Features.HasFlag(TfsVCFeatures.GetFromUnmappedRoot)) { // Get. await tf.GetAsync(localPath : sourcesDirectory); } else { // Perform "get" for each map. foreach (DefinitionWorkspaceMapping definitionMapping in definitionMappings ?? new DefinitionWorkspaceMapping[0]) { if (definitionMapping.MappingType == DefinitionMappingType.Map) { await tf.GetAsync(localPath : definitionMapping.GetRootedLocalPath(sourcesDirectory)); } } } // Steps for shelveset/gated. string shelvesetName = GetEndpointData(endpoint, Constants.EndpointData.SourceTfvcShelveset); if (!string.IsNullOrEmpty(shelvesetName)) { // Steps for gated. ITfsVCShelveset tfShelveset = null; string gatedShelvesetName = GetEndpointData(endpoint, Constants.EndpointData.GatedShelvesetName); if (!string.IsNullOrEmpty(gatedShelvesetName)) { // Clean the last-saved-checkin-metadata for existing workspaces. // // A better long term fix is to add a switch to "tf unshelve" that completely overwrites // the last-saved-checkin-metadata, instead of merging associated work items. // // The targeted workaround for now is to create a trivial change and "tf shelve /move", // which will delete the last-saved-checkin-metadata. if (existingTFWorkspace != null) { executionContext.Output("Cleaning last saved checkin metadata."); // Find a local mapped directory. string firstLocalDirectory = (definitionMappings ?? new DefinitionWorkspaceMapping[0]) .Where(x => x.MappingType == DefinitionMappingType.Map) .Select(x => x.GetRootedLocalPath(sourcesDirectory)) .FirstOrDefault(x => Directory.Exists(x)); if (firstLocalDirectory == null) { executionContext.Warning("No mapped folder found. Unable to clean last-saved-checkin-metadata."); } else { // Create a trival change and "tf shelve /move" to clear the // last-saved-checkin-metadata. string cleanName = "__tf_clean_wksp_metadata"; string tempCleanFile = Path.Combine(firstLocalDirectory, cleanName); try { File.WriteAllText(path: tempCleanFile, contents: "clean last-saved-checkin-metadata", encoding: Encoding.UTF8); await tf.AddAsync(tempCleanFile); await tf.ShelveAsync(shelveset : cleanName, commentFile : tempCleanFile, move : true); } catch (Exception ex) { executionContext.Warning($"Unable to clean last-saved-checkin-metadata. {ex.Message}"); try { await tf.UndoAsync(tempCleanFile); } catch (Exception ex2) { executionContext.Warning($"Unable to undo '{tempCleanFile}'. {ex2.Message}"); } } finally { IOUtil.DeleteFile(tempCleanFile); } } } // Get the shelveset metadata. tfShelveset = await tf.ShelvesetsAsync(shelveset : shelvesetName); // The above command throws if the shelveset is not found, // so the following assertion should never fail. ArgUtil.NotNull(tfShelveset, nameof(tfShelveset)); } // Unshelve. await tf.UnshelveAsync(shelveset : shelvesetName); // Ensure we undo pending changes for shelveset build at the end. _undoShelvesetPendingChanges = true; if (!string.IsNullOrEmpty(gatedShelvesetName)) { // Create the comment file for reshelve. StringBuilder comment = new StringBuilder(tfShelveset.Comment ?? string.Empty); string runCi = GetEndpointData(endpoint, Constants.EndpointData.GatedRunCI); bool gatedRunCi = StringUtil.ConvertToBoolean(runCi, true); if (!gatedRunCi) { if (comment.Length > 0) { comment.AppendLine(); } comment.Append(Constants.Build.NoCICheckInComment); } string commentFile = null; try { commentFile = Path.GetTempFileName(); File.WriteAllText(path: commentFile, contents: comment.ToString(), encoding: Encoding.UTF8); // Reshelve. await tf.ShelveAsync(shelveset : gatedShelvesetName, commentFile : commentFile, move : false); } finally { // Cleanup the comment file. if (File.Exists(commentFile)) { File.Delete(commentFile); } } } } // Cleanup proxy settings. if (!string.IsNullOrEmpty(executionContext.Variables.Agent_ProxyUrl) && !agentProxy.IsBypassed(endpoint.Url)) { executionContext.Debug($"Remove proxy setting for '{tf.FilePath}' to work through proxy server '{executionContext.Variables.Agent_ProxyUrl}'."); tf.CleanupProxySetting(); } }
public async Task GetSourceAsync( AgentTaskPluginExecutionContext executionContext, Pipelines.RepositoryResource repository, CancellationToken cancellationToken) { // Validate args. ArgUtil.NotNull(executionContext, nameof(executionContext)); ArgUtil.NotNull(repository, nameof(repository)); // Validate .NET Framework 4.6 or higher is installed. if (PlatformUtil.RunningOnWindows && !NetFrameworkUtil.Test(new Version(4, 6), executionContext)) { throw new Exception(StringUtil.Loc("MinimumNetFramework46")); } // determine if we've been asked to suppress some checkout step output bool reducedOutput = AgentKnobs.QuietCheckout.GetValue(executionContext).AsBoolean(); if (reducedOutput) { executionContext.Output(StringUtil.Loc("QuietCheckoutModeRequested")); executionContext.SetTaskVariable(AgentKnobs.QuietCheckoutRuntimeVarName, Boolean.TrueString); } // Create the tf command manager. ITfsVCCliManager tf; if (PlatformUtil.RunningOnWindows) { tf = new TFCliManager(); } else { tf = new TeeCliManager(); } tf.CancellationToken = cancellationToken; tf.Repository = repository; tf.ExecutionContext = executionContext; if (repository.Endpoint != null) { // the endpoint should either be the SystemVssConnection (id = guild.empty, name = SystemVssConnection) // or a real service endpoint to external service which has a real id var endpoint = executionContext.Endpoints.Single( x => (repository.Endpoint.Id != Guid.Empty && x.Id == repository.Endpoint.Id) || (repository.Endpoint.Id == Guid.Empty && string.Equals(x.Name, repository.Endpoint.Name.ToString(), StringComparison.OrdinalIgnoreCase))); ArgUtil.NotNull(endpoint, nameof(endpoint)); tf.Endpoint = endpoint; } // Setup proxy. var agentProxy = executionContext.GetProxyConfiguration(); if (agentProxy != null && !string.IsNullOrEmpty(agentProxy.ProxyAddress) && !agentProxy.WebProxy.IsBypassed(repository.Url)) { executionContext.Debug($"Configure '{tf.FilePath}' to work through proxy server '{agentProxy.ProxyAddress}'."); tf.SetupProxy(agentProxy.ProxyAddress, agentProxy.ProxyUsername, agentProxy.ProxyPassword); } // Setup client certificate. var agentCertManager = executionContext.GetCertConfiguration(); if (agentCertManager != null && agentCertManager.SkipServerCertificateValidation) { executionContext.Debug("TF does not support ignoring SSL certificate validation error."); } // prepare client cert, if the repository's endpoint url match the TFS/VSTS url var systemConnection = executionContext.Endpoints.Single(x => string.Equals(x.Name, WellKnownServiceEndpointNames.SystemVssConnection, StringComparison.OrdinalIgnoreCase)); if (!string.IsNullOrEmpty(agentCertManager?.ClientCertificateFile) && Uri.Compare(repository.Url, systemConnection.Url, UriComponents.SchemeAndServer, UriFormat.Unescaped, StringComparison.OrdinalIgnoreCase) == 0) { executionContext.Debug($"Configure '{tf.FilePath}' to work with client cert '{agentCertManager.ClientCertificateFile}'."); tf.SetupClientCertificate(agentCertManager.ClientCertificateFile, agentCertManager.ClientCertificatePrivateKeyFile, agentCertManager.ClientCertificateArchiveFile, agentCertManager.ClientCertificatePassword); } // Add TF to the PATH. string tfPath = tf.FilePath; ArgUtil.File(tfPath, nameof(tfPath)); executionContext.Output(StringUtil.Loc("Prepending0WithDirectoryContaining1", PathUtil.PathVariable, Path.GetFileName(tfPath))); executionContext.PrependPath(Path.GetDirectoryName(tfPath)); executionContext.Debug($"PATH: '{Environment.GetEnvironmentVariable("PATH")}'"); if (PlatformUtil.RunningOnWindows) { // Set TFVC_BUILDAGENT_POLICYPATH string policyDllPath = Path.Combine(executionContext.Variables.GetValueOrDefault("Agent.HomeDirectory")?.Value, "externals", "tf", "Microsoft.TeamFoundation.VersionControl.Controls.dll"); ArgUtil.File(policyDllPath, nameof(policyDllPath)); const string policyPathEnvKey = "TFVC_BUILDAGENT_POLICYPATH"; executionContext.Output(StringUtil.Loc("SetEnvVar", policyPathEnvKey)); executionContext.SetVariable(policyPathEnvKey, policyDllPath); } // Check if the administrator accepted the license terms of the TEE EULA when configuring the agent. if (tf.Features.HasFlag(TfsVCFeatures.Eula) && StringUtil.ConvertToBoolean(executionContext.Variables.GetValueOrDefault("Agent.AcceptTeeEula")?.Value)) { // Check if the "tf eula -accept" command needs to be run for the current user. bool skipEula = false; try { skipEula = tf.TestEulaAccepted(); } catch (Exception ex) { executionContext.Debug("Unexpected exception while testing whether the TEE EULA has been accepted for the current user."); executionContext.Debug(ex.ToString()); } if (!skipEula) { // Run the command "tf eula -accept". try { await tf.EulaAsync(); } catch (Exception ex) { executionContext.Debug(ex.ToString()); executionContext.Warning(ex.Message); } } } // Get the workspaces. executionContext.Output(StringUtil.Loc("QueryingWorkspaceInfo")); ITfsVCWorkspace[] tfWorkspaces = await tf.WorkspacesAsync(); // Determine the workspace name. string buildDirectory = executionContext.Variables.GetValueOrDefault("agent.builddirectory")?.Value; ArgUtil.NotNullOrEmpty(buildDirectory, nameof(buildDirectory)); string workspaceName = $"ws_{Path.GetFileName(buildDirectory)}_{executionContext.Variables.GetValueOrDefault("agent.id")?.Value}"; executionContext.SetVariable("build.repository.tfvc.workspace", workspaceName); // Get the definition mappings. var workspaceMappings = repository.Properties.Get <IList <Pipelines.WorkspaceMapping> >(Pipelines.RepositoryPropertyNames.Mappings); DefinitionWorkspaceMapping[] definitionMappings = workspaceMappings.Select(x => new DefinitionWorkspaceMapping() { ServerPath = x.ServerPath, LocalPath = x.LocalPath, MappingType = x.Exclude ? DefinitionMappingType.Cloak : DefinitionMappingType.Map }).ToArray(); // Determine the sources directory. string sourcesDirectory = repository.Properties.Get <string>(Pipelines.RepositoryPropertyNames.Path); ArgUtil.NotNullOrEmpty(sourcesDirectory, nameof(sourcesDirectory)); // Attempt to re-use an existing workspace if the command manager supports scorch // or if clean is not specified. ITfsVCWorkspace existingTFWorkspace = null; bool clean = StringUtil.ConvertToBoolean(executionContext.GetInput(Pipelines.PipelineConstants.CheckoutTaskInputs.Clean)); if (tf.Features.HasFlag(TfsVCFeatures.Scorch) || !clean) { existingTFWorkspace = WorkspaceUtil.MatchExactWorkspace( executionContext: executionContext, tfWorkspaces: tfWorkspaces, name: workspaceName, definitionMappings: definitionMappings, sourcesDirectory: sourcesDirectory); if (existingTFWorkspace != null) { if (tf.Features.HasFlag(TfsVCFeatures.GetFromUnmappedRoot)) { // Undo pending changes. ITfsVCStatus tfStatus = await tf.StatusAsync(localPath : sourcesDirectory); if (tfStatus?.HasPendingChanges ?? false) { await tf.UndoAsync(localPath : sourcesDirectory); // Cleanup remaining files/directories from pend adds. tfStatus.AllAdds .OrderByDescending(x => x.LocalItem) // Sort descending so nested items are deleted before their parent is deleted. .ToList() .ForEach(x => { executionContext.Output(StringUtil.Loc("Deleting", x.LocalItem)); IOUtil.Delete(x.LocalItem, cancellationToken); }); } } else { // Perform "undo" for each map. foreach (DefinitionWorkspaceMapping definitionMapping in definitionMappings ?? new DefinitionWorkspaceMapping[0]) { if (definitionMapping.MappingType == DefinitionMappingType.Map) { // Check the status. string localPath = definitionMapping.GetRootedLocalPath(sourcesDirectory); ITfsVCStatus tfStatus = await tf.StatusAsync(localPath : localPath); if (tfStatus?.HasPendingChanges ?? false) { // Undo. await tf.UndoAsync(localPath : localPath); // Cleanup remaining files/directories from pend adds. tfStatus.AllAdds .OrderByDescending(x => x.LocalItem) // Sort descending so nested items are deleted before their parent is deleted. .ToList() .ForEach(x => { executionContext.Output(StringUtil.Loc("Deleting", x.LocalItem)); IOUtil.Delete(x.LocalItem, cancellationToken); }); } } } } // Scorch. if (clean) { // Try to scorch. try { await tf.ScorchAsync(); } catch (ProcessExitCodeException ex) { // Scorch failed. // Warn, drop the folder, and re-clone. executionContext.Warning(ex.Message); existingTFWorkspace = null; } } } } // Create a new workspace. if (existingTFWorkspace == null) { // Remove any conflicting workspaces. await RemoveConflictingWorkspacesAsync( tf : tf, tfWorkspaces : tfWorkspaces, name : workspaceName, directory : sourcesDirectory); // Remove any conflicting workspace from a different computer. // This is primarily a hosted scenario where a registered hosted // agent can land on a different computer each time. tfWorkspaces = await tf.WorkspacesAsync(matchWorkspaceNameOnAnyComputer : true); foreach (ITfsVCWorkspace tfWorkspace in tfWorkspaces ?? new ITfsVCWorkspace[0]) { await tf.TryWorkspaceDeleteAsync(tfWorkspace); } // Recreate the sources directory. executionContext.Debug($"Deleting: '{sourcesDirectory}'."); IOUtil.DeleteDirectory(sourcesDirectory, cancellationToken); Directory.CreateDirectory(sourcesDirectory); // Create the workspace. await tf.WorkspaceNewAsync(); // Remove the default mapping. if (tf.Features.HasFlag(TfsVCFeatures.DefaultWorkfoldMap)) { await tf.WorkfoldUnmapAsync("$/"); } // Sort the definition mappings. definitionMappings = (definitionMappings ?? new DefinitionWorkspaceMapping[0]) .OrderBy(x => x.NormalizedServerPath?.Length ?? 0) // By server path length. .ToArray() ?? new DefinitionWorkspaceMapping[0]; // Add the definition mappings to the workspace. foreach (DefinitionWorkspaceMapping definitionMapping in definitionMappings) { switch (definitionMapping.MappingType) { case DefinitionMappingType.Cloak: // Add the cloak. await tf.WorkfoldCloakAsync(serverPath : definitionMapping.ServerPath); break; case DefinitionMappingType.Map: // Add the mapping. await tf.WorkfoldMapAsync( serverPath : definitionMapping.ServerPath, localPath : definitionMapping.GetRootedLocalPath(sourcesDirectory)); break; default: throw new NotSupportedException(); } } } if (tf.Features.HasFlag(TfsVCFeatures.GetFromUnmappedRoot)) { // Get. await tf.GetAsync(localPath : sourcesDirectory, quiet : reducedOutput); } else { // Perform "get" for each map. foreach (DefinitionWorkspaceMapping definitionMapping in definitionMappings ?? new DefinitionWorkspaceMapping[0]) { if (definitionMapping.MappingType == DefinitionMappingType.Map) { await tf.GetAsync(localPath : definitionMapping.GetRootedLocalPath(sourcesDirectory), quiet : reducedOutput); } } } // Steps for shelveset/gated. string shelvesetName = repository.Properties.Get <string>(Pipelines.RepositoryPropertyNames.Shelveset); if (!string.IsNullOrEmpty(shelvesetName)) { // Steps for gated. ITfsVCShelveset tfShelveset = null; string gatedShelvesetName = executionContext.Variables.GetValueOrDefault("build.gated.shelvesetname")?.Value; if (!string.IsNullOrEmpty(gatedShelvesetName)) { // Clean the last-saved-checkin-metadata for existing workspaces. // // A better long term fix is to add a switch to "tf unshelve" that completely overwrites // the last-saved-checkin-metadata, instead of merging associated work items. // // The targeted workaround for now is to create a trivial change and "tf shelve /move", // which will delete the last-saved-checkin-metadata. if (existingTFWorkspace != null) { executionContext.Output("Cleaning last saved checkin metadata."); // Find a local mapped directory. string firstLocalDirectory = (definitionMappings ?? new DefinitionWorkspaceMapping[0]) .Where(x => x.MappingType == DefinitionMappingType.Map) .Select(x => x.GetRootedLocalPath(sourcesDirectory)) .FirstOrDefault(x => Directory.Exists(x)); if (firstLocalDirectory == null) { executionContext.Warning("No mapped folder found. Unable to clean last-saved-checkin-metadata."); } else { // Create a trival change and "tf shelve /move" to clear the // last-saved-checkin-metadata. string cleanName = "__tf_clean_wksp_metadata"; string tempCleanFile = Path.Combine(firstLocalDirectory, cleanName); try { File.WriteAllText(path: tempCleanFile, contents: "clean last-saved-checkin-metadata", encoding: Encoding.UTF8); await tf.AddAsync(tempCleanFile); await tf.ShelveAsync(shelveset : cleanName, commentFile : tempCleanFile, move : true); } catch (Exception ex) { executionContext.Warning($"Unable to clean last-saved-checkin-metadata. {ex.Message}"); try { await tf.UndoAsync(tempCleanFile); } catch (Exception ex2) { executionContext.Warning($"Unable to undo '{tempCleanFile}'. {ex2.Message}"); } } finally { IOUtil.DeleteFile(tempCleanFile); } } } // Get the shelveset metadata. tfShelveset = await tf.ShelvesetsAsync(shelveset : shelvesetName); // The above command throws if the shelveset is not found, // so the following assertion should never fail. ArgUtil.NotNull(tfShelveset, nameof(tfShelveset)); } // Unshelve. bool unshelveErrorsAllowed = AgentKnobs.AllowTfvcUnshelveErrors.GetValue(executionContext).AsBoolean(); await tf.UnshelveAsync(shelveset : shelvesetName, unshelveErrorsAllowed); // Ensure we undo pending changes for shelveset build at the end. executionContext.SetTaskVariable("UndoShelvesetPendingChanges", bool.TrueString); if (!string.IsNullOrEmpty(gatedShelvesetName)) { // Create the comment file for reshelve. StringBuilder comment = new StringBuilder(tfShelveset.Comment ?? string.Empty); string runCi = executionContext.Variables.GetValueOrDefault("build.gated.runci")?.Value; bool gatedRunCi = StringUtil.ConvertToBoolean(runCi, true); if (!gatedRunCi) { if (comment.Length > 0) { comment.AppendLine(); } comment.Append("***NO_CI***"); } string commentFile = null; try { commentFile = Path.GetTempFileName(); File.WriteAllText(path: commentFile, contents: comment.ToString(), encoding: Encoding.UTF8); // Reshelve. await tf.ShelveAsync(shelveset : gatedShelvesetName, commentFile : commentFile, move : false); } finally { // Cleanup the comment file. if (File.Exists(commentFile)) { File.Delete(commentFile); } } } } // Cleanup proxy settings. if (agentProxy != null && !string.IsNullOrEmpty(agentProxy.ProxyAddress) && !agentProxy.WebProxy.IsBypassed(repository.Url)) { executionContext.Debug($"Remove proxy setting for '{tf.FilePath}' to work through proxy server '{agentProxy.ProxyAddress}'."); tf.CleanupProxySetting(); } // Set intra-task variable for post job cleanup executionContext.SetTaskVariable("repository", repository.Alias); }
public async Task GetSourceAsync( IExecutionContext executionContext, ServiceEndpoint endpoint, CancellationToken cancellationToken) { Trace.Entering(); // Validate args. ArgUtil.NotNull(executionContext, nameof(executionContext)); ArgUtil.NotNull(endpoint, nameof(endpoint)); // Create the tf command manager. var tf = HostContext.CreateService <ITfsVCCommandManager>(); tf.CancellationToken = cancellationToken; tf.Endpoint = endpoint; tf.ExecutionContext = executionContext; // Add TF to the PATH. string tfPath = tf.FilePath; ArgUtil.File(tfPath, nameof(tfPath)); var varUtil = HostContext.GetService <IVarUtil>(); executionContext.Output(StringUtil.Loc("Prepending0WithDirectoryContaining1", Constants.PathVariable, Path.GetFileName(tfPath))); varUtil.PrependPath(Path.GetDirectoryName(tfPath)); executionContext.Debug($"{Constants.PathVariable}: '{Environment.GetEnvironmentVariable(Constants.PathVariable)}'"); // Check if the administrator accepted the license terms of the TEE EULA when configuring the agent. AgentSettings settings = HostContext.GetService <IConfigurationStore>().GetSettings(); if (tf.Features.HasFlag(TfsVCFeatures.Eula) && settings.AcceptTeeEula) { // Check if the "tf eula -accept" command needs to be run for the current user. bool skipEula = false; try { skipEula = tf.TestEulaAccepted(); } catch (Exception ex) { executionContext.Debug("Unexpected exception while testing whether the TEE EULA has been accepted for the current user."); executionContext.Debug(ex.ToString()); } if (!skipEula) { // Run the command "tf eula -accept". try { await tf.EulaAsync(); } catch (Exception ex) { executionContext.Debug(ex.ToString()); executionContext.Warning(ex.Message); } } } // Get the workspaces. executionContext.Output(StringUtil.Loc("QueryingWorkspaceInfo")); ITfsVCWorkspace[] tfWorkspaces = await tf.WorkspacesAsync(); // Determine the workspace name. string buildDirectory = executionContext.Variables.Agent_BuildDirectory; ArgUtil.NotNullOrEmpty(buildDirectory, nameof(buildDirectory)); string workspaceName = $"ws_{Path.GetFileName(buildDirectory)}_{settings.AgentId}"; executionContext.Variables.Set(Constants.Variables.Build.RepoTfvcWorkspace, workspaceName); // Get the definition mappings. DefinitionWorkspaceMapping[] definitionMappings = JsonConvert.DeserializeObject <DefinitionWorkspaceMappings>(endpoint.Data[WellKnownEndpointData.TfvcWorkspaceMapping])?.Mappings; // Determine the sources directory. string sourcesDirectory = GetEndpointData(endpoint, Constants.EndpointData.SourcesDirectory); ArgUtil.NotNullOrEmpty(sourcesDirectory, nameof(sourcesDirectory)); // Attempt to re-use an existing workspace if the command manager supports scorch // or if clean is not specified. ITfsVCWorkspace existingTFWorkspace = null; bool clean = endpoint.Data.ContainsKey(WellKnownEndpointData.Clean) && StringUtil.ConvertToBoolean(endpoint.Data[WellKnownEndpointData.Clean], defaultValue: false); if (tf.Features.HasFlag(TfsVCFeatures.Scorch) || !clean) { existingTFWorkspace = WorkspaceUtil.MatchExactWorkspace( executionContext: executionContext, tfWorkspaces: tfWorkspaces, name: workspaceName, definitionMappings: definitionMappings, sourcesDirectory: sourcesDirectory); if (existingTFWorkspace != null) { if (tf.Features.HasFlag(TfsVCFeatures.GetFromUnmappedRoot)) { // Undo pending changes. ITfsVCStatus tfStatus = await tf.StatusAsync(localPath : sourcesDirectory); if (tfStatus?.HasPendingChanges ?? false) { await tf.UndoAsync(localPath : sourcesDirectory); // Cleanup remaining files/directories from pend adds. tfStatus.AllAdds .OrderByDescending(x => x.LocalItem) // Sort descending so nested items are deleted before their parent is deleted. .ToList() .ForEach(x => { executionContext.Output(StringUtil.Loc("Deleting", x.LocalItem)); IOUtil.Delete(x.LocalItem, cancellationToken); }); } } else { // Perform "undo" for each map. foreach (DefinitionWorkspaceMapping definitionMapping in definitionMappings ?? new DefinitionWorkspaceMapping[0]) { if (definitionMapping.MappingType == DefinitionMappingType.Map) { // Check the status. string localPath = definitionMapping.GetRootedLocalPath(sourcesDirectory); ITfsVCStatus tfStatus = await tf.StatusAsync(localPath : localPath); if (tfStatus?.HasPendingChanges ?? false) { // Undo. await tf.UndoAsync(localPath : localPath); // Cleanup remaining files/directories from pend adds. tfStatus.AllAdds .OrderByDescending(x => x.LocalItem) // Sort descending so nested items are deleted before their parent is deleted. .ToList() .ForEach(x => { executionContext.Output(StringUtil.Loc("Deleting", x.LocalItem)); IOUtil.Delete(x.LocalItem, cancellationToken); }); } } } } // Scorch. if (clean) { // Try to scorch. try { await tf.ScorchAsync(); } catch (ProcessExitCodeException ex) { // Scorch failed. // Warn, drop the folder, and re-clone. executionContext.Warning(ex.Message); existingTFWorkspace = null; } } } } // Create a new workspace. if (existingTFWorkspace == null) { // Remove any conflicting workspaces. await RemoveConflictingWorkspacesAsync( tf : tf, tfWorkspaces : tfWorkspaces, name : workspaceName, directory : sourcesDirectory); // Remove any conflicting workspace from a different computer. // This is primarily a hosted scenario where a registered hosted // agent can land on a different computer each time. tfWorkspaces = await tf.WorkspacesAsync(matchWorkspaceNameOnAnyComputer : true); foreach (ITfsVCWorkspace tfWorkspace in tfWorkspaces ?? new ITfsVCWorkspace[0]) { await tf.WorkspaceDeleteAsync(tfWorkspace); } // Recreate the sources directory. executionContext.Debug($"Deleting: '{sourcesDirectory}'."); IOUtil.DeleteDirectory(sourcesDirectory, cancellationToken); Directory.CreateDirectory(sourcesDirectory); // Create the workspace. await tf.WorkspaceNewAsync(); // Remove the default mapping. if (tf.Features.HasFlag(TfsVCFeatures.DefaultWorkfoldMap)) { await tf.WorkfoldUnmapAsync("$/"); } // Sort the definition mappings. definitionMappings = (definitionMappings ?? new DefinitionWorkspaceMapping[0]) .OrderBy(x => x.NormalizedServerPath?.Length ?? 0) // By server path length. .ToArray() ?? new DefinitionWorkspaceMapping[0]; // Add the definition mappings to the workspace. foreach (DefinitionWorkspaceMapping definitionMapping in definitionMappings) { switch (definitionMapping.MappingType) { case DefinitionMappingType.Cloak: // Add the cloak. await tf.WorkfoldCloakAsync(serverPath : definitionMapping.ServerPath); break; case DefinitionMappingType.Map: // Add the mapping. await tf.WorkfoldMapAsync( serverPath : definitionMapping.ServerPath, localPath : definitionMapping.GetRootedLocalPath(sourcesDirectory)); break; default: throw new NotSupportedException(); } } } if (tf.Features.HasFlag(TfsVCFeatures.GetFromUnmappedRoot)) { // Get. await tf.GetAsync(localPath : sourcesDirectory); } else { // Perform "get" for each map. foreach (DefinitionWorkspaceMapping definitionMapping in definitionMappings ?? new DefinitionWorkspaceMapping[0]) { if (definitionMapping.MappingType == DefinitionMappingType.Map) { await tf.GetAsync(localPath : definitionMapping.GetRootedLocalPath(sourcesDirectory)); } } } string shelvesetName = GetEndpointData(endpoint, Constants.EndpointData.SourceTfvcShelveset); if (!string.IsNullOrEmpty(shelvesetName)) { // Get the shelveset details. ITfsVCShelveset tfShelveset = null; string gatedShelvesetName = GetEndpointData(endpoint, Constants.EndpointData.GatedShelvesetName); if (!string.IsNullOrEmpty(gatedShelvesetName)) { tfShelveset = await tf.ShelvesetsAsync(shelveset : shelvesetName); // The command throws if the shelveset is not found. // This assertion should never fail. ArgUtil.NotNull(tfShelveset, nameof(tfShelveset)); } // Unshelve. await tf.UnshelveAsync(shelveset : shelvesetName); if (!string.IsNullOrEmpty(gatedShelvesetName)) { // Create the comment file for reshelve. StringBuilder comment = new StringBuilder(tfShelveset.Comment ?? string.Empty); string runCi = GetEndpointData(endpoint, Constants.EndpointData.GatedRunCI); bool gatedRunCi = StringUtil.ConvertToBoolean(runCi, true); if (!gatedRunCi) { if (comment.Length > 0) { comment.AppendLine(); } comment.Append(Constants.Build.NoCICheckInComment); } string commentFile = null; try { commentFile = Path.GetTempFileName(); File.WriteAllText(path: commentFile, contents: comment.ToString(), encoding: Encoding.UTF8); // Reshelve. await tf.ShelveAsync(shelveset : gatedShelvesetName, commentFile : commentFile); } finally { // Cleanup the comment file. if (File.Exists(commentFile)) { File.Delete(commentFile); } } } } }
/// <summary> /// 获取指定空间范围下相交的要素集合 /// </summary> /// <param name="featureClass">被查询要素类</param> /// <param name="queryClause">查询条件</param> /// <param name="queryGeometry">指定空间范围</param> /// <param name="intersectFeatureDTOs">输出相交要素信息</param> /// <param name="sumIntersectArea">输出相交部分的总面积</param> /// <param name="geometryField">geometry字段名称,默认为Shape</param> public static void GetIntersectFeaturesByQuery(IFeatureClass featureClass, string queryClause, IGeometry queryGeometry, out IList <IntersectFeatureDTO> intersectFeatureDTOs, out double sumIntersectArea, string geometryField = "Shape") { List <IFeature> featureList = new List <IFeature>(); intersectFeatureDTOs = new List <IntersectFeatureDTO>(); sumIntersectArea = 0d; try { ISpatialFilter spatialFilter = new SpatialFilter(); if (queryClause != null) { spatialFilter.WhereClause = queryClause; } if (queryGeometry != null) { spatialFilter.Geometry = queryGeometry; spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects; } if (geometryField != null) { spatialFilter.GeometryField = geometryField; } IFeatureCursor featureCursor = featureClass.Search(spatialFilter, false); IFeature feature = featureCursor.NextFeature(); IntersectFeatureDTO intersectFeatureDTOTemp = null; while (feature != null) { IGeometry intersectGeometry = OverlayCommonTool.GetIntersectGeometry(queryGeometry as IPolygon, feature.Shape as IPolygon); if (null == intersectGeometry || intersectGeometry.IsEmpty) { continue; } intersectFeatureDTOTemp = new IntersectFeatureDTO { Geometry = feature.Shape, OID = feature.OID, Coordinates = GeometryUtil.ConvertGeometryToJson(intersectGeometry, out string message), Area = GeometryUtil.GetArea(intersectGeometry), QueryGeometry = queryGeometry, IntersectGeometry = intersectGeometry, GeoType = EnumUtil.GetEnumName <esriGeometryType>((int)intersectGeometry.GeometryType) }; intersectFeatureDTOs.Add(intersectFeatureDTOTemp); IArea area = intersectGeometry as IArea; double intersectArea = area.Area; sumIntersectArea += intersectArea; featureList.Add(feature); feature = featureCursor.NextFeature(); } WorkspaceUtil.ReleaseComObject(featureCursor); } catch (Exception e) { LOG.Error(e); } }
public override Result Execute() { if (!base.InitComplete) { throw new BusinessException((int)EnumSystemStatusCode.DME_FAIL_INIT, "初始化工作未完成"); } DMEWorkspaceBridge <IWorkspace, IFeatureClass> dmeWorkspaceBridge = new DMEWorkspaceBridge <IWorkspace, IFeatureClass>(); dmeWorkspaceBridge.SetWorkspace(new EsriWorkspace()); // 目前先以ORACLE和MDB为数据源类型 // 获取source feature class this.SourceFeatureClass = dmeWorkspaceBridge.GetFeatureClass(this.sourceFeatureClassDTO); // 获取target feature class this.TargetFeatureClass = dmeWorkspaceBridge.GetFeatureClass(this.targetFeatureClassDTO); if (AnalysisType.COVER == this.AnalysisType) { OverlayCommonTool.GetTopounionGeometryByQuery(this.SourceFeatureClass, null, null, esriSpatialRelEnum.esriSpatialRelUndefined, out IGeometry sourceGeom, out IList <string> oidList); //找出touch的要素oid,排除掉touch的图形 OverlayCommonTool.GetTopounionGeometryByQuery(this.TargetFeatureClass, null, sourceGeom, esriSpatialRelEnum.esriSpatialRelTouches, out IGeometry touchGeom, out IList <string> touchOIDList); //通过intersect查找压盖部分的要素 string queryClause = null; if (touchOIDList != null && touchOIDList.Count > 0) { queryClause = $"OBJECTID NOT in ({string.Join(",", ((List<string>)touchOIDList).ToArray())})"; } // 求取空间相交的部分 OverlayCommonTool.GetIntersectFeaturesByQuery(this.TargetFeatureClass, queryClause, sourceGeom, out IList <IntersectFeatureDTO> intersectFeatureDTOs, out double sumIntersectArea); if (intersectFeatureDTOs?.Count > 0) { OverlayRespDTO overlayRespDTO = new OverlayRespDTO { SumArea = sumIntersectArea }; foreach (var item in intersectFeatureDTOs) { FeatureRespDTO intersectFeatureRespDTO = new FeatureRespDTO { OID = item.OID, Area = item.Area, Coordinates = item.Coordinates, GeoType = item.GeoType }; overlayRespDTO.Features.Add(intersectFeatureRespDTO); } Property resultProp = base.OutputParametersMeta[nameof(Result)]; resultProp.Value = overlayRespDTO; return(new Result(EnumSystemStatusCode.DME_SUCCESS, "运行完成", EnumSystemStatusCode.DME_SUCCESS, null)); } } else if (AnalysisType.OVERTOP == this.AnalysisType) { // 先拷贝一份mdb模板 string sTemplate = System.AppDomain.CurrentDomain.BaseDirectory + GlobalSystemConfig.PATH_TEMPLATE_PGDB;// @"\template\pgdb.mdb"; string sPath = System.AppDomain.CurrentDomain.BaseDirectory + GlobalSystemConfig.DIR_TEMP + "/" + GuidUtil.NewGuid() + ".mdb"; File.Copy(sTemplate, sPath); IWorkspace mdbWorkspace = WorkspaceUtil.OpenMdbWorspace(sPath); if (FeatureClassUtil.ExportToWorkspace(this.SourceFeatureClass, mdbWorkspace)) { // 获取导出的临时要素类信息 IFeatureClass tempExpFeatureClass = WorkspaceUtil.GetFeatureClass(mdbWorkspace, this.sourceFeatureClassDTO.Name); // 进行擦除操作 OverlayCommonTool.Erase(tempExpFeatureClass, this.TargetFeatureClass); // 计算完保存结果,如何保存? if (tempExpFeatureClass != null) { OverlayRespDTO overlayRespDTO = new OverlayRespDTO(); // 总面积 double sumArea = 0; IFeatureCursor pFeatureCursor = tempExpFeatureClass.Search(null, false); IFeature pFeature = null; //获得“Area”字段 //IFields fields = pFeatureCursor.Fields; //int areaIndex = fields.FindField("Area"); while ((pFeature = pFeatureCursor.NextFeature()) != null) { double area = ((IArea)pFeature.Shape).Area;// (double)pFeature.get_Value(areaIndex); sumArea += area; FeatureRespDTO featureRespDTO = new FeatureRespDTO { OID = pFeature.OID, Area = area, Coordinates = GeometryUtil.ConvertGeometryToJson(pFeature.Shape, out string msg) }; overlayRespDTO.Features.Add(featureRespDTO); pFeature = pFeatureCursor.NextFeature(); } overlayRespDTO.SumArea = sumArea; Property resultProp = base.OutputParametersMeta[nameof(Result)]; resultProp.Value = overlayRespDTO; return(new Result(EnumSystemStatusCode.DME_SUCCESS, "运行完成", EnumSystemStatusCode.DME_SUCCESS, null)); } } // 删除临时文件 if (IsClearTemp && File.Exists(sPath)) { File.Delete(sPath); } } else { throw new BusinessException((int)EnumSystemStatusCode.DME_FAIL, "分析类型不匹配"); } return(new Result(EnumSystemStatusCode.DME_SUCCESS, "运行完成,但没有运算结果", EnumSystemStatusCode.DME_SUCCESS, null)); }
public override IFeatureClass GetFeatureClass(IWorkspace workspace, string featureClassName) { return(WorkspaceUtil.GetFeatureClass(workspace, featureClassName)); }
public override IWorkspace Open(OracleConn conn) { return(WorkspaceUtil.OpenSdeWorkspace(conn.Username, conn.Password, conn.Server)); }