Beispiel #1
0
        private IAttributesTable ConvertTags(ICompleteOsmGeo osmObject)
        {
            var table = new AttributesTable(osmObject.Tags.ToDictionary(t => t.Key, t => t.Value as object))
            {
                { FeatureAttributes.ID, osmObject.Type.ToString().ToLower() + "_" + osmObject.Id }
            };

            // HM TODO: Avoid down case, required feature: https://github.com/OsmSharp/core/issues/60
            if (osmObject is CompleteOsmGeo complete)
            {
                if (complete.TimeStamp.HasValue)
                {
                    table.Add(FeatureAttributes.POI_LAST_MODIFIED, complete.TimeStamp.Value.ToString("o"));
                }
                if (!string.IsNullOrWhiteSpace(complete.UserName))
                {
                    table.Add(FeatureAttributes.POI_USER_NAME, complete.UserName);
                    table.Add(FeatureAttributes.POI_USER_ADDRESS, $"//www.openstreetmap.org/user/{Uri.EscapeUriString(complete.UserName)}");
                }
            }
            else if (osmObject is OsmGeo osmGeo)
            {
                if (osmGeo.TimeStamp.HasValue)
                {
                    table.Add(FeatureAttributes.POI_LAST_MODIFIED, osmGeo.TimeStamp.Value.ToString("o"));
                }
                if (!string.IsNullOrWhiteSpace(osmGeo.UserName))
                {
                    table.Add(FeatureAttributes.POI_USER_NAME, osmGeo.UserName);
                    table.Add(FeatureAttributes.POI_USER_ADDRESS, $"//www.openstreetmap.org/user/{Uri.EscapeUriString(osmGeo.UserName)}");
                }
            }

            return(table);
        }
 public Feature ToGeoJson(ICompleteOsmGeo completeOsmGeo)
 {
     if (completeOsmGeo.Tags.Count == 0)
     {
         return null;
     }
     switch (completeOsmGeo.Type)
     {
         case CompleteOsmType.Node:
             var node = completeOsmGeo as Node;
             return new Feature(new Point(ConvertNode(node)), ConvertTags(node.Tags, node.Id.Value));
         case CompleteOsmType.Way:
             var way = completeOsmGeo as CompleteWay;
             if (way == null || way.Nodes.Count <= 1)
             {
                 // can't convert a way with 1 coordinates to geojson.
                 return null;
             }
             var properties = ConvertTags(way.Tags, way.Id);
             var geometry = GetGeometryFromNodes(way.Nodes);
             return new Feature(geometry, properties);
         case CompleteOsmType.Relation:
             return ConvertRelation(completeOsmGeo as CompleteRelation);
         default:
             return null;
     }
 }
Beispiel #3
0
        /// <inheritdoc />
        public Feature ToGeoJson(ICompleteOsmGeo completeOsmGeo)
        {
            if (completeOsmGeo.Tags.Count == 0)
            {
                return(null);
            }
            switch (completeOsmGeo.Type)
            {
            case OsmGeoType.Node:
                var node = completeOsmGeo as Node;
                return(new Feature(new Point(ConvertNode(node)), ConvertTags(node)));

            case OsmGeoType.Way:
                var way = completeOsmGeo as CompleteWay;
                if (way == null || way.Nodes.Length <= 1)
                {
                    // can't convert a way with 1 coordinates to geojson.
                    return(null);
                }
                var properties = ConvertTags(way);
                var geometry   = GetGeometryFromNodes(way.Nodes);
                return(new Feature(geometry, properties));

            case OsmGeoType.Relation:
                return(ConvertRelation(completeOsmGeo as CompleteRelation));

            default:
                return(null);
            }
        }
        /// <inheritdoc />
        public async Task <PointOfInterestExtended> UpdatePointOfInterest(PointOfInterestExtended pointOfInterest, TokenAndSecret tokenAndSecret, string language)
        {
            var             osmGateway     = CreateOsmGateway(tokenAndSecret);
            var             id             = pointOfInterest.Id;
            ICompleteOsmGeo completeOsmGeo = await osmGateway.GetCompleteElement(GeoJsonExtensions.GetOsmId(id), GeoJsonExtensions.GetOsmType(id));

            var featureBeforeUpdate = ConvertOsmToFeature(completeOsmGeo, pointOfInterest.Title);
            var oldIcon             = featureBeforeUpdate.Attributes[FeatureAttributes.POI_ICON].ToString();
            var oldTags             = completeOsmGeo.Tags.ToArray();

            SetWebsiteUrl(completeOsmGeo.Tags, pointOfInterest);
            SetTagByLanguage(completeOsmGeo.Tags, FeatureAttributes.NAME, pointOfInterest.Title, language);
            SetTagByLanguage(completeOsmGeo.Tags, FeatureAttributes.DESCRIPTION, pointOfInterest.Description, language);
            SyncImages(completeOsmGeo.Tags, pointOfInterest.ImagesUrls);
            if (pointOfInterest.Icon != oldIcon && pointOfInterest.Icon != SEARCH_ICON)
            {
                RemoveTagsByIcon(completeOsmGeo.Tags, oldIcon);
                AddTagsByIcon(completeOsmGeo.Tags, pointOfInterest.Icon);
            }
            RemoveEmptyTags(completeOsmGeo.Tags);
            if (AreTagsCollectionEqual(oldTags, completeOsmGeo.Tags.ToArray()))
            {
                return(pointOfInterest);
            }

            var changesetId = await osmGateway.CreateChangeset($"Updated {pointOfInterest.Title} using IsraelHiking.osm.org.il");

            await osmGateway.UpdateElement(changesetId, completeOsmGeo);

            await osmGateway.CloseChangeset(changesetId);

            var featureToReturn = await UpdateElasticSearch(completeOsmGeo, pointOfInterest.Title);

            return(await FeatureToExtendedPoi(featureToReturn, language));
        }
