PageRenderTime 58ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/src/OSMGeoProcessing/OSMGPDownload.cs

https://github.com/alpascual/arcgis-osm-editor
C# | 1664 lines | 1285 code | 291 blank | 88 comment | 205 complexity | 1f8b8bb28c3c7270180f8179630beba3 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception

Large files files are truncated, but you can click here to view the full file

  1. // (c) Copyright Esri, 2010 - 2013
  2. // This source is subject to the Apache 2.0 License.
  3. // Please see http://www.apache.org/licenses/LICENSE-2.0.html for details.
  4. // All other rights reserved.
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Text;
  8. using System.Linq;
  9. using System.Runtime.InteropServices;
  10. using System.Resources;
  11. using ESRI.ArcGIS.Geodatabase;
  12. using ESRI.ArcGIS.Geoprocessing;
  13. using ESRI.ArcGIS.esriSystem;
  14. using System.Xml;
  15. using System.Xml.Serialization;
  16. using ESRI.ArcGIS.Geometry;
  17. using ESRI.ArcGIS.DataSourcesGDB;
  18. using ESRI.ArcGIS.DataSourcesFile;
  19. using System.IO;
  20. using System.Reflection;
  21. using System.Globalization;
  22. using System.Xml.Linq;
  23. using Microsoft.Win32;
  24. using ESRI.ArcGIS.Display;
  25. using ESRI.ArcGIS.OSM.OSMClassExtension;
  26. using System.Net;
  27. using ESRI.ArcGIS.OSM.OSMUtilities;
  28. namespace ESRI.ArcGIS.OSM.GeoProcessing
  29. {
  30. [Guid("b1653cbd-4023-4640-a48c-5ac8d21b4a71")]
  31. [ClassInterface(ClassInterfaceType.None)]
  32. [ComVisible(true)]
  33. [ProgId("OSMEditor.OSMGPDownload")]
  34. public class OSMGPDownload : ESRI.ArcGIS.Geoprocessing.IGPFunction2
  35. {
  36. string m_DisplayName = String.Empty;
  37. int in_downloadURLNumber, in_downloadExtentNumber, out_targetDatasetNumber, in_includeReferencesNumber, out_osmPointsNumber, out_osmLinesNumber, out_osmPolygonsNumber, out_RevTableNumber;
  38. ResourceManager resourceManager = null;
  39. OSMGPFactory osmGPFactory = null;
  40. Dictionary<string, string> m_editorConfigurationSettings = null;
  41. api m_osmAPICapabilities = null;
  42. public OSMGPDownload()
  43. {
  44. resourceManager = new ResourceManager("ESRI.ArcGIS.OSM.GeoProcessing.OSMGPToolsStrings", this.GetType().Assembly);
  45. osmGPFactory = new OSMGPFactory();
  46. m_editorConfigurationSettings = OSMGPFactory.ReadOSMEditorSettings();
  47. }
  48. #region "IGPFunction2 Implementations"
  49. public ESRI.ArcGIS.esriSystem.UID DialogCLSID
  50. {
  51. get
  52. {
  53. return null;
  54. }
  55. }
  56. public string DisplayName
  57. {
  58. get
  59. {
  60. if (String.IsNullOrEmpty(m_DisplayName))
  61. {
  62. m_DisplayName = osmGPFactory.GetFunctionName(OSMGPFactory.m_DownloadDataName).DisplayName;
  63. }
  64. return m_DisplayName;
  65. }
  66. }
  67. private ESRI.ArcGIS.Geodatabase.IGPMessages _message;
  68. public string[] Logs
  69. {
  70. get
  71. {
  72. try
  73. {
  74. string[] stemp = new string[_message.Count];
  75. for (int i = 0; i < _message.Count; i++)
  76. {
  77. IGPMessage msg = _message.GetMessage(i);
  78. stemp[i] = msg.Description;
  79. }
  80. return stemp;
  81. }
  82. catch { }
  83. return null;
  84. }
  85. }
  86. public void Execute(ESRI.ArcGIS.esriSystem.IArray paramvalues, ESRI.ArcGIS.esriSystem.ITrackCancel TrackCancel, ESRI.ArcGIS.Geoprocessing.IGPEnvironmentManager envMgr, ESRI.ArcGIS.Geodatabase.IGPMessages message)
  87. {
  88. _message = message;
  89. IFeatureClass osmPointFeatureClass = null;
  90. IFeatureClass osmLineFeatureClass = null;
  91. IFeatureClass osmPolygonFeatureClass = null;
  92. try
  93. {
  94. DateTime syncTime = DateTime.Now;
  95. IGPUtilities3 gpUtilities3 = new GPUtilitiesClass();
  96. if (TrackCancel == null)
  97. {
  98. TrackCancel = new CancelTrackerClass();
  99. }
  100. IGPParameter baseURLParameter = paramvalues.get_Element(in_downloadURLNumber) as IGPParameter;
  101. IGPString baseURLString = gpUtilities3.UnpackGPValue(baseURLParameter) as IGPString;
  102. if (baseURLString == null)
  103. {
  104. message.AddError(120048, string.Format(resourceManager.GetString("GPTools_NullPointerParameterType"), baseURLParameter.Name));
  105. }
  106. IGPParameter downloadExtentParameter = paramvalues.get_Element(in_downloadExtentNumber) as IGPParameter;
  107. IGPValue downloadExtentGPValue = gpUtilities3.UnpackGPValue(downloadExtentParameter);
  108. esriGPExtentEnum gpExtent;
  109. IEnvelope downloadEnvelope = gpUtilities3.GetExtent(downloadExtentGPValue, out gpExtent);
  110. IGPParameter includeAllReferences = paramvalues.get_Element(in_includeReferencesNumber) as IGPParameter;
  111. IGPBoolean includeAllReferencesGPValue = gpUtilities3.UnpackGPValue(includeAllReferences) as IGPBoolean;
  112. if (includeAllReferencesGPValue == null)
  113. {
  114. message.AddError(120048, string.Format(resourceManager.GetString("GPTools_NullPointerParameterType"), includeAllReferences.Name));
  115. }
  116. IEnvelope newExtent = null;
  117. ISpatialReferenceFactory spatialReferenceFactory = new SpatialReferenceEnvironmentClass() as ISpatialReferenceFactory;
  118. ISpatialReference wgs84 = spatialReferenceFactory.CreateGeographicCoordinateSystem((int)esriSRGeoCSType.esriSRGeoCS_WGS1984) as ISpatialReference;
  119. // this determines the spatial reference as defined from the gp environment settings and the initial wgs84 SR
  120. ISpatialReference downloadSpatialReference = gpUtilities3.GetGPSpRefEnv(envMgr, wgs84, newExtent, 0, 0, 0, 0, null);
  121. downloadEnvelope.Project(wgs84);
  122. Marshal.ReleaseComObject(wgs84);
  123. Marshal.ReleaseComObject(spatialReferenceFactory);
  124. HttpWebRequest httpClient;
  125. System.Xml.Serialization.XmlSerializer serializer = null;
  126. serializer = new XmlSerializer(typeof(osm));
  127. // get the capabilities from the server
  128. HttpWebResponse httpResponse = null;
  129. api apiCapabilities = null;
  130. CultureInfo enUSCultureInfo = new CultureInfo("en-US");
  131. #if DEBUG
  132. Console.WriteLine("Debbuging");
  133. message.AddMessage("Debugging...");
  134. #endif
  135. message.AddMessage(resourceManager.GetString("GPTools_OSMGPDownload_startingDownloadRequest"));
  136. try
  137. {
  138. httpClient = HttpWebRequest.Create(baseURLString.Value + "/api/capabilities") as HttpWebRequest;
  139. httpClient = AssignProxyandCredentials(httpClient);
  140. httpResponse = httpClient.GetResponse() as HttpWebResponse;
  141. osm osmCapabilities = null;
  142. Stream stream = httpResponse.GetResponseStream();
  143. XmlTextReader xmlReader = new XmlTextReader(stream);
  144. osmCapabilities = serializer.Deserialize(xmlReader) as osm;
  145. xmlReader.Close();
  146. apiCapabilities = osmCapabilities.Items[0] as api;
  147. }
  148. catch (Exception ex)
  149. {
  150. System.Diagnostics.Debug.WriteLine(ex.Message);
  151. message.AddError(120009, ex.Message);
  152. if (ex is WebException)
  153. {
  154. WebException webException = ex as WebException;
  155. string serverErrorMessage = webException.Response.Headers["Error"];
  156. if (!String.IsNullOrEmpty(serverErrorMessage))
  157. {
  158. message.AddError(120009, serverErrorMessage);
  159. }
  160. }
  161. }
  162. finally
  163. {
  164. if (httpResponse != null)
  165. {
  166. httpResponse.Close();
  167. }
  168. httpClient = null;
  169. }
  170. if (apiCapabilities != null)
  171. {
  172. // check for the extent
  173. double roiArea = ((IArea)downloadEnvelope).Area;
  174. double capabilitiyArea = Convert.ToDouble(apiCapabilities.area.maximum, new CultureInfo("en-US"));
  175. if (roiArea > capabilitiyArea)
  176. {
  177. message.AddAbort(resourceManager.GetString("GPTools_OSMGPDownload_exceedDownloadROI"));
  178. return;
  179. }
  180. }
  181. // check for user interruption
  182. if (TrackCancel.Continue() == false)
  183. {
  184. return;
  185. }
  186. // list containing either only one document for a single bbox request or multiple if relation references need to be resolved
  187. List<string> downloadedOSMDocuments = new List<string>();
  188. string requestURL = baseURLString.Value + "/api/0.6/map?bbox=" + downloadEnvelope.XMin.ToString("f5", enUSCultureInfo) + "," + downloadEnvelope.YMin.ToString("f5", enUSCultureInfo) + "," + downloadEnvelope.XMax.ToString("f5", enUSCultureInfo) + "," + downloadEnvelope.YMax.ToString("f5", enUSCultureInfo);
  189. string osmMasterDocument = downloadOSMDocument(ref message, requestURL, apiCapabilities);
  190. // check if the initial request was successfull
  191. // it might have failed at this point because too many nodes were requested or because of something else
  192. if (String.IsNullOrEmpty(osmMasterDocument))
  193. {
  194. message.AddAbort(resourceManager.GetString("GPTools_OSMGPDownload_noValidOSMResponse"));
  195. return;
  196. }
  197. // add the "master document" ) original bbox request to the list
  198. downloadedOSMDocuments.Add(osmMasterDocument);
  199. if (includeAllReferencesGPValue.Value)
  200. {
  201. List<string> nodeList = new List<string>();
  202. List<string> wayList = new List<string>();
  203. List<string> relationList = new List<string>();
  204. // check for user interruption
  205. if (TrackCancel.Continue() == false)
  206. {
  207. return;
  208. }
  209. parseOSMDocument(osmMasterDocument, ref message, ref nodeList, ref wayList, ref relationList, ref downloadedOSMDocuments, baseURLString.Value, apiCapabilities);
  210. }
  211. string metadataAbstract = resourceManager.GetString("GPTools_OSMGPDownload_metadata_abstract");
  212. string metadataPurpose = resourceManager.GetString("GPTools_OSMGPDownload_metadata_purpose");
  213. IGPParameter targetDatasetParameter = paramvalues.get_Element(out_targetDatasetNumber) as IGPParameter;
  214. IDEDataset2 targetDEDataset2 = gpUtilities3.UnpackGPValue(targetDatasetParameter) as IDEDataset2;
  215. IGPValue targetDatasetGPValue = gpUtilities3.UnpackGPValue(targetDatasetParameter);
  216. string targetDatasetName = ((IGPValue)targetDEDataset2).GetAsText();
  217. IDataElement targetDataElement = targetDEDataset2 as IDataElement;
  218. IDataset targetDataset = gpUtilities3.OpenDatasetFromLocation(targetDataElement.CatalogPath);
  219. IName parentName = null;
  220. try
  221. {
  222. parentName = gpUtilities3.CreateParentFromCatalogPath(targetDataElement.CatalogPath);
  223. }
  224. catch
  225. {
  226. message.AddError(120033, resourceManager.GetString("GPTools_OSMGPFileReader_unable_to_create_fd"));
  227. return;
  228. }
  229. // test if the feature classes already exists,
  230. // if they do and the environments settings are such that an overwrite is not allowed we need to abort at this point
  231. IGeoProcessorSettings gpSettings = (IGeoProcessorSettings)envMgr;
  232. if (gpSettings.OverwriteOutput == true)
  233. {
  234. }
  235. else
  236. {
  237. if (gpUtilities3.Exists((IGPValue)targetDEDataset2) == true)
  238. {
  239. message.AddError(120010, String.Format(resourceManager.GetString("GPTools_OSMGPDownload_basenamealreadyexists"), targetDataElement.Name));
  240. return;
  241. }
  242. }
  243. string Container = "";
  244. IDEUtilities deUtilities = new DEUtilitiesClass();
  245. deUtilities.ParseContainer(targetDataElement.CatalogPath, ref Container);
  246. IFeatureWorkspace featureWorkspace = gpUtilities3.OpenFromString(Container) as IFeatureWorkspace;
  247. if (featureWorkspace == null)
  248. {
  249. message.AddError(120011, String.Format(resourceManager.GetString("GPTools_OSMGPDownload_nofeatureworkspace"), Container));
  250. return;
  251. }
  252. // load the descriptions from which to derive the domain values
  253. OSMDomains availableDomains = null;
  254. System.Xml.XmlTextReader reader = null;
  255. try
  256. {
  257. if (File.Exists(m_editorConfigurationSettings["osmdomainsfilepath"]))
  258. {
  259. reader = new System.Xml.XmlTextReader(m_editorConfigurationSettings["osmdomainsfilepath"]);
  260. }
  261. }
  262. // If is in the server and hasn't been install all the configuration files
  263. catch
  264. {
  265. if (File.Exists(System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetAssembly(typeof(OSMGPDownload)).Location), "osm_domains.xml")))
  266. {
  267. reader = new System.Xml.XmlTextReader(System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetAssembly(typeof(OSMGPDownload)).Location), "osm_domains.xml"));
  268. }
  269. }
  270. if (reader == null)
  271. {
  272. message.AddError(120012, resourceManager.GetString("GPTools_OSMGPDownload_NoDomainConfigFile"));
  273. return;
  274. }
  275. try
  276. {
  277. serializer = new XmlSerializer(typeof(OSMDomains));
  278. availableDomains = serializer.Deserialize(reader) as OSMDomains;
  279. }
  280. catch (Exception ex)
  281. {
  282. System.Diagnostics.Debug.WriteLine(ex.Message);
  283. System.Diagnostics.Debug.WriteLine(ex.StackTrace);
  284. message.AddError(120013, ex.Message);
  285. return;
  286. }
  287. #region define and add domains to the workspace
  288. // we are using domains to guide the edit templates in the editor for ArcGIS desktop
  289. Dictionary<string, IDomain> codedValueDomains = new Dictionary<string, IDomain>();
  290. foreach (var domain in availableDomains.domain)
  291. {
  292. ICodedValueDomain pointCodedValueDomain = new CodedValueDomainClass();
  293. ((IDomain)pointCodedValueDomain).Name = domain.name + "_pt";
  294. ((IDomain)pointCodedValueDomain).FieldType = esriFieldType.esriFieldTypeString;
  295. ICodedValueDomain lineCodedValueDomain = new CodedValueDomainClass();
  296. ((IDomain)lineCodedValueDomain).Name = domain.name + "_ln";
  297. ((IDomain)lineCodedValueDomain).FieldType = esriFieldType.esriFieldTypeString;
  298. ICodedValueDomain polygonCodedValueDomain = new CodedValueDomainClass();
  299. ((IDomain)polygonCodedValueDomain).Name = domain.name + "_ply";
  300. ((IDomain)polygonCodedValueDomain).FieldType = esriFieldType.esriFieldTypeString;
  301. for (int i = 0; i < domain.domainvalue.Length; i++)
  302. {
  303. for (int domainGeometryIndex = 0; domainGeometryIndex < domain.domainvalue[i].geometrytype.Length; domainGeometryIndex++)
  304. {
  305. switch (domain.domainvalue[i].geometrytype[domainGeometryIndex])
  306. {
  307. case geometrytype.point:
  308. pointCodedValueDomain.AddCode(domain.domainvalue[i].value, domain.domainvalue[i].value);
  309. break;
  310. case geometrytype.line:
  311. lineCodedValueDomain.AddCode(domain.domainvalue[i].value, domain.domainvalue[i].value);
  312. break;
  313. case geometrytype.polygon:
  314. polygonCodedValueDomain.AddCode(domain.domainvalue[i].value, domain.domainvalue[i].value);
  315. break;
  316. default:
  317. break;
  318. }
  319. }
  320. }
  321. // add the domain tables to the domains collection
  322. codedValueDomains.Add(((IDomain)pointCodedValueDomain).Name, (IDomain)pointCodedValueDomain);
  323. codedValueDomains.Add(((IDomain)lineCodedValueDomain).Name, (IDomain)lineCodedValueDomain);
  324. codedValueDomains.Add(((IDomain)polygonCodedValueDomain).Name, (IDomain)polygonCodedValueDomain);
  325. }
  326. IWorkspaceDomains workspaceDomain = featureWorkspace as IWorkspaceDomains;
  327. foreach (var domain in codedValueDomains.Values)
  328. {
  329. IDomain testDomain = null;
  330. try
  331. {
  332. testDomain = workspaceDomain.get_DomainByName(domain.Name);
  333. }
  334. catch (Exception ex)
  335. {
  336. System.Diagnostics.Debug.WriteLine(ex.Message);
  337. System.Diagnostics.Debug.WriteLine(ex.StackTrace);
  338. }
  339. if (testDomain == null)
  340. {
  341. workspaceDomain.AddDomain(domain);
  342. }
  343. }
  344. #endregion
  345. IGPEnvironment configKeyword = getEnvironment(envMgr, "configKeyword");
  346. IGPString gpString = null;
  347. if (configKeyword != null)
  348. gpString = configKeyword.Value as IGPString;
  349. string storageKeyword = String.Empty;
  350. if (gpString != null)
  351. {
  352. storageKeyword = gpString.Value;
  353. }
  354. IFeatureDataset targetFeatureDataset = null;
  355. if (gpUtilities3.Exists((IGPValue)targetDEDataset2))
  356. {
  357. targetFeatureDataset = gpUtilities3.OpenDataset((IGPValue)targetDEDataset2) as IFeatureDataset;
  358. }
  359. else
  360. {
  361. targetFeatureDataset = featureWorkspace.CreateFeatureDataset(targetDataElement.Name, downloadSpatialReference);
  362. }
  363. ESRI.ArcGIS.esriSystem.UID osmClassExtensionUID = new ESRI.ArcGIS.esriSystem.UIDClass();
  364. //GUID for the OSM feature class extension
  365. osmClassExtensionUID.Value = "{65CA4847-8661-45eb-8E1E-B2985CA17C78}";
  366. downloadSpatialReference = ((IGeoDataset)targetFeatureDataset).SpatialReference;
  367. OSMToolHelper osmToolHelper = new OSMToolHelper();
  368. #region create point/line/polygon feature classes and tables
  369. // points
  370. try
  371. {
  372. osmPointFeatureClass = osmToolHelper.CreatePointFeatureClass((IWorkspace2)featureWorkspace, targetFeatureDataset, targetDataElement.Name + "_osm_pt", null, null, osmClassExtensionUID, storageKeyword, availableDomains, metadataAbstract, metadataPurpose);
  373. }
  374. catch (Exception ex)
  375. {
  376. message.AddError(120014, String.Format(resourceManager.GetString("GPTools_OSMGPDownload_nullpointfeatureclass"), ex.Message));
  377. return;
  378. }
  379. if (osmPointFeatureClass == null)
  380. {
  381. return;
  382. }
  383. // change the property set of the osm class extension to skip any change detection during the initial data load
  384. osmPointFeatureClass.RemoveOSMClassExtension();
  385. // lines
  386. try
  387. {
  388. osmLineFeatureClass = osmToolHelper.CreateLineFeatureClass((IWorkspace2)featureWorkspace, targetFeatureDataset, targetDataElement.Name + "_osm_ln", null, null, osmClassExtensionUID, storageKeyword, availableDomains, metadataAbstract, metadataPurpose);
  389. }
  390. catch (Exception ex)
  391. {
  392. message.AddError(120015, String.Format(resourceManager.GetString("GPTools_OSMGPDownload_nulllinefeatureclass"), ex.Message));
  393. return;
  394. }
  395. if (osmLineFeatureClass == null)
  396. {
  397. return;
  398. }
  399. // change the property set of the osm class extension to skip any change detection during the initial data load
  400. osmLineFeatureClass.RemoveOSMClassExtension();
  401. // polygons
  402. try
  403. {
  404. osmPolygonFeatureClass = osmToolHelper.CreatePolygonFeatureClass((IWorkspace2)featureWorkspace, targetFeatureDataset, targetDataElement.Name + "_osm_ply", null, null, osmClassExtensionUID, storageKeyword, availableDomains, metadataAbstract, metadataPurpose);
  405. }
  406. catch (Exception ex)
  407. {
  408. message.AddError(120016, String.Format(resourceManager.GetString("GPTools_OSMGPDownload_nullpolygonfeatureclass"), ex.Message));
  409. return;
  410. }
  411. if (osmPolygonFeatureClass == null)
  412. {
  413. return;
  414. }
  415. // change the property set of the osm class extension to skip any change detection during the initial data load
  416. osmPolygonFeatureClass.RemoveOSMClassExtension();
  417. // relation table
  418. ITable relationTable = null;
  419. try
  420. {
  421. relationTable = osmToolHelper.CreateRelationTable((IWorkspace2)featureWorkspace, targetDataElement.Name + "_osm_relation", null, storageKeyword, metadataAbstract, metadataPurpose);
  422. }
  423. catch (Exception ex)
  424. {
  425. message.AddError(120017, String.Format(resourceManager.GetString("GPTools_OSMGPDownload_nullrelationtable"), ex.Message));
  426. return;
  427. }
  428. if (relationTable == null)
  429. {
  430. return;
  431. }
  432. // revision table
  433. ITable revisionTable = null;
  434. try
  435. {
  436. revisionTable = osmToolHelper.CreateRevisionTable((IWorkspace2)featureWorkspace, targetDataElement.Name + "_osm_revision", null, storageKeyword);
  437. }
  438. catch (Exception ex)
  439. {
  440. message.AddError(120018, String.Format(resourceManager.GetString("GPTools_OSMGPDownload_nullrelationtable"), ex.Message));
  441. return;
  442. }
  443. if (revisionTable == null)
  444. {
  445. return;
  446. }
  447. // check for user interruption
  448. if (TrackCancel.Continue() == false)
  449. {
  450. return;
  451. }
  452. #endregion
  453. #region clean any existing data from loading targets
  454. ESRI.ArcGIS.Geoprocessing.IGeoProcessor2 gp = new ESRI.ArcGIS.Geoprocessing.GeoProcessorClass();
  455. IGeoProcessorResult gpResult = new GeoProcessorResultClass();
  456. try
  457. {
  458. IVariantArray truncateParameters = new VarArrayClass();
  459. truncateParameters.Add(((IWorkspace)featureWorkspace).PathName + "\\" + targetDataElement.Name + "\\" + targetDataElement.Name + "_osm_pt");
  460. gpResult = gp.Execute("TruncateTable_management", truncateParameters, TrackCancel);
  461. truncateParameters = new VarArrayClass();
  462. truncateParameters.Add(((IWorkspace)featureWorkspace).PathName + "\\" + targetDataElement.Name + "\\" + targetDataElement.Name + "_osm_ln");
  463. gpResult = gp.Execute("TruncateTable_management", truncateParameters, TrackCancel);
  464. truncateParameters = new VarArrayClass();
  465. truncateParameters.Add(((IWorkspace)featureWorkspace).PathName + "\\" + targetDataElement.Name + "\\" + targetDataElement.Name + "_osm_ply");
  466. gpResult = gp.Execute("TruncateTable_management", truncateParameters, TrackCancel);
  467. truncateParameters = new VarArrayClass();
  468. truncateParameters.Add(((IWorkspace)featureWorkspace).PathName + "\\" + targetDataElement.Name + "_osm_relation");
  469. gpResult = gp.Execute("TruncateTable_management", truncateParameters, TrackCancel);
  470. truncateParameters = new VarArrayClass();
  471. truncateParameters.Add(((IWorkspace)featureWorkspace).PathName + "\\" + targetDataElement.Name + "_osm_revision");
  472. gpResult = gp.Execute("TruncateTable_management", truncateParameters, TrackCancel);
  473. }
  474. catch (Exception ex)
  475. {
  476. message.AddWarning(ex.Message);
  477. }
  478. #endregion
  479. Dictionary<string, OSMToolHelper.simplePointRef> osmNodeDictionary = null;
  480. foreach (string osmDownloadDocument in downloadedOSMDocuments.Reverse<string>())
  481. {
  482. int nodeCapacity = 0;
  483. int wayCapacity = 0;
  484. int relationCapacity = 0;
  485. message.AddMessage(resourceManager.GetString("GPTools_OSMGPFileReader_countingNodes"));
  486. osmToolHelper.countOSMStuff(osmDownloadDocument, ref nodeCapacity, ref wayCapacity, ref relationCapacity, ref TrackCancel);
  487. message.AddMessage(String.Format(resourceManager.GetString("GPTools_OSMGPFileReader_countedElements"), nodeCapacity, wayCapacity, relationCapacity));
  488. if (osmNodeDictionary == null)
  489. osmNodeDictionary = new Dictionary<string, OSMToolHelper.simplePointRef>(nodeCapacity);
  490. #region load points
  491. osmToolHelper.loadOSMNodes(osmDownloadDocument, ref TrackCancel, ref message, targetDatasetGPValue, osmPointFeatureClass, false, false, nodeCapacity, ref osmNodeDictionary, featureWorkspace, downloadSpatialReference, availableDomains, false);
  492. #endregion
  493. if (TrackCancel.Continue() == false)
  494. {
  495. return;
  496. }
  497. #region load ways
  498. if (wayCapacity > 0)
  499. {
  500. List<string> missingWays = null;
  501. missingWays = osmToolHelper.loadOSMWays(osmDownloadDocument, ref TrackCancel, ref message, targetDatasetGPValue, osmPointFeatureClass, osmLineFeatureClass, osmPolygonFeatureClass, false, false, wayCapacity, ref osmNodeDictionary, featureWorkspace, downloadSpatialReference, availableDomains, false);
  502. }
  503. #endregion
  504. if (TrackCancel.Continue() == false)
  505. {
  506. return;
  507. }
  508. # region for conserve memory condition, update refcount
  509. int refCounterFieldIndex = osmPointFeatureClass.Fields.FindField("wayRefCount");
  510. if (refCounterFieldIndex > -1)
  511. {
  512. foreach (var refNode in osmNodeDictionary)
  513. {
  514. try
  515. {
  516. IFeature updateFeature = osmPointFeatureClass.GetFeature(refNode.Value.pointObjectID);
  517. int refCount = refNode.Value.RefCounter;
  518. if (refCount == 0)
  519. {
  520. refCount = 1;
  521. }
  522. updateFeature.set_Value(refCounterFieldIndex, refCount);
  523. updateFeature.Store();
  524. }
  525. catch { }
  526. }
  527. }
  528. #endregion
  529. // check for user interruption
  530. if (TrackCancel.Continue() == false)
  531. {
  532. return;
  533. }
  534. ESRI.ArcGIS.Geoprocessor.Geoprocessor geoProcessor = new ESRI.ArcGIS.Geoprocessor.Geoprocessor();
  535. #region for local geodatabases enforce spatial integrity
  536. bool storedOriginal = geoProcessor.AddOutputsToMap;
  537. geoProcessor.AddOutputsToMap = false;
  538. try
  539. {
  540. if (osmLineFeatureClass != null)
  541. {
  542. if (((IDataset)osmLineFeatureClass).Workspace.Type == esriWorkspaceType.esriLocalDatabaseWorkspace)
  543. {
  544. IVariantArray lineRepairParameters = new VarArrayClass();
  545. lineRepairParameters.Add(((IWorkspace)featureWorkspace).PathName + "\\" + targetDataElement.Name + "\\" + targetDataElement.Name + "_osm_ln");
  546. lineRepairParameters.Add("DELETE_NULL");
  547. IGeoProcessorResult2 gpResults = gp.Execute("RepairGeometry_management", lineRepairParameters, TrackCancel) as IGeoProcessorResult2;
  548. message.AddMessages(gpResults.GetResultMessages());
  549. }
  550. }
  551. if (osmPolygonFeatureClass != null)
  552. {
  553. if (((IDataset)osmPolygonFeatureClass).Workspace.Type == esriWorkspaceType.esriLocalDatabaseWorkspace)
  554. {
  555. IVariantArray polygonRepairParameters = new VarArrayClass();
  556. polygonRepairParameters.Add(((IWorkspace)featureWorkspace).PathName + "\\" + targetDataElement.Name + "\\" + targetDataElement.Name + "_osm_ply");
  557. polygonRepairParameters.Add("DELETE_NULL");
  558. IGeoProcessorResult2 gpResults = gp.Execute("RepairGeometry_management", polygonRepairParameters, TrackCancel) as IGeoProcessorResult2;
  559. message.AddMessages(gpResults.GetResultMessages());
  560. }
  561. }
  562. }
  563. catch
  564. {
  565. message.AddWarning(resourceManager.GetString("GPTools_OSMGPDownload_repairgeometryfailure"));
  566. }
  567. geoProcessor.AddOutputsToMap = storedOriginal;
  568. #endregion
  569. #region load relations
  570. if (relationCapacity > 0)
  571. {
  572. List<string> missingRelations = null;
  573. missingRelations = osmToolHelper.loadOSMRelations(osmDownloadDocument, ref TrackCancel, ref message, targetDatasetGPValue, osmPointFeatureClass, osmLineFeatureClass, osmPolygonFeatureClass, relationCapacity, relationTable, availableDomains, false, false);
  574. }
  575. #endregion
  576. }
  577. #region update the references counts and member lists for nodes
  578. message.AddMessage(resourceManager.GetString("GPTools_OSMGPFileReader_updatereferences"));
  579. IFeatureCursor pointUpdateCursor = null;
  580. using (SchemaLockManager ptLockManager = new SchemaLockManager(osmPointFeatureClass as ITable))
  581. {
  582. using (ComReleaser comReleaser = new ComReleaser())
  583. {
  584. int updateCount = 0;
  585. pointUpdateCursor = osmPointFeatureClass.Update(null, false);
  586. updateCount = ((ITable)osmPointFeatureClass).RowCount(null);
  587. IStepProgressor stepProgressor = TrackCancel as IStepProgressor;
  588. if (stepProgressor != null)
  589. {
  590. stepProgressor.MinRange = 0;
  591. stepProgressor.MaxRange = updateCount;
  592. stepProgressor.Position = 0;
  593. stepProgressor.Message = resourceManager.GetString("GPTools_OSMGPFileReader_updatepointrefcount");
  594. stepProgressor.StepValue = 1;
  595. stepProgressor.Show();
  596. }
  597. comReleaser.ManageLifetime(pointUpdateCursor);
  598. IFeature pointFeature = pointUpdateCursor.NextFeature();
  599. int osmPointIDFieldIndex = osmPointFeatureClass.FindField("OSMID");
  600. int osmWayRefCountFieldIndex = osmPointFeatureClass.FindField("wayRefCount");
  601. int positionCounter = 0;
  602. while (pointFeature != null)
  603. {
  604. positionCounter++;
  605. string nodeID = Convert.ToString(pointFeature.get_Value(osmPointIDFieldIndex));
  606. // let get the reference counter from the internal node dictionary
  607. if (osmNodeDictionary[nodeID].RefCounter == 0)
  608. {
  609. pointFeature.set_Value(osmWayRefCountFieldIndex, 1);
  610. }
  611. else
  612. {
  613. pointFeature.set_Value(osmWayRefCountFieldIndex, osmNodeDictionary[nodeID].RefCounter);
  614. }
  615. pointUpdateCursor.UpdateFeature(pointFeature);
  616. if (pointFeature != null)
  617. Marshal.ReleaseComObject(pointFeature);
  618. pointFeature = pointUpdateCursor.NextFeature();
  619. if (stepProgressor != null)
  620. {
  621. stepProgressor.Position = positionCounter;
  622. }
  623. }
  624. if (stepProgressor != null)
  625. {
  626. stepProgressor.Hide();
  627. }
  628. }
  629. }
  630. #endregion
  631. // clean all the downloaded OSM files
  632. foreach (string osmFile in downloadedOSMDocuments)
  633. {
  634. if (File.Exists(osmFile))
  635. {
  636. try
  637. {
  638. File.Delete(osmFile);
  639. }
  640. catch { }
  641. }
  642. }
  643. SyncState.StoreLastSyncTime(targetDatasetName, syncTime);
  644. gpUtilities3 = new GPUtilitiesClass() as IGPUtilities3;
  645. // repackage the feature class into their respective gp values
  646. IGPParameter pointFeatureClassParameter = paramvalues.get_Element(out_osmPointsNumber) as IGPParameter;
  647. IGPValue pointFeatureClassPackGPValue = gpUtilities3.UnpackGPValue(pointFeatureClassParameter);
  648. gpUtilities3.PackGPValue(pointFeatureClassPackGPValue, pointFeatureClassParameter);
  649. IGPParameter lineFeatureClassParameter = paramvalues.get_Element(out_osmLinesNumber) as IGPParameter;
  650. IGPValue lineFeatureClassPackGPValue = gpUtilities3.UnpackGPValue(lineFeatureClassParameter);
  651. gpUtilities3.PackGPValue(lineFeatureClassPackGPValue, lineFeatureClassParameter);
  652. IGPParameter polygonFeatureClassParameter = paramvalues.get_Element(out_osmPolygonsNumber) as IGPParameter;
  653. IGPValue polygon1FeatureClassPackGPValue = gpUtilities3.UnpackGPValue(polygonFeatureClassParameter);
  654. gpUtilities3.PackGPValue(polygon1FeatureClassPackGPValue, polygonFeatureClassParameter);
  655. gpUtilities3.ReleaseInternals();
  656. Marshal.ReleaseComObject(gpUtilities3);
  657. Marshal.ReleaseComObject(baseURLString);
  658. Marshal.ReleaseComObject(downloadExtentGPValue);
  659. Marshal.ReleaseComObject(downloadEnvelope);
  660. Marshal.ReleaseComObject(includeAllReferences);
  661. Marshal.ReleaseComObject(downloadSpatialReference);
  662. if (osmToolHelper != null)
  663. osmToolHelper = null;
  664. }
  665. catch (Exception ex)
  666. {
  667. System.Diagnostics.Debug.WriteLine(ex.Message);
  668. System.Diagnostics.Debug.WriteLine(ex.StackTrace);
  669. message.AddError(120019, ex.Message);
  670. }
  671. finally
  672. {
  673. try
  674. {
  675. if (osmPointFeatureClass != null)
  676. {
  677. osmPointFeatureClass.ApplyOSMClassExtension();
  678. Marshal.ReleaseComObject(osmPointFeatureClass);
  679. }
  680. if (osmLineFeatureClass != null)
  681. {
  682. osmLineFeatureClass.ApplyOSMClassExtension();
  683. Marshal.ReleaseComObject(osmLineFeatureClass);
  684. }
  685. if (osmPolygonFeatureClass != null)
  686. {
  687. osmPolygonFeatureClass.ApplyOSMClassExtension();
  688. Marshal.ReleaseComObject(osmPolygonFeatureClass);
  689. }
  690. }
  691. catch (Exception ex)
  692. {
  693. message.AddError(120020, ex.ToString());
  694. }
  695. }
  696. }
  697. private string downloadOSMDocument(ref IGPMessages message, string requestURL, api apiCapabilities)
  698. {
  699. string osmDownloadDocument = String.Empty;
  700. HttpWebResponse httpResponse = null;
  701. try
  702. {
  703. // OSM does not understand URL encoded query parameters
  704. HttpWebRequest httpClient = HttpWebRequest.Create(requestURL) as HttpWebRequest;
  705. httpClient = AssignProxyandCredentials(httpClient);
  706. // read the timeout parameter
  707. int secondsToTimeout = Convert.ToInt32(apiCapabilities.timeout.seconds);
  708. httpClient.Timeout = secondsToTimeout * 1000;
  709. httpResponse = httpClient.GetResponse() as HttpWebResponse;
  710. osmDownloadDocument = System.IO.Path.GetTempFileName();
  711. using (System.IO.FileStream fileStream = new System.IO.FileStream(osmDownloadDocument, FileMode.Append, FileAccess.Write))
  712. {
  713. using (StreamReader streamReader = new StreamReader(httpResponse.GetResponseStream()))
  714. {
  715. UTF8Encoding encoding = new UTF8Encoding();
  716. byte[] byteBuffer = encoding.GetBytes(streamReader.ReadToEnd());
  717. fileStream.Write(byteBuffer, 0, byteBuffer.Length);
  718. }
  719. }
  720. }
  721. catch (Exception ex)
  722. {
  723. System.Diagnostics.Debug.WriteLine(ex.Message);
  724. message.AddError(120009, ex.Message);
  725. if (ex is WebException)
  726. {
  727. WebException webException = ex as WebException;
  728. if (webException != null)
  729. {
  730. if (webException.Response != null)
  731. {
  732. string serverErrorMessage = webException.Response.Headers["Error"];
  733. if (!String.IsNullOrEmpty(serverErrorMessage))
  734. {
  735. message.AddError(120009, serverErrorMessage);
  736. }
  737. }
  738. }
  739. }
  740. }
  741. finally
  742. {
  743. if (httpResponse != null)
  744. {
  745. httpResponse.Close();
  746. }
  747. }
  748. return osmDownloadDocument;
  749. }
  750. static public HttpWebRequest AssignProxyandCredentials(HttpWebRequest httpClient)
  751. {
  752. if (httpClient == null)
  753. return httpClient;
  754. // read the network proxy settings from the IE settings - this includes proxy settings (static, dynamic) and credentials
  755. httpClient.UseDefaultCredentials = true;
  756. // user name and password are coming from registry settings written by ArcCatalog
  757. IProxyServerInfo2 proxyServerInfo = new ProxyServerInfoClass() as IProxyServerInfo2;
  758. if (proxyServerInfo == null)
  759. return httpClient;
  760. if (proxyServerInfo.Enabled)
  761. httpClient.Proxy.Credentials = new NetworkCredential(proxyServerInfo.UserName, proxyServerInfo.Password);
  762. return httpClient;
  763. }
  764. /// <summary>
  765. /// Checks if the baseURL can be used to retrieve the OSM server capabilities. All exceptions will be rethrown to the caller.
  766. /// </summary>
  767. /// <param name="baseURL"></param>
  768. /// <returns></returns>
  769. static public api CheckValidServerURL(string baseURL)
  770. {
  771. osm osmCapabilities = null;
  772. api apiCapabilities = null;
  773. // get the capabilities from the server
  774. HttpWebResponse httpResponse = null;
  775. HttpWebRequest httpClient = HttpWebRequest.Create(baseURL + "/api/capabilities") as HttpWebRequest;
  776. httpClient = AssignProxyandCredentials(httpClient);
  777. httpClient.Timeout = 10000;
  778. System.Xml.Serialization.XmlSerializer serializer = null;
  779. serializer = new XmlSerializer(typeof(osm));
  780. httpResponse = httpClient.GetResponse() as HttpWebResponse;
  781. Stream stream = httpResponse.GetResponseStream();
  782. XmlTextReader xmlReader = new XmlTextReader(stream);
  783. osmCapabilities = serializer.Deserialize(xmlReader) as osm;
  784. xmlReader.Close();
  785. apiCapabilities = osmCapabilities.Items[0] as api;
  786. return apiCapabilities;
  787. }
  788. private string retrieveAdditionalRelations(string osmID, ref ITrackCancel TrackCancel, ESRI.ArcGIS.Geodatabase.IGPMessages message, IGPString baseURLString, HttpWebRequest httpClient, ref HttpWebResponse httpResponse)
  789. {
  790. string osmDocumentLocation = String.Empty;
  791. try
  792. {
  793. if (TrackCancel.Continue() == false)
  794. {
  795. return osmDocumentLocation;
  796. }
  797. httpClient = HttpWebRequest.Create(baseURLString.Value + "/api/0.6/relation/" + osmID + "/full") as HttpWebRequest;
  798. httpClient = AssignProxyandCredentials(httpClient);
  799. httpResponse = httpClient.GetResponse() as HttpWebResponse;
  800. osmDocumentLocation = System.IO.Path.GetTempFileName();
  801. using (System.IO.FileStream fileStream = new System.IO.FileStream(osmDocumentLocation, FileMode.Append, FileAccess.Write))
  802. {
  803. using (StreamReader streamReader = new StreamReader(httpResponse.GetResponseStream()))
  804. {
  805. UTF8Encoding encoding = new UTF8Encoding();
  806. byte[] byteBuffer = encoding.GetBytes(streamReader.ReadToEnd());
  807. fileStream.Write(byteBuffer, 0, byteBuffer.Length);
  808. }
  809. }
  810. }
  811. catch (Exception ex)
  812. {
  813. System.Diagnostics.Debug.WriteLine(ex.Message);
  814. message.AddWarning(ex.Message);
  815. if (ex is WebException)
  816. {
  817. WebException webException = ex as WebException;
  818. string serverErrorMessage = webException.Response.Headers["Error"];
  819. if (!String.IsNullOrEmpty(serverErrorMessage))
  820. {
  821. message.AddWarning(serverErrorMessage);
  822. }
  823. }
  824. }
  825. return osmDocumentLocation;
  826. }
  827. public static IGPEnvironment getEnvironment(IGPEnvironmentManager environmentManager, string name)
  828. {
  829. IGPUtilities3 gpUtils = new GPUtilitiesClass();
  830. IGPEnvironment returnEnv = null;
  831. try
  832. {
  833. if (environmentManager.GetLocalEnvironments().Count > 0)
  834. returnEnv = gpUtils.GetEnvironment(environmentManager.GetLocalEnvironments(), name);
  835. if (returnEnv == null)
  836. returnEnv = gpUtils.GetEnvironment(environmentManager.GetEnvironments(), name);
  837. }
  838. catch (Exception ex)
  839. {
  840. System.Diagnostics.Debug.WriteLine(ex.Message);
  841. System.Diagnostics.Debug.WriteLine(ex.StackTrace);
  842. }
  843. return returnEnv;
  844. }
  845. public ESRI.ArcGIS.esriSystem.IName FullName
  846. {
  847. get
  848. {
  849. IName fullName = null;
  850. if (osmGPFactory != null)
  851. {
  852. fullName = osmGPFactory.GetFunctionName(OSMGPFactory.m_DownloadDataName) as IName;
  853. }
  854. return fullName;
  855. }
  856. }
  857. public object GetRenderer(ESRI.ArcGIS.Geoprocessing.IGPParameter pParam)
  858. {
  859. return null;
  860. }
  861. public int HelpContext
  862. {
  863. get
  864. {
  865. return 0;
  866. }
  867. }
  868. public string HelpFile
  869. {
  870. get
  871. {
  872. return "";
  873. }
  874. }
  875. public bool IsLicensed()
  876. {
  877. return true;
  878. }
  879. public string MetadataFile
  880. {
  881. get
  882. {
  883. string metadafile = "osmgpdownload.xml";
  884. try
  885. {
  886. string[] languageid = System.Threading.Thread.CurrentThread.CurrentUICulture.Name.Split("-".ToCharArray());
  887. string ArcGISInstallationLocation = OSMGPFactory.GetArcGIS10InstallLocation();
  888. string localizedMetaDataFileShort = ArcGISInstallationLocation + System.IO.Path.DirectorySeparatorChar.ToString() + "help" + System.IO.Path.DirectorySeparatorChar.ToString() + "gp" + System.IO.Path.DirectorySeparatorChar.ToString() + "osmgpdownload_" + languageid[0] + ".xml";
  889. string localizedMetaDataFileLong = ArcGISInstallationLocation + System.IO.Path.DirectorySeparatorChar.ToString() + "help" + System.IO.Path.DirectorySeparatorChar.ToString() + "gp" + System.IO.Path.DirectorySeparatorChar.ToString() + "osmgpdownload_" + System.Threading.Thread.CurrentThread.CurrentUICulture.Name + ".xml";
  890. if (System.IO.File.Exists(localizedMetaDataFileShort))
  891. {
  892. metadafile = localizedMetaDataFileShort;
  893. }
  894. else if (System.IO.File.Exists(localizedMetaDataFileLong))
  895. {
  896. metadafile = localizedMetaDataFileLong;
  897. }
  898. }
  899. catch (Exception ex)
  900. {
  901. System.Diagnostics.Debug.WriteLine(ex.Message);
  902. System.Diagnostics.Debug.WriteLine(ex.StackTrace);
  903. }
  904. return metadafile;
  905. }
  906. }
  907. public string Name
  908. {
  909. get
  910. {
  911. return OSMGPFactory.m_DownloadDataName;
  912. }
  913. }
  914. public ESRI.ArcGIS.esriSystem.IArray ParameterInfo
  915. {
  916. get
  917. {
  918. //
  919. IArray parameterArray = new ArrayClass();
  920. // osm download URL (required)
  921. IGPParameterEdit3 downloadURL = new GPParameterClass() as IGPParameterEdit3;
  922. downloadURL.DataType = new GPStringTypeClass();
  923. downloadURL.Direction = esriGPParameterDirection.esriGPParameterDirectionInput;
  924. downloadURL.DisplayName = resourceManager.GetString("GPTools_OSMGPDownload_downloadURL_desc");
  925. downloadURL.Name = "in_osmURL";
  926. downloadURL.ParameterType = esr

Large files files are truncated, but you can click here to view the full file