public GeoSuggestion GetOne(string term)
        {
            if (!string.IsNullOrEmpty(term))
            {
                var key = Regex.Replace(term, @"[\s\.,;:]", "");
                var cache = new Cahching.Cache<GeoSuggestion>();
                var geoSug = cache.Get(key);
                if (geoSug != null)
                    return geoSug;

                System.Net.WebClient client = new System.Net.WebClient();

                // Add a user agent header in case the
                // requested URI contains a query.

                //client.Headers.Add("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)");
                client.QueryString.Add("input", term);
                client.QueryString.Add("sensor", "false");
                client.QueryString.Add("types", "geocode");
                client.QueryString.Add("key", ConfigurationManager.AppSettings["GoogleAPIKey"]);

                System.IO.Stream data = client.OpenRead("https://maps.googleapis.com/maps/api/place/autocomplete/xml");
                System.IO.StreamReader reader = new System.IO.StreamReader(data);
                string str = reader.ReadToEnd();

                data.Close();
                reader.Close();

                XDocument xdoc = XDocument.Parse(str);
                var status = xdoc.Root.Descendants("status").Single();
                if (status.Value == "OK")
                {
                    var suggestions = xdoc.Root.Descendants("prediction")
                        //.Where(p => p.Descendants("type").Any(s => s.Value == "geocode" || s.Value == "route"))
                            .Select(p => new Suggestion
                            {
                                id = p.Descendants("id").Single().Value,
                                descr = p.Descendants("description").Single().Value,
                                refer = p.Descendants("reference").Single().Value,
                                term = p.Descendants("term").Descendants("value").First().Value,
                                matches = p.Descendants("matched_substring").Skip(2).Select(s => new MatchedSubstring {
                                    offset = int.Parse(s.Descendants("offset").Single().Value),
                                    length = int.Parse(s.Descendants("length").Single().Value)}).ToArray()
                            }).ToArray();
                    geoSug = new GeoSuggestion { term = term, suggestions = suggestions };

                    cache.Set(key, geoSug);

                    return geoSug;
                }

            }

            return new GeoSuggestion { term = term, suggestions = new Suggestion[0] };
        }
示例#2
0
        public MapRegion GetOne(string id)
        {
            var connectionString = ConfigurationManager.AppSettings["MongoConnectionString"];

            var hostName = Regex.Replace(connectionString, "^(.*)/(.*)$", "$1");
            var dbName = Regex.Replace(connectionString, "^(.*)/(.*)$", "$2");

            //"#{bounds._left} #{bounds._bottom} #{bounds._right} #{bounds._top} #{map.getZoom()}"
            var spts = id.Split(';');
            double left = double.Parse(spts[0], CultureInfo.InvariantCulture);
            double bottom = double.Parse(spts[1], CultureInfo.InvariantCulture);
            double right = double.Parse(spts[2], CultureInfo.InvariantCulture);
            double top = double.Parse(spts[3], CultureInfo.InvariantCulture);
            string zoom = spts[4];

            IEnumerable<MapCoord> coords = null;

            var cache = new Cahching.Cache<IEnumerable<MapCoord>>();

            if (zoom != "street")
            {
                coords = cache.Get(id);
                if (coords != null)
                    return new MapRegion { id = id, coords = coords.ToArray() };
            }

            var server = MongoServer.Create(hostName);
            server.Connect();
            var db = server.GetDatabase(dbName);
            var collection = db.GetCollection<Doc>("moscow");

            //find and store in cache all district and city results, later get results for them from cache
            if (zoom == "district")
            {
                if (coords == null)
                {
                    var districts = collection.Find(Query.And(Query.NE("parent", BsonType.Null), Query.Exists("district", true)));

                    coords = districts.Select(p => new MapCoord { type = 1,  lat = p.geo != null ? p.geo[0] : 0.0 , lon = p.geo != null ? p.geo[1] : 0.0, count = p.crn != null ? p.crn.Count() : 0, descr = p.district }).ToArray();
                }

                cache.Set("district", coords);
            }
            else if(zoom == "city")
            {
                var regions = collection.Find(Query.Exists("parent", false)).ToArray();

                var districts = collection.Find(Query.In("parent", regions.Select(p=> BsonValue.Create(p._id)))).ToArray();

                var distrCounts = districts.Select(p => new { type = 0, id = p._id, parent = p.parent, count = p.crn != null ? p.crn.Count() : 0 });

                coords = regions.Select(p =>
                    new MapCoord { lat = p.geo != null ? p.geo[0] : 0.0, lon = p.geo != null ? p.geo[1] : 0.0, count = (int)distrCounts.Where(x => x.parent == p._id).Sum(x => x.count), descr = p.district }).ToArray();

                cache.Set("city", coords);
            }

            var geo = Query.WithinRectangle(zoom == "street" ? "station.geo" : "geo", left, bottom, right, top);

            if (zoom == "street")
            {
                var q = collection.Find(Query.And(geo, Query.Exists("station", true)));

                coords = q.Select(p => new MapCoord { type = 2, lat = p.station.geo != null ? p.station.geo[0] : 0.0, lon = p.station.geo != null ? p.station.geo[1] : 0.0, count = 1, descr = p._id.ToString() }).ToArray();
            }
            else
            {
                coords = coords.Where(p=>p.lat >= left && p.lat <= right && p.lon >= bottom && p.lon <= top);
            }

            return new MapRegion { id = id, coords = coords.ToArray() };
        }
