示例#1
0
    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");
    }
示例#2
0
 /// <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);
     }
 }
示例#3
0
 /// <summary>
 /// On relation found.
 /// </summary>
 /// <param name="relation">Relation.</param>
 protected void OnRelationFound(OSMRelation relation)
 {
     if (this.FoundRelation != null)
     {
         this.FoundRelation(relation);
     }
 }
示例#4
0
        /// <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);
            }
        }
示例#5
0
 public void AddRelation(OSMRelation relation)
 {
     if (relation != null)
     {
         if (!relations.Keys.Contains(relation.Id))
         {
             relations.Add(relation.Id, relation);
         }
     }
 }
示例#6
0
    //<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);
    }
示例#7
0
 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;
 }
示例#8
0
        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();
        }
示例#9
0
    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);
    }
示例#10
0
        /// <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();
        }
示例#11
0
    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"));
    }
示例#12
0
    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);
    }
示例#13
0
        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);
        }
示例#14
0
    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);
    }
示例#15
0
 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;
 }
示例#16
0
    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");
    }
示例#17
0
 private void WriteRelation(OSMRelation relation)
 {
     byte[] writtenData = null;
     this.WriteRelation(relation, out writtenData);
 }
示例#18
0
        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;
        }
示例#19
0
        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);
        }