All pastes #2077210 Raw Edit

DataStorage

public text v1 · immutable
#2077210 ·published 2011-06-09 09:00 UTC
rendered paste body
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using ISM4IaRouteplanner.Parser;
using ISM4IaRouteplanner.Algoritmes;
using ISM4IaRouteplanner.GFX;

namespace ISM4IaRouteplanner.Data
{
    public static class DataStorage
    {
        #region Attributes of DataStorage
        /// <summary>
        /// Dictionary of sections called cities
        /// </summary>
        public static Dictionary<string, Section> Cities { get; set; }

        /// <summary>
        /// Temporary dictionary of edges for use in linking
        /// </summary>
        private static Dictionary<string, Edge> tmpEdges;

        /// <summary>
        /// Temporary dictionary of nodes for use in linking
        /// </summary>
        private static Dictionary<string, Node> tmpNodes;

        /// <summary>
        /// Temporary dictionary for the centrum points
        /// </summary>
        private static Dictionary<string, Node> tmpCentrum;

        /// <summary>
        /// List with all areas which can be used for drawing areas
        /// </summary>
        public static List<Area> listArea = new List<Area>();

        /// <summary>
        /// List of Points of Interest
        /// </summary>
        public static List<POI> listPetrolStation = new List<POI>();
        public static List<POI> listParkingGarage = new List<POI>();
        public static List<POI> listHotel = new List<POI>();
        public static List<POI> listRestaurant = new List<POI>();
        public static List<POI> listTouristInformationOffice = new List<POI>();
        public static List<POI> listMuseum = new List<POI>();
        public static List<POI> listTheatre = new List<POI>();
        public static List<POI> listHospital = new List<POI>();
        public static List<POI> listPoliceStation = new List<POI>();
        public static List<POI> listPostOffice = new List<POI>();
        public static List<POI> listZoo = new List<POI>();
        public static List<POI> listPanoramicView = new List<POI>();
        public static List<POI> listCampingGround = new List<POI>();
        public static List<POI> listSchool = new List<POI>();
        public static List<POI> listImportantTouristAttraction = new List<POI>();
        public static List<POI> listRailwayStation = new List<POI>();

        #endregion

        #region Methods of Location

        /// <summary>
        /// Navigate from 1 location to another with the shortest path available.
        /// 
        /// Leon Koppel 17-05-11
        /// </summary>
        public static Route Navigate(List<Location> locations, Options options)
        {
            List<Node> nodes = new List<Node>(locations.Count);
            List <Edge> tmpEdges = new List<Edge>();
            //Convert all the locations to nodes
            foreach (Location l in locations)
            {
                nodes.Add(GetNode(l));
            }

            Route route = AStarAlgorithm.CalculateRoute(nodes, options);

            //TODO give route to the drawing group
            GlControl.DrawRoute(route);
            return route;
        }



        private static Boolean UntangleBrunnel(RelationshipRecord relation)
        {
            // So at this point, theres a relationship defining a brunnel (basically a shared node between lines
            // We don't want this, because our model requires each node to be part of ONE node, not two

            // So lets find all the edges in the two line features, and the node they have in common

            if (relation.RelationshipCatagories.Count != 3)
            {
                return false; // Won't fit the profile
            }


            List<Edge> lineOne = null;
            List<Edge> lineTwo = null;

            Node commonNode = null;
            foreach (RelationshipCat RC in relation.RelationshipCatagories)
            {
                
                if (RC.CatId == 3)
                {
                    // False alarm, just a bridge over water (phew!)

                    return false; // LEAVE BRITNEY ALONE
                }
                if (RC.CatId == 2)
                {
                    // We got ourselves a line feature!
                    LineFeatureRecord lfr = ParsedData.LineFeatures[RC.SectionID + RC.FeatureId.ToString()];
                    List<LineFeatureEdge> lfeList = lfr.RoadParticles;
                    List<Edge> edges = new List<Edge>();
                    foreach (LineFeatureEdge lfe in lfeList)
                    {
                        if (lfr.FeatCode == 4210)
                        {
                            // False alarm, just a railway under/over a road

                            return false; // LEAVE BRITNEY ALONE
                        }
                        edges.Add(tmpEdges[lfr.SectionId + lfe.EdgeId.ToString()]);
                    }
                    if (lineOne == null)
                    {
                        lineOne = edges;
                    }
                    else if (lineTwo == null)
                    {
                        lineTwo = edges;
                    }
                    else
                    {
                        return false; // Can't be right!
                    }
                }
                else if (RC.CatId == 1)
                {
                    PointFeatureRecord lfr = ParsedData.PointFeatures[RC.SectionID + RC.FeatureId.ToString()];
                    if (lfr.FeatCode == 7500)
                    {
                        commonNode = tmpNodes[lfr.SectionId + lfr.NodesId[0].ToString()];
                    }
                    else
                    {
                        return false; // This isnt a brunnel between two roads
                    }
                }
                if (commonNode != null && lineOne != null && lineTwo != null)
                {
                    break; // This can't be right.. (Yay for defensive programming!)
                }
            }

            // right now, i should have all the variables i need to untangle them.
            if (commonNode != null && lineOne != null && lineTwo != null)
            {
                // So in this case, we've found ourself the only situation that doesn't naturally work with our model.
                // This needs untanglement!
                Node duplicateNode = commonNode;
                duplicateNode.ID = -commonNode.ID;
                // Lets keep the commonNode for lineOne, but delete all edges that are in lineTwo
                foreach (Edge e in lineTwo)
                {
                    commonNode.Edges.Remove(e);
                    // We also need to replace the commonNode in the Edges in lineTwo with the duplicate
                    
                    if(e.FromNode.ID == commonNode.ID)
                    {
                        e.FromNode = duplicateNode;
                    }
                    else if (e.ToNode.ID == commonNode.ID)
                    {
                        e.ToNode = duplicateNode;
                    }
                }
                // Remove the references between lineOne and the duplicateNode's edges
                foreach (Edge e in lineOne)
                {
                    duplicateNode.Edges.Remove(e);
                }

                // Now we need to insert the duplicate node next to its commonNode brother

                foreach (Edge e in duplicateNode.Edges)
                {
                    Cities[duplicateNode.PlaceName].Streets[e.RoadName].Add(e);
                }

                // AAAND that tackles THAT!
                return true; // Succesfully untangled

            }
            return false; // Not untangled anything.
        }