Beispiel #5
0
        /// <inheritdoc />
        public Feature ToGeoJson(ICompleteOsmGeo completeOsmGeo)
        {
            if (completeOsmGeo.Tags.Count == 0)
            {
                return(null);
            }
            switch (completeOsmGeo.Type)
            {
            case OsmGeoType.Node:
                var node = completeOsmGeo as Node;
                return(new Feature(new Point(ConvertNode(node)), ConvertTags(node)));

            case OsmGeoType.Way:
                if (!(completeOsmGeo is CompleteWay way) || way.Nodes.Length <= 1)
                {
                    // can't convert a way with 1 coordinates to geojson.
                    return(null);
                }
                var properties = ConvertTags(way);
                properties.AddAttribute(FeatureAttributes.OSM_NODES, way.Nodes.Select(n => n.Id).ToArray());
                var geometry = GetGeometryFromNodes(way.Nodes);
                return(new Feature(geometry, properties));

            case OsmGeoType.Relation:
                return(ConvertRelation(completeOsmGeo as CompleteRelation));

            default:
                return(null);
            }
        }
Beispiel #6
0
 public static bool IsNodeInBuilding(Node node, ICompleteOsmGeo building)
 {
     if (building is Node buildingNode)
     {
         return(DistanceMeters(node, buildingNode) <= 1);
     }
     else if (building is CompleteWay buildingWay)
     {
         var point = new NetTopologySuite.Geometries.Point(node.Longitude.Value, node.Latitude.Value);
         if (buildingWay.Nodes.Length < 4 || (buildingWay.Nodes.First() != buildingWay.Nodes.Last()))
         {
             return(false);
         }
         var ring = new NetTopologySuite.Geometries.LinearRing(
             buildingWay.Nodes.Select(n => new Coordinate(n.Longitude.Value, n.Latitude.Value)).ToArray());
         var polygon = new NetTopologySuite.Geometries.Polygon(ring);
         return(point.Within(polygon));
     }
     else if (building is CompleteRelation buildingRelation)
     {
         // "in" means that even if I land in the center of a donut, I'm still "in" the building.
         // This isn't 100% accurate (false negative) for polygons where the closed outer ring is defined by more than 2 open ways.
         return(buildingRelation.Members.Any(m => m.Role != "inner" && IsNodeInBuilding(node, m.Member)));
     }
     throw new Exception("ICompleteOsmGeo wasn't a Node, Way or Relation.");
 }
Beispiel #7
0
 public static Bounds AsBounds(this ICompleteOsmGeo element)
 {
     if (element is Node node)
     {
         return(new Bounds()
         {
             MaxLatitude = (float)node.Latitude,
             MinLatitude = (float)node.Latitude,
             MaxLongitude = (float)node.Longitude,
             MinLongitude = (float)node.Longitude
         });
     }
     else if (element is CompleteWay way)
     {
         return(new Bounds()
         {
             MaxLatitude = (float)way.Nodes.Max(n => n.Latitude),
             MinLatitude = (float)way.Nodes.Min(n => n.Latitude),
             MaxLongitude = (float)way.Nodes.Max(n => n.Longitude),
             MinLongitude = (float)way.Nodes.Min(n => n.Longitude)
         });
     }
     else if (element is CompleteRelation relation)
     {
         var allBounds = relation.Members.Select(m => AsBounds(m.Member));
         return(new Bounds()
         {
             MaxLatitude = (float)allBounds.Max(n => n.MaxLatitude),
             MinLatitude = (float)allBounds.Min(n => n.MinLatitude),
             MaxLongitude = (float)allBounds.Max(n => n.MaxLongitude),
             MinLongitude = (float)allBounds.Min(n => n.MinLongitude)
         });
     }
     throw new Exception("element wasn't a node, way or relation");
 }
Beispiel #8
0
 private void MergeTags(ICompleteOsmGeo fromItem, ICompleteOsmGeo toItem)
 {
     foreach (var tag in fromItem.Tags.Except(toItem.Tags, new TagKeyComparer()))
     {
         toItem.Tags.Add(tag);
     }
 }
