Exemplo n.º 1
0
        internal static SimpleChangeSet ConvertToSimple(Osm.Xml.v0_6.modify modify)
        {
            // create change set record.
            SimpleChangeSet change_set = new SimpleChangeSet();

            // create change record.
            SimpleChange change = new SimpleChange();
            change.Type = SimpleChangeType.Modify;
            change.OsmGeo = new List<SimpleOsmGeo>();

            // add all relations to the list.
            if (modify.relation != null)
            {
                foreach (Osm.Xml.v0_6.relation osm_geo in modify.relation)
                {
                    change.OsmGeo.Add(XmlSimpleConverter.ConvertToSimple(osm_geo));
                }
            }

            // add all ways to the list.
            if (modify.way != null)
            {
                foreach (Osm.Xml.v0_6.way osm_geo in modify.way)
                {
                    change.OsmGeo.Add(XmlSimpleConverter.ConvertToSimple(osm_geo));
                }
            }

            // add all nodes to the list.
            if (modify.node != null)
            {
                foreach (Osm.Xml.v0_6.node osm_geo in modify.node)
                {
                    change.OsmGeo.Add(XmlSimpleConverter.ConvertToSimple(osm_geo));
                }
            }

            // add change to changeset
            change_set.Changes = new List<SimpleChange>();
            change_set.Changes.Add(change);

            return change_set;
        }
