public OSMData(string osmXMLpath) { XmlTextReader xmlReader = new XmlTextReader(osmXMLpath); xmlReader.MoveToContent(); while (xmlReader.Read()) { if (xmlReader.NodeType.Equals(XmlNodeType.Element)) { switch (xmlReader.LocalName) { case "node": OSMNode n = ParseOSMNode(xmlReader); nodes.Add(n.Id, n); break; case "way": OSMWay way = ParseOSMWay(xmlReader); ways.Add(way.Id, way); break; case "relation": OSMRelation relation = ParseOSMRelation(xmlReader); relations.Add(relation.Id, relation); break; default: //ignore other nodes break; } } } UnityEngine.Debug.Log("New OSMDATA: " + nodes.Count + " Nodes " + ways.Count + " Ways " + relations.Count + " Relations"); Console.AddMessage("New OSMDATA: " + nodes.Count + " Nodes " + ways.Count + " Ways " + relations.Count + " Relations"); }
/// <summary> /// On relation found. /// </summary> /// <param name="relation">Relation.</param> /// <param name="rawData">Raw data.</param> /// <param name="infos">Infos.</param> protected void OnRelationFound(OSMRelation relation, byte[] rawData, ElementDebugInfos infos) { if (this.FoundRelationRaw != null) { this.FoundRelationRaw(relation, rawData, infos); } }
/// <summary> /// On relation found. /// </summary> /// <param name="relation">Relation.</param> protected void OnRelationFound(OSMRelation relation) { if (this.FoundRelation != null) { this.FoundRelation(relation); } }
/// <summary> /// Raises the RelationRead event /// </summary> /// <param name="node">The OSMRelation read from the database</param> protected void OnRelationRead(OSMRelation relation) { OSMRelationReadHandler temp = RelationRead; if (temp != null) { temp(relation); } }
public void AddRelation(OSMRelation relation) { if (relation != null) { if (!relations.Keys.Contains(relation.Id)) { relations.Add(relation.Id, relation); } } }
//<relation id="448540" user="******" uid="172947" visible="true" version="21" changeset="4699466" timestamp="2010-05-14T20:09:09Z"> public static OSMRelation ParseRelation(XmlNode node, ref OSMMap map) { OSMRelation osmRelation = new OSMRelation(); //HashDictionary<int, OSMNode> tmpNodesDict = new HashDictionary<int, OSMNode>(); //bool keep = false; // parse node-attributes foreach (XmlAttribute attribute in node.Attributes) { string name = attribute.Name; switch (name) { case "id": osmRelation.Id = int.Parse(attribute.Value); break; case "visible": osmRelation.Visible = bool.Parse(attribute.Value); break; case "version": osmRelation.version = int.Parse(attribute.Value); break; default: break; } } // parse <nd /> Nodes foreach (XmlNode childnode in node.ChildNodes) { switch (childnode.Name) { case "member": //osmRelation.AddMember(OSMRelationMember.ParseRelationMember(childnode)); osmRelation.Members.Add(OSMMember.ParseRelationMember(childnode)); break; case "tag": //osmRelation.AddTag(OSMParser.ReadKeyValue(childnode)); osmRelation.AddTag(childnode.Attributes[0].Value, childnode.Attributes[0].Value); //KeyValuePair<string, string> tag = OSMParser.ReadKeyValue(childnode); break; default: break; } } return(osmRelation); }
public static bool TryCreateFromOSM(OSMRelation relation, Tile tile) { if (relation.Tags.ContainsKey("waterway")) { if (relation.Tags["waterway"] == "riverbank") { new River(relation, tile.Query.OSM, tile.TileMesh); return true; } } return false; }
private void ReadRelation() { string attId = _xmlReader.GetAttribute("id"); if (attId == null) { throw new XmlException("Attribute 'id' is missing."); } int relationId = int.Parse(attId, CultureInfo.InvariantCulture); OSMRelation relation = new OSMRelation(relationId); if (false == _xmlReader.IsEmptyElement) { _xmlReader.Read(); while (_xmlReader.NodeType != XmlNodeType.EndElement) { switch (_xmlReader.NodeType) { case XmlNodeType.Element: switch (_xmlReader.Name) { case "member": relation.Members.Add(ReadRelationMember()); continue; case "tag": relation.Tags.Add(ReadTag()); continue; default: _xmlReader.Skip(); continue; } default: _xmlReader.Skip(); break; } } } OnRelationRead(relation); _xmlReader.Skip(); }
public static OSMMap ParseMap(XmlDocument doc, ref XmlTextReader xmlReader, ref OSMMap osmMap) { //osmMap = new OSMMap(); XmlNode rootnode = doc.ReadNode(xmlReader); OSMMap.ParseOSMHeader(rootnode, ref osmMap); int nodeCount = 0; int wayCount = 0; int relationCount = 0; foreach (XmlNode node in rootnode.ChildNodes) { switch (node.Name) { case "bounds": osmMap.AddBounds(OSMMap.ParseBounds(node, ref osmMap)); break; case "node": nodeCount++; osmMap.AddNode(OSMNode.ParseNode(node)); break; case "way": wayCount++; osmMap.AddWay(OSMWay.ParseWay(node, ref osmMap)); break; case "relation": relationCount++; osmMap.AddRelation(OSMRelation.ParseRelation(node, ref osmMap)); break; default: break; } } //Console.WriteLine("nodeCount = {0} = {1}", nodeCount, osmMap.nodes.Count); //Console.WriteLine("wayCount = {0} = {1}", wayCount, osmMap.ways.Count); //Console.WriteLine("relationCount = {0} = {1}", relationCount, osmMap.relations.Count); return(osmMap); }
/// <summary> /// Writes the specific OSMRelation to the output /// </summary> /// <param name="relation">The OSMRelation to be written.</param> public void WriteRelation(OSMRelation relation) { _xmlWriter.WriteStartElement("relation"); WriteOSMObjectAttributes(relation); foreach (var member in relation.Members) { _xmlWriter.WriteStartElement("member"); _xmlWriter.WriteAttributeString("type", member.Type.ToString()); _xmlWriter.WriteAttributeString("ref", member.Reference.ToString(System.Globalization.NumberFormatInfo.InvariantInfo)); _xmlWriter.WriteAttributeString("role", member.Role); _xmlWriter.WriteEndElement(); } WriteOSMObjectTags(relation); _xmlWriter.WriteEndElement(); }
public River(OSMRelation rel, OSMData osm, ModularMesh mesh) { Debug.Log("RIVERBANKS"); //layout = new Polyline(); //OSMNode node; ////Discard last waynode if its the same as first //if (way.WayNodes[0] == way.WayNodes[way.WayNodes.Count - 1]) //{ // for (int i = 0; i < way.WayNodes.Count - 1; i++) // { // if (nodes.TryGetValue(way.WayNodes[i], out node)) // { // Vector3 pos = new Vector3(node.X, SRTMHeightProvider.GetInterpolatedHeight(node.Latitude, node.Longitude), node.Z); // layout.Add(new Vertex(pos, mesh)); // } // } //} //else //{ // for (int i = 0; i < way.WayNodes.Count; i++) // { // if (nodes.TryGetValue(way.WayNodes[i], out node)) // { // Vector3 pos = new Vector3(node.X, SRTMHeightProvider.GetInterpolatedHeight(node.Latitude, node.Longitude), node.Z); // layout.Add(new Vertex(pos, mesh)); // } // } //} ////layout.MakeClockwise(); //leveledLayout = layout.LevelUp(null); //leftBorder = leveledLayout.Inset(-50f, mesh); //rightBorder = leveledLayout.Inset(50f, mesh); //area = new TriangleStrip(leftBorder, rightBorder, mesh, MaterialManager.GetMaterial("diffuseBlue")); }
public OSMRelation ParseOSMRelation(XmlTextReader xmlReader) { OSMRelation relation = new OSMRelation(long.Parse(xmlReader.GetAttribute("id"))); string childs = xmlReader.ReadOuterXml(); XmlTextReader outerXmlReader = new XmlTextReader(new System.IO.StringReader(childs)); outerXmlReader.MoveToContent(); while (outerXmlReader.Read()) { if (outerXmlReader.NodeType.Equals(XmlNodeType.Element) && outerXmlReader.LocalName.Equals("tag")) { relation.Tags.Add(outerXmlReader.GetAttribute("k"), outerXmlReader.GetAttribute("v")); } if (outerXmlReader.NodeType.Equals(XmlNodeType.Element) && outerXmlReader.LocalName.Equals("member")) { relation.Members.Add(new OSMMember(outerXmlReader.GetAttribute("type"), long.Parse(outerXmlReader.GetAttribute("ref")), outerXmlReader.GetAttribute("role"))); } } return(relation); }
private OSMRelation ParseRelationData( byte[] data #if DEBUG , ElementDebugInfos debugInfos #endif ) { var bufferOffset = 0; #if DEBUG var idPosition = (uint)bufferOffset + 1; #endif var relationId = VarInt.ParseInt64(data, ref bufferOffset) + this._lastRelationId; #if DEBUG debugInfos.Add(idPosition, "start of 'id' (" + relationId + ")."); #endif var o5mRelation = new OSMRelation((ulong)relationId); this._lastRelationId = (long)o5mRelation.Id; #if DEBUG this.ParseVersionData(data, o5mRelation, ref bufferOffset, debugInfos); #else this.ParseVersionData(data, o5mRelation, ref bufferOffset); #endif if (data[bufferOffset] > 0) { KeyValuePair <byte[], byte[]>?typeAndRole; #if DEBUG var referenceLengthPosition = (uint)bufferOffset + 1; #endif var referenceLength = VarInt.ParseUInt64(data, ref bufferOffset); #if DEBUG debugInfos.Add(referenceLengthPosition, "start of 'length of reference section' (" + referenceLength + ")."); #endif var startOffset = bufferOffset; var bytesUnread = referenceLength; while (bytesUnread > 0) { #if DEBUG var referenceIdPosition = (uint)bufferOffset + 1; #endif var currentReferenceId = VarInt.ParseInt64(data, ref bufferOffset) + this._lastReferenceId; #if DEBUG debugInfos.Add(referenceIdPosition, "start of 'reference-id' (" + currentReferenceId + ")."); #endif this._lastReferenceId = currentReferenceId; if (data[bufferOffset] == 0) { #if DEBUG debugInfos.Add((uint)bufferOffset + 1, "start of 'type/role'-pair (raw)."); #endif typeAndRole = StringPair.ParseToTypeRoleByteArray(data, ref bufferOffset); if (typeAndRole.HasValue) { var typeAndRoleValue = typeAndRole.Value; if (typeAndRoleValue.Key.Length + typeAndRoleValue.Value.Length <= 250) { this._storedStringPairs.Insert(0, typeAndRoleValue); } } } else { #if DEBUG var typeRolePosition = (uint)bufferOffset + 1; #endif var storedPosition = VarInt.ParseUInt32(data, ref bufferOffset); #if DEBUG debugInfos.Add(typeRolePosition, "start of stored 'type/role'-pair (" + storedPosition + ")."); #endif typeAndRole = this._storedStringPairs[(int)storedPosition - 1]; } if (typeAndRole?.Key.Length > 0) { var typeValue = (MemberType)(typeAndRole.Value.Key[0] - 0x30); var roleValue = Encoding.UTF8.GetString(typeAndRole.Value.Value); o5mRelation.Members.Add(new OSMMember(typeValue, (ulong)currentReferenceId, roleValue)); } bytesUnread = referenceLength - ((ulong)bufferOffset - (ulong)startOffset); } } #if DEBUG this.ParseTagsData(data, o5mRelation, ref bufferOffset, debugInfos); #else this.ParseTagsData(data, o5mRelation, ref bufferOffset); #endif return(o5mRelation); }
IEnumerator ProceduralLocal() { msg.Stop(Job.StartProcedural); msg.Start(Job.ProceduralPreparation); SimpleClient.jobStatus[jobNumber] = msg; this.transform.position = TilePosition - new Vector3((float)TileManager.TileWidth * (float)TileManager.Scaling / 2f, 0f, (float)TileManager.TileWidth * (float)TileManager.Scaling / 2f); terrain = this.gameObject.GetOrAddComponent <Terrain>(); tC = this.gameObject.GetOrAddComponent <TerrainCollider>(); Building.Clear(); Intersection.Clear(); Street.Clear(); Water.Clear(); River.Clear(); Bridge.Clear(); unusedWays.Clear(); streets.Clear(); streetPolygons.Clear(); msg.Stop(Job.ProceduralPreparation); #region LOD0 if (lOD == 0) { Console.AddMessage("Procedural lod 0"); Debug.Log("Procedural lod 0"); #region terrain TerrainData terrainData = new TerrainData(); //HeightMap terrainData.heightmapResolution = 257; float[,] heights = new float[257, 257]; for (int x = 0; x < heights.GetLength(0); x++) { for (int y = 0; y < heights.GetLength(1); y++) { heights[x, y] = 1f; } } terrainData.SetHeights(0, 0, heights); terrainData.size = new Vector3((float)TileManager.TileWidth * (float)TileManager.Scaling, 10f, (float)TileManager.TileWidth * (float)TileManager.Scaling); ////SplatPrototypes //SplatPrototype[] splatPrototypes = new SplatPrototype[1]; //splatPrototypes[0] = new SplatPrototype(); ////splatPrototypes[0].texture = (Texture2D)Resources.Load("Textures/White1px"); //splatPrototypes[0].texture = (Texture2D)Resources.Load("Textures/Terrain/Grass (Hill)"); //terrainData.splatPrototypes = splatPrototypes; terrain.terrainData = terrainData; tC.terrainData = terrainData; #endregion terrain #region mesh TileMesh.Clear(); Vertex[] tileQuadVertices = new Vertex[4]; tileQuadVertices[0] = new Vertex(new Vector3((float)(-TileManager.TileWidth * TileManager.Scaling / 2d), 0f, (float)(-TileManager.TileWidth * TileManager.Scaling / 2d)) + TilePosition); tileQuadVertices[1] = new Vertex(new Vector3((float)(-TileManager.TileWidth * TileManager.Scaling / 2d), 0f, (float)(TileManager.TileWidth * TileManager.Scaling / 2d)) + TilePosition); tileQuadVertices[2] = new Vertex(new Vector3((float)(TileManager.TileWidth * TileManager.Scaling / 2d), 0f, (float)(TileManager.TileWidth * TileManager.Scaling / 2d)) + TilePosition); tileQuadVertices[3] = new Vertex(new Vector3((float)(TileManager.TileWidth * TileManager.Scaling / 2d), 0f, (float)(-TileManager.TileWidth * TileManager.Scaling / 2d)) + TilePosition); new Quad(tileQuadVertices, TileMesh, MaterialManager.GetMaterial("diffuseBrown")); TileMesh.FillMeshDivideMaterialsKeepMeshStructure(transform, true); #endregion Debug.Log("Procedural lod 0 - Done"); } #endregion #region LOD5 if (lOD == 5) { msg.Start(Job.CreateTerrain); SimpleClient.jobStatus[jobNumber] = msg; #region terrain if (terrain.terrainData == null) { terrain.terrainData = new TerrainData(); } //HeightMap terrain.terrainData.heightmapResolution = 257; terrain.terrainData.alphamapResolution = 257; float height = 0f; terrain.terrainData.SetHeights(0, 0, SRTMHeightProvider.GetInterpolatedTerrain(this.Query.BoundingBox, out height)); terrain.terrainData.size = new Vector3((float)TileManager.TileWidth * (float)TileManager.Scaling, height, (float)TileManager.TileWidth * (float)TileManager.Scaling); tC.terrainData = terrain.terrainData; msg.Stop(Job.CreateTerrain); #endregion terrain #region mesh msg.Start(Job.MeshPreparation); SimpleClient.jobStatus[jobNumber] = msg; TileMesh.Clear(); if (BackgroundMesh != null) { BackgroundMesh.Clear(); } else { BackgroundMesh = new ModularMesh(TileMesh, "BackgroundMesh"); } if (BuildingMesh != null) { BuildingMesh.Clear(); } else { BuildingMesh = new ModularMesh(TileMesh, "BuildingMesh"); } if (StreetMesh != null) { StreetMesh.Clear(); } else { StreetMesh = new ModularMesh(TileMesh, "StreetMesh"); } if (OtherMesh != null) { OtherMesh.Clear(); } else { OtherMesh = new ModularMesh(TileMesh, "OtherMesh"); } msg.Stop(Job.MeshPreparation); msg.Start(Job.TileQuad); SimpleClient.jobStatus[jobNumber] = msg; Vertex[] tileQuadVertices = new Vertex[4]; tileQuadVertices[0] = new Vertex(new Vector3((float)(-TileManager.TileWidth * TileManager.Scaling / 2d), 0f, (float)(-TileManager.TileWidth * TileManager.Scaling / 2d)) + TilePosition); tileQuadVertices[1] = new Vertex(new Vector3((float)(-TileManager.TileWidth * TileManager.Scaling / 2d), 0f, (float)(TileManager.TileWidth * TileManager.Scaling / 2d)) + TilePosition); tileQuadVertices[2] = new Vertex(new Vector3((float)(TileManager.TileWidth * TileManager.Scaling / 2d), 0f, (float)(TileManager.TileWidth * TileManager.Scaling / 2d)) + TilePosition); tileQuadVertices[3] = new Vertex(new Vector3((float)(TileManager.TileWidth * TileManager.Scaling / 2d), 0f, (float)(-TileManager.TileWidth * TileManager.Scaling / 2d)) + TilePosition); new Quad(tileQuadVertices, BackgroundMesh, MaterialManager.GetMaterial("diffuseBlack")); msg.Stop(Job.TileQuad); yield return(null); msg.Start(Job.River); SimpleClient.jobStatus[jobNumber] = msg; //Create Domain Objects ///Relations foreach (KeyValuePair <long, OSMRelation> kV in Query.OSM.relations) { OSMRelation relation = kV.Value; River.TryCreateFromOSM(relation, this); yield return(null); } msg.Stop(Job.River); msg.Start(Job.Ways); SimpleClient.jobStatus[jobNumber] = msg; ///Ways foreach (KeyValuePair <long, OSMWay> kV in Query.OSM.ways) { OSMWay way = kV.Value; if (!way.FirstInBounds(Query.BoundingBox, Query.OSM)) { continue; } if (!Building.TryCreateFromOSM(way, this)) { if (!Intersection.TryCreateFromOSM(way, this)) { if (!Water.TryCreateFromOSM(way, this)) { } } } yield return(null); } msg.Stop(Job.Ways); //Nodes!? //foreach (KeyValuePair<long, OSMNode> kV in Query.OSM.nodes) //{ // OSMNode node = kV.Value; // TrafficSignal.TryCreateFromOSM(node, this); //} //Debug.Log("CreateStreets"); ////Create Streets (and Bridges) //Street.CreateStreets(this); //CreateTheMeshes //Debug.Log("CreateAllMeshes StreetMesh"); //Street.CreateAllMeshes(StreetMesh); //Debug.Log("CreateAllMeshes StreetMesh Bridge"); //Bridge.CreateAllMeshes(StreetMesh); //Debug.Log("CreateAllMeshes StreetMesh Intersection"); //Intersection.CreateAllMeshes(StreetMesh); //Debug.Log("CreateAllMeshes StreetMesh Street"); //Street.CreateAllMeshes(StreetMesh); // A second time, cause Intersections change streetproperties msg.Start(Job.CreateBuildingMesh); SimpleClient.jobStatus[jobNumber] = msg; Building.CreateAllMeshes(BuildingMesh); msg.Stop(Job.CreateBuildingMesh); //Debug.Log("CreateAllMeshes Water"); //Water.CreateAllMeshes(OtherMesh); //Debug.Log("CreateAllMeshes TrafficSignal"); //TrafficSignal.CreateAllMeshes(OtherMesh); //StreetPolygon currentStreetPolygon; //bool hasLeftPolygon = false; //bool hasRightPolygon = false; //for (int i = 0; i < streets.Count; i++) //{ // for (int j = 0; j < streetPolygons.Count; j++) // { // hasLeftPolygon = streetPolygons[j].IsLefthandPolygonOf(streets[i]); // hasRightPolygon = streetPolygons[j].IsRighthandPolygonOf(streets[i]); // } // if (!hasLeftPolygon) // { // if (StreetPolygon.GetLefthandStreetPolygon(streets[i], out currentStreetPolygon)) // streetPolygons.Add(currentStreetPolygon); // } // if (!hasRightPolygon) // { // if (StreetPolygon.GetRighthandStreetPolygon(streets[i], out currentStreetPolygon)) // streetPolygons.Add(currentStreetPolygon); // } // hasLeftPolygon = false; // hasRightPolygon = false; //} //for (int i = 0; i < streetPolygons.Count; i++) //{ // streetPolygons[i].Triangulate(StreetMesh , MaterialManager.GetMaterial("error")); //} msg.Start(Job.FillMeshDivideMaterials); SimpleClient.jobStatus[jobNumber] = msg; TileMesh.FillMeshDivideMaterialsKeepMeshStructure(transform, true); msg.Stop(Job.FillMeshDivideMaterials); #endregion } #endregion msg.Start(Job.GarbageCollection); SimpleClient.jobStatus[jobNumber] = msg; System.GC.Collect(); msg.Stop(Job.GarbageCollection); yield return(null); msg.Start(Job.ProceduralDone); SimpleClient.jobStatus[jobNumber] = msg; OnProceduralDoneLocal(); msg.Stop(Job.Worker); msg.Stop(); yield return(true); }
protected static ICollection<OSMRelation> GetRelations(IEnumerable<OSMWay> ways) { Dictionary<string,OSMRelation> result = new Dictionary<string,OSMRelation>(); foreach (OSMWay way in ways) { string CLC_ID; if (way.Tags.TryGetValue("CLC:id", out CLC_ID)) { if (!result.ContainsKey(CLC_ID)) { OSMRelation tmprelation = new OSMRelation(); tmprelation.Tags = new Dictionary<string, string>(way.Tags); tmprelation.Tags.Add("type", "multipolygon"); result.Add(CLC_ID, tmprelation); } } } return result.Values; }
public OSMData(XmlDocument doc) { XmlNodeList xmlNodes = doc.GetElementsByTagName("node"); XmlNodeList xmlWays = doc.GetElementsByTagName("way"); XmlNodeList xmlRelations = doc.GetElementsByTagName("relation"); long id; float longitude; float latitude; foreach (XmlNode node in xmlNodes) { if (!long.TryParse(node.Attributes["id"].Value, out id)) { continue; } if (!float.TryParse(node.Attributes["lon"].Value, out longitude)) { continue; } if (!float.TryParse(node.Attributes["lat"].Value, out latitude)) { continue; } OSMNode n = new OSMNode(id, latitude, longitude); nodes.Add(id, n); XmlNodeList childNodes = node.ChildNodes; foreach (XmlNode tagNode in childNodes) { if (tagNode.Name == "tag") { n.Tags.Add(tagNode.Attributes["k"].Value, tagNode.Attributes["v"].Value); } } } foreach (XmlNode wayNode in xmlWays) { if (!long.TryParse(wayNode.Attributes["id"].Value, out id)) { continue; } OSMWay way = new OSMWay(id); ways.Add(id, way); XmlNodeList childNodes = wayNode.ChildNodes; foreach (XmlNode childNode in childNodes) { if (childNode.Name == "nd") { long referenceId; if (long.TryParse(childNode.Attributes["ref"].Value, out referenceId)) { way.WayNodes.Add(referenceId); } } if (childNode.Name == "tag") { way.Tags.Add(childNode.Attributes["k"].Value, childNode.Attributes["v"].Value); } } } foreach (XmlNode relNode in xmlRelations) { if (!long.TryParse(relNode.Attributes["id"].Value, out id)) { continue; } OSMRelation relation = new OSMRelation(id); relations.Add(id, relation); XmlNodeList childNodes = relNode.ChildNodes; foreach (XmlNode childNode in childNodes) { if (childNode.Name == "member") { if (!long.TryParse(childNode.Attributes["ref"].Value, out id)) { continue; } relation.Members.Add(new OSMMember(childNode.Attributes["type"].Value, id, childNode.Attributes["role"].Value)); } if (childNode.Name == "tag") { relation.Tags.Add(childNode.Attributes["k"].Value, childNode.Attributes["v"].Value); } } } Console.AddMessage("New OSMDATA: " + nodes.Count + " Nodes " + ways.Count + " Ways " + relations.Count + " Relations"); }
private void WriteRelation(OSMRelation relation) { byte[] writtenData = null; this.WriteRelation(relation, out writtenData); }
internal List<string> loadOSMRelations(string osmFileLocation, ref ITrackCancel TrackCancel, ref IGPMessages message, IGPValue targetGPValue, IFeatureClass osmPointFeatureClass, IFeatureClass osmLineFeatureClass, IFeatureClass osmPolygonFeatureClass, int relationCapacity, ITable relationTable, OSMDomains availableDomains, bool fastLoad, bool checkForExisting) { List<string> missingRelations = null; XmlReader osmFileXmlReader = null; XmlSerializer relationSerializer = null; try { missingRelations = new List<string>(); if (osmLineFeatureClass == null) { throw new ArgumentNullException("osmLineFeatureClass"); } if (osmPolygonFeatureClass == null) { throw new ArgumentNullException("osmPolygonFeatureClass"); } if (relationTable == null) { throw new ArgumentNullException("relationTable"); } int osmPointIDFieldIndex = osmPointFeatureClass.FindField("OSMID"); Dictionary<string, int> osmPointDomainAttributeFieldIndices = new Dictionary<string, int>(); foreach (var domains in availableDomains.domain) { int currentFieldIndex = osmPointFeatureClass.FindField(domains.name); if (currentFieldIndex != -1) { osmPointDomainAttributeFieldIndices.Add(domains.name, currentFieldIndex); } } int tagCollectionPointFieldIndex = osmPointFeatureClass.FindField("osmTags"); int osmUserPointFieldIndex = osmPointFeatureClass.FindField("osmuser"); int osmUIDPointFieldIndex = osmPointFeatureClass.FindField("osmuid"); int osmVisiblePointFieldIndex = osmPointFeatureClass.FindField("osmvisible"); int osmVersionPointFieldIndex = osmPointFeatureClass.FindField("osmversion"); int osmChangesetPointFieldIndex = osmPointFeatureClass.FindField("osmchangeset"); int osmTimeStampPointFieldIndex = osmPointFeatureClass.FindField("osmtimestamp"); int osmMemberOfPointFieldIndex = osmPointFeatureClass.FindField("osmMemberOf"); int osmSupportingElementPointFieldIndex = osmPointFeatureClass.FindField("osmSupportingElement"); int osmWayRefCountFieldIndex = osmPointFeatureClass.FindField("wayRefCount"); int osmLineIDFieldIndex = osmLineFeatureClass.FindField("OSMID"); Dictionary<string, int> osmLineDomainAttributeFieldIndices = new Dictionary<string, int>(); Dictionary<string, int> osmLineDomainAttributeFieldLength = new Dictionary<string, int>(); foreach (var domains in availableDomains.domain) { int currentFieldIndex = osmLineFeatureClass.FindField(domains.name); if (currentFieldIndex != -1) { osmLineDomainAttributeFieldIndices.Add(domains.name, currentFieldIndex); osmLineDomainAttributeFieldLength.Add(domains.name, osmLineFeatureClass.Fields.get_Field(currentFieldIndex).Length); } } int tagCollectionPolylineFieldIndex = osmLineFeatureClass.FindField("osmTags"); int osmUserPolylineFieldIndex = osmLineFeatureClass.FindField("osmuser"); int osmUIDPolylineFieldIndex = osmLineFeatureClass.FindField("osmuid"); int osmVisiblePolylineFieldIndex = osmLineFeatureClass.FindField("osmvisible"); int osmVersionPolylineFieldIndex = osmLineFeatureClass.FindField("osmversion"); int osmChangesetPolylineFieldIndex = osmLineFeatureClass.FindField("osmchangeset"); int osmTimeStampPolylineFieldIndex = osmLineFeatureClass.FindField("osmtimestamp"); int osmMemberOfPolylineFieldIndex = osmLineFeatureClass.FindField("osmMemberOf"); int osmMembersPolylineFieldIndex = osmLineFeatureClass.FindField("osmMembers"); int osmSupportingElementPolylineFieldIndex = osmLineFeatureClass.FindField("osmSupportingElement"); int osmPolygonIDFieldIndex = osmPolygonFeatureClass.FindField("OSMID"); Dictionary<string, int> osmPolygonDomainAttributeFieldIndices = new Dictionary<string, int>(); Dictionary<string, int> osmPolygonDomainAttributeFieldLength = new Dictionary<string, int>(); foreach (var domains in availableDomains.domain) { int currentFieldIndex = osmPolygonFeatureClass.FindField(domains.name); if (currentFieldIndex != -1) { osmPolygonDomainAttributeFieldIndices.Add(domains.name, currentFieldIndex); osmPolygonDomainAttributeFieldLength.Add(domains.name, osmPolygonFeatureClass.Fields.get_Field(currentFieldIndex).Length); } } int tagCollectionPolygonFieldIndex = osmPolygonFeatureClass.FindField("osmTags"); int osmUserPolygonFieldIndex = osmPolygonFeatureClass.FindField("osmuser"); int osmUIDPolygonFieldIndex = osmPolygonFeatureClass.FindField("osmuid"); int osmVisiblePolygonFieldIndex = osmPolygonFeatureClass.FindField("osmvisible"); int osmVersionPolygonFieldIndex = osmPolygonFeatureClass.FindField("osmversion"); int osmChangesetPolygonFieldIndex = osmPolygonFeatureClass.FindField("osmchangeset"); int osmTimeStampPolygonFieldIndex = osmPolygonFeatureClass.FindField("osmtimestamp"); int osmMemberOfPolygonFieldIndex = osmPolygonFeatureClass.FindField("osmMemberOf"); int osmMembersPolygonFieldIndex = osmPolygonFeatureClass.FindField("osmMembers"); int osmSupportingElementPolygonFieldIndex = osmPolygonFeatureClass.FindField("osmSupportingElement"); int osmRelationIDFieldIndex = relationTable.FindField("OSMID"); int tagCollectionRelationFieldIndex = relationTable.FindField("osmTags"); int osmUserRelationFieldIndex = relationTable.FindField("osmuser"); int osmUIDRelationFieldIndex = relationTable.FindField("osmuid"); int osmVisibleRelationFieldIndex = relationTable.FindField("osmvisible"); int osmVersionRelationFieldIndex = relationTable.FindField("osmversion"); int osmChangesetRelationFieldIndex = relationTable.FindField("osmchangeset"); int osmTimeStampRelationFieldIndex = relationTable.FindField("osmtimestamp"); int osmMemberOfRelationFieldIndex = relationTable.FindField("osmMemberOf"); int osmMembersRelationFieldIndex = relationTable.FindField("osmMembers"); int osmSupportingElementRelationFieldIndex = relationTable.FindField("osmSupportingElement"); // list for reference count and relation list for lines/polygons/relations // set up the progress indicator IStepProgressor stepProgressor = TrackCancel as IStepProgressor; if (stepProgressor != null) { stepProgressor.MinRange = 0; stepProgressor.MaxRange = relationCapacity; stepProgressor.Position = 0; stepProgressor.Message = _resourceManager.GetString("GPTools_OSMGPFileReader_loadingRelations"); stepProgressor.StepValue = 1; stepProgressor.Show(); } bool relationIndexRebuildRequired = false; if (relationTable != null) { osmFileXmlReader = System.Xml.XmlReader.Create(osmFileLocation); relationSerializer = new XmlSerializer(typeof(relation)); using (ComReleaser comReleaser = new ComReleaser()) { using (SchemaLockManager linelock = new SchemaLockManager(osmLineFeatureClass as ITable), polygonLock = new SchemaLockManager(osmPolygonFeatureClass as ITable), relationLock = new SchemaLockManager(relationTable)) { ICursor rowCursor = relationTable.Insert(true); comReleaser.ManageLifetime(rowCursor); IRowBuffer rowBuffer = relationTable.CreateRowBuffer(); comReleaser.ManageLifetime(rowBuffer); IFeatureCursor lineFeatureInsertCursor = osmLineFeatureClass.Insert(true); comReleaser.ManageLifetime(lineFeatureInsertCursor); IFeatureBuffer lineFeatureBuffer = osmLineFeatureClass.CreateFeatureBuffer(); comReleaser.ManageLifetime(lineFeatureBuffer); IFeatureCursor polygonFeatureInsertCursor = osmPolygonFeatureClass.Insert(true); comReleaser.ManageLifetime(polygonFeatureInsertCursor); IFeatureBuffer polygonFeatureBuffer = osmPolygonFeatureClass.CreateFeatureBuffer(); comReleaser.ManageLifetime(polygonFeatureBuffer); int relationCount = 1; int relationDebugCount = 1; string lineSQLIdentifier = osmLineFeatureClass.SqlIdentifier("OSMID"); string polygonSQLIdentifier = osmPolygonFeatureClass.SqlIdentifier("OSMID"); message.AddMessage(_resourceManager.GetString("GPTools_OSMGPFileReader_resolvegeometries")); osmFileXmlReader.MoveToContent(); while (osmFileXmlReader.Read()) { if (osmFileXmlReader.IsStartElement()) { if (osmFileXmlReader.Name == "relation") { relation currentRelation = null; try { // read the full relation node string currentrelationString = osmFileXmlReader.ReadOuterXml(); using (StringReader relationReader = new System.IO.StringReader(currentrelationString)) { // de-serialize the xml into to the class instance currentRelation = relationSerializer.Deserialize(relationReader) as relation; } if (currentRelation == null) continue; relationDebugCount = relationDebugCount + 1; esriGeometryType detectedGeometryType = determineRelationGeometryType(osmLineFeatureClass, osmPolygonFeatureClass, relationTable, currentRelation); if (checkForExisting) { switch (detectedGeometryType) { case esriGeometryType.esriGeometryAny: if (CheckIfExists(relationTable, currentRelation.id)) continue; break; case esriGeometryType.esriGeometryBag: if (CheckIfExists(relationTable, currentRelation.id)) continue; break; case esriGeometryType.esriGeometryBezier3Curve: break; case esriGeometryType.esriGeometryCircularArc: break; case esriGeometryType.esriGeometryEllipticArc: break; case esriGeometryType.esriGeometryEnvelope: break; case esriGeometryType.esriGeometryLine: if (CheckIfExists(osmLineFeatureClass as ITable, currentRelation.id)) continue; break; case esriGeometryType.esriGeometryMultiPatch: break; case esriGeometryType.esriGeometryMultipoint: break; case esriGeometryType.esriGeometryNull: if (CheckIfExists(relationTable, currentRelation.id)) continue; break; case esriGeometryType.esriGeometryPath: break; case esriGeometryType.esriGeometryPoint: break; case esriGeometryType.esriGeometryPolygon: if (CheckIfExists(osmPolygonFeatureClass as ITable, currentRelation.id)) continue; break; case esriGeometryType.esriGeometryPolyline: if (CheckIfExists(osmLineFeatureClass as ITable, currentRelation.id)) continue; break; case esriGeometryType.esriGeometryRay: break; case esriGeometryType.esriGeometryRing: break; case esriGeometryType.esriGeometrySphere: break; case esriGeometryType.esriGeometryTriangleFan: break; case esriGeometryType.esriGeometryTriangleStrip: break; case esriGeometryType.esriGeometryTriangles: break; default: break; } } List<tag> relationTagList = new List<tag>(); List<member> relationMemberList = new List<member>(); Dictionary<string, string> wayList = new Dictionary<string, string>(); // sanity check that the overall relation notation contains at least something if (currentRelation.Items == null) continue; List<OSMNodeFeature> osmPointList = null; List<OSMLineFeature> osmLineList = null; List<OSMPolygonFeature> osmPolygonList = null; List<OSMRelation> osmRelationList = null; rowBuffer = relationTable.CreateRowBuffer(); comReleaser.ManageLifetime(rowBuffer); lineFeatureBuffer = osmLineFeatureClass.CreateFeatureBuffer(); comReleaser.ManageLifetime(lineFeatureBuffer); polygonFeatureBuffer = osmPolygonFeatureClass.CreateFeatureBuffer(); comReleaser.ManageLifetime(polygonFeatureBuffer); foreach (var item in currentRelation.Items) { if (item is member) { member memberItem = item as member; relationMemberList.Add(memberItem); switch (memberItem.type) { case memberType.way: if (!wayList.ContainsKey(memberItem.@ref)) wayList.Add(memberItem.@ref, memberItem.role); if (IsThisWayALine(memberItem.@ref, osmLineFeatureClass, lineSQLIdentifier, osmPolygonFeatureClass, polygonSQLIdentifier)) { if (osmLineList == null) { osmLineList = new List<OSMLineFeature>(); } OSMLineFeature lineFeature = new OSMLineFeature(); lineFeature.relationList = new List<string>(); lineFeature.lineID = memberItem.@ref; if (detectedGeometryType == esriGeometryType.esriGeometryPolygon) { lineFeature.relationList.Add(currentRelation.id + "_ply"); } else if (detectedGeometryType == esriGeometryType.esriGeometryPolyline) { lineFeature.relationList.Add(currentRelation.id + "_ln"); } else { lineFeature.relationList.Add(currentRelation.id + "_rel"); } osmLineList.Add(lineFeature); } else { if (osmPolygonList == null) { osmPolygonList = new List<OSMPolygonFeature>(); } OSMPolygonFeature polygonFeature = new OSMPolygonFeature(); polygonFeature.relationList = new List<string>(); polygonFeature.polygonID = memberItem.@ref; if (detectedGeometryType == esriGeometryType.esriGeometryPolygon) { polygonFeature.relationList.Add(currentRelation.id + "_ply"); } else if (detectedGeometryType == esriGeometryType.esriGeometryPolyline) { polygonFeature.relationList.Add(currentRelation.id + "_ln"); } else { polygonFeature.relationList.Add(currentRelation.id + "_rel"); } osmPolygonList.Add(polygonFeature); } break; case memberType.node: if (osmPointList == null) { osmPointList = new List<OSMNodeFeature>(); } OSMNodeFeature nodeFeature = new OSMNodeFeature(); nodeFeature.relationList = new List<string>(); nodeFeature.nodeID = memberItem.@ref; nodeFeature.relationList.Add(currentRelation.id + "_rel"); osmPointList.Add(nodeFeature); break; case memberType.relation: if (osmRelationList == null) { osmRelationList = new List<OSMRelation>(); } OSMRelation relation = new OSMRelation(); relation.relationList = new List<string>(); relation.relationID = memberItem.@ref; relation.relationList.Add(currentRelation.id + "_rel"); break; default: break; } } else if (item is tag) { relationTagList.Add((tag)item); } } // if there is a defined geometry type use it to generate a multipart geometry if (detectedGeometryType == esriGeometryType.esriGeometryPolygon) { #region create multipart polygon geometry //IFeature mpFeature = osmPolygonFeatureClass.CreateFeature(); IPolygon relationMPPolygon = new PolygonClass(); relationMPPolygon.SpatialReference = ((IGeoDataset)osmPolygonFeatureClass).SpatialReference; ISegmentCollection relationPolygonGeometryCollection = relationMPPolygon as ISegmentCollection; IQueryFilter osmIDQueryFilter = new QueryFilterClass(); string sqlPolyOSMID = osmPolygonFeatureClass.SqlIdentifier("OSMID"); object missing = Type.Missing; bool relationComplete = true; // loop through the list of referenced ways that are listed in a relation // for each of the items we need to make a decision if they have merit to qualify as stand-alone features // due to the presence of meaningful attributes (tags) foreach (KeyValuePair<string, string> wayKey in wayList) { if (relationComplete == false) break; if (TrackCancel.Continue() == false) { return missingRelations; } osmIDQueryFilter.WhereClause = sqlPolyOSMID + " = '" + wayKey.Key + "'"; System.Diagnostics.Debug.WriteLine("Relation (Polygon) #: " + relationDebugCount + " :___: " + currentRelation.id + " :___: " + wayKey.Key); using (ComReleaser relationComReleaser = new ComReleaser()) { IFeatureCursor featureCursor = osmPolygonFeatureClass.Search(osmIDQueryFilter, false); relationComReleaser.ManageLifetime(featureCursor); IFeature partFeature = featureCursor.NextFeature(); // set the appropriate field attribute to become invisible as a standalone features if (partFeature != null) { IGeometryCollection ringCollection = partFeature.Shape as IGeometryCollection; // test for available content in the geometry collection if (ringCollection.GeometryCount > 0) { // test if we dealing with a valid geometry if (ringCollection.get_Geometry(0).IsEmpty == false) { // add it to the new geometry and mark the added geometry as a supporting element relationPolygonGeometryCollection.AddSegmentCollection((ISegmentCollection)ringCollection.get_Geometry(0)); if (osmSupportingElementPolygonFieldIndex > -1) { // if the member of a relation has the role of "inner" and it has tags, then let's keep it // as a standalone feature as well // the geometry is then a hole in the relation but due to the tags it also has merits to be // considered a stand-alone feature if (wayKey.Value.ToLower().Equals("inner")) { if (!_osmUtility.DoesHaveKeys(partFeature, tagCollectionPolygonFieldIndex, null)) { partFeature.set_Value(osmSupportingElementPolygonFieldIndex, "yes"); } } else { // relation member without an explicit role or the role of "outer" are turned into // supporting features if they don't have relevant attribute if (!_osmUtility.DoesHaveKeys(partFeature, tagCollectionPolylineFieldIndex, null)) { partFeature.set_Value(osmSupportingElementPolygonFieldIndex, "yes"); } } } partFeature.Store(); } } } else { // it still can be a line geometry that will be pieced together into a polygon IFeatureCursor lineFeatureCursor = osmLineFeatureClass.Search(osmIDQueryFilter, false); relationComReleaser.ManageLifetime(lineFeatureCursor); partFeature = lineFeatureCursor.NextFeature(); if (partFeature != null) { IGeometryCollection ringCollection = partFeature.Shape as IGeometryCollection; // test for available content in the geometry collection if (ringCollection.GeometryCount > 0) { // test if we dealing with a valid geometry if (ringCollection.get_Geometry(0).IsEmpty == false) { // add it to the new geometry and mark the added geometry as a supporting element relationPolygonGeometryCollection.AddSegmentCollection((ISegmentCollection)ringCollection.get_Geometry(0)); if (osmSupportingElementPolylineFieldIndex > -1) { // if the member of a relation has the role of "inner" and it has tags, then let's keep it // as a standalone feature as well // the geometry is then a hole in the relation but due to the tags it also has merits to be // considered a stand-alone feature if (wayKey.Value.ToLower().Equals("inner")) { if (!_osmUtility.DoesHaveKeys(partFeature, tagCollectionPolylineFieldIndex, null)) { partFeature.set_Value(osmSupportingElementPolylineFieldIndex, "yes"); } } else { // relation member without an explicit role or the role of "outer" are turned into // supporting features if they don't have relevant attribute if (!_osmUtility.DoesHaveKeys(partFeature, tagCollectionPolylineFieldIndex, null)) { partFeature.set_Value(osmSupportingElementPolylineFieldIndex, "yes"); } } } partFeature.Store(); } } } else { relationComplete = false; continue; } } } } // mark the relation as incomplete if (relationComplete == false) { missingRelations.Add(currentRelation.id); continue; } // transform the added collections for geometries into a topological correct geometry representation ((IPolygon4)relationMPPolygon).SimplifyEx(true, false, true); polygonFeatureBuffer.Shape = relationMPPolygon; if (_osmUtility.DoesHaveKeys(currentRelation)) { } else { relationTagList = MergeTagsFromOuterPolygonToRelation(currentRelation, osmPolygonFeatureClass); } insertTags(osmPolygonDomainAttributeFieldIndices, osmPolygonDomainAttributeFieldLength, tagCollectionPolygonFieldIndex, polygonFeatureBuffer, relationTagList.ToArray()); if (fastLoad == false) { if (osmMembersPolygonFieldIndex > -1) { _osmUtility.insertMembers(osmMembersPolygonFieldIndex, (IFeature)polygonFeatureBuffer, relationMemberList.ToArray()); } // store the administrative attributes // user, uid, version, changeset, timestamp, visible if (osmUserPolygonFieldIndex != -1) { if (!String.IsNullOrEmpty(currentRelation.user)) { polygonFeatureBuffer.set_Value(osmUserPolygonFieldIndex, currentRelation.user); } } if (osmUIDPolygonFieldIndex != -1) { if (!String.IsNullOrEmpty(currentRelation.uid)) { polygonFeatureBuffer.set_Value(osmUIDPolygonFieldIndex, Convert.ToInt32(currentRelation.uid)); } } if (osmVisiblePolygonFieldIndex != -1) { if (String.IsNullOrEmpty(currentRelation.visible) == false) { polygonFeatureBuffer.set_Value(osmVisiblePolygonFieldIndex, currentRelation.visible.ToString()); } else { polygonFeatureBuffer.set_Value(osmVisiblePolygonFieldIndex, "unknown"); } } if (osmVersionPolygonFieldIndex != -1) { if (!String.IsNullOrEmpty(currentRelation.version)) { polygonFeatureBuffer.set_Value(osmVersionPolygonFieldIndex, Convert.ToInt32(currentRelation.version)); } } if (osmChangesetPolygonFieldIndex != -1) { if (!String.IsNullOrEmpty(currentRelation.changeset)) { polygonFeatureBuffer.set_Value(osmChangesetPolygonFieldIndex, Convert.ToInt32(currentRelation.changeset)); } } if (osmTimeStampPolygonFieldIndex != -1) { if (!String.IsNullOrEmpty(currentRelation.timestamp)) { polygonFeatureBuffer.set_Value(osmTimeStampPolygonFieldIndex, Convert.ToDateTime(currentRelation.timestamp)); } } if (osmPolygonIDFieldIndex != -1) { polygonFeatureBuffer.set_Value(osmPolygonIDFieldIndex, currentRelation.id); } if (osmSupportingElementPolygonFieldIndex > -1) { polygonFeatureBuffer.set_Value(osmSupportingElementPolygonFieldIndex, "no"); } } try { //mpFeature.Store(); polygonFeatureInsertCursor.InsertFeature(polygonFeatureBuffer); } catch (Exception ex) { message.AddWarning(ex.Message); } #endregion } else if (detectedGeometryType == esriGeometryType.esriGeometryPolyline) { #region create multipart polyline geometry //IFeature mpFeature = osmLineFeatureClass.CreateFeature(); IPolyline relationMPPolyline = new PolylineClass(); relationMPPolyline.SpatialReference = ((IGeoDataset)osmLineFeatureClass).SpatialReference; IGeometryCollection relationPolylineGeometryCollection = relationMPPolyline as IGeometryCollection; IQueryFilter osmIDQueryFilter = new QueryFilterClass(); object missing = Type.Missing; // loop through the foreach (KeyValuePair<string, string> wayKey in wayList) { if (TrackCancel.Continue() == false) { return missingRelations; } osmIDQueryFilter.WhereClause = osmLineFeatureClass.WhereClauseByExtensionVersion(wayKey.Key, "OSMID", 2); System.Diagnostics.Debug.WriteLine("Relation (Polyline) #: " + relationDebugCount + " :___: " + currentRelation.id + " :___: " + wayKey); using (ComReleaser relationComReleaser = new ComReleaser()) { IFeatureCursor featureCursor = osmLineFeatureClass.Search(osmIDQueryFilter, false); relationComReleaser.ManageLifetime(featureCursor); IFeature partFeature = featureCursor.NextFeature(); // set the appropriate field attribute to become invisible as a standalone features if (partFeature != null) { if (partFeature.Shape.IsEmpty == false) { IGeometryCollection pathCollection = partFeature.Shape as IGeometryCollection; relationPolylineGeometryCollection.AddGeometry(pathCollection.get_Geometry(0), ref missing, ref missing); if (osmSupportingElementPolylineFieldIndex > -1) { if (!_osmUtility.DoesHaveKeys(partFeature, tagCollectionPolylineFieldIndex, null)) { partFeature.set_Value(osmSupportingElementPolylineFieldIndex, "yes"); } } partFeature.Store(); } } } } lineFeatureBuffer.Shape = relationMPPolyline; insertTags(osmLineDomainAttributeFieldIndices, osmLineDomainAttributeFieldLength, tagCollectionPolylineFieldIndex, lineFeatureBuffer, relationTagList.ToArray()); if (fastLoad == false) { if (osmMembersPolylineFieldIndex > -1) { _osmUtility.insertMembers(osmMembersPolylineFieldIndex, (IFeature)lineFeatureBuffer, relationMemberList.ToArray()); } // store the administrative attributes // user, uid, version, changeset, timestamp, visible if (osmUserPolylineFieldIndex != -1) { if (!String.IsNullOrEmpty(currentRelation.user)) { lineFeatureBuffer.set_Value(osmUserPolylineFieldIndex, currentRelation.user); } } if (osmUIDPolylineFieldIndex != -1) { if (!String.IsNullOrEmpty(currentRelation.uid)) { lineFeatureBuffer.set_Value(osmUIDPolylineFieldIndex, Convert.ToInt32(currentRelation.uid)); } } if (osmVisiblePolylineFieldIndex != -1) { if (String.IsNullOrEmpty(currentRelation.visible) == false) { lineFeatureBuffer.set_Value(osmVisiblePolylineFieldIndex, currentRelation.visible.ToString()); } else { lineFeatureBuffer.set_Value(osmVisiblePolylineFieldIndex, "unknown"); } } if (osmVersionPolylineFieldIndex != -1) { if (!String.IsNullOrEmpty(currentRelation.version)) { lineFeatureBuffer.set_Value(osmVersionPolylineFieldIndex, Convert.ToInt32(currentRelation.version)); } } if (osmChangesetPolylineFieldIndex != -1) { if (!String.IsNullOrEmpty(currentRelation.changeset)) { lineFeatureBuffer.set_Value(osmChangesetPolylineFieldIndex, Convert.ToInt32(currentRelation.changeset)); } } if (osmTimeStampPolylineFieldIndex != -1) { if (!String.IsNullOrEmpty(currentRelation.timestamp)) { lineFeatureBuffer.set_Value(osmTimeStampPolylineFieldIndex, Convert.ToDateTime(currentRelation.timestamp)); } } if (osmLineIDFieldIndex != -1) { lineFeatureBuffer.set_Value(osmLineIDFieldIndex, currentRelation.id); } if (osmSupportingElementPolylineFieldIndex > -1) { lineFeatureBuffer.set_Value(osmSupportingElementPolylineFieldIndex, "no"); } } try { lineFeatureInsertCursor.InsertFeature(lineFeatureBuffer); } catch (Exception ex) { message.AddWarning(ex.Message); } #endregion } else if (detectedGeometryType == esriGeometryType.esriGeometryPoint) { System.Diagnostics.Debug.WriteLine("Relation #: " + relationDebugCount + " :____: POINT!!!"); if (TrackCancel.Continue() == false) { return missingRelations; } } else // otherwise it is relation that needs to be dealt with separately { if (TrackCancel.Continue() == false) { return missingRelations; } System.Diagnostics.Debug.WriteLine("Relation #: " + relationDebugCount + " :____: Kept as relation"); if (tagCollectionRelationFieldIndex != -1) { _osmUtility.insertOSMTags(tagCollectionRelationFieldIndex, rowBuffer, relationTagList.ToArray()); } if (fastLoad == false) { if (osmMembersRelationFieldIndex != -1) { _osmUtility.insertMembers(osmMembersRelationFieldIndex, rowBuffer, relationMemberList.ToArray()); } // store the administrative attributes // user, uid, version, changeset, timestamp, visible if (osmUserRelationFieldIndex != -1) { if (!String.IsNullOrEmpty(currentRelation.user)) { rowBuffer.set_Value(osmUserRelationFieldIndex, currentRelation.user); } } if (osmUIDRelationFieldIndex != -1) { if (!String.IsNullOrEmpty(currentRelation.uid)) { rowBuffer.set_Value(osmUIDRelationFieldIndex, Convert.ToInt64(currentRelation.uid)); } } if (osmVisibleRelationFieldIndex != -1) { if (currentRelation.visible != null) { rowBuffer.set_Value(osmVisibleRelationFieldIndex, currentRelation.visible.ToString()); } } if (osmVersionRelationFieldIndex != -1) { if (!String.IsNullOrEmpty(currentRelation.version)) { rowBuffer.set_Value(osmVersionRelationFieldIndex, Convert.ToInt32(currentRelation.version)); } } if (osmChangesetRelationFieldIndex != -1) { if (!String.IsNullOrEmpty(currentRelation.changeset)) { rowBuffer.set_Value(osmChangesetRelationFieldIndex, Convert.ToInt32(currentRelation.changeset)); } } if (osmTimeStampRelationFieldIndex != -1) { if (!String.IsNullOrEmpty(currentRelation.timestamp)) { try { rowBuffer.set_Value(osmTimeStampRelationFieldIndex, Convert.ToDateTime(currentRelation.timestamp)); } catch (Exception ex) { message.AddWarning(String.Format(_resourceManager.GetString("GPTools_OSMGPFileReader_invalidTimeFormat"), ex.Message)); } } } if (osmRelationIDFieldIndex != -1) { rowBuffer.set_Value(osmRelationIDFieldIndex, currentRelation.id); } } try { rowCursor.InsertRow(rowBuffer); relationCount = relationCount + 1; relationIndexRebuildRequired = true; } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); } // check for user interruption if (TrackCancel.Continue() == false) { return missingRelations; } } // update the isMemberOf fields of the attached features if (osmPointList != null) { foreach (OSMNodeFeature nodeFeature in osmPointList) { updateIsMemberOf(osmLineFeatureClass, osmMemberOfPolylineFieldIndex, nodeFeature.nodeID, nodeFeature.relationList); } } if (osmLineList != null) { foreach (OSMLineFeature lineFeature in osmLineList) { updateIsMemberOf(osmLineFeatureClass, osmMemberOfPolylineFieldIndex, lineFeature.lineID, lineFeature.relationList); } } if (osmPolygonList != null) { foreach (OSMPolygonFeature polygonFeature in osmPolygonList) { updateIsMemberOf(osmLineFeatureClass, osmMemberOfPolylineFieldIndex, polygonFeature.polygonID, polygonFeature.relationList); } } if (stepProgressor != null) { stepProgressor.Position = relationCount; } if ((relationCount % 50000) == 0) { message.AddMessage(String.Format(_resourceManager.GetString("GPTools_OSMGPFileReader_relationsloaded"), relationCount)); } } catch (Exception ex) { message.AddWarning(ex.Message); } finally { if (rowBuffer != null) { Marshal.ReleaseComObject(rowBuffer); if (rowBuffer != null) rowBuffer = null; } if (lineFeatureBuffer != null) { Marshal.ReleaseComObject(lineFeatureBuffer); if (lineFeatureBuffer != null) lineFeatureBuffer = null; } if (polygonFeatureBuffer != null) { Marshal.ReleaseComObject(polygonFeatureBuffer); if (polygonFeatureBuffer != null) polygonFeatureBuffer = null; } currentRelation = null; } } } } // close the OSM file osmFileXmlReader.Close(); // flush any remaining entities from the cursor rowCursor.Flush(); polygonFeatureInsertCursor.Flush(); lineFeatureInsertCursor.Flush(); // force a garbage collection System.GC.Collect(); // let the user know that we are done dealing with the relations message.AddMessage(String.Format(_resourceManager.GetString("GPTools_OSMGPFileReader_relationsloaded"), relationCount)); } } if (stepProgressor != null) { stepProgressor.Hide(); } // Addd index for osmid column as well IGeoProcessor2 geoProcessor = new GeoProcessorClass(); bool storedOriginalLocal = geoProcessor.AddOutputsToMap; IGPUtilities3 gpUtilities3 = new GPUtilitiesClass(); try { geoProcessor.AddOutputsToMap = false; if (relationIndexRebuildRequired) { IIndexes tableIndexes = relationTable.Indexes; int indexPosition = -1; tableIndexes.FindIndex("osmID_IDX", out indexPosition); if (indexPosition == -1) { IGPValue relationTableGPValue = gpUtilities3.MakeGPValueFromObject(relationTable); string sddd = targetGPValue.GetAsText(); string tableLocation = GetLocationString(targetGPValue, relationTable); IVariantArray parameterArrary = CreateAddIndexParameterArray(tableLocation, "OSMID", "osmID_IDX", "UNIQUE", ""); IGeoProcessorResult2 gpResults2 = geoProcessor.Execute("AddIndex_management", parameterArrary, TrackCancel) as IGeoProcessorResult2; } } } catch (Exception ex) { message.AddWarning(ex.Message); } finally { geoProcessor.AddOutputsToMap = storedOriginalLocal; Marshal.FinalReleaseComObject(gpUtilities3); Marshal.FinalReleaseComObject(geoProcessor); } } } catch (Exception ex) { } finally { if (relationSerializer != null) relationSerializer = null; if (osmFileXmlReader != null) osmFileXmlReader = null; System.GC.Collect(); System.GC.WaitForPendingFinalizers(); } return missingRelations; }
private void WriteRelation(OSMRelation relation, out byte[] writtenData) { if (!this._relationsStarted) { this.Reset(); this._stream.WriteByte((byte)O5MFileByteMarker.Reset); this._relationsStarted = true; } this._stream.WriteByte((byte)O5MFileByteMarker.Relation); var bytes = new List <byte>(); var diffId = (long)relation.Id - this._lastRelationId; var idBytes = VarintBitConverter.GetVarintBytes(diffId); bytes.AddRange(idBytes); this._lastRelationId = (long)relation.Id; this.WriteVersionData(relation, bytes); if (relation.Members.Count == 0) { bytes.Add(0x00); } else { var membersBytes = new List <byte>(); foreach (var member in relation.Members) { var nextReferenceDiff = (long)member.Ref - this._lastReferenceId; var memberRefBytes = VarintBitConverter.GetVarintBytes(nextReferenceDiff); this._lastReferenceId = (long)member.Ref; membersBytes.AddRange(memberRefBytes); var typeBytes = new byte[] { (byte)((int)member.Type + 0x30) }; var roleBytes = Encoding.UTF8.GetBytes(member.Role); var position = this._storedStringPairs.GetElementPosition(typeBytes, roleBytes); if (position == -1) { membersBytes.Add(0x00); membersBytes.AddRange(typeBytes); membersBytes.AddRange(roleBytes); membersBytes.Add(0x00); if (1 + roleBytes.Length <= 250) { var typeAndRole = new KeyValuePair <byte[], byte[]>(typeBytes, roleBytes); this._storedStringPairs.Insert(0, typeAndRole); } } else { var positionBytes = VarintBitConverter.GetVarintBytes((uint)position); membersBytes.AddRange(positionBytes); } } var membersBytesCountBytes = VarintBitConverter.GetVarintBytes((ulong)membersBytes.Count); bytes.AddRange(membersBytesCountBytes); bytes.AddRange(membersBytes); } this.WriteTags(relation, bytes); var length = VarintBitConverter.GetVarintBytes((ulong)bytes.Count); this._stream.Write(length, 0, length.Length); writtenData = bytes.ToArray(); this._stream.Write(writtenData, 0, bytes.Count); }