public OsmEntityInfoDatabaseTests() { _nodeData = new NodeInfo[3]; _nodeData[0] = new NodeInfo(1, 10.1, 11.1, new TagsCollection()); _nodeData[1] = new NodeInfo(2, 10.2, 11.2, new TagsCollection()); _nodeData[2] = new NodeInfo(3, 10.3, 11.3, new TagsCollection()); _wayData = new WayInfo[2]; _wayData[0] = new WayInfo(10, new TagsCollection(), _nodeData.Select(n => n.ID).ToArray()); _wayData[1] = new WayInfo(11, new TagsCollection(), _nodeData.Select(n => n.ID).Skip(1).ToArray()); _relationData = new RelationInfo[2]; _relationData[0] = new RelationInfo(100, new TagsCollection(), new RelationMemberInfo[] { new RelationMemberInfo() { Reference = 10, Role = "way" }, new RelationMemberInfo() { Reference = 1, Role = "node" } }); _relationData[1] = new RelationInfo(101, new TagsCollection(), new RelationMemberInfo[] { new RelationMemberInfo() { Reference = 101, Role = "relation" }, new RelationMemberInfo() { Reference = 1, Role = "node" } }); _data = _nodeData.Concat <IEntityInfo>(_wayData).Concat <IEntityInfo>(_relationData).ToArray(); }
/// <summary> /// Creates a new instance of the Way class based on data from WayInfo object /// </summary> /// <param name="info">The WayInfo object that contains data about way</param> /// <param name="entities">The entities that can be referenced by way</param> /// <param name="throwOnMissing">bool value indicating whether references to the missing nodes should cause exception</param> /// <returns>The Way object created from WayInfo or null if referenced node is missing</returns> public static Way FromWayInfo(WayInfo info, IEntityCollection <IOsmGeometry> entities, bool throwOnMissing) { Way result = new Way(info.ID) { Tags = info.Tags, Metadata = info.Metadata }; result.Nodes.Capacity = info.Nodes.Count; foreach (var nodeID in info.Nodes) { Node node = entities[nodeID, EntityType.Node] as Node; if (node != null) { result.Nodes.Add(node); } else { if (throwOnMissing) { throw new ArgumentException(string.Format("Referenced Node (ID = {0}) not found in entities collection.", nodeID), "info.ID"); } return(null); } } return(result); }
/// <summary> /// Processes all ways from the PrimitiveGroup and adds them to the output queue. /// </summary> /// <param name="block">The PrimitiveBlock that contains specified PrimitiveGroup.</param> /// <param name="group">The PrimitiveGroup with nodes to process.</param> private void ProcessWays(PrimitiveBlock block, PrimitiveGroup group) { if (group.Ways == null) { return; } foreach (var way in group.Ways) { long refStore = 0; List <long> refs = new List <long>(way.Refs.Count); for (int i = 0; i < way.Refs.Count; i++) { refStore += (long)way.Refs[i]; refs.Add(refStore); } List <Tag> tags = new List <Tag>(); if (way.Keys != null) { for (int i = 0; i < way.Keys.Count; i++) { tags.Add(new Tag(block.StringTable[way.Keys[i]], block.StringTable[way.Values[i]])); } } EntityMetadata metadata = this.ProcessMetadata(way.Metadata, block); WayInfo parsed = new WayInfo((long)way.ID, new TagsCollection(tags), refs, metadata); _cache.Enqueue(parsed); } }
/// <summary> /// Adds specific entity to buffer /// </summary> /// <param name="item">The entity to add</param> public void Add(T item) { _storage.Add(item); foreach (var tag in item.Tags) { this.GetStringIndex(tag.Key); this.GetStringIndex(tag.Value); _estimatedEntityDataSize += 8; } if (item.EntityType == EntityType.Node) { _estimatedEntityDataSize += 3 * 8; } else if (item.EntityType == EntityType.Way) { WayInfo wayItem = item as WayInfo; _estimatedEntityDataSize += 8 + wayItem.Nodes.Count * 8; } else if (item.EntityType == EntityType.Relation) { RelationInfo relationItem = item as RelationInfo; _estimatedEntityDataSize += 8 + relationItem.Members.Count * 12; } if (_writeMetadata) { _estimatedEntityDataSize += 28; } }
public void Read_ReadsWayWithoutNodes() { OsmXmlReader target = new OsmXmlReader(new MemoryStream(XmlTestData.osm_way_without_nodes), new OsmXmlReaderSettings() { ReadMetadata = false }); WayInfo readWay = target.Read() as WayInfo; this.CompareWays(_wayWithoutNodes, readWay); }
public void Read_ReadsSimpleWay() { OsmXmlReader target = new OsmXmlReader(TestDataReader.OpenXml("osm-simple-way.osm"), new OsmXmlReaderSettings() { ReadMetadata = false }); WayInfo readWay = target.Read() as WayInfo; this.CompareWays(_way, readWay); }
public void Read_ReadsWayWithUnknownElement() { OsmXmlReader target = new OsmXmlReader(TestDataReader.OpenXml("osm-way-with-tags-and-unknown-element.osm"), new OsmXmlReaderSettings() { ReadMetadata = false }); WayInfo readWay = target.Read() as WayInfo; this.CompareWays(_wayTags, readWay); }
public void Read_ReadsWayWithAllAttributes() { OsmXmlReader target = new OsmXmlReader(new MemoryStream(XmlTestData.osm_way_all_properties), new OsmXmlReaderSettings() { ReadMetadata = true }); WayInfo readWay = target.Read() as WayInfo; this.CompareWays(_wayProperties, readWay); }
public void Read_ReadsWayWithAllAttributes() { OsmXmlReader target = new OsmXmlReader(TestDataReader.OpenXml("osm-way-all-properties.osm"), new OsmXmlReaderSettings() { ReadMetadata = true }); WayInfo readWay = target.Read() as WayInfo; this.CompareWays(_wayProperties, readWay); }
public void Read_ReadsSimpleWay() { OsmXmlReader target = new OsmXmlReader(new MemoryStream(XmlTestData.osm_simple_way), new OsmXmlReaderSettings() { ReadMetadata = false }); WayInfo readWay = target.Read() as WayInfo; this.CompareWays(_way, readWay); }
public void Read_SkipsWayMetadataIfProcessMetadataIsFalse_NoCompresion() { PbfReader target = new PbfReader(new MemoryStream(PbfTestData.pbf_n_way_all_properties), new OsmReaderSettings() { ReadMetadata = false }); WayInfo readWay = target.Read() as WayInfo; Assert.Null(readWay.Metadata); }
public void Read_ReadsWayWithMetadata_NoCompresion() { PbfReader target = new PbfReader(new MemoryStream(PbfTestData.pbf_n_way_all_properties), new OsmReaderSettings() { ReadMetadata = true }); WayInfo readWay = target.Read() as WayInfo; this.CompareWays(_wayProperties, readWay); }
public void Read_ReadsWayWithoutNodes_NoCompresion() { PbfReader target = new PbfReader(TestDataReader.OpenPbf("pbf-n-way-without-nodes.pbf"), new OsmReaderSettings() { ReadMetadata = false }); WayInfo readWay = target.Read() as WayInfo; this.CompareWays(_wayWithoutNodes, readWay); }
public void Read_ReadsWayWithoutNodes_NoCompresion() { PbfReader target = new PbfReader(new MemoryStream(PbfTestData.pbf_n_way_without_nodes), new OsmReaderSettings() { ReadMetadata = false }); WayInfo readWay = target.Read() as WayInfo; this.CompareWays(_wayWithoutNodes, readWay); }
public void Read_SkipsWayMetadataIfProcessMetadataIsFalse_NoCompresion() { PbfReader target = new PbfReader(TestDataReader.OpenPbf("pbf-n-way-all-properties.pbf"), new OsmReaderSettings() { ReadMetadata = false }); WayInfo readWay = target.Read() as WayInfo; Assert.Null(readWay.Metadata); }
public void Read_ReadsWayWithMetadata_NoCompresion() { PbfReader target = new PbfReader(TestDataReader.OpenPbf("pbf-n-way-all-properties.pbf"), new OsmReaderSettings() { ReadMetadata = true }); WayInfo readWay = target.Read() as WayInfo; this.CompareWays(_wayProperties, readWay); }
public void Read_ReadsWayWithoutNodes() { OsmXmlReader target = new OsmXmlReader(TestDataReader.OpenXml("osm-way-without-nodes.osm"), new OsmXmlReaderSettings() { ReadMetadata = false }); WayInfo readWay = target.Read() as WayInfo; this.CompareWays(_wayWithoutNodes, readWay); }
public void Read_ReadsWayWithUnknownElement() { OsmXmlReader target = new OsmXmlReader(new MemoryStream(XmlTestData.osm_way_with_tags_and_unknown_element), new OsmXmlReaderSettings() { ReadMetadata = false }); WayInfo readWay = target.Read() as WayInfo; this.CompareWays(_wayTags, readWay); }
/// <summary> /// Reads Way from the currnt element in the _xmlReader. /// </summary> /// <returns>Information about parsed way.</returns> private WayInfo ReadWay() { string attId = _xmlReader.GetAttribute("id"); if (attId == null) { throw new Sys.XmlException("Attribute 'id' is missing."); } var wayId = long.Parse(attId, System.Globalization.CultureInfo.InvariantCulture); EntityMetadata additionalInfo = null; if (this.Settings.ReadMetadata) { additionalInfo = this.ReadMetadata(); } WayInfo way = new WayInfo(wayId, new TagsCollection(), new List <long>(), additionalInfo); if (_xmlReader.IsEmptyElement == false) { _xmlReader.Read(); while (_xmlReader.NodeType != Sys.XmlNodeType.EndElement) { switch (_xmlReader.NodeType) { case Sys.XmlNodeType.Element: switch (_xmlReader.Name) { case "nd": way.Nodes.Add(this.ReadWayNd()); continue; case "tag": way.Tags.Add(this.ReadTag()); continue; default: _xmlReader.Skip(); continue; } default: _xmlReader.Skip(); break; } } } _xmlReader.Skip(); return(way); }
private bool IsWater(OSMMetaManager manager, WayInfo wayInfo) { if (wayInfo.ContainsKeyValue(manager, "waterway", "river")) { return(false); // not area } if (wayInfo.ContainsKeyValue(manager, "type", "waterway")) { return(false); // not area } return(wayInfo.ContainsKeyValue(manager, "natural", "water")); }
private void CompareWays(WayInfo expected, WayInfo actual) { Assert.Equal(expected.ID, actual.ID); Assert.Equal(expected.Nodes.Count, actual.Nodes.Count); for (int i = 0; i < expected.Nodes.Count; i++) { Assert.Equal(expected.Nodes[i], actual.Nodes[i]); } this.CompareTags(expected.Tags, actual.Tags); this.CompareEntityDetails(expected.Metadata, actual.Metadata); }
public void Constructor_Way_SetsProperties() { Way way = new Way(10, new Node[0], new TagsCollection()) { Metadata = new EntityMetadata() }; WayInfo target = new WayInfo(way); Assert.Equal(way.ID, target.ID); Assert.Same(way.Tags, target.Tags); Assert.Same(way.Metadata, target.Metadata); }
public void Constructor_PropertiesWithoutEntityDetails_SetsProperties() { int id = 45; TagsCollection tags = new TagsCollection(); List <long> nodes = new List <long>(); WayInfo target = new WayInfo(id, tags, nodes); Assert.Equal(EntityType.Way, target.EntityType); Assert.Equal(id, target.ID); Assert.Same(tags, target.Tags); Assert.Same(nodes, target.Nodes); Assert.Null(target.Metadata); }
public void Constructor_Properties_SetsProperties() { int id = 45; TagsCollection tags = new TagsCollection(); List <int> nodes = new List <int>(); EntityMetadata details = new EntityMetadata(); WayInfo target = new WayInfo(id, tags, nodes, details); Assert.Equal(EntityType.Way, target.EntityType); Assert.Equal(id, target.ID); Assert.Same(tags, target.Tags); Assert.Same(nodes, target.Nodes); Assert.Same(details, target.Metadata); }
public void Constructor_Way_SetsNodesReferences() { Way way = new Way(10, new Node[] { new Node(1), new Node(2), new Node(3) }, new TagsCollection()) { Metadata = new EntityMetadata() }; WayInfo target = new WayInfo(way); Assert.Equal(way.Nodes.Count, target.Nodes.Count); for (int i = 0; i < way.Nodes.Count; i++) { Assert.Equal(way.Nodes[i].ID, target.Nodes[i]); } }
public OsmXmlReaderTests() { _details = new EntityMetadata() { Timestamp = new DateTime(2010, 11, 19, 22, 5, 56, DateTimeKind.Utc), Uid = 127998, User = "******", Visible = true, Version = 2, Changeset = 6410629 }; _node = new NodeInfo(1, 50.4, 16.2, new TagsCollection()); _nodeTags = new NodeInfo(2, 50.4, 16.2, new TagsCollection(new Tag[] { new Tag("name", "test"), new Tag("name-2", "test-2") })); _nodeProperties = new NodeInfo(3, 50.4, 16.2, new TagsCollection(), _details); _way = new WayInfo(1, new TagsCollection(), new long[] { 10, 11, 12 }); _wayTags = new WayInfo(2, new TagsCollection(new Tag[] { new Tag("name", "test"), new Tag("name-2", "test-2") }), new long[] { 10, 11, 12 }); _wayProperties = new WayInfo(1, new TagsCollection(), new long[] { 10, 11, 12 }, _details); _wayWithoutNodes = new WayInfo(1, new TagsCollection(), new long[] { }); _relationNode = new RelationInfo(1, new TagsCollection(), new RelationMemberInfo[] { new RelationMemberInfo() { MemberType = EntityType.Node, Reference = 10, Role = "test" } }); _relationWay = new RelationInfo(1, new TagsCollection(), new RelationMemberInfo[] { new RelationMemberInfo() { MemberType = EntityType.Way, Reference = 10, Role = "test" } }); _relationRelation = new RelationInfo(1, new TagsCollection(), new RelationMemberInfo[] { new RelationMemberInfo() { MemberType = EntityType.Relation, Reference = 10, Role = "test" } }); _relationTags = new RelationInfo( 2, new TagsCollection(new Tag[] { new Tag("name", "test"), new Tag("name-2", "test-2") }), new RelationMemberInfo[] { new RelationMemberInfo() { MemberType = EntityType.Node, Reference = 10, Role = "test" } }); _relationProperties = new RelationInfo(1, new TagsCollection(), new RelationMemberInfo[] { new RelationMemberInfo() { MemberType = EntityType.Node, Reference = 10, Role = "test" } }, _details); _relationWithoutMembers = new RelationInfo(1, new TagsCollection(), new RelationMemberInfo[] { }); }
/// <summary> /// Writes way to the output stream /// </summary> /// <param name="info">The Way to be written</param> private void WriteWay(WayInfo info) { _writer.WriteStartElement("way"); _writer.WriteAttributeString("id", info.ID.ToString(_culture)); if (this.Settings.WriteMetadata) { this.WriteMetadata(info.Metadata); } this.WriteTags(info.Tags); for (int i = 0; i < info.Nodes.Count; i++) { _writer.WriteStartElement("nd"); _writer.WriteAttributeString("ref", info.Nodes[i].ToString(_culture)); _writer.WriteEndElement(); } _writer.WriteEndElement(); }
// http://www.openstreetmap.org/api/0.6/map?bbox=-1.080351,50.895238,-1.054516,50.907688 private void workerThread() { // Disable 'Go' button until processing is done m_goButtonEnabled = false; m_myForm.Invoke(m_myForm.m_myGoButtonEnabledDelegate); // Load Theme data ArrayList keys = new ArrayList(); //ArrayList allWayTags = new ArrayList(); // All keys in all ways XmlDocument themeDoc = new XmlDocument(); themeDoc.Load(themeTextBox.Text); // Load key list XmlNodeList keyNodeList = themeDoc.SelectNodes("osm2tab/keys/key"); foreach (XmlNode keyNode in keyNodeList) { keys.Add(keyNode.SelectSingleNode("@name").Value); } double[] pointsX = new double[2000]; // 2000 is 0.6 OSM spec double[] pointsY = new double[2000]; // Optimal settings? // 1. Don't add features that don't match 'style key's in the theme // 2. <next criteria of optimal> // 3. <next criteria of optimal> // Regions bool optimalRegions = false; XmlNode regionStylesNode = themeDoc.SelectSingleNode("osm2tab/regionStyles"); XmlNode optimalRegionStylesNode = regionStylesNode.SelectSingleNode("@optimal"); if(optimalRegionStylesNode != null) optimalRegions = optimalRegionStylesNode.Value == "yes"; // Lines bool optimalLines = false; XmlNode lineStylesNode = themeDoc.SelectSingleNode("osm2tab/lineStyles"); XmlNode optimalLineStylesNode = lineStylesNode.SelectSingleNode("@optimal"); if (optimalLineStylesNode != null) optimalLines = optimalLineStylesNode.Value == "yes"; // Load OSM data System.IO.FileStream bz2Stream = System.IO.File.OpenRead(inputTextBox.Text); ICSharpCode.SharpZipLib.BZip2.BZip2InputStream osmStream = new ICSharpCode.SharpZipLib.BZip2.BZip2InputStream(bz2Stream); XmlTextReader reader = new XmlTextReader(osmStream); SortedList nodeList = new SortedList(); SortedList wayList = new SortedList(); SortedList tagKeyLengthList = new SortedList(); WayInfo currentWay = null; NodeInfo currentNode = null; m_status = "Starting"; m_myForm.Invoke(m_myForm.m_myCurrentWayDelegate); // Used to calculate TAB database field format //needs to Be an Array of longest strings per field otherwise all fields will Get same width. even simple ones //but field widths should be consistent so what do we do int longestString = 0; int loadedNodeCount = 0; // Cache XML file as fast-readable database in ram while (reader.Read()) { // Log progress if (loadedNodeCount++ % 100000 == 0) { m_status = "Loading OSM: " + Convert.ToString(loadedNodeCount/100000); m_myForm.Invoke(m_myForm.m_myCurrentWayDelegate); } switch (reader.NodeType) { case System.Xml.XmlNodeType.Element: { if (reader.Name.Equals("node")) { //currentWay = null; // tags can be for nodes or ways int id = Convert.ToInt32(reader.GetAttribute("id")); NodeInfo node = new NodeInfo(); node.tags = new SortedList(); node.lat = Convert.ToDouble(reader.GetAttribute("lat")); node.lon = Convert.ToDouble(reader.GetAttribute("lon")); if(!nodeList.Contains(id)) nodeList.Add(id, node); else { // need to trace data source error } currentWay = null; currentNode = node; } else if (reader.Name.Equals("way")) { WayInfo way = new WayInfo(); way.nodes = new ArrayList(); way.tags = new SortedList(); way.id = Convert.ToInt32(reader.GetAttribute("id")); // this can be a duplicate in an error in the osm data // therefore current node should be null and nd and way needs to check for null if (!wayList.Contains(way.id)) wayList.Add(way.id, way); else { // !! need to trace error currentWay.corrupt = true; } currentWay = way; currentNode = null; } else if (reader.Name.Equals("nd")) { int ndRef = Convert.ToInt32(reader.GetAttribute("ref")); NodeInfo ni = (NodeInfo)nodeList[ndRef]; if (ni != null) { currentWay.nodes.Add(ni); } else { // Node ref not found - error! currentWay.corrupt = true; } } else if (reader.Name.Equals("tag")) { // Way Tags //if (currentWay != null) //{ // Way Keys only TagInfo ki = new TagInfo(); ki.k = reader.GetAttribute("k"); ki.v = reader.GetAttribute("v"); if (currentWay != null) { currentWay.tags.Add(ki.k, ki); } if (currentNode != null) { currentNode.tags.Add(ki.k, ki); } // Compile list of tags for TAB fields if not specified in theme.xml if ((keyNodeList.Count == 0) && !keys.Contains(ki.k)) keys.Add(ki.k); // Update max key name size for MI tab field width // Each Key if (!tagKeyLengthList.Contains(ki.k)) { // If there is not a TagKeyLength tkl = new TagKeyLength(); tkl.k = ki.k; tkl.max = ki.v.Length; tagKeyLengthList.Add(ki.k, tkl); } else { TagKeyLength tkl = (TagKeyLength)tagKeyLengthList[ki.k]; if (tkl.max < ki.v.Length) tkl.max = ki.v.Length; } // log longest string if (ki.v.Length > longestString) longestString = ki.v.Length; //} //else if (currentRelation blah blah != null) //{ //} } else if (reader.Name.Equals("relation")) { currentWay = null; currentNode = null; int a = 0; int b = a + 1; } break; } } } // Create MapInfo tabs IntPtr regionTabFile = MiApi.mitab_c_create(outputTextBox.Text + "\\" + tabPrefix.Text + "_region.tab", "tab", "Earth Projection 1, 104", 0, 0, 0, 0); IntPtr lineTabFile = MiApi.mitab_c_create(outputTextBox.Text + "\\" + tabPrefix.Text + "_line.tab", "tab", "Earth Projection 1, 104", 0, 0, 0, 0); IntPtr pointTabFile = MiApi.mitab_c_create(outputTextBox.Text + "\\" + tabPrefix.Text + "_point.tab", "tab", "Earth Projection 1, 104", 0, 0, 0, 0); // Create fields int index = 0; // Max MapInfo fields is 255 (not 256 it seems) if (keys.Count > 250) { m_debug += "Too many fields"; m_myForm.Invoke(m_myForm.m_myDebugDelegate); int amountToReduce = keys.Count - 250; keys.RemoveRange(250, amountToReduce); } foreach (string key in keys) { // Get max field width TagKeyLength tkl = (TagKeyLength)tagKeyLengthList[key]; if (tkl != null) { MiApi.mitab_c_add_field(regionTabFile, key, 1, tkl.max, 0, 0, 0); MiApi.mitab_c_add_field(lineTabFile, key, 1, tkl.max, 0, 0, 0); MiApi.mitab_c_add_field(pointTabFile, key, 1, tkl.max, 0, 0, 0); } else { // No key exists in the dataset so there is no max length - make it 32 MiApi.mitab_c_add_field(regionTabFile, key, 1, 32, 0, 0, 0); MiApi.mitab_c_add_field(lineTabFile, key, 1, 32, 0, 0, 0); MiApi.mitab_c_add_field(pointTabFile, key, 1, 32, 0, 0, 0); } index++; } // Create MapInfo tabs from cached database m_maxWays = wayList.Count; m_myForm.Invoke(m_myForm.m_myMaxWaysDelegate); // Points for (int i = 0; i < nodeList.Count; i++) { NodeInfo node = (NodeInfo)nodeList.GetByIndex(i); // If a node has tags then it's a point object. // Not entirely convinced this is the best way to deduce point objects. if (node.tags.Count >= 1) { } } // Lines and Regions for (int i = 0; i < wayList.Count; i++) { // Log progress if (i % 10000 == 0) { m_status = "Translating : " + Convert.ToString((100* i) / wayList.Count) + "%"; m_myForm.Invoke(m_myForm.m_myCurrentWayDelegate); } WayInfo way = (WayInfo)wayList.GetByIndex(i); if (way.corrupt) continue; bool iAmARegion = false; ArrayList nodes = ((WayInfo)wayList.GetByIndex(i)).nodes; // Is this a region? i.e. first and last nodes the same NodeInfo firstNode = (NodeInfo)nodes[0]; NodeInfo lastNode = (NodeInfo)nodes[nodes.Count - 1]; if ((firstNode.lat == lastNode.lat) && (firstNode.lon == lastNode.lon)) { iAmARegion = true; } for (int j = 0; j < nodes.Count; j++) { NodeInfo node = (NodeInfo)nodes[j]; pointsX[j] = node.lon; pointsY[j] = node.lat; } if (iAmARegion && nodes.Count >=3) { // Region IntPtr feat = MiApi.mitab_c_create_feature(regionTabFile, 7); // 7 = region // 'part' param is -1 for single part regions. Need to use relation nodes to add 'holes' to -1 part polys which have poly numbers 1+ MiApi.mitab_c_set_points(feat, -1, nodes.Count - 1, pointsX, pointsY); // nodes.Count -1 as last and first nodes are the same int gti = 0; // get tag info foreach (string key in keys) { TagInfo tag = (TagInfo)way.tags[key]; if (tag != null) // Not every field is used MiApi.mitab_c_set_field(feat, gti, tag.v); gti++; } // Set Region Style XmlNodeList styleNodeList = themeDoc.SelectNodes("osm2tab/regionStyles/style"); bool styleFoundForThisFeature = false; // Used in conjunction with 'optimal' region option foreach (XmlNode styleNode in styleNodeList) { string styleKey = styleNode.SelectSingleNode("@key").Value; TagInfo tag = (TagInfo)way.tags[styleKey]; if (tag != null) // Not every field is used { XmlNode valueAttribute = styleNode.SelectSingleNode("@value"); string styleKeyValue = ""; if (valueAttribute != null) styleKeyValue = valueAttribute.Value; // If there is no value attribute for this key then all features with this key have style applied if (tag.v == styleKeyValue || valueAttribute == null) { int pattern = Convert.ToInt32(styleNode.SelectSingleNode("@pattern").Value); int foreground = Convert.ToInt32(styleNode.SelectSingleNode("@foreground").Value); int background = Convert.ToInt32(styleNode.SelectSingleNode("@background").Value); int transparent = Convert.ToInt32(styleNode.SelectSingleNode("@transparent").Value); int penPattern = Convert.ToInt32(styleNode.SelectSingleNode("@penPattern").Value); int penColour = Convert.ToInt32(styleNode.SelectSingleNode("@penColour").Value); int penWidth = Convert.ToInt32(styleNode.SelectSingleNode("@penWidth").Value); MiApi.mitab_c_set_brush(feat, foreground, background, pattern, transparent); MiApi.mitab_c_set_pen(feat, penWidth, penPattern, penColour); styleFoundForThisFeature = true; } } } if (!(!styleFoundForThisFeature && optimalRegions) && // Only write feature to TAB if style is specified way.tags.Count != 0) // Don't write feature if it has no tags. TODO make this optional in Theme xml file { MiApi.mitab_c_write_feature(regionTabFile, feat); } MiApi.mitab_c_destroy_feature(feat); } else if (nodes.Count >= 2) { // Line IntPtr feat = MiApi.mitab_c_create_feature(regionTabFile, 5); // 5 = region MiApi.mitab_c_set_points(feat, 0, nodes.Count, pointsX, pointsY); // part is 0 - can we use relation nodes to associate further (>0) parts? int gti = 0; // get tag info foreach (string key in keys) { TagInfo tag = (TagInfo)way.tags[key]; if(tag != null) // Not every field is used MiApi.mitab_c_set_field(feat, gti, tag.v); gti++; } // Set Line Style XmlNodeList styleNodeList = themeDoc.SelectNodes("osm2tab/lineStyles/style"); bool styleFoundForThisFeature = false; // Used in conjunction with 'optimal' line option foreach (XmlNode styleNode in styleNodeList) { string styleKey = styleNode.SelectSingleNode("@key").Value; TagInfo tag = (TagInfo)way.tags[styleKey]; if (tag != null) // Not every field is used { XmlNode valueAttribute = styleNode.SelectSingleNode("@value"); string styleKeyValue = ""; if (valueAttribute != null) styleKeyValue = valueAttribute.Value; // If there is no value attribute for this key then all features with this key have style applied if (tag.v == styleKeyValue || valueAttribute == null) { int penPattern = Convert.ToInt32(styleNode.SelectSingleNode("@penPattern").Value); int penColour = Convert.ToInt32(styleNode.SelectSingleNode("@penColour").Value); int penWidth = Convert.ToInt32(styleNode.SelectSingleNode("@penWidth").Value); MiApi.mitab_c_set_pen(feat, penWidth, penPattern, penColour); styleFoundForThisFeature = true; } } } if (!(!styleFoundForThisFeature && optimalLines) && // Only write feature to TAB if style is specified way.tags.Count != 0) // Don't write feature if it has no tags. TODO make this optional in Theme xml file { MiApi.mitab_c_write_feature(lineTabFile, feat); } MiApi.mitab_c_destroy_feature(feat); } } MiApi.mitab_c_close(regionTabFile); MiApi.mitab_c_close(lineTabFile); m_status = "Done!"; //m_status = longestString.ToString(); m_myForm.Invoke(m_myForm.m_myCurrentWayDelegate); // Enable 'Go' button m_goButtonEnabled = true; m_myForm.Invoke(m_myForm.m_myGoButtonEnabledDelegate); }
internal void LoadAll(string fileName) { string filePath = Path.Combine(OSMPaths.GetLocalCacheRoot(), fileName); using (var reader = File.Open(filePath, FileMode.Open)) { using (var br = new BinaryReader(reader)) { int edgeInfoCount = br.ReadInt32(); for (int j = 0; j < edgeInfoCount; j++) { EdgeInfo e = new EdgeInfo(); e.wayID = br.ReadInt64(); e.node1 = br.ReadInt64(); e.node2 = br.ReadInt64(); e.longLat1 = new LongLat(br.ReadDouble(), br.ReadDouble()); e.longLat2 = new LongLat(br.ReadDouble(), br.ReadDouble()); if (!edgeInfo.Contains(e)) { edgeInfo.Add(e); } } int wayInfoCount = br.ReadInt32(); for (int j = 0; j < wayInfoCount; j++) { WayInfo w = new WayInfo(); w.id = br.ReadInt64(); w.startNode = br.ReadInt64(); w.endNode = br.ReadInt64(); int keyValueCount = br.ReadInt32(); w.keys = new List <int>(); w.values = new List <int>(); w.relations = new List <long>(); for (int k = 0; k < keyValueCount; k++) { w.keys.Add(LoadIntoStringTable(br.ReadString())); w.values.Add(LoadIntoStringTable(br.ReadString())); } if (!wayInfo.ContainsKey(w.id)) { wayInfo[w.id] = w; } } int relationInfoCount = br.ReadInt32(); for (int j = 0; j < relationInfoCount; j++) { RelationInfo r = new RelationInfo(); r.id = br.ReadInt64(); int keyValueCount = br.ReadInt32(); r.keys = new List <int>(); r.values = new List <int>(); for (int k = 0; k < keyValueCount; k++) { r.keys.Add(LoadIntoStringTable(br.ReadString())); r.values.Add(LoadIntoStringTable(br.ReadString())); } int roleValuesCount = br.ReadInt32(); r.roleValues = new List <int>(); for (int k = 0; k < roleValuesCount; k++) { r.roleValues.Add(LoadIntoStringTable(br.ReadString())); } int memidsCount = br.ReadInt32(); r.memids = new List <long>(); for (int k = 0; k < memidsCount; k++) { r.memids.Add(br.ReadInt64()); if (wayInfo.ContainsKey(r.memids.Last())) { wayInfo[r.memids.Last()].relations.Add(r.id); } } int typesCount = br.ReadInt32(); r.types = new List <int>(); for (int k = 0; k < typesCount; k++) { r.types.Add(br.ReadInt32()); } if (!relationInfo.ContainsKey(r.id)) { relationInfo[r.id] = r; } } } } }
// http://www.openstreetmap.org/api/0.6/map?bbox=-1.080351,50.895238,-1.054516,50.907688 private void workerThread() { // Disable 'Go' button until processing is done m_goButtonEnabled = false; m_myForm.Invoke(m_myForm.m_myGoButtonEnabledDelegate); // Load Theme data ArrayList keys = new ArrayList(); //ArrayList allWayTags = new ArrayList(); // All keys in all ways XmlDocument themeDoc = new XmlDocument(); themeDoc.Load(themeTextBox.Text); // Load key list XmlNodeList keyNodeList = themeDoc.SelectNodes("osm2tab/keys/key"); foreach (XmlNode keyNode in keyNodeList) { keys.Add(keyNode.SelectSingleNode("@name").Value); } double[] pointsX = new double[2000]; // 2000 is 0.6 OSM spec double[] pointsY = new double[2000]; // Optimal settings? // 1. Don't add features that don't match 'style key's in the theme // 2. <next criteria of optimal> // 3. <next criteria of optimal> // Regions bool optimalRegions = false; XmlNode regionStylesNode = themeDoc.SelectSingleNode("osm2tab/regionStyles"); XmlNode optimalRegionStylesNode = regionStylesNode.SelectSingleNode("@optimal"); if (optimalRegionStylesNode != null) { optimalRegions = optimalRegionStylesNode.Value == "yes"; } // Lines bool optimalLines = false; XmlNode lineStylesNode = themeDoc.SelectSingleNode("osm2tab/lineStyles"); XmlNode optimalLineStylesNode = lineStylesNode.SelectSingleNode("@optimal"); if (optimalLineStylesNode != null) { optimalLines = optimalLineStylesNode.Value == "yes"; } // Load OSM data System.IO.FileStream bz2Stream = System.IO.File.OpenRead(inputTextBox.Text); ICSharpCode.SharpZipLib.BZip2.BZip2InputStream osmStream = new ICSharpCode.SharpZipLib.BZip2.BZip2InputStream(bz2Stream); XmlTextReader reader = new XmlTextReader(osmStream); SortedList nodeList = new SortedList(); SortedList wayList = new SortedList(); SortedList tagKeyLengthList = new SortedList(); WayInfo currentWay = null; NodeInfo currentNode = null; m_status = "Starting"; m_myForm.Invoke(m_myForm.m_myCurrentWayDelegate); // Used to calculate TAB database field format //needs to Be an Array of longest strings per field otherwise all fields will Get same width. even simple ones //but field widths should be consistent so what do we do int longestString = 0; int loadedNodeCount = 0; // Cache XML file as fast-readable database in ram while (reader.Read()) { // Log progress if (loadedNodeCount++ % 100000 == 0) { m_status = "Loading OSM: " + Convert.ToString(loadedNodeCount / 100000); m_myForm.Invoke(m_myForm.m_myCurrentWayDelegate); } switch (reader.NodeType) { case System.Xml.XmlNodeType.Element: { if (reader.Name.Equals("node")) { //currentWay = null; // tags can be for nodes or ways int id = Convert.ToInt32(reader.GetAttribute("id")); NodeInfo node = new NodeInfo(); node.tags = new SortedList(); node.lat = Convert.ToDouble(reader.GetAttribute("lat")); node.lon = Convert.ToDouble(reader.GetAttribute("lon")); if (!nodeList.Contains(id)) { nodeList.Add(id, node); } else { // need to trace data source error } currentWay = null; currentNode = node; } else if (reader.Name.Equals("way")) { WayInfo way = new WayInfo(); way.nodes = new ArrayList(); way.tags = new SortedList(); way.id = Convert.ToInt32(reader.GetAttribute("id")); // this can be a duplicate in an error in the osm data // therefore current node should be null and nd and way needs to check for null if (!wayList.Contains(way.id)) { wayList.Add(way.id, way); } else { // !! need to trace error currentWay.corrupt = true; } currentWay = way; currentNode = null; } else if (reader.Name.Equals("nd")) { int ndRef = Convert.ToInt32(reader.GetAttribute("ref")); NodeInfo ni = (NodeInfo)nodeList[ndRef]; if (ni != null) { currentWay.nodes.Add(ni); } else { // Node ref not found - error! currentWay.corrupt = true; } } else if (reader.Name.Equals("tag")) { // Way Tags //if (currentWay != null) //{ // Way Keys only TagInfo ki = new TagInfo(); ki.k = reader.GetAttribute("k"); ki.v = reader.GetAttribute("v"); if (currentWay != null) { currentWay.tags.Add(ki.k, ki); } if (currentNode != null) { currentNode.tags.Add(ki.k, ki); } // Compile list of tags for TAB fields if not specified in theme.xml if ((keyNodeList.Count == 0) && !keys.Contains(ki.k)) { keys.Add(ki.k); } // Update max key name size for MI tab field width // Each Key if (!tagKeyLengthList.Contains(ki.k)) { // If there is not a TagKeyLength tkl = new TagKeyLength(); tkl.k = ki.k; tkl.max = ki.v.Length; tagKeyLengthList.Add(ki.k, tkl); } else { TagKeyLength tkl = (TagKeyLength)tagKeyLengthList[ki.k]; if (tkl.max < ki.v.Length) { tkl.max = ki.v.Length; } } // log longest string if (ki.v.Length > longestString) { longestString = ki.v.Length; } //} //else if (currentRelation blah blah != null) //{ //} } else if (reader.Name.Equals("relation")) { currentWay = null; currentNode = null; int a = 0; int b = a + 1; } break; } } } // Create MapInfo tabs IntPtr regionTabFile = MiApi.mitab_c_create(outputTextBox.Text + "\\" + tabPrefix.Text + "_region.tab", "tab", "Earth Projection 1, 104", 0, 0, 0, 0); IntPtr lineTabFile = MiApi.mitab_c_create(outputTextBox.Text + "\\" + tabPrefix.Text + "_line.tab", "tab", "Earth Projection 1, 104", 0, 0, 0, 0); IntPtr pointTabFile = MiApi.mitab_c_create(outputTextBox.Text + "\\" + tabPrefix.Text + "_point.tab", "tab", "Earth Projection 1, 104", 0, 0, 0, 0); // Create fields int index = 0; // Max MapInfo fields is 255 (not 256 it seems) if (keys.Count > 250) { m_debug += "Too many fields"; m_myForm.Invoke(m_myForm.m_myDebugDelegate); int amountToReduce = keys.Count - 250; keys.RemoveRange(250, amountToReduce); } foreach (string key in keys) { // Get max field width TagKeyLength tkl = (TagKeyLength)tagKeyLengthList[key]; if (tkl != null) { MiApi.mitab_c_add_field(regionTabFile, key, 1, tkl.max, 0, 0, 0); MiApi.mitab_c_add_field(lineTabFile, key, 1, tkl.max, 0, 0, 0); MiApi.mitab_c_add_field(pointTabFile, key, 1, tkl.max, 0, 0, 0); } else { // No key exists in the dataset so there is no max length - make it 32 MiApi.mitab_c_add_field(regionTabFile, key, 1, 32, 0, 0, 0); MiApi.mitab_c_add_field(lineTabFile, key, 1, 32, 0, 0, 0); MiApi.mitab_c_add_field(pointTabFile, key, 1, 32, 0, 0, 0); } index++; } // Create MapInfo tabs from cached database m_maxWays = wayList.Count; m_myForm.Invoke(m_myForm.m_myMaxWaysDelegate); // Points for (int i = 0; i < nodeList.Count; i++) { NodeInfo node = (NodeInfo)nodeList.GetByIndex(i); // If a node has tags then it's a point object. // Not entirely convinced this is the best way to deduce point objects. if (node.tags.Count >= 1) { } } // Lines and Regions for (int i = 0; i < wayList.Count; i++) { // Log progress if (i % 10000 == 0) { m_status = "Translating : " + Convert.ToString((100 * i) / wayList.Count) + "%"; m_myForm.Invoke(m_myForm.m_myCurrentWayDelegate); } WayInfo way = (WayInfo)wayList.GetByIndex(i); if (way.corrupt) { continue; } bool iAmARegion = false; ArrayList nodes = ((WayInfo)wayList.GetByIndex(i)).nodes; // Is this a region? i.e. first and last nodes the same NodeInfo firstNode = (NodeInfo)nodes[0]; NodeInfo lastNode = (NodeInfo)nodes[nodes.Count - 1]; if ((firstNode.lat == lastNode.lat) && (firstNode.lon == lastNode.lon)) { iAmARegion = true; } for (int j = 0; j < nodes.Count; j++) { NodeInfo node = (NodeInfo)nodes[j]; pointsX[j] = node.lon; pointsY[j] = node.lat; } if (iAmARegion && nodes.Count >= 3) { // Region IntPtr feat = MiApi.mitab_c_create_feature(regionTabFile, 7); // 7 = region // 'part' param is -1 for single part regions. Need to use relation nodes to add 'holes' to -1 part polys which have poly numbers 1+ MiApi.mitab_c_set_points(feat, -1, nodes.Count - 1, pointsX, pointsY); // nodes.Count -1 as last and first nodes are the same int gti = 0; // get tag info foreach (string key in keys) { TagInfo tag = (TagInfo)way.tags[key]; if (tag != null) // Not every field is used { MiApi.mitab_c_set_field(feat, gti, tag.v); } gti++; } // Set Region Style XmlNodeList styleNodeList = themeDoc.SelectNodes("osm2tab/regionStyles/style"); bool styleFoundForThisFeature = false; // Used in conjunction with 'optimal' region option foreach (XmlNode styleNode in styleNodeList) { string styleKey = styleNode.SelectSingleNode("@key").Value; TagInfo tag = (TagInfo)way.tags[styleKey]; if (tag != null) // Not every field is used { XmlNode valueAttribute = styleNode.SelectSingleNode("@value"); string styleKeyValue = ""; if (valueAttribute != null) { styleKeyValue = valueAttribute.Value; } // If there is no value attribute for this key then all features with this key have style applied if (tag.v == styleKeyValue || valueAttribute == null) { int pattern = Convert.ToInt32(styleNode.SelectSingleNode("@pattern").Value); int foreground = Convert.ToInt32(styleNode.SelectSingleNode("@foreground").Value); int background = Convert.ToInt32(styleNode.SelectSingleNode("@background").Value); int transparent = Convert.ToInt32(styleNode.SelectSingleNode("@transparent").Value); int penPattern = Convert.ToInt32(styleNode.SelectSingleNode("@penPattern").Value); int penColour = Convert.ToInt32(styleNode.SelectSingleNode("@penColour").Value); int penWidth = Convert.ToInt32(styleNode.SelectSingleNode("@penWidth").Value); MiApi.mitab_c_set_brush(feat, foreground, background, pattern, transparent); MiApi.mitab_c_set_pen(feat, penWidth, penPattern, penColour); styleFoundForThisFeature = true; } } } if (!(!styleFoundForThisFeature && optimalRegions) && // Only write feature to TAB if style is specified way.tags.Count != 0) // Don't write feature if it has no tags. TODO make this optional in Theme xml file { MiApi.mitab_c_write_feature(regionTabFile, feat); } MiApi.mitab_c_destroy_feature(feat); } else if (nodes.Count >= 2) { // Line IntPtr feat = MiApi.mitab_c_create_feature(regionTabFile, 5); // 5 = region MiApi.mitab_c_set_points(feat, 0, nodes.Count, pointsX, pointsY); // part is 0 - can we use relation nodes to associate further (>0) parts? int gti = 0; // get tag info foreach (string key in keys) { TagInfo tag = (TagInfo)way.tags[key]; if (tag != null) // Not every field is used { MiApi.mitab_c_set_field(feat, gti, tag.v); } gti++; } // Set Line Style XmlNodeList styleNodeList = themeDoc.SelectNodes("osm2tab/lineStyles/style"); bool styleFoundForThisFeature = false; // Used in conjunction with 'optimal' line option foreach (XmlNode styleNode in styleNodeList) { string styleKey = styleNode.SelectSingleNode("@key").Value; TagInfo tag = (TagInfo)way.tags[styleKey]; if (tag != null) // Not every field is used { XmlNode valueAttribute = styleNode.SelectSingleNode("@value"); string styleKeyValue = ""; if (valueAttribute != null) { styleKeyValue = valueAttribute.Value; } // If there is no value attribute for this key then all features with this key have style applied if (tag.v == styleKeyValue || valueAttribute == null) { int penPattern = Convert.ToInt32(styleNode.SelectSingleNode("@penPattern").Value); int penColour = Convert.ToInt32(styleNode.SelectSingleNode("@penColour").Value); int penWidth = Convert.ToInt32(styleNode.SelectSingleNode("@penWidth").Value); MiApi.mitab_c_set_pen(feat, penWidth, penPattern, penColour); styleFoundForThisFeature = true; } } } if (!(!styleFoundForThisFeature && optimalLines) && // Only write feature to TAB if style is specified way.tags.Count != 0) // Don't write feature if it has no tags. TODO make this optional in Theme xml file { MiApi.mitab_c_write_feature(lineTabFile, feat); } MiApi.mitab_c_destroy_feature(feat); } } MiApi.mitab_c_close(regionTabFile); MiApi.mitab_c_close(lineTabFile); m_status = "Done!"; //m_status = longestString.ToString(); m_myForm.Invoke(m_myForm.m_myCurrentWayDelegate); // Enable 'Go' button m_goButtonEnabled = true; m_myForm.Invoke(m_myForm.m_myGoButtonEnabledDelegate); }
public void StartMainWayJourney(long id, string wayNanme, string fromName, string toName, int taget) { Character character; WayInfo fromWay; WayInfo toWay; WayInfo mainWay; if (characters.TryGetValue(id, out character) && wayInfoByName.TryGetValue(wayNanme, out mainWay) && wayInfoByName.TryGetValue(fromName, out fromWay) && wayInfoByName.TryGetValue(toName, out toWay)) { WayInfo wayInfo = new WayInfo(); wayInfo.direction = toWay.direction; wayInfo.callbackName = toWay.callbackName; wayInfo.repeatType = toWay.repeatType; Vector3 fromPos = fromWay.positions[fromWay.positions.Length - 1]; Vector3 toPos = toWay.positions[0]; int FN_index = 0; //fromPos_Nearest_index 离开始点最近的点的下标 int TN_index = 0; //toPos_Nearest_index 离结束点最近的点的下标 for (int i = 0; i < mainWay.positions.Length - 1; i++) { if (Vector3.Distance(fromPos, mainWay.positions[i]) < Vector3.Distance(fromPos, mainWay.positions[i + 1])) { if (Vector3.Distance(fromPos, mainWay.positions[i]) < Vector3.Distance(fromPos, mainWay.positions[FN_index])) { FN_index = i; } } else { if (Vector3.Distance(fromPos, mainWay.positions[i + 1]) < Vector3.Distance(fromPos, mainWay.positions[FN_index])) { FN_index = i + 1; } } if (Vector3.Distance(toPos, mainWay.positions[i]) < Vector3.Distance(toPos, mainWay.positions[i + 1])) { if (Vector3.Distance(toPos, mainWay.positions[i]) < Vector3.Distance(toPos, mainWay.positions[TN_index])) { TN_index = i; } } else { if (Vector3.Distance(toPos, mainWay.positions[i + 1]) < Vector3.Distance(toPos, mainWay.positions[TN_index])) { TN_index = i + 1; } } } Vector3[] wayPositions = new Vector3[Mathf.Abs(TN_index - FN_index) + fromWay.positions.Length + toWay.positions.Length + 1]; for (int i = 0; i < fromWay.positions.Length; i++) { wayPositions[i] = fromWay.positions[i]; } int idx = fromWay.positions.Length; if (FN_index <= TN_index) { for (int i = FN_index; i <= TN_index; i++) { wayPositions[idx] = mainWay.positions[i]; idx = idx + 1; } } else { for (int i = FN_index; i >= TN_index; i--) { wayPositions[idx] = mainWay.positions[i]; idx = idx + 1; } } for (int i = 0; i < toWay.positions.Length; i++) { wayPositions[idx + i] = toWay.positions[i]; } wayInfo.positions = wayPositions; if (character.agent != null) { if (taget == -1) { int _min = Mathf.FloorToInt(wayInfo.positions.Length * 0.2f); int _max = Mathf.CeilToInt(wayInfo.positions.Length * 0.8f); taget = UnityEngine.Random.Range(_min, _max); } else if (taget >= wayInfo.positions.Length) { Debug.Log("taget is overflow"); taget = 0; } character.obj.transform.position = wayInfo.positions[taget]; character.moving = true; character.wayInfo = wayInfo; character.target = taget; character.agent.isStopped = false; character.agent.SetDestination(wayInfo.positions[taget]); } } }