Beispiel #9
0
        private static AttributesTable TagsAndIdToAttributes(ICompleteOsmGeo osmObject)
        {
            var attr = osmObject.Tags.ToAttributeTable();

            attr.Add("id", osmObject.Id);

            return(attr);
        }
Beispiel #10
0
 private bool IsMultipolygon(ICompleteOsmGeo relation)
 {
     if (relation.Tags.ContainsKey(TYPE) == false)
     {
         return(false);
     }
     return(relation.Tags[TYPE] == MULTIPOLYGON || relation.Tags[TYPE] == BOUNDARY);
 }
        private async Task <Feature> UpdateElasticSearch(ICompleteOsmGeo osm, string name)
        {
            var feature = ConvertOsmToFeature(osm, name);

            if (feature != null)
            {
                await _elasticSearchGateway.UpdateNamesData(feature);
            }
            return(feature);
        }
Beispiel #12
0
        private async Task <Feature> UpdateElasticSearch(ICompleteOsmGeo osm, string name)
        {
            var feature = ConvertOsmToFeature(osm, name);

            if (feature != null)
            {
                await _elasticSearchGateway.UpdatePointsOfInterestData(new List <Feature> {
                    feature
                });
            }
            return(feature);
        }
        private Feature ConvertOsmToFeature(ICompleteOsmGeo osm, string name)
        {
            var features = _osmGeoJsonPreprocessorExecutor.Preprocess(
                new Dictionary <string, List <ICompleteOsmGeo> >
            {
                { name ?? string.Empty, new List <ICompleteOsmGeo> {
                      osm
                  } }
            });

            return(features.Any() ? features.First() : null);
        }
Beispiel #14
0
        private IAttributesTable ConvertTags(ICompleteOsmGeo osmObject)
        {
            var properties = osmObject.Tags.ToDictionary(t => t.Key, t => t.Value);

            properties.Add(FeatureAttributes.ID, osmObject.Id.ToString());
            var table = new AttributesTable();

            foreach (var key in properties.Keys)
            {
                table.Add(key, properties[key]);
            }
            return(table);
        }
Beispiel #15
0
 private string GetName(ICompleteOsmGeo osm)
 {
     if (osm.Tags.ContainsKey(NAME))
     {
         return osm.Tags[NAME];
     }
     foreach (var tag in osm.Tags)
     {
         if (tag.Key.Contains(NAME))
         {
             return tag.Value;
         }
     }
     return string.Empty;
 }
Beispiel #16
0
 private string GetName(ICompleteOsmGeo osm)
 {
     if (osm.Tags.ContainsKey(NAME))
     {
         return(osm.Tags[NAME]);
     }
     foreach (var tag in osm.Tags)
     {
         if (tag.Key.Contains(NAME))
         {
             return(tag.Value);
         }
     }
     return(string.Empty);
 }
        private async Task <Feature> UpdateElasticSearch(ICompleteOsmGeo osm, string name)
        {
            var feature = ConvertOsmToFeature(osm, name);

            if (feature == null)
            {
                return(null);
            }
            var featureFromDb = await _elasticSearchGateway.GetPointOfInterestById(feature.Attributes[FeatureAttributes.ID].ToString(), Sources.OSM);

            if (featureFromDb != null)
            {
                foreach (var attributeKey in featureFromDb.Attributes.GetNames().Where(n => n.StartsWith(FeatureAttributes.POI_PREFIX)))
                {
                    if (!feature.Attributes.GetNames().Any(n => n == attributeKey))
                    {
                        feature.Attributes.AddOrUpdate(attributeKey, featureFromDb.Attributes[attributeKey]);
                    }
                }
                if (feature.Geometry.OgcGeometryType == OgcGeometryType.Point &&
                    featureFromDb.Geometry.OgcGeometryType != OgcGeometryType.Point)
                {
                    feature.Geometry = featureFromDb.Geometry;
                }
            }

            await _elasticSearchGateway.UpdatePointsOfInterestData(new List <Feature> {
                feature
            });

            foreach (var language in Languages.Array)
            {
                var title = feature.Attributes.GetWikipediaTitle(language);
                if (string.IsNullOrWhiteSpace(title))
                {
                    continue;
                }
                var pageFetaure = await _wikipediaGateway.GetByPageTitle(title, language);

                if (pageFetaure == null)
                {
                    continue;
                }
                await _elasticSearchGateway.DeletePointOfInterestById(pageFetaure.Attributes[FeatureAttributes.ID].ToString(), Sources.WIKIPEDIA);
            }
            return(feature);
        }
Beispiel #18
0
 public static Node[] AsNodes(this ICompleteOsmGeo element)
 {
     if (element is Node node)
     {
         return new[] { node }
     }
     ;
     else if (element is CompleteWay way)
     {
         return(way.Nodes);
     }
     else if (element is CompleteRelation relation)
     {
         return(relation.Members.SelectMany(m => AsNodes(m.Member)).ToArray());
     }
     throw new Exception("element wasn't a node, way or relation");
 }
