public static XElement ToXElement(OSMRelation relation) { XElement output = new XElement("relation"); AddElementDetailsToXElement(relation, output); foreach (OSMRelationMember member in relation.Members) { XElement memberElement = new XElement("member"); if (!string.IsNullOrWhiteSpace(member.Type)) { memberElement.SetAttributeValue("type", member.Type); } if (!string.IsNullOrWhiteSpace(member.Ref)) { memberElement.SetAttributeValue("ref", member.Ref); } if (!string.IsNullOrWhiteSpace(member.Role)) { memberElement.SetAttributeValue("role", member.Role); } output.Add(memberElement); } AddElementTagsToXElement(relation, output); return(output); }
private void writeRelation(XElement parent, OSMRelation relation) { XElement relationElement = relation.ToXElement(); parent.Add(relationElement); }
/// <summary> /// Load OSM objects from an OSM XML file /// </summary> /// <param name="calculateDistances">Calculate distances between nodes on load</param> /// <param name="calculateBounds">Calculate way bounding boxes on load</param> /// <param name="strictMode">Discard node references from ways if the nodes to not exist</param> /// <returns></returns> public bool Load(bool calculateDistances = false, bool calculateBounds = false, bool strictMode = false) { try { clearValues(); XDocument doc = XDocument.Load(File.FullName); List <XElement> nodeElements = doc.Descendants("node").ToList(); List <XElement> wayElements = doc.Descendants("way").ToList(); List <XElement> relationElements = doc.Descendants("relation").ToList(); double lat, lon; foreach (XElement nodeElement in nodeElements) { OSMNode node = new OSMNode(); node.GetElementDetailsFromXElement(nodeElement); if (double.TryParse(nodeElement.Attribute("lat").Value, out lat)) { node.Latitude = lat; } if (double.TryParse(nodeElement.Attribute("lon").Value, out lon)) { node.Longitude = lon; } node.Latitude = double.TryParse(nodeElement.Attribute("lat").Value, out lat) ? lat : double.NaN; node.Longitude = double.TryParse(nodeElement.Attribute("lon").Value, out lon) ? lon : double.NaN; Bounds.ExtendBounds(node.Latitude, node.Longitude); NodesById[node.ID] = node; //WaysForNodes[node.ID] = new List<OSMNodeWayInfo>(); } foreach (XElement wayElement in wayElements) { OSMWay way = new OSMWay(); way.GetElementDetailsFromXElement(wayElement); if (way.ID == "15200801") { var str = "str"; } List <XElement> nodes = wayElement.Descendants("nd").ToList(); foreach (XElement node in nodes) { string refValue = node.Attribute("ref").Value; if (!string.IsNullOrEmpty(refValue)) { OSMNode osmNode; if (!NodesById.TryGetValue(refValue, out osmNode)) { if (strictMode) { continue; } else { osmNode = new OSMNode() { ID = refValue }; NodesById.Add(refValue, osmNode); } } osmNode.WayReferences.Add(way.ID); way.NodeReferences.Add(osmNode.ID); } } XElement oneWayTag = wayElement.Descendants("tag").Where(t => t.Attribute("k").Value == "oneway").SingleOrDefault(); if (oneWayTag != null && (oneWayTag.Attribute("v").Value == "yes" || oneWayTag.Attribute("v").Value == "true")) { way.Oneway = true; } XElement maxSpeedTag = wayElement.Descendants("tag").Where(t => t.Attribute("k").Value == "maxspeed").SingleOrDefault(); if (maxSpeedTag != null) { way.MaxSpeed = maxSpeedTag.Attribute("v").Value; } WaysById[way.ID] = way; } foreach (XElement relationElement in relationElements) { OSMRelation relation = new OSMRelation(); relation.GetElementDetailsFromXElement(relationElement); List <XElement> members = relationElement.Descendants("member").ToList(); foreach (XElement member in members) { OSMRelationMember rm = new OSMRelationMember(); rm.Type = member.Attribute("type")?.Value; rm.Ref = member.Attribute("ref")?.Value; rm.Role = member.Attribute("role")?.Value; relation.Members.Add(rm); } RelationsById[relation.ID] = relation; } if (calculateDistances) { CalculateNodeDistances(); } if (calculateBounds) { CalculateWayBounds(); } return(true); } catch (Exception ex) { LogHelper.LogException(ex, "Error loading OSM file", true); return(false); } }