示例#3
0
        public Station GetOne(string key)
        {
            var matchType = "not_found";

            if (!string.IsNullOrEmpty(key))
            {
                var cache = new Cahching.Cache<Station>();
                var k = Regex.Replace(key, @"[\s\.,;:]", "");
                Station station = cache.Get(k);
                if (station != null)
                    return station;

                int id;
                var connectionString = ConfigurationManager.AppSettings["MongoConnectionString"];

                var hostName = Regex.Replace(connectionString, "^(.*)/(.*)$", "$1");
                var dbName = Regex.Replace(connectionString, "^(.*)/(.*)$", "$2");

                var server = MongoServer.Create(hostName);
                server.Connect();
                var db = server.GetDatabase(dbName);
                var collection = db.GetCollection<Doc>("moscow");

                IEnumerable<Doc> found = null;
                FoundBy foundBy = null;

                string foundPattern = null;

                if (!int.TryParse(key, out id))
                {
                    found = GetAllByStrictSearch(collection, key, out foundPattern).OrderBy(p => p.boundary.Count());

                    matchType = "similar";

                    if (found.Count() == 0)
                    {
                        found = GetAllBySuggestion(collection, string.Format("Россия, Москва, {0}", key), out foundBy);

                        matchType = "geo";
                    }

                }
                else
                {
                    found = collection.Find(Query.EQ("_id", id)).ToArray();

                    matchType = "id";
                }

                var res = found.FirstOrDefault();

                if (res != null)
                {
                    var similar = found.Where(p => p._id != res._id);

                    var twins = collection.Find(Query.Near("station.geo", res.station.geo[0], res.station.geo[1], 0.0)).Take(6).ToArray().Where(p => p._id != res._id);
                    var twinIds = twins.Select(p => p._id).ToArray();
                    var near = collection.Find(Query.And(Query.NotIn("_id", BsonArray.Create(twinIds)),  Query.Near("station.geo", res.station.geo[0], res.station.geo[1]))).Take(6).ToArray().Where(p => p._id != res._id);

                    var st = new Station
                    {
                        key = key,
                        id = res._id,
                        matchType = matchType, //not_found, similar, geo, id
                        foundBy = foundBy
                    };

                    st.boundary = res.boundary.Select(s => new Line { addr = s, matches = foundPattern != null ? GetMatches(s, foundPattern).ToArray() : new MatchedSubstring[0] }).ToArray();

                    st.station = new Address
                    {
                        addr = res.station.addr,
                        aux = res.station.aux,
                        org = res.station.org,
                        phone = res.station.phone,
                        geo = res.station.geo != null ? new GeoPoint { lat = res.station.geo[0], lon = res.station.geo[1] } : null
                    };

                    st.uik = new Address
                    {
                        addr = res.uik.addr,
                        aux = res.uik.aux,
                        org = res.uik.org,
                        phone = res.station.phone,
                        geo = res.uik.geo != null ? new GeoPoint { lat = res.uik.geo[0], lon = res.uik.geo[1] } : null
                    };

                    st.twins = twins.Select(p => new Ref { id = p._id }).ToArray();
                    st.near = near.Select(p => new Ref { id = p._id, descr = p.station.addr }).ToArray();

                    if (matchType == "similar" && foundPattern != null)
                    {
                        st.similar =
                            similar.Select((p) =>
                                {
                                    var matches = p.boundary.Select(s => new { s = s, m = GetMatches(s, foundPattern).ToArray() }).Where(s => s.m.Count() != 0).ToArray();
                                    return new RefLines { id = p._id, lines = matches.Select(x => new Line { addr = x.s, matches = x.m }).ToArray() };

                                }).ToArray();
                    }
                    else
                    {
                        st.similar = new RefLines[0];
                    }

                    cache.Set(k, st);

                    return st;
                }
            }

            return new Station { key = key, matchType = "not_found" };
        }