        private static Boolean UntangleBrunnelJunctions(RelationshipRecord relation)
        {
            if (relation.RelationshipCatagories.Count != 3)
            {
                return false; // Won't fit the profile
            }

            PointFeatureRecord junctionOne = null;
            PointFeatureRecord junctionTwo = null;
            PointFeatureRecord brunnel = null;
            foreach (RelationshipCat RC in relation.RelationshipCatagories)
            {
                if (RC.CatId == 1)
                {
                    PointFeatureRecord pfr = ParsedData.PointFeatures[RC.SectionID + RC.FeatureId.ToString()];
                    if (pfr.FeatCode == 7500)
                    {
                        brunnel = pfr;
                    }
                    else if (pfr.FeatCode == 4120)
                    {
                        if (junctionOne == null)
                        {
                            junctionOne = pfr;
                        }
                        else
                        {
                            junctionTwo = pfr;
                        }
                    }
                }
                else
                {
                    return false; // invalid for our cause
                }
            }

            if (junctionOne != null && junctionTwo != null && brunnel != null)
            {
                // So here we have it. The two junctions and the brunnel that binds them all

                String streetOne = null;
                String streetTwo = null;
                Node originalNode = tmpNodes[junctionOne.SectionId + junctionOne.NodesId[0].ToString()];
                foreach (Edge e in originalNode.Edges)
                {
                    if (streetOne == null)
                    {
                        streetOne = e.RoadName;
                    }
                    else if (streetTwo == null)
                    {
                        streetTwo = e.RoadName;
                    }
                    else
                    {
                        break; //Two streets found
                    }
                }

                Node duplicateNode = new Node()
                {
                    Edges = new List<Edge>(originalNode.Edges),
                    ID = -originalNode.ID,
                    PlaceName = originalNode.PlaceName,
                    Position = originalNode.Position,
                    SectionID = originalNode.SectionID,
                    Type = originalNode.Type
                };


                // The following process makes sure that the originalNode and DuplicateNode no longer share edges
                foreach (Edge e in originalNode.Edges)
                {
                    if (e.RoadName == streetOne)
                    {
                        duplicateNode.Edges.Remove(e);
                    }
                }

                


                foreach (Edge e in duplicateNode.Edges)
                {
                    if (e.RoadName == streetTwo)
                    {
                        originalNode.Edges.Remove(e);
                    }

                    if (e.FromNode == originalNode)
                    {
                        e.FromNode = duplicateNode;
                    }
                    else if (e.ToNode == originalNode)
                    {
                        e.ToNode = duplicateNode;
                    }

                    if(originalNode.PlaceName.Equals(String.Empty)){
                    foreach(Section s in Cities.Values)
                    {
                        if(e.Postcode.Count != 0)
                        {
                            if (e.RoadName == null)
                            {
                                e.RoadName = "Onbekende weg";
                            }
                            if (s.Streets.ContainsKey(e.RoadName))
                            {
                                s.Streets[e.RoadName].Add(e); // Oh, lets add it to the correct cities while we're loopin' it anyway
                                break;
                            }
                            else
                            {
                                List<Edge> tmp = new List<Edge>();
                                tmp.Add(e);
                                s.Streets.Add(e.RoadName, tmp);
                                break;
                            }

                        }
                    }
                    }
                    else{
                        if (e.RoadName == null)
                        {
                            e.RoadName = "Onbekende weg";
                        }
                        if (Cities[originalNode.PlaceName].Streets.ContainsKey(e.RoadName))
                        {
                            Cities[originalNode.PlaceName].Streets[e.RoadName].Add(e);
                        }
                        else
                        {
                            List<Edge> x = new List<Edge>();
                            x.Add(e);
                            Cities[originalNode.PlaceName].Streets.Add(e.RoadName, x);
                        }
                    }
                }
                return true;

            }
            return false;
        }
   

        public static void ParseRelationships()
        {
            List<RelationshipRecord> postProcessing = new List<RelationshipRecord>();
            foreach (RelationshipRecord relation in ParsedData.Relationships.Values)
            {
                if (relation.RelCode == 2200 || relation.RelCode == 1022)
                {
                    postProcessing.Add(relation);
                }
                else
                {
                    RelationshipCat area = null, line = null;
                    String cityName = "";
                    String sectionId = relation.SectionId.ToString();
                    foreach (RelationshipCat cat in relation.RelationshipCatagories)
                    {
                        switch (cat.CatId)
                        {
                            case (2):
                                line = cat;
                                break;
                            case (3):
                                area = cat;
                                break;
                        }
                        if (line != null && area != null)
                            break;
                    }
                    if (line == null || area == null)
                        continue;

                    AreaFeatureRecord areaFeature = ParsedData.AreaFeatures[sectionId + area.FeatureId];
                    LineFeatureRecord lineFeatureRecord = ParsedData.LineFeatures[sectionId + line.FeatureId];
                    // check if the feature code is an area order N feature.
                    if (areaFeature.FeatCode < 1112 || areaFeature.FeatCode > 1120)
                        continue;
                    if (lineFeatureRecord.FeatCode != 4110)
                        continue;

                    foreach (int segAttId in areaFeature.SegmentedAttributes)
                    {
                        SegmentedAttributeRecord segAtt =
                            ParsedData.SegmentedAttributes[sectionId + segAttId];

                        foreach (SegAttributeType segAttType in segAtt.Attributes)
                        {
                            switch (segAttType.TypeCode)
                            {
                                case ("ON"):
                                    NameRecord name =
                                        ParsedData.Names[sectionId + segAttType.AttVal.Trim()];
                                    cityName = name.Text.Trim();
                                    break;
                            }
                        }
                    }


                    foreach (LineFeatureEdge lfe in lineFeatureRecord.RoadParticles)
                    {
                        Edge edge = tmpEdges[sectionId + lfe.EdgeId];
                        if (!Cities.ContainsKey(cityName))
                        {
                            Section newSec = new Section();
                            if (tmpCentrum.ContainsKey(sectionId))
                            {
                                newSec.CentrumNode = tmpCentrum[sectionId];
                            }
                            Cities.Add(cityName, newSec);
                            Console.WriteLine(cityName);
                        }
                        bool added = false;

                        //Adding edges to the streetindexed dictionary
                        if (edge.RoadName != null)
                        {
                            edge.FromNode.PlaceName = cityName;
                            edge.ToNode.PlaceName = cityName;
                            added = true;
                            if (!Cities[cityName].Streets.ContainsKey(edge.RoadName))
                            {
                                List<Edge> edgelist = new List<Edge>();
                                edgelist.Add(edge);
                                Cities[cityName].Streets.Add(edge.RoadName, edgelist);
                            }
                            else
                            {
                                Cities[cityName].Streets[edge.RoadName].Add(edge);
                            }
                        }

                        //Adding edges to the postcodeindexed dictionary
                        if (edge.Postcode != null)
                        {
                            added = true;
                            foreach (String s in edge.Postcode)
                            {
                                if (!Cities[cityName].ZipCodes.ContainsKey(s))
                                {
                                    List<Edge> edgelist = new List<Edge>();
                                    edgelist.Add(edge);
                                    Cities[cityName].ZipCodes.Add(s, edgelist);
                                }
                                else
                                {
                                    Cities[cityName].ZipCodes[s].Add(edge);
                                }
                            }
                            
                        }
                        if (!added)
                        {
                            if (edge.status != 1)
                            {
                                Console.WriteLine(edge.EdgeID + " Has not been added " + edge.SectionID);
                                Console.WriteLine(edge.Type + " Has not been added");
                                Console.WriteLine(edge.RoadName);
                            }

                        }
                    }
                }
            }
            foreach (RelationshipRecord relation in postProcessing)
            {
                if (relation.RelCode == 2200)
                {
                    Boolean unTangled = UntangleBrunnel(relation);
                    if (!unTangled)
                    {
                        unTangled = UntangleBrunnelJunctions(relation);
                        if (!unTangled)
                        {
                            UntangleLineBrunnel(relation);
                        }
                    }
                }
                else if (relation.RelCode == 1022)
                {
                    Edge e = null;
                    Node n = null;
                    foreach (RelationshipCat rc in relation.RelationshipCatagories)
                    {
                        if (rc.CatId == 2)
                        {
                            e = tmpEdges[rc.SectionID + ParsedData.LineFeatures[rc.SectionID + rc.FeatureId.ToString()].RoadParticles[0].EdgeId.ToString()];
                        }
                        else if (rc.CatId == 1)
                        {
                            n = tmpNodes[rc.SectionID + ParsedData.Nodes[rc.SectionID + ParsedData.PointFeatures[rc.SectionID + rc.FeatureId.ToString()].NodesId[0].ToString()].Id.ToString()];
                            // umad?
                        }
                    }
                    if (e != null && n != null)
                    {
                        // e is an edge near the node
                        // n is the node
                        // ???
                        // profit
                    }
                }
            }
        }