Beispiel #19
0
        public static bool IsTouching(this Bounds bounds, ICompleteOsmGeo geo)
        {
            switch (geo)
            {
            case Node node:
                return(IsTouching(bounds, node));

            case CompleteWay way:
                return(IsTouching(bounds, way));

            case CompleteRelation relation:
                return(IsTouching(bounds, relation));

            default:
                throw new Exception("Unknown Complete Element Type.");
            }
        }
Beispiel #20
0
        private async Task <Feature> UpdateElasticSearch(ICompleteOsmGeo osm, string name)
        {
            var features = _osmGeoJsonPreprocessorExecutor.Preprocess(
                new Dictionary <string, List <ICompleteOsmGeo> >
            {
                { name, new List <ICompleteOsmGeo> {
                      osm
                  } }
            });
            var feature = features.Values.FirstOrDefault()?.FirstOrDefault();

            if (feature != null)
            {
                await _elasticSearchGateway.UpdateNamesData(feature);
            }
            return(feature);
        }
Beispiel #21
0
        /// <summary>
        /// Converts a complete element into its simple counterpart,
        /// including the simple versions of its component elements.
        /// </summary>
        public static OsmGeo[] ToSimpleWithChildren(this ICompleteOsmGeo complete)
        {
            switch (complete)
            {
            case Node node:
                return(new [] { node });

            case CompleteWay way:
                return(way.ToSimpleWithChildren());

            case CompleteRelation relation:
                return(relation.ToSimpleWithChildren());

            default:
                throw new Exception("Unknown Complete Element Type.");
            }
        }
Beispiel #22
0
        /// <inheritdoc />
        public async Task <int> UpdateElement(long changesetId, ICompleteOsmGeo osmGeo)
        {
            switch (osmGeo.Type)
            {
            case OsmGeoType.Node:
                return(await UpdateElement(changesetId, osmGeo as OsmGeo));

            case OsmGeoType.Way:
                return(await UpdateElement(changesetId, ((CompleteWay)osmGeo).ToSimple()));

            case OsmGeoType.Relation:
                return(await UpdateElement(changesetId, ((CompleteRelation)osmGeo).ToSimple()));

            default:
                throw new Exception($"Invalid OSM geometry type: {osmGeo.Type}");
            }
        }
Beispiel #23
0
        private IAttributesTable ConvertTags(ICompleteOsmGeo osmObject)
        {
            var table = new AttributesTable(osmObject.Tags.ToDictionary(t => t.Key, t => t.Value as object))
            {
                { FeatureAttributes.ID, osmObject.GetId() }
            };

            if (osmObject.TimeStamp.HasValue)
            {
                table.Add(FeatureAttributes.POI_LAST_MODIFIED, osmObject.TimeStamp.Value.ToString("o"));
            }
            if (!string.IsNullOrWhiteSpace(osmObject.UserName))
            {
                table.Add(FeatureAttributes.POI_USER_NAME, osmObject.UserName);
                table.Add(FeatureAttributes.POI_USER_ADDRESS, $"https://www.openstreetmap.org/user/{Uri.EscapeUriString(osmObject.UserName)}");
            }
            return(table);
        }
Beispiel #24
0
 public static string OsmIDString(ICompleteOsmGeo geo)
 {
     if (geo is Node)
     {
         return("n" + geo.Id);
     }
     else if (geo is CompleteWay)
     {
         return("w" + geo.Id);
     }
     else if (geo is CompleteRelation)
     {
         return("r" + geo.Id);
     }
     else
     {
         return("x");
     }
 }
Beispiel #25
0
        public static Coordinate AsPosition(this ICompleteOsmGeo element)
        {
            if (element is Node node)
            {
                return(new Coordinate(node.Longitude.Value, node.Latitude.Value));
            }
            else if (element is CompleteWay way)
            {
                return(new Coordinate(way.Nodes.Average(n => n.Longitude.Value), way.Nodes.Average(n => n.Latitude.Value)));
            }
            else if (element is CompleteRelation relation)
            {
                // This isn't exact for relations. Good enough.
                var positions = relation.Members.Select(m => AsPosition(m.Member));

                return(new Coordinate(positions.Average(n => n.X), positions.Average(n => n.Y)));
            }
            throw new Exception("element wasn't a node, way or relation");
        }
Beispiel #26
0
        public void AddChange(ICompleteOsmGeo geo)
        {
            modifiedComplete.Add(geo);
            switch (geo)
            {
            case CompleteWay w:
                modified.Add(w.ToSimple());
                break;

            case Node n:
                modified.Add(n);
                break;

            case CompleteRelation r:
                modified.Add(r.ToSimple());
                break;

            default:
                throw new Exception($"Unknown type: {geo}");
            }
        }
 public void Pull()
 {
     this._source.Initialize();
     this.Initialize();
     while (this._source.MoveNext())
     {
         ICompleteOsmGeo completeOsmGeo = this._source.Current();
         if (completeOsmGeo is Node)
         {
             this.AddNode(completeOsmGeo as Node);
         }
         else if (completeOsmGeo is CompleteWay)
         {
             this.AddWay(completeOsmGeo as CompleteWay);
         }
         else if (completeOsmGeo is CompleteRelation)
         {
             this.AddRelation(completeOsmGeo as CompleteRelation);
         }
     }
     this.Flush();
     this.Close();
 }