Exemplo n.º 2
0
 /// <summary>
 /// Applies a change to the target.
 /// </summary>
 /// <param name="change"></param>
 public abstract void ApplyChange(SimpleChangeSet change);
        /// <summary>
        /// Returns true if any part of this changeset exists inside the bounding box.
        /// </summary>
        /// <param name="simpleChangeSet"></param>
        /// <returns></returns>
        private bool IsInsideBox(SimpleChangeSet simpleChangeSet)
        {
            // keep a list of tested relation to prevent circular references from hanging this process.
            _tested_relations = new List<long>();

            // keep all the objects that could not be checked and check them later.
            List<SimpleOsmGeo> objects_not_checked = new List<SimpleOsmGeo>();

            // loop over all objects inside this box and if they are nodes they can be checked.
            foreach (SimpleChange change in simpleChangeSet.Changes)
            {
                foreach (SimpleOsmGeo geo in change.OsmGeo)
                {
                    if (geo is SimpleNode)
                    {
                        SimpleNode node = geo as SimpleNode;
                        GeoCoordinate coord = new GeoCoordinate(node.Latitude.Value, node.Longitude.Value);

                        if (_box.IsInsideAny(new OsmSharp.Tools.Math.PointF2D[] { coord }))
                        {
                            return true;
                        }
                    }
                    else
                    {
                        objects_not_checked.Add(geo as SimpleOsmGeo);
                    }
                }
            }

            // try all ways.
            foreach (SimpleOsmGeo geo in objects_not_checked)
            {
                if (geo is SimpleWay && (geo as SimpleWay).Nodes != null)
                {
                    OsmSharp.Osm.Way way = _data_source.GetWay(geo.Id.Value);
                    if (way != null && way.Nodes != null)
                    {
                        foreach (Osm.Node node in way.Nodes)
                        {
                            if (node != null)
                            { // only if the node is found
                                if (_box.IsInsideAny(new OsmSharp.Tools.Math.PointF2D[] { node.Coordinate }))
                                {
                                    return true;
                                }
                            }
                        }
                    }
                }
            }

            // try all relations.
            foreach (SimpleOsmGeo geo in objects_not_checked)
            {
                if (geo is SimpleRelation)
                {
                    if (!_tested_relations.Contains(geo.Id.Value))
                    {
                        _tested_relations.Add(geo.Id.Value);
                        if (this.IsInsideBoxRelation((geo as SimpleRelation).Members))
                        {
                            return true;
                        }
                    }
                }
            }
            return false;
        }
        /// <summary>
        /// Filters the geo objects in the changeset and omits the ones not inside the bb.
        /// </summary>
        /// <param name="simpleChangeSet"></param>
        /// <returns></returns>
        private KeyValuePair<SimpleChangeSet, GeoCoordinateBox> FilterChanges(SimpleChangeSet simpleChangeSet)
        {
            List<GeoCoordinate> changes_coordinates = new List<GeoCoordinate>();

            SimpleChangeSet filtered_changeset = new SimpleChangeSet();
            filtered_changeset.Changes = new List<SimpleChange>();

            // keep a list of tested relation to prevent circular references from hanging this process.
            _tested_relations = new List<long>();

            // keep all the objects that could not be checked and check them later.
            List<KeyValuePair<SimpleOsmGeo, SimpleChange>> objects_not_checked = new List<KeyValuePair<SimpleOsmGeo, SimpleChange>>();

            // loop over all objects inside this box and if they are nodes they can be checked.
            HashSet<long> nodes_inside = new HashSet<long>(); // keep track of all the nodes inside for quick checks later!
            foreach (SimpleChange change in simpleChangeSet.Changes)
            {
                // keep the changed nodes that are ok for the filter.
                List<SimpleOsmGeo> nodes_changed = new List<SimpleOsmGeo>();

                // loop over all objects in this set and keep the nodes.
                foreach (SimpleOsmGeo geo in change.OsmGeo)
                {
                    if (geo is SimpleNode)
                    {
                        SimpleNode node = geo as SimpleNode;
                        GeoCoordinate coord = new GeoCoordinate(node.Latitude.Value, node.Longitude.Value);

                        if (_box.IsInsideAny(new OsmSharp.Tools.Math.PointF2D[] { coord }))
                        {
                            nodes_changed.Add(node);
                            nodes_inside.Add(node.Id.Value);
                            changes_coordinates.Add(coord);
                        }
                    }
                    else
                    {
                        objects_not_checked.Add(new  KeyValuePair<SimpleOsmGeo,SimpleChange>(geo as SimpleOsmGeo,change));
                    }
                }

                // are there changes in the nodes?
                if (nodes_changed.Count > 0)
                {
                   SimpleChange nodes_change = new SimpleChange();
                    nodes_change.OsmGeo = nodes_changed;
                    nodes_change.Type = change.Type;

                    filtered_changeset.Changes.Add(nodes_change);
                }
            }

            // try all ways.
            HashSet<long> ways_inside = new HashSet<long>(); // keep the ways inside for quick checks later!
            foreach(KeyValuePair<SimpleOsmGeo,SimpleChange> change_pair in objects_not_checked)
            {
                SimpleOsmGeo geo = change_pair.Key;
                SimpleChange change = change_pair.Value;

                // keep the changed ways that are ok for the filter.
                List<SimpleOsmGeo> ways_changed = new List<SimpleOsmGeo>();

                // detect if the way is part of the filter!
                if (geo is SimpleWay && (geo as SimpleWay).Nodes != null)
                {
                    // try the cached nodes.
                    foreach (long node_id in (geo as SimpleWay).Nodes)
                    {
                        if (nodes_inside.Contains(node_id))
                        {
                            ways_changed.Add(geo);
                            ways_inside.Add(geo.Id.Value);
                            break;
                        }
                    }

                    // first try to load the complete way.
                    OsmSharp.Osm.Way way = _data_source.GetWay(geo.Id.Value);
                    if (way != null && way.Nodes != null)
                    {
                        foreach (Osm.Node node in way.Nodes)
                        {
                            if (node != null)
                            { // only if the node is found
                                changes_coordinates.Add(node.Coordinate);
                                if (_box.IsInsideAny(new OsmSharp.Tools.Math.PointF2D[] { node.Coordinate }))
                                {
                                    changes_coordinates.Add(node.Coordinate);
                                    ways_changed.Add(geo);
                                    ways_inside.Add(geo.Id.Value);
                                    break;
                                }
                            }
                        }
                    }
                    if (change.Type == SimpleChangeType.Delete && way != null && (way.Nodes == null || way.Nodes.Count == 0))
                    { // alway delete empty ways!
                        ways_changed.Add(geo);
                        ways_inside.Add(geo.Id.Value);
                    }

                    // second try to load the nodes individually.
                    foreach (long node_id in (geo as SimpleWay).Nodes)
                    {
                        OsmSharp.Osm.Node node = _data_source.GetNode(node_id);
                        if (node != null)
                        { // only if the node is found
                            if (_box.IsInsideAny(new OsmSharp.Tools.Math.PointF2D[] { node.Coordinate }))
                            {
                                changes_coordinates.Add(node.Coordinate);
                                ways_changed.Add(geo);
                                ways_inside.Add(geo.Id.Value);
                                break;
                            }
                        }
                    }
                }

                // are there changes in the nodes?
                if (ways_changed.Count > 0)
                {
                    SimpleChange ways_change = new SimpleChange();
                    ways_change.OsmGeo = ways_changed;
                    ways_change.Type = change.Type;

                    filtered_changeset.Changes.Add(ways_change);
                }
            }

            // try all relations.
            foreach(KeyValuePair<SimpleOsmGeo,SimpleChange> change_pair in objects_not_checked)
            {
                SimpleOsmGeo geo = change_pair.Key;
                SimpleChange change = change_pair.Value;

                // keep the changed ways that are ok for the filter.
                List<SimpleOsmGeo> relations_changed = new List<SimpleOsmGeo>();

                // test all relations.
                if (geo is SimpleRelation)
                {
                    if (!_tested_relations.Contains(geo.Id.Value))
                    {
                        _tested_relations.Add(geo.Id.Value);
                        if (this.IsInsideBoxRelation((geo as SimpleRelation).Members,nodes_inside,ways_inside))
                        {
                            relations_changed.Add(geo);
                        }
                    }
                }

                // are there changes in the nodes?
                if (relations_changed.Count > 0)
                {
                    SimpleChange relations_change = new SimpleChange();
                    relations_change.OsmGeo = relations_changed;
                    relations_change.Type = change.Type;

                    filtered_changeset.Changes.Add(relations_change);
                }
            }

            // create bounding box of the found changes!
            GeoCoordinateBox box = null;
            if (changes_coordinates.Count > 0)
            {
                box = new GeoCoordinateBox(changes_coordinates);
            }
            return new KeyValuePair<SimpleChangeSet, GeoCoordinateBox>(filtered_changeset, box);
        }
        /// <summary>
        /// Move to the next object.
        /// </summary>
        /// <returns></returns>
        public override bool MoveNext()
        {
            // move to the next change available.
            while (this.Source.MoveNext())
            {
                // convert the changeset to only data withing this bb!
                KeyValuePair<SimpleChangeSet,GeoCoordinateBox> changes_inside = this.FilterChanges(this.Source.Current());
                if (changes_inside.Key.Changes.Count > 0)
                {
                    // some data in this changeset is ok!
                    OsmSharp.Tools.Output.OutputStreamHost.WriteLine(string.Empty);
                    OsmSharp.Tools.Output.OutputStreamHost.Write("Changeset accepted:");

                    // set the converted changeset as the current one!
                    _current = changes_inside.Key;

                    // report to the listener.
                    if (_listener != null && changes_inside.Value != null)
                    {
                        _listener.ReportChangeDetected(changes_inside.Value);
                    }

                    return true;
                }
            }
            _current = null;
            return false;
        }
        /// <summary>
        /// Moves to the next changeset.
        /// </summary>
        /// <returns></returns>
        public override bool MoveNext()
        {
            while (_reader.Read())
            {
                if (_reader.NodeType == XmlNodeType.Element && (_reader.Name == "modify" || _reader.Name == "create"||_reader.Name == "delete"))
                {
                    // create a stream for only this element.
                    string name = _reader.Name;
                    string next_element = _reader.ReadOuterXml();
                    XmlReader reader = XmlReader.Create(new MemoryStream(Encoding.UTF8.GetBytes(next_element)));
                    object osm_obj = null;

                    // select type of element.
                    switch (name)
                    {
                        case "delete":
                            osm_obj = _ser_delete.Deserialize(reader);
                            if (osm_obj is OsmSharp.Osm.Xml.v0_6.delete)
                            {
                                _next = XmlSimpleConverter.ConvertToSimple(osm_obj as OsmSharp.Osm.Xml.v0_6.delete);
                                return true;
                            }
                            break;
                        case "modify":
                            osm_obj = _ser_modify.Deserialize(reader);
                            if (osm_obj is OsmSharp.Osm.Xml.v0_6.modify)
                            {
                                _next = XmlSimpleConverter.ConvertToSimple(osm_obj as OsmSharp.Osm.Xml.v0_6.modify);
                                return true;
                            }
                            break;
                        case "create":
                            osm_obj = _ser_create.Deserialize(reader);
                            if (osm_obj is OsmSharp.Osm.Xml.v0_6.create)
                            {
                                _next = XmlSimpleConverter.ConvertToSimple(osm_obj as OsmSharp.Osm.Xml.v0_6.create);
                                return true;
                            }
                            break;
                    }
                }
            }
            _next = null;
            return false;
        }
        /// <summary>
        /// Initializes this changeset source.
        /// </summary>
        public override void Initialize()
        {
            _next = null;
            _ser_create = new XmlSerializer(typeof(Osm.Xml.v0_6.create));
            _ser_modify = new XmlSerializer(typeof(Osm.Xml.v0_6.modify));
            _ser_delete = new XmlSerializer(typeof(Osm.Xml.v0_6.delete));

            XmlReaderSettings settings = new XmlReaderSettings();
            settings.CloseInput = true;
            settings.CheckCharacters = false;
            settings.IgnoreComments = true;
            settings.IgnoreProcessingInstructions = true;

            if (_stream != null)
            {
                _reader = XmlReader.Create(_stream, settings);
            }
            else
            {
                TextReader text_reader = new StreamReader(new FileInfo(_file_name).OpenRead(), Encoding.UTF8);
                _reader = XmlReader.Create(text_reader, settings);
            }
        }
 /// <summary>
 /// Applies a change.
 /// </summary>
 /// <param name="change"></param>
 public override void ApplyChange(SimpleChangeSet change)
 {
 }
 public override void ApplyChange(SimpleChangeSet change)
 {
     throw new NotSupportedException();
 }
 /// <summary>
 /// Apply the given changeset.
 /// </summary>
 /// <param name="change_set"></param>
 public override void ApplyChange(SimpleChangeSet change_set)
 {
     if (change_set != null && change_set.Changes != null)
     {
         foreach (SimpleChange change in change_set.Changes)
         {
             switch (change.Type)
             {
                 case SimpleChangeType.Create:
                     foreach (SimpleOsmGeo geo in change.OsmGeo)
                     {
                         // start applying the simplechange.
                         OracleTransaction trans = _connection.BeginTransaction();
                         try
                         {
                             if (geo is SimpleNode)
                             {
                                 this.Create(geo as SimpleNode);
                                 OsmSharp.Tools.Output.OutputStreamHost.Write("+(n:{0})", geo.Id.Value);
                             }
                             else if (geo is SimpleWay)
                             {
                                 this.Create(geo as SimpleWay);
                                 OsmSharp.Tools.Output.OutputStreamHost.Write("+(w:{0})", geo.Id.Value);
                             }
                             else if (geo is SimpleRelation)
                             {
                                 this.Create(geo as SimpleRelation);
                                 OsmSharp.Tools.Output.OutputStreamHost.Write("+(r:{0})", geo.Id.Value);
                             }
                             trans.Commit();
                         }
                         catch (OracleException ex)
                         {
                             trans.Rollback();
                             if (!_pragmatic)
                             {
                                 throw ex;
                             }
                             else
                             {
                                 OsmSharp.Tools.Output.OutputStreamHost.Write("+(E:{0}-{1})", geo.Id.Value,geo.Type.ToString());
                             }
                         }
                     }
                     break;
                 case SimpleChangeType.Delete:
                     foreach (SimpleOsmGeo geo in change.OsmGeo)
                     {
                         // start applying the simplechange.
                         OracleTransaction trans = _connection.BeginTransaction();
                         try
                         {
                             if (geo is SimpleNode)
                             {
                                 this.Delete(geo as SimpleNode);
                                 OsmSharp.Tools.Output.OutputStreamHost.Write("-(n:{0})", geo.Id.Value);
                             }
                             else if (geo is SimpleWay)
                             {
                                 this.Delete(geo as SimpleWay);
                                 OsmSharp.Tools.Output.OutputStreamHost.Write("-(w:{0})", geo.Id.Value);
                             }
                             else if (geo is SimpleRelation)
                             {
                                 this.Delete(geo as SimpleRelation);
                                 OsmSharp.Tools.Output.OutputStreamHost.Write("-(r:{0})", geo.Id.Value);
                             }
                             trans.Commit();
                         }
                         catch (OracleException ex)
                         {
                             trans.Rollback();
                             if (!_pragmatic)
                             {
                                 throw ex;
                             }
                             else
                             {
                                 OsmSharp.Tools.Output.OutputStreamHost.Write("-(E:{0}-{1})", geo.Id.Value, geo.Type.ToString());
                             }
                         }
                     }
                     break;
                 case SimpleChangeType.Modify:
                     foreach (SimpleOsmGeo geo in change.OsmGeo)
                     {
                         // start applying the simplechange.
                         OracleTransaction trans = _connection.BeginTransaction();
                         try
                         {
                             if (geo is SimpleNode)
                             {
                                 this.Modify(geo as SimpleNode);
                                 OsmSharp.Tools.Output.OutputStreamHost.Write("/(n:{0})", geo.Id.Value);
                             }
                             else if (geo is SimpleWay)
                             {
                                 this.Modify(geo as SimpleWay);
                                 OsmSharp.Tools.Output.OutputStreamHost.Write("/(w:{0})", geo.Id.Value);
                             }
                             else if (geo is SimpleRelation)
                             {
                                 this.Modify(geo as SimpleRelation);
                                 OsmSharp.Tools.Output.OutputStreamHost.Write("/(r:{0})", geo.Id.Value);
                             }
                             trans.Commit();
                         }
                         catch (OracleException ex)
                         {
                             trans.Rollback();
                             if (!_pragmatic)
                             {
                                 throw ex;
                             }
                             else
                             {
                                 OsmSharp.Tools.Output.OutputStreamHost.Write("/(E:{0}-{1})", geo.Id.Value, geo.Type.ToString());
                             }
                         }
                     }
                     break;
             }
         }
     }
 }