        private static Boolean UntangleLineBrunnel(RelationshipRecord relation)
        {
            PointFeatureRecord junction = null;
            PointFeatureRecord brunnel = null;
            LineFeatureRecord road = null;

            foreach (RelationshipCat RC in relation.RelationshipCatagories)
            {
                if (RC.CatId == 1)
                {
                    PointFeatureRecord pfr = ParsedData.PointFeatures[RC.SectionID + RC.FeatureId.ToString()];
                    if (pfr.FeatCode == 7500)
                    {
                        brunnel = pfr;
                    }
                    else if (pfr.FeatCode == 4120)
                    {
                        if (junction == null)
                        {
                            junction = pfr;
                        }
                    }
                }
                else if (RC.CatId == 2)
                {
                    LineFeatureRecord line = ParsedData.LineFeatures[RC.SectionID + RC.FeatureId.ToString()];
                    if (line.FeatCode == 4110)
                    {
                        road = line;
                    }
                }
                else
                {
                    return false; // invalid for our cause
                }
            }
            if (junction != null && brunnel != null && road != null)
            {
                Node originalNode = tmpNodes[junction.SectionId + junction.NodesId[0].ToString()];
                Node duplicateNode = new Node()
                {
                    Edges = new List<Edge>(originalNode.Edges),
                    ID = -originalNode.ID,
                    PlaceName = originalNode.PlaceName,
                    Position = originalNode.Position,
                    SectionID = originalNode.SectionID,
                    Type = originalNode.Type
                };


                foreach (LineFeatureEdge e in road.RoadParticles)
                {
                    Edge tmp = tmpEdges[road.SectionId + e.EdgeId.ToString()];
                    duplicateNode.Edges.Remove(tmp);
                }

                foreach (Edge e in duplicateNode.Edges)
                {
                    originalNode.Edges.Remove(e);
                    if (e.FromNode == originalNode)
                    {
                        e.FromNode = duplicateNode;
                    }
                    else if (e.ToNode == originalNode)
                    {
                        e.ToNode = duplicateNode;
                    }
                    if (e.RoadName != null)
                    {
                        Cities[duplicateNode.PlaceName].Streets[e.RoadName].Add(e);
                        if (e.Postcode.Count != 0)
                        {
                            foreach (String s in e.Postcode)
                            {
                                if (Cities[duplicateNode.PlaceName].ZipCodes.ContainsKey(s))
                                {
                                    Cities[duplicateNode.PlaceName].ZipCodes[s].Add(e);
                                }
                                else
                                {
                                    List<Edge> x = new List<Edge>();
                                    x.Add(e);
                                    Cities[duplicateNode.PlaceName].ZipCodes.Add(s, x);
                                }
                            }

                        }
                    }
                    else
                    {
                        if (e.Postcode.Count != 0)
                        {
                            foreach (String s in e.Postcode)
                            {
                                if (Cities[duplicateNode.PlaceName].ZipCodes.ContainsKey(s))
                                {
                                    Cities[duplicateNode.PlaceName].ZipCodes[s].Add(e);
                                }
                                else
                                {
                                    List<Edge> x = new List<Edge>();
                                    x.Add(e);
                                    Cities[duplicateNode.PlaceName].ZipCodes.Add(s, x);
                                }
                            }
                        }
                    }
                }
            }
            return true;
        }

        /// <summary>
        /// Method to cast the complex data from the parser group to the simple datamodel and link all the references
        /// 
        /// Leon Koppel 12-05-11
        /// </summary>
        public static void LinkAll()
        {
            Cities = new Dictionary<string, Section>();
            LinkNodes();
            linkEdges();
            LinkAreaToSegAttr();
            LinkConvertions();
            ParseRelationships();
            tmpNodes.Clear();
            tmpEdges.Clear();
            tmpCentrum.Clear();
            ParsedData.ClearData();
        }