Beispiel #28
0
 /// <summary>
 /// Pulls the changes from the source to this target.
 /// </summary>
 public void Pull()
 {
     _source.Initialize();
     this.Initialize();
     while (_source.MoveNext())
     {
         ICompleteOsmGeo sourceObject = _source.Current();
         if (sourceObject is Node)
         {
             this.AddNode(sourceObject as Node);
         }
         else if (sourceObject is CompleteWay)
         {
             this.AddWay(sourceObject as CompleteWay);
         }
         else if (sourceObject is CompleteRelation)
         {
             this.AddRelation(sourceObject as CompleteRelation);
         }
     }
     this.Flush();
     this.Close();
 }
Beispiel #29
0
        /// <inheritdoc />
        public async Task <PointOfInterestExtended> UpdatePointOfInterest(PointOfInterestExtended pointOfInterest, TokenAndSecret tokenAndSecret, string language)
        {
            var             osmGateway     = _httpGatewayFactory.CreateOsmGateway(tokenAndSecret);
            var             id             = pointOfInterest.Id;
            ICompleteOsmGeo completeOsmGeo = await osmGateway.GetElement(id, pointOfInterest.Type);

            var featureBeforeUpdate = ConvertOsmToFeature(completeOsmGeo, pointOfInterest.Title);
            var oldIcon             = featureBeforeUpdate.Attributes[FeatureAttributes.ICON].ToString();
            var oldTags             = completeOsmGeo.Tags.ToArray();

            SetWebsiteUrl(completeOsmGeo.Tags, pointOfInterest);
            SetTagByLanguage(completeOsmGeo.Tags, FeatureAttributes.NAME, pointOfInterest.Title, language);
            SetTagByLanguage(completeOsmGeo.Tags, FeatureAttributes.DESCRIPTION, pointOfInterest.Description, language);
            SyncImages(completeOsmGeo.Tags, pointOfInterest.ImagesUrls);
            if (pointOfInterest.Icon != oldIcon)
            {
                RemoveTagsByIcon(completeOsmGeo.Tags, oldIcon);
                AddTagsByIcon(completeOsmGeo.Tags, pointOfInterest.Icon);
            }
            RemoveEmptyTags(completeOsmGeo.Tags);
            if (AreTagsCollectionEqual(oldTags, completeOsmGeo.Tags.ToArray()))
            {
                var feature = ConvertOsmToFeature(completeOsmGeo, pointOfInterest.Title);
                return(await FeatureToExtendedPoi(feature, language));
            }

            var changesetId = await osmGateway.CreateChangeset("Update POI interface from IHM site.");

            await osmGateway.UpdateElement(changesetId, completeOsmGeo);

            await osmGateway.CloseChangeset(changesetId);

            var featureToReturn = await UpdateElasticSearch(completeOsmGeo, pointOfInterest.Title);

            return(await FeatureToExtendedPoi(featureToReturn, language));
        }