Exemplo n.º 11
0
        /// <summary>
        /// Converts an API v6 xml osmChange object to a SimpleChange object.
        /// </summary>
        /// <param name="osm_change"></param>
        /// <returns></returns>
        private SimpleChangeSet Convertv6XmlChanges(OsmSharp.Osm.Xml.v0_6.osmChange osm_change)
        {
            List<SimpleChange> changes = new List<SimpleChange>();

            if (osm_change.create != null)
            {
                for (int idx = 0; idx < osm_change.create.Length; idx++)
                {
                    OsmSharp.Osm.Xml.v0_6.create create = osm_change.create[idx];

                    List<SimpleOsmGeo> changed_objects = new List<SimpleOsmGeo>();

                    if (create.node != null)
                    { // change represents a change in a node.
                        for (int node_idx = 0; node_idx < create.node.Length; node_idx++)
                        {
                            changed_objects.Add(this.Convertv6XmlNode(create.node[node_idx]));
                        }
                    }
                    if (create.way != null)
                    { // change represents a change in a way.
                        for (int way_idx = 0; way_idx < create.way.Length; way_idx++)
                        {
                            changed_objects.Add(this.Convertv6XmlWay(create.way[way_idx]));
                        }
                    }
                    if (create.relation != null)
                    { // change represents a change in a relation.
                        for (int relation_idx = 0; relation_idx < create.relation.Length; relation_idx++)
                        {
                            changed_objects.Add(this.Convertv6XmlRelation(create.relation[relation_idx]));
                        }
                    }

                    if (changed_objects.Count > 0)
                    { // there are actually changed objects.
                        changes.Add(new SimpleChange()
                        {
                            OsmGeo = changed_objects,
                            Type = SimpleChangeType.Create
                        });
                    }
                }
            }

            SimpleChangeSet simple_change_set = new SimpleChangeSet();
            simple_change_set.Changes = changes;

            return simple_change_set;
        }
Exemplo n.º 12
0
 /// <summary>
 /// Apply a changeset to the database.
 /// </summary>
 /// <param name="change"></param>
 public override void ApplyChange(SimpleChangeSet change)
 {
     throw new NotSupportedException("Relation are not supported in the redis target!");
 }