        /// <summary>
        /// Cast all the nodes from the complex data and place it in a temporary dictionary
        /// 
        /// Leon Koppel 12-05-11
        /// </summary>
        private static void LinkNodes()
        {
            tmpNodes = new Dictionary<string, Node>();
            tmpCentrum = new Dictionary<string, Node>();
            foreach (KeyValuePair<string, PointFeatureRecord> pair in ParsedData.PointFeatures)
            {
                if (pair.Value.FeatCode == 4120)
                {
                    String placeName = "";
                    NodeType type = NodeType.Normal;
                    foreach (int id in pair.Value.SegmentedAttributesId)
                    {
                        SegmentedAttributeRecord setAtt = ParsedData.SegmentedAttributes[pair.Value.SectionId + id.ToString()];
                        foreach (SegAttributeType attType in setAtt.Attributes)
                        {
                            switch (attType.TypeCode)
                            {
                                case ("ON"):
                                    placeName = ParsedData.Names[setAtt.SectionId + attType.AttVal.Trim()].Text;
                                    break;
                            }
                        }
                    }

                    foreach (int id in pair.Value.NodesId)
                    {
                        NodeRecord n = ParsedData.Nodes[pair.Value.SectionId + id.ToString()];
                        if (!tmpNodes.ContainsKey(n.SectionId + id.ToString()))
                        {
                            CoordinatesRecord coord = ParsedData.Coordinates[n.SectionId + n.XyzId.ToString()];

                            Node newNode = new Node();
                            newNode.Type = type;
                            newNode.PlaceName = placeName;
                            newNode.Position = coord.Coords[0];
                            newNode.SectionID = n.SectionId;
                            tmpNodes.Add(n.SectionId + id.ToString(), newNode);
                        }
                    }
                }
                else
                {
                    NodeRecord n = ParsedData.Nodes[pair.Value.SectionId + pair.Value.NodesId[0].ToString()];
                    CoordinatesRecord coord = ParsedData.Coordinates[n.SectionId + n.XyzId.ToString()];
                    POI poi = new POI();
                    switch (pair.Value.FeatCode)
                    {
                        case (7360): //Camping
                            poi.Type = POIType.CampingGround;
                            listCampingGround.Add(poi);
                            break;
                        case (9927): //Dierentuin
                            poi.Type = POIType.Zoo;
                            listZoo.Add(poi);
                            break;
                        case (7314): //Hotel
                            poi.Type = POIType.Hotel;
                            listHotel.Add(poi);
                            break;
                        case (7317): //Museum
                            poi.Type = POIType.Museum;
                            listMuseum.Add(poi);
                            break;
                        case (7313): //ParkeerGarage
                            poi.Type = POIType.ParkingGarage;
                            listParkingGarage.Add(poi);
                            break;
                        case (7322): //Politie
                            poi.Type = POIType.PoliceStation;
                            listPoliceStation.Add(poi);
                            break;
                        case (7324): //Post
                            poi.Type = POIType.PostOffice;
                            listPostOffice.Add(poi);
                            break;
                        case (7315): //Restaurant
                            poi.Type = POIType.Restaurant;
                            listRestaurant.Add(poi);
                            break;
                        case (7372): //School
                            poi.Type = POIType.School;
                            listSchool.Add(poi);
                            break;
                        case (7380): //Station
                            poi.Type = POIType.RailwayStation;
                            listRailwayStation.Add(poi);
                            break;
                        case (7311): //Tankstation
                            poi.Type = POIType.PetrolStation;
                            listPetrolStation.Add(poi);
                            break;
                        case (7318): //Theater
                            poi.Type = POIType.Theatre;
                            listTheatre.Add(poi);
                            break;
                        case (7376): //ToeristenAttractie
                            poi.Type = POIType.ImportantTouristAttraction;
                            listImportantTouristAttraction.Add(poi);
                            break;
                        case (7337): //Uitzichtspunt
                            poi.Type = POIType.PanoramicView;
                            listPanoramicView.Add(poi);
                            break;
                        case (7316): //VVV
                            poi.Type = POIType.TouristInformationOffice;
                            listTouristInformationOffice.Add(poi);
                            break;
                        case (7321): // Ziekenhuis
                            poi.Type = POIType.Hospital;
                            listHospital.Add(poi);
                            break;
                        case (7379): // Centrum
                            if (!tmpCentrum.ContainsKey(n.SectionId.ToString()))
                            {
                                Node newNode = new Node();
                                newNode.Position = coord.Coords[0];
                                tmpCentrum.Add(n.SectionId.ToString(), newNode);
                            }
                            break;
                        default:
                            poi.Type = POIType.Undefined;
                            break;
                    }
                    if (poi.Type != POIType.Undefined)
                    {
                        poi.Position = coord.Coords[0];
                    }
                }

            }
            foreach (KeyValuePair<string, NodeRecord> nr in ParsedData.Nodes)
            {
                if (!tmpNodes.ContainsKey(nr.Value.SectionId + nr.Value.Id.ToString()))
                {
                    Node n = new Node();
                    n.ID = nr.Value.Id;
                    n.Position = ParsedData.Coordinates[nr.Value.SectionId + nr.Value.XyzId.ToString()].Coords[0];
                    n.SectionID = nr.Value.SectionId;
                    tmpNodes.Add(nr.Value.SectionId + nr.Value.Id.ToString(), n);
                    if (tmpCentrum.ContainsKey(n.SectionID.ToString()))
                    {
                        if (tmpCentrum[n.SectionID.ToString()].Position == n.Position)
                        {
                            tmpCentrum[n.SectionID.ToString()] = n;
                        }
                    }
                }
            }
        }