Beispiel #30
0
        /// <summary>
        /// Adds the given tag to the given object, iff that tag did not exist yet.
        /// Emits a warning if the tag already exists and has a different value
        /// </summary>
        /// <param name="geo"></param>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public static void AddNewTag(this ICompleteOsmGeo geo, string key, string value)
        {
            if (string.IsNullOrWhiteSpace(key) || string.IsNullOrWhiteSpace(value))
            {
                throw new ArgumentException("Key or value are either null or whitespace");
            }

            var oldValue = geo.Tags.GetValue(key);

            if (!string.IsNullOrEmpty(oldValue))
            {
                if (!oldValue.Equals(value))
                {
                    // Hmm, our mechanical edit would like to change something - lets warn for this; human interaction is needed
                    throw new ArgumentException(
                              $"Warning for object {geo}: not overriding tag {key}={oldValue} with {value}");
                }

                // The tag already exists! We don't do anything
                return;
            }

            geo.Tags.Add(key, value);
        }
        /// <summary>
        /// Interprets an OSM-object and returns the corresponding geometry.
        /// </summary>
        /// <param name="osmObject"></param>
        /// <returns></returns>
        public override FeatureCollection Interpret(ICompleteOsmGeo osmObject)
        {
            // DISCLAIMER: this is a very very very simple geometry interpreter and
            // contains hardcoded all relevant tags.

            var collection = new FeatureCollection();
            TagsCollectionBase tags;
            if (osmObject != null)
            {
                switch (osmObject.Type)
                {
                    case CompleteOsmType.Node:
                        var newCollection = new TagsCollection(
                            osmObject.Tags);
                        newCollection.RemoveKey("FIXME");
                        newCollection.RemoveKey("node");
                        newCollection.RemoveKey("source");

                        if (newCollection.Count > 0)
                        { // there is still some relevant information left.
                            collection.Add(new Feature(new Point((osmObject as Node).Coordinate),
                                new SimpleGeometryAttributeCollection(osmObject.Tags)));
                        }
                        break;
                    case CompleteOsmType.Way:
                        tags = osmObject.Tags;

                        bool isArea = false;
                        if ((tags.ContainsKey("building") && !tags.IsFalse("building")) ||
                            (tags.ContainsKey("landuse") && !tags.IsFalse("landuse")) ||
                            (tags.ContainsKey("amenity") && !tags.IsFalse("amenity")) ||
                            (tags.ContainsKey("harbour") && !tags.IsFalse("harbour")) ||
                            (tags.ContainsKey("historic") && !tags.IsFalse("historic")) ||
                            (tags.ContainsKey("leisure") && !tags.IsFalse("leisure")) ||
                            (tags.ContainsKey("man_made") && !tags.IsFalse("man_made")) ||
                            (tags.ContainsKey("military") && !tags.IsFalse("military")) ||
                            (tags.ContainsKey("natural") && !tags.IsFalse("natural")) ||
                            (tags.ContainsKey("office") && !tags.IsFalse("office")) ||
                            (tags.ContainsKey("place") && !tags.IsFalse("place")) ||
                            (tags.ContainsKey("power") && !tags.IsFalse("power")) ||
                            (tags.ContainsKey("public_transport") && !tags.IsFalse("public_transport")) ||
                            (tags.ContainsKey("shop") && !tags.IsFalse("shop")) ||
                            (tags.ContainsKey("sport") && !tags.IsFalse("sport")) ||
                            (tags.ContainsKey("tourism") && !tags.IsFalse("tourism")) ||
                            (tags.ContainsKey("waterway") && !tags.IsFalse("waterway")) ||
                            (tags.ContainsKey("wetland") && !tags.IsFalse("wetland")) ||
                            (tags.ContainsKey("water") && !tags.IsFalse("water")) ||
                            (tags.ContainsKey("aeroway") && !tags.IsFalse("aeroway")))
                        { // these tags usually indicate an area.
                            isArea = true;
                        }

                        if (tags.IsTrue("area"))
                        { // explicitly indicated that this is an area.
                            isArea = true;
                        }
                        else if (tags.IsFalse("area"))
                        { // explicitly indicated that this is not an area.
                            isArea = false;
                        }

                        if (isArea)
                        { // area tags leads to simple polygon
                            var lineairRing = new Feature(new LineairRing((osmObject as CompleteWay).GetCoordinates().ToArray<GeoCoordinate>()),
                                new SimpleGeometryAttributeCollection(tags));
                            collection.Add(lineairRing);
                        }
                        else
                        { // no area tag leads to just a line.
                            var lineString = new Feature(new LineString((osmObject as CompleteWay).GetCoordinates().ToArray<GeoCoordinate>()),
                                new SimpleGeometryAttributeCollection(tags));
                            collection.Add(lineString);
                        }
                        break;
                    case CompleteOsmType.Relation:
                        var relation = (osmObject as CompleteRelation);
                        tags = relation.Tags;

                        string typeValue;
                        if (tags.TryGetValue("type", out typeValue))
                        { // there is a type in this relation.
                            if (typeValue == "multipolygon")
                            { // this relation is a multipolygon.
                                var feature = this.InterpretMultipolygonRelation(relation);
                                if (feature != null)
                                { // add the geometry.
                                    collection.Add(feature);
                                }
                            }
                            else if (typeValue == "boundary")
                            { // this relation is a boundary.

                            }
                        }
                        break;
                }
            }
            return collection;
        }
Beispiel #32
0
 /// <summary>
 /// Interprets an OSM-object and returns the corresponding geometry.
 /// </summary>
 /// <param name="osmObject"></param>
 /// <returns></returns>
 public abstract FeatureCollection Interpret(ICompleteOsmGeo osmObject);
Beispiel #33
0
 /// <summary>
 /// Translates the given OSM objects into corresponding geometries.
 /// </summary>
 /// <param name="projection">The projection to use.</param>
 /// <param name="osmGeo">The osm object.</param>
 /// <param name="scene">The scene to fill with the resulting geometries.</param>
 /// <returns></returns>
 public abstract void Translate(Scene2D scene, IProjection projection, ICompleteOsmGeo osmGeo);
 /// <summary>
 /// Interprets an OSM-object and returns the corresponding geometry.
 /// </summary>
 /// <param name="osmObject"></param>
 /// <returns></returns>
 public abstract GeometryCollection Interpret(ICompleteOsmGeo osmObject);
