abbr works only on full words; changes on nodes don't work
[osm-helpers.git] / DataBase.cs
blob9f0c956e17d815b19047bbb3c15ab6cce1e5bb0f
1 /*
2 * Author: Paolo Molaro
3 * Copyright (c) 2008 Paolo Molaro lupus@oddwiz.org
4 * License: MIT/X11, see the MIT.X11 file.
5 */
6 using System;
7 using System.IO;
8 using System.Net;
9 using System.Xml;
10 using System.Text;
11 using System.Collections.Generic;
13 namespace OpenStreetMap {
15 public class DataBase {
17 static readonly string BaseUrl = "http://api.openstreetmap.org/api/0.5/";
18 string url;
20 public DataBase () : this (BaseUrl) {
23 public DataBase (string base_url) {
24 url = base_url;
27 static bool ParseBool (string v)
29 if (v == "true")
30 return true;
31 if (v == "false")
32 return false;
33 throw new Exception ("Invalid boolean values: " + v);
36 public static List<OsmObject> Load (string filename)
38 return Load (File.OpenRead (filename));
41 public static List<OsmObject> Load (Stream stream)
43 List<OsmObject> list = new List<OsmObject> ();
44 foreach (OsmObject obj in LoadObjects (stream))
45 list.Add (obj);
46 return list;
49 public static IEnumerable<OsmObject> LoadObjects (string filename)
51 return LoadObjects (File.OpenRead (filename));
54 public static IEnumerable<OsmObject> LoadObjects (Stream stream)
56 //XmlTextReader reader = new XmlTextReader (stream);
57 XmlTextReader reader = XmlTextReader.Create (stream) as XmlTextReader;
58 Way way = null;
59 Node node = null;
60 Relation relation = null;
61 OsmObject bobject = null;
62 List<long> nodelist = null;
63 List<RelationMember> members = null;
64 bool do_yield = false;
66 while (reader.Read ()) {
67 if (reader.NodeType == XmlNodeType.Element) {
68 string name = reader.Name;
69 if (name == "node") {
70 bobject = node = new Node ();
71 do_yield = reader.IsEmptyElement;
72 } else if (name == "way") {
73 bobject = way = new Way ();
74 do_yield = reader.IsEmptyElement;
75 } else if (name == "relation") {
76 bobject = relation = new Relation ();
77 do_yield = reader.IsEmptyElement;
78 } else if (name == "osm" || name == "bounds") {
79 continue;
80 } else if (name == "member") {
81 long refid = -1;
82 string role = null;
83 string type = null;
84 if (members == null)
85 members = new List<RelationMember> ();
86 for (int i = 0; i < reader.AttributeCount; ++i) {
87 reader.MoveToAttribute (i);
88 if (reader.Name == "ref")
89 refid = long.Parse (reader.Value);
90 else if (reader.Name == "role")
91 role = reader.Value;
92 else if (reader.Name == "type")
93 type = reader.Value;
94 else
95 throw new Exception ("Invalid member attribute: " + reader.Name);
97 members.Add (new RelationMember (relation, type, role, refid));
98 continue;
99 } else if (name == "nd") {
100 if (nodelist == null)
101 nodelist = new List<long> ();
102 for (int i = 0; i < reader.AttributeCount; ++i) {
103 reader.MoveToAttribute (i);
104 if (reader.Name == "ref")
105 nodelist.Add (long.Parse (reader.Value));
106 else
107 throw new Exception ("Invalid nd attribute: " + reader.Name);
109 continue;
110 } else if (name == "tag") {
111 string k = null, v = null;
112 for (int i = 0; i < reader.AttributeCount; ++i) {
113 reader.MoveToAttribute (i);
114 if (reader.Name == "k")
115 k = reader.Value;
116 else if (reader.Name == "v")
117 v = reader.Value;
118 else
119 throw new Exception ("Invalid tag attribute: " + reader.Name);
121 if (k == null | v == null)
122 throw new Exception ("Invalid tag");
123 bobject [k] = v;
124 continue;
125 } else {
126 //Console.WriteLine ("element: {0}", name);
127 continue;
129 for (int i = 0; i < reader.AttributeCount; ++i) {
130 reader.MoveToAttribute (i);
131 name = reader.Name;
132 if (name == "id") {
133 bobject.ID = long.Parse (reader.Value);
134 } else if (name == "user") {
135 bobject.User = reader.Value;
136 } else if (name == "timestamp") {
137 bobject.TimeStamp = reader.Value;
138 } else if (name == "visible") {
139 bobject.Visible = ParseBool (reader.Value);
140 } else if (name == "lon") {
141 node.Longitude = double.Parse (reader.Value);
142 } else if (name == "lat") {
143 node.Latitude = double.Parse (reader.Value);
147 } else if (reader.NodeType == XmlNodeType.EndElement) {
148 string name = reader.Name;
149 if (name == "way" || name == "node" || name == "relation")
150 do_yield = true;
152 if (do_yield) {
153 if (bobject != null) {
154 do_yield = reader.IsEmptyElement;
155 if (bobject is Way && nodelist != null) {
156 way.Nodes = nodelist.ToArray ();
157 nodelist = null;
158 } else if (bobject is Relation && members != null) {
159 relation.Members = members.ToArray ();
160 members = null;
162 yield return bobject;
163 bobject = null;
165 do_yield = false;
171 public OsmObject LoadObject (string type, long id)
173 HttpWebRequest req = WebRequest.Create (string.Format (url + "{0}/{1}", type, id)) as HttpWebRequest;
174 req.Timeout = 5000;
175 HttpWebResponse res = req.GetResponse () as HttpWebResponse;
176 //Console.WriteLine ("{0}: {1}", res.StatusCode, res.StatusDescription);
177 Stream s = res.GetResponseStream ();
178 List<OsmObject> list = Load (s);
179 s.Close ();
180 return list [0];
183 public OsmObject LoadWay (long id)
185 return LoadObject ("way", id);
188 public OsmObject LoadNode (long id)
190 return LoadObject ("node", id);
193 public OsmObject LoadRelation (long id)
195 return LoadObject ("relation", id);
198 public IEnumerable<OsmObject> LoadHistory (string type, long id)
200 HttpWebRequest req = WebRequest.Create (string.Format (url + "{0}/{1}/history", type, id)) as HttpWebRequest;
201 HttpWebResponse res = req.GetResponse () as HttpWebResponse;
202 //Console.WriteLine ("{0}: {1}", res.StatusCode, res.StatusDescription);
203 Stream s = res.GetResponseStream ();
204 List<OsmObject> list = Load (s);
205 s.Close ();
206 return list;
209 public List<OsmObject> Load (double lon1, double lat1, double lon2, double lat2)
211 HttpWebRequest req = WebRequest.Create (string.Format (url + "map?bbox={0},{1},{2},{3}", lon1, lat1, lon2, lat2)) as HttpWebRequest;
212 HttpWebResponse res = req.GetResponse () as HttpWebResponse;
213 //Console.WriteLine ("{0}: {1}", res.StatusCode, res.StatusDescription);
214 Stream s = res.GetResponseStream ();
215 List<OsmObject> list = Load (s);
216 s.Close ();
217 return list;
220 public bool UpLoad (OsmObject obj, string username, string password)
222 if (obj is Relation)
223 return false;
224 //ServicePointManager.Expect100Continue = false;
225 CredentialCache creds = new CredentialCache ();
226 creds.Add (new Uri (url), "Basic", new NetworkCredential (username, password));
227 HttpWebRequest req = WebRequest.Create (string.Format ("{0}{1}/{2}", url, obj.ObjectType, obj.ID)) as HttpWebRequest;
228 req.Method = "PUT";
229 req.Credentials = creds;
230 // stupid apps don't support Expect and it's used by default
231 req.ServicePoint.Expect100Continue = false;
232 req.ReadWriteTimeout = 5000;
233 req.Timeout = 5000;
234 Stream s = req.GetRequestStream ();
235 XmlTextWriter xmlw = new XmlTextWriter (s, new UTF8Encoding (false, false));
236 xmlw.Formatting = Formatting.Indented;
237 xmlw.WriteStartDocument ();
238 xmlw.WriteStartElement ("osm");
239 xmlw.WriteAttributeString ("version", "0.5");
240 xmlw.WriteAttributeString ("creator", "osm-lupus-tools 0.1");
241 obj.WriteXml (xmlw);
242 xmlw.WriteEndElement ();
243 xmlw.WriteEndDocument ();
244 xmlw.Close ();
245 s.Close ();
246 HttpWebResponse res = req.GetResponse () as HttpWebResponse;
247 // need to get the stream and close it to avoid deadlocks
248 s = res.GetResponseStream ();
249 s.Close ();
250 //Console.WriteLine ("{0}: {1}", res.StatusCode, res.StatusDescription);
251 return false;