        // <summary>
        // Link a Area to a segmentedAttribute
        // 
        // Wim Eikelboom 16-5-2011
        // </summary>
        private static void LinkAreaToSegAttr()
        {
            foreach (KeyValuePair<string, AreaFeatureRecord> area in ParsedData.AreaFeatures)
            {
                AreaType type = new AreaType();
                String name = "";
                List<Point> positions = new List<Point>();
                if (area.Value.FeatCode == 4310)
                {
                    type = AreaType.WaterElement;
                }
                else if ((area.Value.FeatCode == 7170) || (area.Value.FeatCode == 7120))
                {
                    type = AreaType.ParkElement;
                }
                else if ((area.Value.FeatCode == 9715) || (area.Value.FeatCode == 9720))
                {
                    type = AreaType.IndustrialElement;
                }
                else if (area.Value.FeatCode == 3110)
                {
                    type = AreaType.UrbanElement;
                }
                else
                    continue;
                foreach (int segAttrId in area.Value.SegmentedAttributes)
                {
                    SegmentedAttributeRecord segAttr = ParsedData.SegmentedAttributes[area.Value.SectionId + segAttrId.ToString()];
                    foreach (SegAttributeType attType in segAttr.Attributes)
                    {
                        switch (attType.TypeCode)
                        {
                            case ("ON"):
                                name = ParsedData.Names[segAttr.SectionId + attType.AttVal.Trim()].Text;
                                break;
                        }
                    }

                    foreach (int face in area.Value.FaceId)
                    {
                        Area a = new Area();
                        FaceRecord fr = ParsedData.Faces[area.Value.SectionId + face.ToString()];
                        foreach (FaceEdge faceEdge in fr.Edges)
                        {
                            EdgeRecord er = ParsedData.Edges[area.Value.SectionId + faceEdge.EdgeId.ToString()];

                            NodeRecord fromNode = ParsedData.Nodes[er.SectionId + er.FNodeId.ToString()];
                            NodeRecord toNode = ParsedData.Nodes[er.SectionId + er.TNodeId.ToString()];

                            CoordinatesRecord fNCoord = ParsedData.Coordinates[er.SectionId + fromNode.XyzId.ToString()];
                            CoordinatesRecord tNCoord = ParsedData.Coordinates[er.SectionId + toNode.XyzId.ToString()];
                            CoordinatesRecord coord = null;
                            if (er.XyzId != -1)
                                coord = ParsedData.Coordinates[er.SectionId + er.XyzId.ToString()];

                            if (faceEdge.Orientation == 0)
                            {
                                // from fromNode to toNode
                                a.Positions.Add(fNCoord.Coords[0]);
                                if (coord != null)
                                {
                                    foreach (Point p in coord.Coords)
                                        a.Positions.Add(p);
                                }
                            }
                            else
                            {
                                // from toNode to fromNode
                                a.Positions.Add(tNCoord.Coords[0]);
                                if (coord != null)
                                {
                                    for (int i = coord.Coords.Count - 1; i >= 0; i--)
                                    {
                                        a.Positions.Add(coord.Coords[i]);
                                    }
                                }
                            }
                        }

                        a.Name = name;
                        a.Type = type;
                        listArea.Add(a);
                    }
                }
            }
        }