Beispiel #35
0
        /// <summary>
        /// The actual conflation.
        /// Returns true if conflation is finished and this grbPoly has been matched
        /// </summary>
        private static bool AttemptConflate(Geometry grbPoly, Geometry osmPoly, TagsCollectionBase grbTags,
                                            ICompleteOsmGeo osmObj, EasyChangeset cs)
        {
            // Is there geographical match?
            if (Math.Abs(osmPoly.Centroid.Distance(grbPoly.Centroid)) > 0.000001)
            {
                return(false);
            }

            if (osmPoly.Difference(grbPoly).Area > 0.000000001)
            {
                return(false);
            }

            if (grbPoly.Difference(osmPoly).Area > 0.000000001)
            {
                return(false);
            }

            if (grbTags == null)
            {
                Console.WriteLine("PANIC for grb object " + grbPoly);
                return(false);
            }


            if (osmObj.Tags.TryGetValue("building", out var osmBuildingValue))
            {
                if (osmBuildingValue.Equals("yes"))
                {
                    osmObj.Tags.RemoveKey("building");
                }
                else
                {
                    grbTags.TryGetValue("building", out var grbBuildingValue);
                    if (grbBuildingValue == null)
                    {
                        Console.WriteLine("GRB Building value is null");
                    }
                    else if (osmBuildingValue != grbBuildingValue)
                    {
                        if (!grbBuildingValue.Equals("yes"))
                        {
                            Console.WriteLine(
                                $"Preferring OSM building-tag '{osmBuildingValue}' over the grb tag '{grbBuildingValue}'");
                        }

                        grbTags.RemoveKey("building");
                    }
                }
            }

            if (osmObj.Tags.TryGetValue("source:geometry:ref", out var osmSourceRef))
            {
                grbTags.TryGetValue("source:geometry:ref", out var grbRef);
                if (!osmSourceRef.Equals(grbRef))
                {
                    throw new Exception($"MISMATCH for {osmObj}: {osmSourceRef} != {grbRef}");
                }

                osmObj.Tags.RemoveKey("source:geometry:date");
            }


            if (osmObj.Tags.TryGetValue("addr:housenumber", out var osmHouseNumber))
            {
                grbTags.TryGetValue("addr:housenumber", out var grbHouseNumber);
                if (!osmHouseNumber.Equals(grbHouseNumber))
                {
                    grbTags.RemoveKey("addr:housenumber");

                    var msg = "GRB thinks that this has number " +
                              (string.IsNullOrEmpty(grbHouseNumber) ? "no number" : grbHouseNumber);

                    Console.WriteLine(
                        $"GRB and OSM disagree over housenumber of {osmObj}. Putting a fixme instead: grb: {grbHouseNumber} != osm {osmHouseNumber}");
                    if (grbTags.ContainsKey("fixme"))
                    {
                        msg += ";" + grbTags.GetValue("fixme");
                    }

                    grbTags.AddOrReplace("fixme", msg);
                }
            }

            if (osmObj.Tags.TryGetValue("addr:street", out var osmStreet))
            {
                grbTags.TryGetValue("addr:street", out var grbStreet);
                if (!string.IsNullOrEmpty(grbStreet) && !osmStreet.Equals(grbStreet))
                {
                    grbTags.RemoveKey("addr:street");

                    var msg = "GRB thinks that this lays in street " + grbStreet;

                    Console.WriteLine(
                        $"GRB and OSM disagree over streetname of {osmObj}. Putting a fixme instead: grb: {grbStreet} != osm {osmStreet}");
                    if (grbTags.ContainsKey("fixme"))
                    {
                        msg += ";" + grbTags.GetValue("fixme");
                    }

                    grbTags.AddOrReplace("fixme", msg);
                }
            }


            try
            {
                foreach (var grbTag in grbTags)
                {
                    if (grbTag.Key.Contains("wrong"))
                    {
                        continue;
                    }

                    osmObj.AddNewTag(grbTag.Key, grbTag.Value);
                }

                cs.AddChange(osmObj);
            }
            catch (Exception e)
            {
                Console.WriteLine($"{osmObj}: {e.Message}: skipping match");
            }


            return(true);
        }