        /// <summary>
        /// Method to get a node from a location, 
        /// </summary>
        /// <param name="l">Location</param>
        /// <returns>Node</returns>
        public static Node GetNode(Location l)
        {
            List<Edge> edges = new List<Edge>();
            Node houseNode = new Node();
            if (!string.IsNullOrEmpty(l.ZipCode))
            {
                edges = Cities[l.City].ZipCodes[l.ZipCode];
            }
            else if (!string.IsNullOrEmpty(l.Street))
            {
                edges = Cities[l.City].Streets[l.Street];
            }

            if (string.IsNullOrEmpty(l.Housenumber))
            {
                if (edges.Count != 0)
                {
                    houseNode = edges[0].ToNode;
                }
                else if(!string.IsNullOrEmpty(l.City))
                {

                    houseNode = Cities[l.City].Streets.Values.ElementAt(0).ElementAt(0).FromNode;
                }
                return houseNode;
            }
            else
            {
                int numericHousenumber = SplitHouseNumber(l.Housenumber);
                bool found = false;
                bool even = (numericHousenumber % 2 == 0) ? true : false;
                bool left = false;

                foreach (Edge e in edges)
                {
                    //1 No House Numbers at All
                    if (e.HousenumbersTotal == TotalHousenumberStructure.None)
                    {
                        continue;
                    }

                    int maxHousenumberLeft = -1;
                    int minHousenumberLeft = -1;
                    int maxHousenumberRight = -1;
                    int minHousenumberRight = -1;


                    if (e.HousenumbersLeft != HousenumberStructure.None)
                    {
                        int h1 = SplitHouseNumber(e.FirstHouseNumberLeft);
                        int h2 = SplitHouseNumber(e.LastHouseNumberLeft);
                        maxHousenumberLeft = (h1 > h2) ? h1 : h2;
                        minHousenumberLeft = (h1 < h2) ? h1 : h2;
                    }

                    if (e.HousenumbersRight != HousenumberStructure.None)
                    {
                        int h1 = SplitHouseNumber(e.FirstHouseNumberRight);
                        int h2 = SplitHouseNumber(e.LastHouseNumberRight);
                        maxHousenumberRight = (h1 > h2) ? h1 : h2;
                        minHousenumberRight = (h1 < h2) ? h1 : h2;
                    }


                    //2 Regular with Odd & Even Numbers at Both Sides
                    if (e.HousenumbersTotal == TotalHousenumberStructure.Both)
                    {
                        if (minHousenumberLeft <= numericHousenumber && numericHousenumber <= maxHousenumberLeft)
                        {
                            found = true;
                            left = true;
                        }
                        else if (minHousenumberRight <= numericHousenumber && numericHousenumber <= maxHousenumberRight)
                        {
                            found = true;
                        }
                    }
                    //3 Regular with Odd & Even Numbers at Different Sides
                    else if (e.HousenumbersTotal == TotalHousenumberStructure.Different)
                    {
                        if (even)
                        {
                            if (e.HousenumbersLeft == HousenumberStructure.Even)
                            {
                                if (minHousenumberLeft <= numericHousenumber && numericHousenumber <= maxHousenumberLeft)
                                {
                                    found = true;
                                    left = true;
                                }
                            }
                            else if (e.HousenumbersRight == HousenumberStructure.Even)
                            {
                                if (minHousenumberRight <= numericHousenumber && numericHousenumber <= maxHousenumberRight)
                                {
                                    found = true;
                                }
                            }
                        }

                        //if housenumer is odd
                        else
                        {
                            if (e.HousenumbersLeft == HousenumberStructure.Odd)
                            {
                                if (minHousenumberLeft <= numericHousenumber && numericHousenumber <= maxHousenumberLeft)
                                {
                                    found = true;
                                    left = true;
                                }
                            }
                            else if (e.HousenumbersRight == HousenumberStructure.Odd)
                            {
                                if (minHousenumberRight <= numericHousenumber && numericHousenumber <= maxHousenumberRight)
                                {
                                    found = true;
                                }
                            }
                        }
                    }
                    //4 Irregular House Number Structure
                    else if (e.HousenumbersTotal == TotalHousenumberStructure.Irregular)
                    {
                        //Left side
                        if (e.HousenumbersLeft == HousenumberStructure.Irregular)
                        {
                            if (minHousenumberLeft <= numericHousenumber && numericHousenumber <= maxHousenumberLeft)
                            {
                                found = true;
                                left = true;
                            }
                        }
                        else if (e.HousenumbersLeft == HousenumberStructure.Even)
                        {
                            if (even)
                            {
                                if (minHousenumberLeft <= numericHousenumber && numericHousenumber <= maxHousenumberLeft)
                                {
                                    found = true;
                                    left = true;
                                }
                            }
                        }
                        else if (e.HousenumbersLeft == HousenumberStructure.Odd)
                        {
                            if (!even)
                            {
                                if (minHousenumberLeft <= numericHousenumber && numericHousenumber <= maxHousenumberLeft)
                                {
                                    found = true;
                                    left = true;
                                }
                            }
                        }

                        //Right side
                        else if (e.HousenumbersRight == HousenumberStructure.Irregular)
                        {
                            if (minHousenumberRight <= numericHousenumber && numericHousenumber <= maxHousenumberRight)
                            {
                                found = true;
                            }
                        }
                        else if (e.HousenumbersRight == HousenumberStructure.Even)
                        {
                            if (even)
                            {
                                if (minHousenumberRight <= numericHousenumber && numericHousenumber <= maxHousenumberRight)
                                {
                                    found = true;
                                }
                            }
                        }
                        else if (e.HousenumbersRight == HousenumberStructure.Odd)
                        {
                            if (!even)
                            {
                                if (minHousenumberRight <= numericHousenumber && numericHousenumber <= maxHousenumberRight)
                                {
                                    found = true;
                                }
                            }
                        }
                    }

                    if (found)
                    {
                        return e.ToNode;

                        //calculate percentage factor on the edge
                        float factor;
                        if (left)
                        {
                            factor = maxHousenumberLeft - minHousenumberLeft;
                            factor = factor / maxHousenumberLeft;
                        }
                        else
                        {
                            factor = maxHousenumberRight - minHousenumberRight;
                            factor = factor / maxHousenumberRight;
                        }

                        //if the factor is 1.0 (100%) return the highest node
                        if (factor == 1.0)
                        {
                            if (left)
                            {
                                houseNode = (maxHousenumberLeft == SplitHouseNumber(e.LastHouseNumberLeft)) ? e.FromNode : e.ToNode;
                            }
                            else
                            {
                                houseNode = (maxHousenumberRight == SplitHouseNumber(e.LastHouseNumberRight)) ? e.FromNode : e.ToNode;
                            }
                            return houseNode;
                        }

                        //if the factor is 1.0 (100%) return the lowest node
                        if (factor == 0.0)
                        {
                            if (left)
                            {
                                houseNode = (maxHousenumberLeft == SplitHouseNumber(e.FirstHouseNumberLeft)) ? e.FromNode : e.ToNode;
                            }
                            else
                            {
                                houseNode = (maxHousenumberRight == SplitHouseNumber(e.FirstHouseNumberRight)) ? e.FromNode : e.ToNode;
                            }
                            return houseNode;
                        }

                        //Calculate distance from a to p
                        float edgeLength = e.GetLength();
                        int distAP = (int)(edgeLength * factor);

                        //if the founded edge has no positions
                        if (e.Positions == null || e.Positions.Count == 0)
                        {
                            float deltaX = e.ToNode.Position.X - e.FromNode.Position.X;
                            float deltaY = e.ToNode.Position.Y - e.FromNode.Position.Y;
                            float distAB = edgeLength;
                            float deltaXAP = (deltaX * distAP) / distAB;
                            float deltaYAP = (deltaY * distAP) / distAB;
                            Point p = new Point();
                            p.X = (int)(e.FromNode.Position.X + deltaXAP);
                            p.Y = (int)(e.ToNode.Position.Y + deltaYAP);
                            houseNode.Position = p;
                            houseNode.ID = -1;

                            Edge edgeAP = new Edge();
                            edgeAP.EdgeID = -1;
                            edgeAP.FromNode = houseNode;
                            edgeAP.ToNode = e.ToNode;
                            edgeAP.MaxSpeed = e.MaxSpeed;
                            edgeAP.Bidirectional = e.Bidirectional;
                            edgeAP.UsableByBike = e.UsableByBike;
                            edgeAP.UsableByCar = e.UsableByCar;
                            edgeAP.UsableByFoot = e.UsableByFoot;

                            Edge edgePB = new Edge();
                            edgePB.EdgeID = -1;
                            edgePB.FromNode = e.FromNode;
                            edgePB.ToNode = houseNode;
                            edgePB.MaxSpeed = e.MaxSpeed;
                            edgePB.Bidirectional = e.Bidirectional;
                            edgePB.UsableByBike = e.UsableByBike;
                            edgePB.UsableByCar = e.UsableByCar;
                            edgePB.UsableByFoot = e.UsableByFoot;

                            houseNode.Edges.Add(edgeAP);
                            houseNode.Edges.Add(edgePB);

                            e.ToNode.Edges.Add(edgeAP);
                            e.FromNode.Edges.Add(edgePB);

                            return houseNode;
                        }


                        //Calculate the position on the edge
                        float length = 0;
                        for (int i = 0; i < e.Positions.Count + 1; i++)
                        {
                            Point a = (i == 0) ? e.FromNode.Position : e.Positions[i - 1];
                            Point b = (i == e.Positions.Count) ? e.ToNode.Position : e.Positions[i];
                            Point c = new Point(b.X, a.Y);

                            float xd = c.X - a.X;
                            float yd = b.Y - c.Y;
                            length += (float)Math.Sqrt(xd * xd + yd * yd);

                            if (length >= distAP)
                            {
                                float deltaX = a.X - b.X;
                                float deltaY = a.Y - b.Y;
                                c = new Point(b.X, a.Y);
                                xd = c.X - a.X;
                                yd = b.Y - c.Y;
                                float distAB = (int)Math.Sqrt(xd * xd + yd * yd);
                                float newDistAP = (int)(distAP - length);
                                float deltaXAP = (deltaX * newDistAP) / distAB;
                                float deltaYAP = (deltaY * newDistAP) / distAB;
                                Point p = new Point();
                                p.X = (int)(a.X + deltaXAP);
                                p.Y = (int)(b.Y + deltaYAP);
                                houseNode.Position = p;
                                houseNode.ID = -1;

                                Edge edgeAP = new Edge();
                                edgeAP.EdgeID = -1;
                                edgeAP.FromNode = houseNode;
                                edgeAP.ToNode = e.ToNode;
                                edgeAP.MaxSpeed = e.MaxSpeed;
                                edgeAP.Bidirectional = e.Bidirectional;
                                edgeAP.UsableByBike = e.UsableByBike;
                                edgeAP.UsableByCar = e.UsableByCar;
                                edgeAP.UsableByFoot = e.UsableByFoot;

                                Edge edgePB = new Edge();
                                edgePB.EdgeID = -1;
                                edgePB.FromNode = e.FromNode;
                                edgePB.ToNode = houseNode;
                                edgePB.MaxSpeed = e.MaxSpeed;
                                edgePB.Bidirectional = e.Bidirectional;
                                edgePB.UsableByBike = e.UsableByBike;
                                edgePB.UsableByCar = e.UsableByCar;
                                edgePB.UsableByFoot = e.UsableByFoot;

                                for (int u = 1; u < i; u++)
                                {
                                    edgeAP.Positions.Add(e.Positions[u]);
                                    edgePB.Positions.Add(e.Positions[e.Positions.Count - u]);
                                }

                                houseNode.Edges.Add(edgeAP);
                                houseNode.Edges.Add(edgePB);

                                e.ToNode.Edges.Add(edgeAP);
                                e.FromNode.Edges.Add(edgePB);

                                return houseNode;
                            }
                        }
                    }

                }
            }
            throw new Exception("Housenumber not found");
        }