Beispiel #36
0
 /// <summary>
 /// Interprets an OSM-object and returns the corresponding geometry.
 /// </summary>
 /// <param name="osmObject"></param>
 /// <returns></returns>
 public abstract GeometryCollection Interpret(ICompleteOsmGeo osmObject);
        /// <summary>
        /// Translates OSM objects into basic renderable primitives.
        /// </summary>
        /// <param name="scene">The scene to add primitives to.</param>
        /// <param name="projection">The projection used to convert the objects.</param>
        /// <param name="osmGeo">The osm object.</param>
        /// <returns></returns>
        public override void Translate(Scene2D scene, IProjection projection, ICompleteOsmGeo osmGeo)
        {
            // set the scene backcolor.
            scene.BackColor = this.GetCanvasColor().Value;

            if (osmGeo == null) { return; }

            if (_mapCSSFile == null) { return; }

            // store the object count.
            int countBefore = scene.Count;

            // interpret the osm-objects.
            switch (osmGeo.Type)
            {
                case CompleteOsmType.Node:
                    if (!_mapCSSFile.HasNodeIdSelector &&
                        osmGeo.Tags.Count == 0)
                    { // this node can never be selected, no tags and no id selectors.
                        break;
                    }
                    if (!_mapCSSFile.HasNodeIdSelector &&
                        _keysForNodes != null &&
                        !osmGeo.Tags.ContainsOneOfKeys(_keysForNodes))
                    { // no good keys present.
                        break;
                    }
                    this.TranslateNode(scene, projection, osmGeo as Node);
                    break;
                case CompleteOsmType.Way:
                    var relevantWayTags = osmGeo.Tags;
                    if (_keysForWays != null)
                    { // filter the collection.
                        relevantWayTags = relevantWayTags.KeepKeysOf(_keysForWays);
                    }
                    if (!_mapCSSFile.HasWayIdSelector &&
                        _keysForWays != null &&
                        relevantWayTags.Count == 0)
                    { // no good keys present.
                        break;
                    }
                    if (!_unsuccesfullWays.Contains(relevantWayTags))
                    { // way has some potential.
                        var completeWay = osmGeo as CompleteWay;
                        if (completeWay.Nodes.Count > 0 && !this.TranslateWay(scene, projection, completeWay, relevantWayTags))
                        { // ... but translate was unsuccesfull.
                            _unsuccesfullWays.Add(relevantWayTags);
                        }
                    }
                    break;
                case CompleteOsmType.Relation:
                    if (!_mapCSSFile.HasRelationIdSelector &&
                        _keysForRelations != null &&
                        !osmGeo.Tags.ContainsOneOfKeys(_keysForRelations))
                    { // no good keys present.
                        break;
                    }
                    this.TranslateRelation(scene, projection, osmGeo as CompleteRelation);
                    break;
            }

            // interpret the osmGeo object and check if it makes up an area.
            if (osmGeo.Type != CompleteOsmType.Node)
            { // nodes cannot lead to a geometry for MapCSS.
                if (_keysForLines == null || osmGeo.Tags.ContainsOneOfKeys(_keysForLines) ||
                    _keysForAreas == null || osmGeo.Tags.ContainsOneOfKeys(_keysForAreas))
                { // good keys present.
                    var collection = _geometryInterpreter.Interpret(osmGeo);
                    foreach (Geometry geometry in collection)
                    {
                        if (geometry is LineairRing)
                        { // a simple lineair ring.
                            this.TranslateLineairRing(scene, projection, geometry as LineairRing);
                        }
                        else if (geometry is Polygon)
                        { // a simple polygon.
                            this.TranslatePolygon(scene, projection, geometry as Polygon);
                        }
                        else if (geometry is MultiPolygon)
                        { // a multipolygon.
                            this.TranslateMultiPolygon(scene, projection, geometry as MultiPolygon);
                        }
                    }
                }
            }

            // check if any objects have been added to the scene.
            if (scene.Count <= countBefore)
            { // no objects have been added. Apply default styles if needed.
                if (osmGeo.Type == CompleteOsmType.Node &&
                    _mapCSSFile != null &&
                    _mapCSSFile.DefaultPoints)
                { // apply default points style.
                    Node node = (osmGeo as Node);
                    uint pointId = scene.AddPoint(projection.LongitudeToX(node.Coordinate.Longitude), projection.LatitudeToY(node.Coordinate.Latitude));
                    scene.AddStylePoint(pointId, this.CalculateSceneLayer(OffsetPoint, 0), float.MinValue, float.MaxValue,
                        SimpleColor.FromKnownColor(KnownColor.Black).Value, 2);
                }
                else if (osmGeo.Type == CompleteOsmType.Way &&
                    _mapCSSFile != null &&
                    _mapCSSFile.DefaultLines)
                { // apply default lines style.
                    CompleteWay way = (osmGeo as CompleteWay);
                    // get x/y.
                    double[] x = null, y = null;
                    if (x == null)
                    { // pre-calculate x/y.
                        x = new double[way.Nodes.Count];
                        y = new double[way.Nodes.Count];
                        for (int idx = 0; idx < way.Nodes.Count; idx++)
                        {
                            x[idx] = projection.LongitudeToX(
                                way.Nodes[idx].Coordinate.Longitude);
                            y[idx] = projection.LatitudeToY(
                                way.Nodes[idx].Coordinate.Latitude);
                        }

                        // simplify.
                        if (x.Length > 2)
                        {
                            double[][] simplified = SimplifyCurve.Simplify(new double[][] { x, y }, 0.0001);
                            x = simplified[0];
                            y = simplified[1];
                        }
                    }
                    uint? points = scene.AddPoints(x, y);
                    if (points.HasValue)
                    {
                        scene.AddStyleLine(points.Value, this.CalculateSceneLayer(OffsetLine, 0), float.MinValue, float.MaxValue,
                            SimpleColor.FromKnownColor(KnownColor.Red).Value, 1, LineJoin.Round, null);
                    }
                }
            }
        }