        /// <summary>
        /// Returns a housnumber in a short instead of a string
        /// </summary>
        /// <param name="houseNumber"></param>
        /// <returns></returns>
        public static short SplitHouseNumber(string houseNumber)
        {
            if (houseNumber == null)
            {
                LogException.Log("SplitHouseNumber", new Exception("Empty housenumber"));
                return 0;
            }
            String tmp = string.Empty;
            char[] c = houseNumber.ToCharArray();
            for (int i = 0; i < c.Length; i++)
            {
                if (Char.IsNumber(c[i]))
                {
                    tmp += c[i];
                }
                else
                {
                    break;
                }
            }
            return Int16.Parse(tmp);
        }

        /// <summary>
        /// Grabs all edge information from the Parser objects, and stuffs this into a temporary dictionary called edges for use in later linking with nodes.
        /// </summary>
        private static void linkEdges()
        {
            tmpEdges = new Dictionary<string, Edge>();
            foreach (LineFeatureRecord lfr in ParsedData.LineFeatures.Values)
            {
                if (lfr.FeatCode == 4110)
                {
                    string roadName = null;
                    bool isRail = false;
                    LineType type = LineType.UnspecifiedElement;
                    int maxSpeed = 0;
                    string postcode = null;
                    

                    TotalHousenumberStructure houseNStructure = TotalHousenumberStructure.None;
                    HousenumberStructure houseRStructure = HousenumberStructure.None;
                    HousenumberStructure houseLStructure = HousenumberStructure.None;
                    string firstHouseNumberRight = null;
                    string lastHouseNumberRight = null;
                    string firstHouseNumberLeft = null;
                    string lastHouseNumberLeft = null;
                    int directionality = -1;
                    List<String> routeNumbers = new List<String>();
                    List<String> postalCodes = new List<string>();
                    int accesstype = -1;
                    foreach (int i in lfr.SegmentedAttributes)
                    {
                        SegmentedAttributeRecord sar = ParsedData.SegmentedAttributes[lfr.SectionId + i.ToString()];

                        foreach (SegAttributeType sat in sar.Attributes)
                        {
                            if (sat.TypeCode.Equals("ON"))
                            {
                                roadName = ParsedData.Names[lfr.SectionId + sat.AttVal.Trim()].Text.Trim();
                            }
                            else if (sat.TypeCode.Equals("FW"))
                            {
                                if (sat.AttVal.Trim() == "14" || sat.AttVal.Trim() == "15")
                                {
                                    accesstype = 2;
                                }
                                else if (sat.AttVal.Trim() == "4")
                                {
                                    roadName = "Rotonde " + roadName;
                                    accesstype = 0;
                                }
                                else
                                {
                                    accesstype = 0;
                                }
                            }
                            else if (sat.TypeCode.Equals("3A"))
                            {
                                type = LineType.RailElement;
                                isRail = true;
                            }
                            else if (sat.TypeCode.Equals("SP"))
                            {
                                maxSpeed = int.Parse(sat.AttVal);
                                if (maxSpeed >= 100)
                                {
                                    accesstype = 5;
                                }
                                else if (accesstype != 0 || accesstype != 3)
                                {
                                    accesstype = 0;
                                }
                            }
                            else if (sat.TypeCode.Equals("RN"))
                            {
                                routeNumbers.Add(ParsedData.Names[lfr.SectionId + sat.AttVal.Trim()].Text.Trim());
                            }
                            else if (sat.TypeCode.Equals("FC") && !isRail)
                            {
                                int intType = int.Parse(sat.AttVal);
                                type = (LineType)intType;
                            }
                            else if (sat.TypeCode.Equals("5S"))
                            {
                                postcode = ParsedData.Names[lfr.SectionId + sat.AttVal.Trim()].Text.Trim();
                            }
                            else if (sat.TypeCode.Equals("5M"))
                            {
                                if (postcode == null || postcode.Trim() == String.Empty)
                                {
                                    postcode = ParsedData.Names[lfr.SectionId + sat.AttVal.Trim()].Text.Trim();
                                }
                            }
                            else if (sat.TypeCode.Equals("HS"))
                            {
                                int intHouseStruct = int.Parse(sat.AttVal);
                                intHouseStruct--;
                                houseNStructure = (TotalHousenumberStructure)intHouseStruct;
                            }
                            else if (sat.TypeCode.Equals("4L"))
                            {
                                int intHouseStruct = int.Parse(sat.AttVal);
                                intHouseStruct--;
                                houseLStructure = (HousenumberStructure)intHouseStruct;
                            }
                            else if (sat.TypeCode.Equals("4R"))
                            {
                                int intHouseStruct = int.Parse(sat.AttVal);
                                intHouseStruct--;
                                houseRStructure = (HousenumberStructure)intHouseStruct;
                            }
                            else if (sat.TypeCode.Equals("RS"))
                            {
                                firstHouseNumberRight = ParsedData.Names[lfr.SectionId + sat.AttVal.Trim()].Text;
                            }
                            else if (sat.TypeCode.Equals("RE"))
                            {
                                lastHouseNumberRight = ParsedData.Names[lfr.SectionId + sat.AttVal.Trim()].Text;
                            }
                            else if (sat.TypeCode.Equals("LS"))
                            {
                                firstHouseNumberLeft = ParsedData.Names[lfr.SectionId + sat.AttVal.Trim()].Text;
                            }
                            else if (sat.TypeCode.Equals("LE"))
                            {
                                lastHouseNumberLeft = ParsedData.Names[lfr.SectionId + sat.AttVal.Trim()].Text;
                            }
                            else if (sat.TypeCode.Equals("VT"))
                            {
                                if (sat.AttVal.Trim() == "24")
                                {
                                    if (accesstype == 0)
                                    {
                                        accesstype = 3;
                                    }
                                    else if (accesstype == 2)
                                    {
                                        accesstype = 4;
                                    }
                                    else 
                                    {
                                        accesstype = 2;
                                    }
                                
                                }
                            }
                            else if (sat.TypeCode.Equals("SR"))
                            {
                                if (sat.AttVal.Trim() == "2")
                                {
                                    accesstype = -2;
                                }
                            }
                            else if (sat.TypeCode.Equals("2T"))
                            {
                                if (sat.AttVal.Trim() == "1")
                                {
                                    accesstype = -2;
                                }
                            }
                            else if (sat.TypeCode.Equals("DF"))
                            {
                                directionality = int.Parse(sat.AttVal.Trim());
                            }

                            if (!string.IsNullOrEmpty(postcode))
                            {
                                postalCodes.Add(postcode);
                            }
                        }
                    }

                    foreach (LineFeatureEdge lfe in lfr.RoadParticles)
                    {
                        Edge e;
                        if (!tmpEdges.ContainsKey(lfr.SectionId + lfe.EdgeId.ToString()))
                        {
                            e = new Edge();
                            tmpEdges.Add(lfr.SectionId + lfe.EdgeId.ToString(), e);
                        }
                        else
                        {
                            e = tmpEdges[lfr.SectionId + lfe.EdgeId.ToString()];
                        }
                        e.EdgeID = lfe.EdgeId;
                        e.Type = type;
                        e.FirstHouseNumberLeft = firstHouseNumberLeft;
                        e.FirstHouseNumberRight = firstHouseNumberRight;
                        e.LastHouseNumberLeft = lastHouseNumberLeft;
                        e.LastHouseNumberRight = lastHouseNumberRight;
                        e.HousenumbersTotal = houseNStructure;
                        e.HousenumbersLeft = houseLStructure;
                        e.HousenumbersRight = houseRStructure;
                        e.MaxSpeed = maxSpeed;
                        e.Postcode.AddRange(postalCodes);
                        e.Routenumbers.AddRange(routeNumbers);


                        if (accesstype == 0)
                        {
                            e.UsableByCar = true;
                            e.UsableByFoot = true;
                            e.UsableByBike = true;
                        }
                        else if (accesstype == 3)
                        {
                            e.UsableByCar = true;
                            e.UsableByBike = true;
                        }
                        else if (accesstype == 4)
                        {
                            e.UsableByFoot = true;
                            e.UsableByBike = true;
                        }
                        else if (accesstype == 5)
                        {
                            e.UsableByCar = true;
                        }
                        else if (accesstype == 2)
                        {
                            e.UsableByFoot = true;
                        }
                        else if (accesstype == 1)
                        {
                            e.UsableByBike = true;
                        }
                        else if (accesstype == -2)
                        {
                            // NONE SHALL PASS
                            e.UsableByBike = false;
                            e.UsableByFoot = false;
                            e.UsableByCar = false;
                        }


                        if (roadName != null && !roadName.Equals(String.Empty))
                        {
                            e.RoadName = roadName;
                        }
                        else
                        {
                            foreach (String s in routeNumbers)
                            {
                                e.RoadName += "(" + s + ")";
                            }
                        }

                        if (directionality == 1)
                        {
                            e.Bidirectional = 0;
                        }
                        else if (directionality == 2)
                        {
                            e.Bidirectional = 1;
                        }
                        else if (directionality == 3)
                        {
                            e.Bidirectional = 2;
                        }
                        else if (directionality == 4)
                        {
                            e.Bidirectional = 3;
                        }
                        e.SectionID = lfr.SectionId;
                        EdgeRecord er;
                        ParsedData.Edges.TryGetValue(lfr.SectionId + lfe.EdgeId.ToString(), out er);
                        if (er != null)
                        {
                            e.FromNode = tmpNodes[lfr.SectionId + er.FNodeId.ToString()];
                            e.FromNode.Edges.Add(e);
                            e.ToNode = tmpNodes[lfr.SectionId + er.TNodeId.ToString()];
                            e.ToNode.Edges.Add(e);
                            e.status = er.Status;
                            if (er.XyzId != -1)
                            {
                                e.Positions = ParsedData.Coordinates[lfr.SectionId + er.XyzId.ToString()].Coords;
                            }
                        }
                        else
                        {
                            LogException.Log("LinkEdges", new Exception("Edge record not found" + lfr.SectionId + lfe.EdgeId));
                        }
                    }
                }


            }


        }


        private static void LinkConvertions()
        {
            foreach (ConversionRecord conversion in ParsedData.Conversions)
            {
                int sectionIntern = conversion.SectionInt;
                int sectionExtern = conversion.SectionExt;

                int featCodeIntern = conversion.FeatInt;
                int featCodeExtern = conversion.FeatExt;

                int idIntern = conversion.IntId;
                int idExtern = conversion.ExtId;

                if (featCodeExtern != featCodeIntern)
                    continue;

                switch (featCodeIntern)
                {
                    // point feature
                    case (1):
                        String internKey = sectionIntern + idIntern.ToString();
                        String externKey = sectionExtern + idExtern.ToString();
                        
                        if (!ParsedData.PointFeatures.ContainsKey(internKey))
                            continue;
                        if (!ParsedData.PointFeatures.ContainsKey(externKey))
                            continue;

                        PointFeatureRecord pFint = ParsedData.PointFeatures[internKey];
                        PointFeatureRecord pFext = ParsedData.PointFeatures[externKey];

                        for (int i = 0; i < pFint.NodesId.Count; i++)
                        {
                            Node nodeIntern = tmpNodes[sectionIntern + pFint.NodesId[i].ToString()];
                            Node nodeExtern = tmpNodes[sectionExtern + pFext.NodesId[i].ToString()];

                            for (int j = 0; j < nodeExtern.Edges.Count; j++)
                            {
                                Edge edge = nodeExtern.Edges[j];

                                nodeIntern.Edges.Add(edge);

                                if (edge.FromNode == nodeExtern)
                                    edge.FromNode = nodeIntern;
                                else if(edge.ToNode == nodeExtern)
                                    edge.ToNode = nodeIntern;
                            }
                        }
                        break;
                }
            }
        }


        #endregion
    }
}