Example #1
0
        public IEnumerable <ChargePoint> Get()
        {
            // use custom query string parsing for compatibility
            var filter = new APIRequestParams();

            //set defaults
            var paramList = new NullSafeDictionary <string, string>();

            foreach (var k in Request.Query.Keys)
            {
                paramList.Add(k.ToLower(), Request.Query[k]);
            }

            filter.ParseParameters(filter, paramList);

            if (string.IsNullOrEmpty(filter.APIKey))
            {
                if (Request.Headers.ContainsKey("X-API-Key"))
                {
                    filter.APIKey = Request.Headers["X-API-Key"];
                }
            }

            var api = new POIManager();

            var list = api.GetPOIList(filter);

            return(list);
        }
Example #2
0
 public CoreReferenceData Get([FromQuery] APIRequestParams filter)
 {
     using (var refData = new ReferenceDataManager())
     {
         return(refData.GetCoreReferenceData(filter));
     }
 }
Example #3
0
        /// <summary>
        /// Output compact (id's only for reference data) POI list
        /// </summary>
        /// <param name="context"></param>
        /// <param name="filter"></param>
        private void OutputCompactPOIList(HttpContext context, APIRequestParams filter)
        {
            //get list of charge points as compact POISearchResult List for output:
            List <OCM.API.Common.Model.ChargePoint> dataList = new POIManager().GetChargePoints(filter);
            int numResults = dataList.Count;

            List <POISearchResult> poiList = new List <POISearchResult>();

            foreach (var c in dataList)
            {
                var poi = new POISearchResult
                {
                    ID           = c.ID,
                    Title        = c.AddressInfo.Title,
                    Address      = c.AddressInfo.AddressLine1,
                    Distance     = c.AddressInfo.Distance,
                    Latitude     = (double)c.AddressInfo.Latitude,
                    Longitude    = (double)c.AddressInfo.Longitude,
                    Postcode     = c.AddressInfo.Postcode,
                    UsageTypeID  = c.UsageType != null ? c.UsageType.ID : 0,
                    StatusTypeID = c.StatusType != null ? c.StatusType.ID : 0
                };
                poiList.Add(poi);
            }
            var    o           = new JSONOutputProvider();
            string description = "Compact POI List: id=ID, t= Title, u= UsageTypeID, s= StatusTypeID, a=Address, p=Postcode, lt=Latitude, lg=Longitude, d= Distance";

            o.PerformSerialisationV2(context.Response.OutputStream, new { status = "OK", description = description, count = poiList.Count, results = poiList }, filter.Callback);
        }
Example #4
0
        public void ProcessRequest(HttpContext context)
        {
            OutputProviders.ImageOutputProvider outputProvider = new OutputProviders.ImageOutputProvider();
            APIRequestParams settings = new APIRequestParams();

            List <OCM.API.Common.Model.ChargePoint> dataList = new List <Common.Model.ChargePoint>();

            context.Response.ContentType = outputProvider.ContentType;
            outputProvider.GetOutput(context.Response.OutputStream, dataList, settings);
        }
Example #5
0
 public static OCM.API.Common.Model.CoreReferenceData GetCoreReferenceData(APIRequestParams filter)
 {
     try
     {
         return(CacheProviderMongoDB.DefaultInstance.GetCoreReferenceData(filter));
     }
     catch (Exception)
     {
         return(null);
     }
 }
Example #6
0
 public static List <OCM.API.Common.Model.ChargePoint> GetPOIList(APIRequestParams filter)
 {
     try
     {
         return(new CacheProviderMongoDB().GetPOIList(filter));
     }
     catch (Exception)
     {
         return(null);
     }
 }
Example #7
0
        public void ProcessRequest(HttpContext context)
        {
            if (dataSummaryManager == null)
            {
                dataSummaryManager = new DataSummaryManager();
            }

            APIRequestParams filterSettings = new APIRequestParams();

            filterSettings.ParseParameters(filterSettings, context);

            string action = "totals_per_country";

            if (!String.IsNullOrEmpty(context.Request["action"]))
            {
                action = context.Request["action"].ToString();
            }

            if (action == "totals_per_country")
            {
                context.Response.ContentType = "application/javascript";
                context.Response.Write(dataSummaryManager.GetTotalsPerCountrySummary(true, "ocm_getdatasummary", filterSettings));
                context.Response.Flush();
            }

            if (action == "full_summary")
            {
                // Output JSON summary of:
                // - Current totals per country
                // - Total added (per country? based on date range, location/distance filter?)
                // - Total modified
                // - User Comments Count

                // - per month values, current month first? default last 12 months
            }

            if (action == "activity_summary")
            {
                // Based on date range, location and distance:
                // - list of recent comments, checkins, id & title etc of items added & modified
                var o = new JSONOutputProvider();

                context.Response.ContentType = o.ContentType;
                var summary = dataSummaryManager.GetActivitySummary(filterSettings);
                o.PerformSerialisationV2(context.Response.OutputStream, summary, filterSettings.Callback);

                context.Response.Flush();
            }
        }
Example #8
0
        public POIRecentActivity GetActivitySummary(APIRequestParams filterSettings)
        {
            //default to last month
            DateTime dateFrom = DateTime.UtcNow.AddMonths(-1);

            if (filterSettings != null)
            {
                if (filterSettings.ChangesFromDate != null)
                {
                    dateFrom = filterSettings.ChangesFromDate.Value;
                }
                else
                {
                    filterSettings.ChangesFromDate = dateFrom;
                }
            }

            //populate recently added comments
            var recentComments = from c in DataModel.UserComments
                                 where c.DateCreated >= dateFrom
                                 select c;

            var summary = new POIRecentActivity();

            summary.RecentComments = new List <UserComment>();
            foreach (var c in recentComments.OrderByDescending(c => c.DateCreated).Take(10).ToList())
            {
                summary.RecentComments.Add(Model.Extensions.UserComment.FromDataModel(c, true));
            }

            //populate recently modified charge points TODO: differentiate between updated since and created since?
            var poiManager = new POIManager();

            var allRecentPOIChanges = poiManager.GetChargePoints(filterSettings);

            summary.POIRecentlyAdded   = allRecentPOIChanges.Where(p => p.DateCreated >= dateFrom).OrderByDescending(p => p.DateCreated).Take(10).ToList();
            summary.POIRecentlyUpdated = allRecentPOIChanges.Where(p => p.DateLastStatusUpdate >= dateFrom && p.DateCreated != p.DateLastStatusUpdate).OrderByDescending(p => p.DateLastStatusUpdate).Take(10).ToList();

            var recentMedia = DataModel.MediaItems.Where(m => m.DateCreated > dateFrom && m.IsEnabled == true).OrderByDescending(m => m.DateCreated).Take(10).ToList();

            summary.RecentMedia = new List <MediaItem>();
            foreach (var mediaItem in recentMedia.OrderByDescending(m => m.DateCreated))
            {
                summary.RecentMedia.Add(Model.Extensions.MediaItem.FromDataModel(mediaItem));
            }

            return(summary);
        }
        public POIRecentActivity GetActivitySummary(APIRequestParams filterSettings)
        {
            //default to last month
            DateTime dateFrom = DateTime.UtcNow.AddMonths(-1);

            if (filterSettings != null)
            {
                if (filterSettings.ChangesFromDate != null)
                {
                    dateFrom = filterSettings.ChangesFromDate.Value;
                }
                else
                {
                    filterSettings.ChangesFromDate = dateFrom;
                }
            }

            //populate recently added comments
            var recentComments = from c in DataModel.UserComments
                                 where c.DateCreated >= dateFrom
                                 select c;

            var summary = new POIRecentActivity();
            summary.RecentComments = new List<UserComment>();
            foreach (var c in recentComments.OrderByDescending(c => c.DateCreated).Take(10).ToList())
            {
                summary.RecentComments.Add(Model.Extensions.UserComment.FromDataModel(c, true));
            }

            //populate recently modified charge points TODO: differentiate between updated since and created since?
            var poiManager = new POIManager();

            var allRecentPOIChanges = poiManager.GetChargePoints(filterSettings);
            summary.POIRecentlyAdded = allRecentPOIChanges.Where(p => p.DateCreated >= dateFrom).OrderByDescending(p => p.DateCreated).Take(10).ToList();
            summary.POIRecentlyUpdated = allRecentPOIChanges.Where(p => p.DateLastStatusUpdate >= dateFrom && p.DateCreated != p.DateLastStatusUpdate).OrderByDescending(p => p.DateLastStatusUpdate).Take(10).ToList();

            var recentMedia = DataModel.MediaItems.Where(m => m.DateCreated > dateFrom && m.IsEnabled == true).OrderByDescending(m => m.DateCreated).Take(10).ToList();
            summary.RecentMedia = new List<MediaItem>();
            foreach (var mediaItem in recentMedia.OrderByDescending(m => m.DateCreated))
            {
                summary.RecentMedia.Add(Model.Extensions.MediaItem.FromDataModel(mediaItem));
            }

            return summary;
        }
        public List <BenchmarkResult> PerformPOIQueryBenchmark(int numQueries, string mode = "country")
        {
            List <BenchmarkResult> results = new List <BenchmarkResult>();

            for (int i = 0; i < numQueries; i++)
            {
                BenchmarkResult result = new BenchmarkResult();

                try
                {
                    result.Description = "Cached POI Query " + i;

                    APIRequestParams filter = new APIRequestParams();
                    filter.MaxResults = 100;

                    if (mode == "country")
                    {
                        filter.CountryCode = "NL";
                    }
                    else
                    {
                        filter.Latitude  = 57.10604;
                        filter.Longitude = -2.62214;
                        filter.Distance  = 50;

                        filter.DistanceUnit = DistanceUnit.Miles;
                    }

                    var stopwatch = new Stopwatch();
                    stopwatch.Start();
                    var poiList = this.GetPOIList(filter);
                    stopwatch.Stop();
                    result.Description += " results:" + poiList.Count;
                    result.TimeMS       = stopwatch.ElapsedMilliseconds;
                }
                catch (Exception exp)
                {
                    result.Description += " Failed:" + exp.ToString();
                }

                results.Add(result);
            }
            return(results);
        }
Example #11
0
        private void OutputGeocodingResult(IOutputProvider outputProvider, HttpContext context, APIRequestParams filter)
        {
            GeocodingResult result = null;

            //get or get and cache result

            /*if (context.Cache["Geocoding_" + filter.HashKey] != null && filter.EnableCaching)
             * {
             *  result = (GeocodingResult)context.Cache["Geocoding_" + filter.HashKey];
             * }
             * else
             * {
             *
             *
             *  //context.Cache.Add("Geocoding_" + filter.HashKey, result, null, Cache.NoAbsoluteExpiration, new TimeSpan(1, 0, 0), CacheItemPriority.Normal, null);
             * }*/

            var geocoder = new GeocodingHelper(_settings);

            geocoder.IncludeExtendedData = false;

            if (!string.IsNullOrEmpty(filter.Address))
            {
                result = geocoder.GeolocateAddressInfo_MapquestOSM(filter.Address);
            }
            else if (filter.Latitude != null && filter.Longitude != null)
            {
                result = geocoder.ReverseGecode_MapquestOSM((double)filter.Latitude, (double)filter.Longitude, new ReferenceDataManager());

                if (!result.ResultsAvailable)
                {
                    result = geocoder.ReverseGecode_OSM((double)filter.Latitude, (double)filter.Longitude, new ReferenceDataManager());
                }
            }

            //send API response
            if (filter.IsEnvelopedResponse)
            {
                var responseEnvelope = new APIResponseEnvelope();
                responseEnvelope.Data = result;
                outputProvider.GetOutput(context, context.Response.Body, responseEnvelope, filter);
            }
            else
            {
                outputProvider.GetOutput(context, context.Response.Body, result, filter);
            }
        }
Example #12
0
        /// <summary>
        /// Handle output from API
        /// </summary>
        /// <param name="context"></param>
        private async void PerformOutput(HttpContext context)
        {
            HttpContext.Current.Server.ScriptTimeout = 120; //max script execution time is 2 minutes

            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
            stopwatch.Start();

            //decide correct reponse type
            IOutputProvider outputProvider = null;
            var             filter         = new APIRequestParams();

            //set defaults
            string outputType = "xml";

            filter.DistanceUnit  = DistanceUnit.Miles;
            filter.MaxResults    = 100;
            filter.EnableCaching = true;

            filter.ParseParameters(context);

            //override ?v=2 etc if called via /api/v2/ or /api/v1
            if (APIBehaviourVersion > 0)
            {
                filter.APIVersion = APIBehaviourVersion;
            }
            if (APIBehaviourVersion >= 2)
            {
                filter.Action = DefaultAction;
            }

            if (context.Request.Url.Host.ToLower().StartsWith("api") && filter.APIVersion == null)
            {
                //API version is mandatory for api V2 onwards via api.openchargemap.* hostname
                OutputBadRequestMessage(context, "mandatory API Version not specified in request");
                return;
            }

            if (!String.IsNullOrEmpty(context.Request["output"]))
            {
                outputType = ParseString(context.Request["output"]);
            }
            else
            {
                //new default after API V2 is json instead of XML
                if (filter.APIVersion >= 2)
                {
                    outputType = "json";
                }
            }

            //change defaults and override settings for deprecated api features
            if (filter.APIVersion >= 2)
            {
                //the following output types are deprecated and will default as JSON
                if (outputType == "carwings" || outputType == "rss")
                {
                    OutputBadRequestMessage(context, "specified output type not supported in this API version");
                    return;
                }
            }

            if (IsRequestByRobot)
            {
                OutputBadRequestMessage(context, "API requests by robots are temporarily disabled.", statusCode: 503);
                return;
            }

            //determine output provider
            switch (outputType)
            {
            case "xml":
                outputProvider = new XMLOutputProvider();
                break;

            case "carwings":
            case "rss":
                outputProvider = new RSSOutputProvider();
                if (outputType == "carwings")
                {
                    ((RSSOutputProvider)outputProvider).EnableCarwingsMode = true;
                }
                break;

            case "json":
                outputProvider = new JSONOutputProvider();
                break;

            case "geojson":
                outputProvider = new GeoJSONOutputProvider();
                break;

            case "csv":
                outputProvider = new CSVOutputProvider();
                break;

            case "kml":
                outputProvider = new KMLOutputProvider(KMLOutputProvider.KMLVersion.V2);
                break;

            case "png":
                outputProvider = new ImageOutputProvider();
                break;

            default:
                outputProvider = new XMLOutputProvider();
                break;
            }

            if (outputProvider != null)
            {
                context.Response.ContentEncoding = Encoding.Default;
                context.Response.ContentType     = outputProvider.ContentType;

                if (!(filter.Action == "getcorereferencedata" && String.IsNullOrEmpty(context.Request["SessionToken"])))
                {
                    //by default output is cacheable for 24 hrs, unless requested by a specific user.
                    context.Response.Cache.SetExpires(DateTime.Now.AddDays(1));
                    context.Response.Cache.SetCacheability(HttpCacheability.Public);
                    context.Response.Cache.SetValidUntilExpires(true);
                }

                if (ConfigurationManager.AppSettings["EnableOutputCompression"] == "true")
                {
                    //apply compression if accepted
                    string encodings = context.Request.Headers.Get("Accept-Encoding");

                    if (encodings != null)
                    {
                        encodings = encodings.ToLower();

                        if (encodings.ToLower().Contains("gzip"))
                        {
                            context.Response.Filter = new GZipStream(context.Response.Filter, CompressionLevel.Optimal, false);
                            context.Response.AppendHeader("Content-Encoding", "gzip");
                            //context.Trace.Warn("GZIP Compression on");
                        }
                        else
                        {
                            context.Response.Filter = new DeflateStream(context.Response.Filter, CompressionMode.Compress);
                            context.Response.AppendHeader("Content-Encoding", "deflate");
                            //context.Trace.Warn("Deflate Compression on");
                        }
                    }
                }
                if (filter.Action == "getchargepoints" || filter.Action == "getpoilist")
                {
                    System.Diagnostics.Debug.WriteLine("At getpoilist output: " + stopwatch.ElapsedMilliseconds + "ms");
                    OutputPOIList(outputProvider, context, filter);
                }

                if (filter.Action == "getcompactpoilist")
                {
                    //experimental::
                    OutputCompactPOIList(context, filter);
                }

                if (filter.Action == "getcorereferencedata")
                {
                    OutputCoreReferenceData(outputProvider, context, filter);
                }

                if (filter.Action == "geocode")
                {
                    this.OutputGeocodingResult(outputProvider, context, filter);
                }

                if (filter.Action == "availability")
                {
                    this.OutputAvailabilityResult(outputProvider, context, filter);
                }

                if (filter.Action == "profile.authenticate")
                {
                    this.OutputProfileSignInResult(outputProvider, context, filter);
                }

                if (filter.Action == "refreshmirror")
                {
                    try
                    {
                        var itemsUpdated = await OCM.Core.Data.CacheManager.RefreshCachedData();

                        new JSONOutputProvider().GetOutput(context.Response.OutputStream, new { POICount = itemsUpdated, Status = "OK" }, filter);
                    }
                    catch (Exception exp)
                    {
                        new JSONOutputProvider().GetOutput(context.Response.OutputStream, new { Status = "Error", Message = exp.ToString() }, filter);
                    }
                }

                stopwatch.Stop();
                System.Diagnostics.Debug.WriteLine("Total output time: " + stopwatch.ElapsedMilliseconds + "ms");
            }
        }
Example #13
0
        /// <summary>
        /// Output standard POI List results
        /// </summary>
        /// <param name="outputProvider"></param>
        /// <param name="context"></param>
        /// <param name="filter"></param>
        private void OutputPOIList(IOutputProvider outputProvider, HttpContext context, APIRequestParams filter)
        {
#if DEBUG
            var stopwatch = Stopwatch.StartNew();
#endif
            List <OCM.API.Common.Model.ChargePoint> dataList = null;

            //get list of charge points for output:
            dataList = new POIManager().GetChargePoints(filter);

#if DEBUG
            System.Diagnostics.Debug.WriteLine("OutputPOIList: Time for Query/Conversion: " + stopwatch.ElapsedMilliseconds + "ms");
            stopwatch.Restart();
#endif
            //send response
            outputProvider.GetOutput(context.Response.OutputStream, dataList, filter);

#if DEBUG
            System.Diagnostics.Debug.WriteLine("OutputPOIList: Time for Output to stream: " + stopwatch.ElapsedMilliseconds + "ms");
#endif
        }
        public void GetOutput(Stream outputStream, List <Common.Model.ChargePoint> dataList, APIRequestParams settings)
        {
            XmlTextWriter xml = new XmlTextWriter(outputStream, Encoding.UTF8);

            //start xml document
            xml.WriteStartDocument();

            //output rss tags
            xml.WriteStartElement("rss");
            xml.WriteAttributeString("version", "2.0");

            if (EnableCarwingsMode)
            {
                xml.WriteAttributeString("xmlns", "carwings", "http://www.w3.org/2000/xmlns/", "http://www.nissan.co.jp/dtd/carwings.dtd");
            }
            if (EnableGeoRSS)
            {
                xml.WriteAttributeString("xmlns", "georss", "http://www.w3.org/2000/xmlns/", "http://www.georss.org/georss/10");
            }

            //output feed details
            xml.WriteStartElement("channel");
            xml.WriteElementString("title", "OpenChargeMap Charge Points");
            xml.WriteElementString("link", "https://openchargemap.org");
            xml.WriteElementString("description", "Charge Point data contributed by OpenChargeMap community");
            xml.WriteElementString("copyright", "openchargemap.org");

            //output feed items
            foreach (var item in dataList)
            {
                if (item.AddressInfo != null)
                {
                    xml.WriteStartElement("item");
                    xml.WriteStartElement("guid");
                    xml.WriteAttributeString("isPermaLink", "false");
                    xml.WriteString(item.UUID);
                    xml.WriteEndElement();

                    xml.WriteElementString("title", item.AddressInfo.Title);

                    if (EnableCarwingsMode)
                    {
                        xml.WriteElementString("carwings:readtitle", item.AddressInfo.Title);
                    }

                    string description = item.GetSummaryDescription(true);
                    string address     = item.GetAddressSummary(true);

                    xml.WriteElementString("description", description);

                    if (item.AddressInfo.RelatedURL != null)
                    {
                        xml.WriteElementString("link", item.AddressInfo.RelatedURL);
                    }

                    if (EnableCarwingsMode)
                    {
                        if (address != "")
                        {
                            xml.WriteElementString("carwings:address", address);
                        }
                        if (item.AddressInfo.ContactTelephone1 != null)
                        {
                            xml.WriteElementString("carwings:tel", item.AddressInfo.ContactTelephone1);
                        }
                        xml.WriteElementString("carwings:lat", item.AddressInfo.Latitude.ToString());
                        xml.WriteElementString("carwings:lon", item.AddressInfo.Longitude.ToString());
                    }

                    if (EnableGeoRSS)
                    {
                        xml.WriteElementString("georss:point", item.AddressInfo.Latitude.ToString() + " " + item.AddressInfo.Longitude.ToString());
                    }

                    xml.WriteEndElement();
                }
            }

            xml.WriteEndElement();  //end channel
            xml.WriteEndElement();  //end rss
            xml.WriteEndDocument(); //end xml
            xml.Flush();
            //xml.Close();

            #region example rss

            /*
             * <?xml version="1.0" encoding="UTF-8"?>
             * <rss version="2.0" xmlns:carwings="http://www.nissan.co.jp/dtd/carwings.dtd">
             * <channel>
             *  <title> WEB site update: NISSAN Topics </ title>
             *  <link> http://rss.nissan.co.jp/ </ link>
             *  <description> Nissan will deliver the latest information. </ Description>
             *  <language>en</ language>
             *  <copyright> Copyright NISSAN MOTOR CO., LTD. 2005 All Rights Reserved. </ copyright>
             *  <lastBuildDate> Wed, 25 Oct 2006 12:18:36 +0900 </ lastBuildDate>
             *  <docs> http://blogs.law.harvard.edu/tech/rss </ docs>
             *  <item>
             *      <title>update information</ title>
             *      <carwings:readtitle> Trail Jam update information </ carwings: readtitle>
             *      <description> X-TRAIL JAM IN TOKYO DOME general tickets on sale! ! </ Description>
             *      <carwings:readtext> Trail Jam Tokyo Dome tickets, general sale.</ Carwings: readtext>
             *      <Carwings:itemimage> http://eplus.jp/sys/web/irg/2006x-trail/images/topmain.jpg </ Carwings: Itemimage>
             *      <Carwings:data> <! [CDATA [
             *              TRAIL <body> <br> <img src="http://lab.nissan-carwings.com/CWC/images/x-trail.jpg"> </ body>
             *              ]]>
             *      </ Carwings: data>
             *      <carwings:lat> 35.70568 </ carwings: lat>
             *      <carwings:lon> 139.75187 </ carwings: lon>
             *      <link> http://blog.nissan.co.jp/X-TRAIL/?rss </ link>
             *      <guid> http://blog.nissan.co.jp/X-TRAIL/?rss </ guid>
             *      <Carwings:link> Http://Www.nissan.co.jp/Event/....../Coupon.html </ Carwings: Link>
             *      <category> content </ category>
             *      <pubDate> Mon, 16 Oct 2006 20:15:02 +0900 </ pubDate>
             *  </item>
             * </channel>
             * </rss>
             * */
            #endregion example rss
        }
        public string GetTotalsPerCountrySummary(bool outputAsFunction, string functionName, APIRequestParams filterSettings)
        {
            //TODO: optionally output as normal JSON
            string output = "function " + functionName + "() { var ocm_summary = new Array(); \r\n";

            if (HttpContext.Current.Cache["ocm_summary"] == null)
            {
                var list = GetAllCountryStats();
                HttpContext.Current.Cache["ocm_summary"] = list.OrderByDescending(i => i.ItemCount).ToList();
            }
            var cachedresults = (List<CountrySummary>)HttpContext.Current.Cache["ocm_summary"];
            foreach (var item in cachedresults)
            {
                output += "ocm_summary[ocm_summary.length]={\"country\":\"" + item.CountryName + "\", \"isocode\":\"" + item.ISOCode + "\", \"itemcount\":" + item.LocationCount + ", \"locationcount\":" + item.LocationCount + ", \"stationcount\":" + item.StationCount + "}; \r\n";
            }
            output += " return ocm_summary; }";
            return output;
        }
Example #16
0
        public async Task <List <ChargePoint> > DeDuplicateList(List <ChargePoint> cpList, bool updateDuplicate, CoreReferenceData coreRefData, ImportReport report, bool allowDupeWithDifferentOperator = false, bool fetchExistingFromAPI = false)
        {
            var stopWatch = new Stopwatch();

            stopWatch.Start();

            var poiManager = new POIManager();

            //get list of all current POIs (in relevant countries) including most delisted ones
            int[] countryIds = (from poi in cpList
                                where poi.AddressInfo.Country != null
                                select poi.AddressInfo.Country.ID).Distinct().ToArray();

            APIRequestParams filters = new APIRequestParams {
                CountryIDs = countryIds, MaxResults = 1000000, EnableCaching = true, SubmissionStatusTypeID = 0
            };

            List <ChargePoint> masterListCollection = new List <ChargePoint>();

            if (fetchExistingFromAPI)
            {
                // fetch from API
                masterListCollection = await new OCMClient(false).GetLocations(new SearchFilters
                {
                    CountryIDs              = countryIds,
                    MaxResults              = 1000000,
                    EnableCaching           = true,
                    SubmissionStatusTypeIDs = new int[0]
                });
            }
            else
            {
                // use local database

                masterListCollection = poiManager.GetChargePoints(filters);
            }

            var spec = new i4o.IndexSpecification <ChargePoint>()
                       .Add(i => i.DataProviderID)
                       .Add(i => i.DataProvidersReference)
            ;

            var masterList = new i4o.IndexSet <ChargePoint>(masterListCollection, spec);

            List <ChargePoint> masterListCopy = new List <ChargePoint>();

            foreach (var tmp in masterList)
            {
                //fully copy of master list item so we have before/after
                masterListCopy.Add(JsonConvert.DeserializeObject <ChargePoint>(JsonConvert.SerializeObject(tmp)));
            }

            //if we failed to get a master list, quit with no result
            if (masterListCollection.Count == 0)
            {
                return(new List <ChargePoint>());
            }

            List <ChargePoint> duplicateList = new List <ChargePoint>();
            List <ChargePoint> updateList    = new List <ChargePoint>();

            ChargePoint previousCP = null;

            //for each item to be imported, deduplicate by adding to updateList only the items which we don't already haves
            var cpListSortedByPos = cpList.OrderBy(c => c.AddressInfo.Latitude).ThenBy(c => c.AddressInfo.Longitude);

            int poiProcessed = 0;
            int totalPOI     = cpListSortedByPos.Count();

            Stopwatch dupeIdentWatch = new Stopwatch();

            dupeIdentWatch.Start();

            foreach (var item in cpListSortedByPos)
            {
                var itemGeoPos = new System.Device.Location.GeoCoordinate(item.AddressInfo.Latitude, item.AddressInfo.Longitude);

                //item is duplicate if we already seem to have it based on Data Providers reference or approx position match
                var dupeList = masterList.Where(c =>
                                                (
                                                    // c.DataProvider != null &&
                                                    c.DataProviderID == item.DataProviderID && c.DataProvidersReference == item.DataProvidersReference) ||
                                                (c.AddressInfo.Title == item.AddressInfo.Title && c.AddressInfo.AddressLine1 == item.AddressInfo.AddressLine1 && c.AddressInfo.Postcode == item.AddressInfo.Postcode) ||
                                                (GeoManager.IsClose(c.AddressInfo.Latitude, c.AddressInfo.Longitude, item.AddressInfo.Latitude, item.AddressInfo.Longitude) && new System.Device.Location.GeoCoordinate(c.AddressInfo.Latitude, c.AddressInfo.Longitude).GetDistanceTo(itemGeoPos) < DUPLICATE_DISTANCE_METERS) //meters distance apart
                                                );

                if (dupeList.Any())
                {
                    if (updateDuplicate)
                    {
                        //if updating duplicates, get exact matching duplicate based on provider reference and update/merge with this item to update status/merge properties
                        var updatedItem = dupeList.FirstOrDefault(d => d.DataProviderID == (item.DataProvider != null ? item.DataProvider.ID : item.DataProviderID) && d.DataProvidersReference == item.DataProvidersReference);
                        if (updatedItem != null)
                        {
                            //only merge/update from live published items
                            if (updatedItem.SubmissionStatus.IsLive == (bool?)true ||
                                updatedItem.SubmissionStatus.ID == (int)StandardSubmissionStatusTypes.Delisted_RemovedByDataProvider ||
                                updatedItem.SubmissionStatus.ID == (int)StandardSubmissionStatusTypes.Delisted_NotPublicInformation)
                            {
                                //item is an exact match from same data provider
                                //overwrite existing with imported data (use import as master)
                                //updatedItem = poiManager.PreviewPopulatedPOIFromModel(updatedItem);
                                MergeItemChanges(item, updatedItem, false);

                                updateList.Add(updatedItem);
                            }
                        }

                        if (updatedItem == null)
                        {
                            //duplicates are not exact match
                            //TODO: resolve whether imported data should change duplicate

                            //merge new properties from imported item
                            //if (item.StatusType != null) updatedItem.StatusType = item.StatusType;
                            //updateList.Add(updatedItem);
                        }
                    }

                    //item has one or more likely duplicates, add it to list of items to remove
                    duplicateList.Add(item);
                }

                //mark item as duplicate if location/title exactly matches previous entry or lat/long is within DuplicateDistance meters

                if (previousCP != null)
                {
                    //this branch is the most expensive part of dedupe:
                    if (IsDuplicateLocation(item, previousCP, true))
                    {
                        if (!duplicateList.Contains(item))
                        {
                            if (allowDupeWithDifferentOperator && item.OperatorID != previousCP.OperatorID)
                            {
                                Log("Duplicated allowed due to different operator:" + item.AddressInfo.Title);
                            }
                            else
                            {
                                Log("Duplicated item removed:" + item.AddressInfo.Title);
                                duplicateList.Add(item);
                            }
                        }
                    }
                }

                previousCP = item;

                poiProcessed++;

                if (poiProcessed % 300 == 0)
                {
                    System.Diagnostics.Debug.WriteLine("Deduplication: " + poiProcessed + " processed of " + totalPOI);
                }
            }

            dupeIdentWatch.Stop();
            Log("De-dupe pass took " + dupeIdentWatch.Elapsed.TotalSeconds + " seconds. " + (dupeIdentWatch.Elapsed.TotalMilliseconds / cpList.Count) + "ms per item.");

            //remove duplicates from list to apply
            foreach (var dupe in duplicateList)
            {
                cpList.Remove(dupe);
            }

            Log("Duplicates removed from import:" + duplicateList.Count);

            //add updated items (replace duplicates with property changes)

            foreach (var updatedItem in updateList)
            {
                if (!cpList.Contains(updatedItem))
                {
                    cpList.Add(updatedItem);
                }
            }

            Log("Updated items to import:" + updateList.Count);

            //populate missing location info from geolocation cache if possible
            Stopwatch geoWatch = new Stopwatch();

            geoWatch.Start();
            PopulateLocationFromGeolocationCache(cpList, coreRefData);
            geoWatch.Stop();
            Log("Populate Country from Lat/Long took " + geoWatch.Elapsed.TotalSeconds + " seconds. " + (geoWatch.Elapsed.TotalMilliseconds / cpList.Count) + "ms per item.");

            //final pass to catch duplicates present in data source, mark additional items as Delisted Duplicate so we have a record for them
            var submissionStatusDelistedDupe = coreRefData.SubmissionStatusTypes.First(s => s.ID == 1001); //delisted duplicate

            previousCP = null;

            //sort current cp list by position again
            cpListSortedByPos = cpList.OrderBy(c => c.AddressInfo.Latitude).ThenBy(c => c.AddressInfo.Longitude);

            //mark any duplicates in final list as delisted duplicates (submitted to api)
            foreach (var cp in cpListSortedByPos)
            {
                bool isDuplicate = false;
                if (previousCP != null)
                {
                    isDuplicate = IsDuplicateLocation(cp, previousCP, false);
                    if (isDuplicate)
                    {
                        cp.SubmissionStatus       = submissionStatusDelistedDupe;
                        cp.SubmissionStatusTypeID = submissionStatusDelistedDupe.ID;
                        if (previousCP.ID > 0)
                        {
                            if (cp.GeneralComments == null)
                            {
                                cp.GeneralComments = "";
                            }
                            cp.GeneralComments    += " [Duplicate of OCM-" + previousCP.ID + "]";
                            cp.ParentChargePointID = previousCP.ID;
                        }
                    }
                }

                if (!isDuplicate)
                {
                    previousCP = cp;
                }
            }

            report.Added      = cpListSortedByPos.Where(cp => cp.ID == 0).ToList();
            report.Updated    = cpListSortedByPos.Where(cp => cp.ID > 0).ToList();
            report.Duplicates = duplicateList; //TODO: add additional pass of duplicates from above

            //determine which POIs in our master list are no longer referenced in the import
            report.Delisted = masterList.Where(cp => cp.DataProviderID == report.ProviderDetails.DataProviderID && cp.SubmissionStatus != null && (cp.SubmissionStatus.IsLive == true || cp.SubmissionStatusTypeID == (int)StandardSubmissionStatusTypes.Imported_UnderReview) &&
                                               !cpListSortedByPos.Any(master => master.ID == cp.ID) && !report.Duplicates.Any(master => master.ID == cp.ID) &&
                                               cp.UserComments == null && cp.MediaItems == null).ToList();
            //safety check to ensure we're not delisting items just because we have incomplete import data:
            if (cpList.Count < 50)// || (report.Delisted.Count > cpList.Count))
            {
                report.Delisted = new List <ChargePoint>();
            }

            //determine list of low quality POIs (incomplete address info etc)
            report.LowDataQuality = new List <ChargePoint>();
            report.LowDataQuality.AddRange(GetLowDataQualityPOIs(report.Added));
            report.LowDataQuality.AddRange(GetLowDataQualityPOIs(report.Updated));

            Log("Removing " + report.LowDataQuality.Count + " low quality POIs from added/updated");

            //remove references in added/updated to any low quality POIs
            foreach (var p in report.LowDataQuality)
            {
                report.Added.Remove(p);
            }
            foreach (var p in report.LowDataQuality)
            {
                report.Updated.Remove(p);
            }

            //remove updates which only change datelaststatusupdate
            var updatesToIgnore = new List <ChargePoint>();

            foreach (var poi in report.Updated)
            {
                var origPOI     = masterListCopy.FirstOrDefault(p => p.ID == poi.ID);
                var updatedPOI  = poiManager.PreviewPopulatedPOIFromModel(poi);
                var differences = poiManager.CheckDifferences(origPOI, updatedPOI);
                differences.RemoveAll(d => d.Context == ".MetadataValues");
                differences.RemoveAll(d => d.Context == ".DateLastStatusUpdate");
                differences.RemoveAll(d => d.Context == ".UUID");

                differences.RemoveAll(d => d.Context == ".DataProvider.DateLastImported");
                differences.RemoveAll(d => d.Context == ".IsRecentlyVerified");
                differences.RemoveAll(d => d.Context == ".DateLastVerified");
                differences.RemoveAll(d => d.Context == ".UserComments");
                differences.RemoveAll(d => d.Context == ".MediaItems");

                if (!differences.Any())
                {
                    updatesToIgnore.Add(poi);
                }
                else
                {
                    //differences exist
                    CompareLogic compareLogic = new CompareLogic();
                    compareLogic.Config.MaxDifferences           = 100;
                    compareLogic.Config.IgnoreObjectTypes        = false;
                    compareLogic.Config.IgnoreUnknownObjectTypes = true;
                    compareLogic.Config.CompareChildren          = true;
                    ComparisonResult result = compareLogic.Compare(origPOI, updatedPOI);

                    var diffReport = new KellermanSoftware.CompareNetObjects.Reports.UserFriendlyReport();
                    result.Differences.RemoveAll(d => d.PropertyName == ".MetadataValues");
                    result.Differences.RemoveAll(d => d.PropertyName == ".DateLastStatusUpdate");
                    result.Differences.RemoveAll(d => d.PropertyName == ".UUID");
                    result.Differences.RemoveAll(d => d.PropertyName == ".DataProvider.DateLastImported");
                    result.Differences.RemoveAll(d => d.PropertyName == ".IsRecentlyVerified");
                    result.Differences.RemoveAll(d => d.PropertyName == ".DateLastVerified");
                    result.Differences.RemoveAll(d => d.PropertyName == ".UserComments");
                    result.Differences.RemoveAll(d => d.PropertyName == ".MediaItems");
                    System.Diagnostics.Debug.WriteLine("Difference:" + diffReport.OutputString(result.Differences));

                    if (!result.Differences.Any())
                    {
                        updatesToIgnore.Add(poi);
                    }
                }
            }

            foreach (var p in updatesToIgnore)
            {
                if (report.Unchanged == null)
                {
                    report.Unchanged = new List <ChargePoint>();
                }
                report.Unchanged.Add(p);
                report.Updated.Remove(p);
            }

            //TODO: if POi is a duplicate ensure imported data provider reference/URL  is included as reference metadata in OCM's version of the POI

            stopWatch.Stop();
            Log("Deduplicate List took " + stopWatch.Elapsed.TotalSeconds + " seconds");

            //return final processed list ready for applying as insert/updates
            return(cpListSortedByPos.ToList());
        }
 public void GetOutput(Stream outputStream, Object data, APIRequestParams settings)
 {
     throw new NotImplementedException();
 }
Example #18
0
        private async Task OutputProfileRegisterResult(IOutputProvider outputProvider, HttpContext context, APIRequestParams filter)
        {
            var    sr           = new System.IO.StreamReader(context.Request.Body);
            string jsonContent  = sr.ReadToEnd();
            var    registration = JsonConvert.DeserializeObject <RegistrationModel>(jsonContent);

            User user = null;

            if (!string.IsNullOrEmpty(registration.EmailAddress) && registration.EmailAddress.Trim().Length > 5 && registration.EmailAddress.Contains("@"))
            {
                if (!string.IsNullOrWhiteSpace(registration.Password) && registration.Password.Trim().Length > 4)
                {
                    user = new OCM.API.Common.UserManager().RegisterNewUser(registration);
                }
            }
            else
            {
                context.Response.StatusCode = 401;
            }

            string access_token     = null;
            var    responseEnvelope = new APIResponseEnvelope();

            if (user != null)
            {
                context.Response.StatusCode = 401;
                return;
            }
            else
            {
                access_token = Security.JWTAuth.GenerateEncodedJWT(user);
            }

            responseEnvelope.Data = new { UserProfile = user, access_token = access_token };

            await outputProvider.GetOutput(context, context.Response.Body, responseEnvelope, filter);
        }
Example #19
0
 public Task GetOutput(HttpContext context, Stream outputStream, Object data, APIRequestParams settings)
 {
     throw new NotImplementedException();
 }
Example #20
0
        private void OutputProfileSignInResult(IOutputProvider outputProvider, HttpContext context, APIRequestParams filter)
        {
            var    sr          = new System.IO.StreamReader(context.Request.InputStream);
            string jsonContent = sr.ReadToEnd();
            var    loginModel  = JsonConvert.DeserializeObject <LoginModel>(jsonContent);

            User   user             = new OCM.API.Common.UserManager().GetUser(loginModel);
            string access_token     = null;
            var    responseEnvelope = new APIResponseEnvelope();

            if (user == null)
            {
                context.Response.StatusCode = 401;
                context.Response.Flush();
                return;
            }
            else
            {
                access_token = Security.JWTAuth.GenerateEncodedJWT(user);

                /*
                 * var validatedToken = Security.JWTAuthTicket.ValidateJWTForUser(testTicket, user);
                 */
            }

            responseEnvelope.Data = new { UserProfile = user, access_token = access_token };

            outputProvider.GetOutput(context.Response.OutputStream, responseEnvelope, filter);
        }
Example #21
0
        /// <summary>
        /// Handle input to API
        /// </summary>
        /// <param name="context"></param>
        private void PerformInput(HttpContext context)
        {
            if (!bool.Parse(ConfigurationManager.AppSettings["EnableDataWrites"]))
            {
                OutputBadRequestMessage(context, "API is read only. Submissions not currently being accepted.");
                return;
            }
            OCM.API.InputProviders.IInputProvider inputProvider = null;

            var filter = new APIRequestParams();

            //set defaults
            filter.ParseParameters(context);

            //override ?v=2 etc if called via /api/v2/ or /api/v1
            if (APIBehaviourVersion > 0)
            {
                filter.APIVersion = APIBehaviourVersion;
            }
            if (APIBehaviourVersion >= 2)
            {
                filter.Action = DefaultAction;
            }

            if (context.Request.Url.Host.ToLower().StartsWith("api") && filter.APIVersion == null)
            {
                //API version is mandatory for api V2 onwards via api.openchargemap.* hostname
                OutputBadRequestMessage(context, "mandatory API Version not specified in request");
                return;
            }

            bool performSubmissionCompletedRedirects = false;

            //Use JSON format submission if explictly specified or by default if API v3
            if (context.Request["format"] == "json" || (String.IsNullOrEmpty(context.Request["format"]) && filter.APIVersion >= 3))
            {
                inputProvider = new InputProviders.JSONInputProvider();
            }
            else
            {
                inputProvider = new InputProviders.HTMLFormInputProvider();
                performSubmissionCompletedRedirects = true;
            }
            SubmissionManager submissionManager = new SubmissionManager();

            //attempt to determine user from api call
            User user = inputProvider.GetUserFromAPICall(context);

            if (user != null && user.IsCurrentSessionTokenValid == false)
            {
                //session token provided didn't match latest in user details, reject user details.
                context.Response.StatusCode = 401;
            }
            else
            {
                //allow contact us input whether use is authenticated or not
                if (context.Request["action"] == "contactus_submission" || filter.Action == "contact")
                {
                    ContactSubmission contactSubmission = new ContactSubmission();
                    bool processedOK = inputProvider.ProcessContactUsSubmission(context, ref contactSubmission);

                    bool resultOK = submissionManager.SendContactUsMessage(contactSubmission.Name, contactSubmission.Email, contactSubmission.Comment);
                    if (resultOK == true)
                    {
                        context.Response.Write("OK");
                    }
                    else
                    {
                        context.Response.Write("Error");
                    }
                }

                //if user not authenticated reject any other input
                if (user == null)
                {
                    context.Response.StatusCode = 401;
                    return;
                }

                //gather input variables
                if (context.Request["action"] == "cp_submission" || filter.Action == "poi")
                {
                    //gather/process data for submission
                    OCM.API.Common.Model.ChargePoint cp = new Common.Model.ChargePoint();

                    bool processedOK = inputProvider.ProcessEquipmentSubmission(context, ref cp);
                    bool submittedOK = false;

                    if (processedOK == true)
                    {
                        //perform submission

                        int submissionId = submissionManager.PerformPOISubmission(cp, user);
                        if (submissionId > -1)
                        {
                            submittedOK = true;
                        }
                    }

                    if (processedOK && submittedOK)
                    {
                        if (performSubmissionCompletedRedirects)
                        {
                            if (submittedOK)
                            {
                                context.Response.Redirect("http://openchargemap.org/submissions/complete.aspx", true);
                            }
                            else
                            {
                                context.Response.Redirect("http://openchargemap.org/submissions/error.aspx", true);
                            }
                        }
                        else
                        {
                            context.Response.StatusCode = 202;
                        }
                    }
                    else
                    {
                        if (performSubmissionCompletedRedirects)
                        {
                            context.Response.Redirect("http://openchargemap.org/submissions/error.aspx", true);
                        }
                        else
                        {
                            context.Response.StatusCode = 500;
                        }
                    }
                }

                if (context.Request["action"] == "comment_submission" || filter.Action == "comment")
                {
                    UserComment comment     = new UserComment();
                    bool        processedOK = inputProvider.ProcessUserCommentSubmission(context, ref comment);
                    if (processedOK == true)
                    {
                        //perform submission
                        int result = submissionManager.PerformSubmission(comment, user);
                        if (filter.APIVersion >= 3)
                        {
                            if (result > 0)
                            {
                                OutputSubmissionReceivedMessage(context, "OK", true);
                            }
                            else
                            {
                                OutputBadRequestMessage(context, "Failed");
                            }
                        }
                        else
                        {
                            if (result >= 0)
                            {
                                context.Response.Write("OK:" + result);
                            }
                            else
                            {
                                context.Response.Write("Error:" + result);
                            }
                        }
                    }
                    else
                    {
                        context.Response.Write("Error: Validation Failed");
                    }
                }

                if (context.Request["action"] == "mediaitem_submission" || filter.Action == "mediaitem")
                {
                    var       p        = inputProvider;// as OCM.API.InputProviders.HTMLFormInputProvider;
                    MediaItem m        = new MediaItem();
                    bool      accepted = false;
                    string    msg      = "";
                    try
                    {
                        accepted = p.ProcessMediaItemSubmission(context, ref m, user.ID);
                    }
                    catch (Exception exp)
                    {
                        msg += exp.ToString();
                    }
                    if (accepted)
                    {
                        submissionManager.PerformSubmission(m, user);
                        //OutputSubmissionReceivedMessage(context, "OK :" + m.ID, true);

                        if (filter.APIVersion >= 3)
                        {
                            OutputSubmissionReceivedMessage(context, "OK", true);
                        }
                        else
                        {
                            context.Response.Write("OK");
                        }
                    }
                    else
                    {
                        if (filter.APIVersion >= 3)
                        {
                            OutputBadRequestMessage(context, "Failed");
                        }
                        else
                        {
                            context.Response.Write("Error");
                        }
                    }
                }
            }
        }
        public List <OCM.API.Common.Model.ChargePoint> GetPOIList(APIRequestParams settings)
        {
            var stopwatch = Stopwatch.StartNew();

            bool freshCache         = false;
            int  maxCacheAgeMinutes = int.Parse(ConfigurationManager.AppSettings["MaxCacheAgeMinutes"]);

            if (status != null && status.LastUpdated.AddMinutes(maxCacheAgeMinutes) > DateTime.UtcNow)
            {
                freshCache = true;
            }

            if (!freshCache)
            {
                return(null);
            }

            //TODO: share common between POIManager and this
            int maxResults = settings.MaxResults;

            bool requiresDistance = false;
            GeoJsonPoint <GeoJson2DGeographicCoordinates> searchPoint = null;

            if (settings.Latitude != null && settings.Longitude != null)
            {
                requiresDistance = true;

                if (settings.Distance == null)
                {
                    settings.Distance = 100;
                }
                searchPoint = GeoJson.Point(GeoJson.Geographic((double)settings.Longitude, (double)settings.Latitude));
            }
            else
            {
                searchPoint       = GeoJson.Point(GeoJson.Geographic(0, 0));
                settings.Distance = 100;
            }

            //if distance filter provided in miles, convert to KM before use

            if (settings.DistanceUnit == OCM.API.Common.Model.DistanceUnit.Miles && settings.Distance != null)
            {
                settings.Distance = GeoManager.ConvertMilesToKM((double)settings.Distance);
            }

            bool filterByConnectionTypes = false;
            bool filterByLevels          = false;
            bool filterByOperators       = false;
            bool filterByCountries       = false;
            bool filterByUsage           = false;
            bool filterByStatus          = false;
            bool filterByDataProvider    = false;
            bool filterByChargePoints    = false;

            if (settings.ConnectionTypeIDs != null)
            {
                filterByConnectionTypes = true;
            }
            else
            {
                settings.ConnectionTypeIDs = new int[] { -1 };
            }

            if (settings.LevelIDs != null)
            {
                filterByLevels = true;
            }
            else
            {
                settings.LevelIDs = new int[] { -1 };
            }

            if (settings.OperatorIDs != null)
            {
                filterByOperators = true;
            }
            else
            {
                settings.OperatorIDs = new int[] { -1 };
            }

            if (settings.ChargePointIDs != null)
            {
                filterByChargePoints = true;
            }
            else
            {
                settings.ChargePointIDs = new int[] { -1 };
            }

            //either filter by named country code or by country id list
            if (settings.CountryCode != null)
            {
                var referenceData = database.GetCollection <OCM.API.Common.Model.CoreReferenceData>("reference").FindOne();

                var filterCountry = referenceData.Countries.FirstOrDefault(c => c.ISOCode.ToUpper() == settings.CountryCode.ToUpper());
                if (filterCountry != null)
                {
                    filterByCountries   = true;
                    settings.CountryIDs = new int[] { filterCountry.ID };
                }
                else
                {
                    filterByCountries   = false;
                    settings.CountryIDs = new int[] { -1 };
                }
            }
            else
            {
                if (settings.CountryIDs != null && settings.CountryIDs.Any())
                {
                    filterByCountries = true;
                }
                else
                {
                    settings.CountryIDs = new int[] { -1 };
                }
            }

            if (settings.UsageTypeIDs != null)
            {
                filterByUsage = true;
            }
            else
            {
                settings.UsageTypeIDs = new int[] { -1 };
            }

            if (settings.StatusTypeIDs != null)
            {
                filterByStatus = true;
            }
            else
            {
                settings.StatusTypeIDs = new int[] { -1 };
            }

            if (settings.DataProviderIDs != null)
            {
                filterByDataProvider = true;
            }
            else
            {
                settings.DataProviderIDs = new int[] { -1 };
            }

            if (settings.SubmissionStatusTypeID == -1)
            {
                settings.SubmissionStatusTypeID = null;
            }
            /////////////////////////////////////
            if (database != null)
            {
                var collection = database.GetCollection <OCM.API.Common.Model.ChargePoint>("poi");
                IQueryable <OCM.API.Common.Model.ChargePoint> poiList = from c in collection.AsQueryable <OCM.API.Common.Model.ChargePoint>() select c;

                //filter by points along polyline or bounding box (TODO: polygon)
                if (
                    (settings.Polyline != null && settings.Polyline.Any()) ||
                    (settings.BoundingBox != null && settings.BoundingBox.Any()) ||
                    (settings.Polygon != null && settings.Polygon.Any())
                    )
                {
                    //override lat.long specified in search, use polyline or bounding box instead
                    settings.Latitude  = null;
                    settings.Longitude = null;

                    double[,] pointList;
                    //filter by locationwithin polylinne expanded to a polygon
                    //TODO; conversion to Km if required
                    IEnumerable <LatLon> searchPolygon = null;

                    if (settings.Polyline != null && settings.Polyline.Any())
                    {
                        searchPolygon = OCM.Core.Util.PolylineEncoder.SearchPolygonFromPolyLine(settings.Polyline, (double)settings.Distance);
                    }

                    if (settings.BoundingBox != null && settings.BoundingBox.Any())
                    {
                        searchPolygon = settings.BoundingBox;
                    }

                    if (settings.Polygon != null && settings.Polygon.Any())
                    {
                        searchPolygon = settings.Polygon;
                    }

                    pointList = new double[searchPolygon.Count(), 2];
                    int pointIndex = 0;
                    foreach (var p in searchPolygon)
                    {
                        pointList[pointIndex, 0] = (double)p.Longitude;
                        pointList[pointIndex, 1] = (double)p.Latitude;
                        pointIndex++;
#if DEBUG
                        System.Diagnostics.Debug.WriteLine(" {lat: " + p.Latitude + ", lng: " + p.Longitude + "},");
#endif
                    }
                    poiList = poiList.Where(q => Query.WithinPolygon("SpatialPosition", pointList).Inject());
                }
                else
                {
                    if (requiresDistance)
                    {
                        //filter by distance from lat/lon first
                        poiList = poiList.Where(q => Query.Near("SpatialPosition", searchPoint, (double)settings.Distance * 1000).Inject());//.Take(settings.MaxResults);
                    }
                }

                poiList = (from c in poiList
                           where

                           (c.AddressInfo != null) &&             //c.AddressInfo.Latitude != null && c.AddressInfo.Longitude != null && c.AddressInfo.CountryID != null)
                           ((settings.SubmissionStatusTypeID == null && (c.SubmissionStatusTypeID == null || c.SubmissionStatusTypeID == (int)StandardSubmissionStatusTypes.Imported_Published || c.SubmissionStatusTypeID == (int)StandardSubmissionStatusTypes.Submitted_Published)) ||
                            (settings.SubmissionStatusTypeID == 0) ||                  //return all regardless of status
                            (settings.SubmissionStatusTypeID != null && c.SubmissionStatusTypeID != null && c.SubmissionStatusTypeID == settings.SubmissionStatusTypeID)
                           ) &&                //by default return live cps only, otherwise use specific submission statusid
                           (c.SubmissionStatusTypeID != null && c.SubmissionStatusTypeID != (int)StandardSubmissionStatusTypes.Delisted_NotPublicInformation)
                           //&& (settings.ChargePointID == null || (settings.ChargePointID!=null && (c.ID!=null && c.ID == settings.ChargePointID)))
                           && (settings.OperatorName == null || c.OperatorInfo.Title == settings.OperatorName) &&
                           (settings.IsOpenData == null || (settings.IsOpenData != null && ((settings.IsOpenData == true && c.DataProvider.IsOpenDataLicensed == true) || (settings.IsOpenData == false && c.DataProvider.IsOpenDataLicensed != true)))) &&
                           (settings.DataProviderName == null || c.DataProvider.Title == settings.DataProviderName) &&
                           (filterByCountries == false || (filterByCountries == true && settings.CountryIDs.Contains((int)c.AddressInfo.CountryID))) &&
                           (filterByOperators == false || (filterByOperators == true && settings.OperatorIDs.Contains((int)c.OperatorID))) &&
                           (filterByChargePoints == false || (filterByChargePoints == true && settings.ChargePointIDs.Contains((int)c.ID))) &&
                           (filterByUsage == false || (filterByUsage == true && settings.UsageTypeIDs.Contains((int)c.UsageTypeID))) &&
                           (filterByStatus == false || (filterByStatus == true && settings.StatusTypeIDs.Contains((int)c.StatusTypeID))) &&
                           (filterByDataProvider == false || (filterByDataProvider == true && settings.DataProviderIDs.Contains((int)c.DataProviderID)))
                           select c);

                if (settings.ChangesFromDate != null)
                {
                    poiList = poiList.Where(c => c.DateLastStatusUpdate >= settings.ChangesFromDate.Value);
                }

                if (settings.CreatedFromDate != null)
                {
                    poiList = poiList.Where(c => c.DateCreated >= settings.CreatedFromDate.Value);
                }

                //if (settings.LevelOfDetail != null && settings.LevelOfDetail > 1)
                //{
                //    poiList = poiList.Where(q => Query.Mod("ID", (int)settings.LevelOfDetail, 0).Inject());
                //}

                //where level of detail is greater than 1 we decide how much to return based on the given level of detail (1-10) Level 10 will return the least amount of data and is suitable for a global overview
                if (settings.LevelOfDetail > 1)
                {
                    //return progressively less matching results (across whole data set) as requested Level Of Detail gets higher

                    if (settings.LevelOfDetail > 3)
                    {
                        settings.LevelOfDetail = 1; //highest priority LOD
                    }
                    else
                    {
                        settings.LevelOfDetail = 2; //include next level priority items
                    }
                    poiList = poiList.Where(c => c.LevelOfDetail <= settings.LevelOfDetail);
                }

                //apply connectionInfo filters, all filters must match a distinct connection within the charge point, rather than any filter matching any connectioninfo
                if (settings.ConnectionType != null || settings.MinPowerKW != null || filterByConnectionTypes || filterByLevels)
                {
                    poiList = from c in poiList
                              where
                              c.Connections.Any(conn =>
                                                (settings.ConnectionType == null || (settings.ConnectionType != null && conn.ConnectionType.Title == settings.ConnectionType)) &&
                                                (settings.MinPowerKW == null || (settings.MinPowerKW != null && conn.PowerKW >= settings.MinPowerKW)) &&
                                                (filterByConnectionTypes == false || (filterByConnectionTypes == true && settings.ConnectionTypeIDs.Contains(conn.ConnectionType.ID))) &&
                                                (filterByLevels == false || (filterByLevels == true && settings.LevelIDs.Contains((int)conn.Level.ID)))
                                                )
                              select c;
                }

                List <API.Common.Model.ChargePoint> results = null;
                if (!requiresDistance || (settings.Latitude == null || settings.Longitude == null))
                {
                    //distance is not required or can't be provided
                    results = poiList.OrderByDescending(p => p.DateCreated).Take(settings.MaxResults).ToList();
                }
                else
                {
                    //distance is required, calculate and populate in results
                    results = poiList.ToList();
                    //populate distance
                    foreach (var p in results)
                    {
                        p.AddressInfo.Distance     = GeoManager.CalcDistance((double)settings.Latitude, (double)settings.Longitude, p.AddressInfo.Latitude, p.AddressInfo.Longitude, settings.DistanceUnit);
                        p.AddressInfo.DistanceUnit = settings.DistanceUnit;
                    }
                    results = results.OrderBy(r => r.AddressInfo.Distance).Take(settings.MaxResults).ToList();
                }

                if (settings.IsCompactOutput)
                {
                    //dehydrate POI object by removing navigation properties which are based on reference data. Client can then rehydrate using reference data, saving on data transfer KB
                    foreach (var p in results)
                    {
                        //need to null reference data objects so they are not included in output. caution required here to ensure compact output via SQL is same as Cache DB output
                        p.DataProvider        = null;
                        p.OperatorInfo        = null;
                        p.UsageType           = null;
                        p.StatusType          = null;
                        p.SubmissionStatus    = null;
                        p.AddressInfo.Country = null;
                        if (p.Connections != null)
                        {
                            foreach (var c in p.Connections)
                            {
                                c.ConnectionType = null;
                                c.CurrentType    = null;
                                c.Level          = null;
                                c.StatusType     = null;
                            }
                        }
                        if (p.UserComments != null)
                        {
                            foreach (var c in p.UserComments)
                            {
                                c.CheckinStatusType = null;
                                c.CommentType       = null;
                            }
                        }

                        /* if (p.MediaItems != null)
                         * {
                         *   foreach (var c in p.MediaItems)
                         *   {
                         *       c.User = null;
                         *   }
                         * }*/
                    }
                }

                stopwatch.Stop();
                System.Diagnostics.Debug.WriteLine("Cache Provider POI Query Time:" + stopwatch.ElapsedMilliseconds + "ms");

                return(results);
            }
            else
            {
                return(null);
            }
        }
Example #23
0
 public async static Task <IEnumerable <OCM.API.Common.Model.ChargePoint> > GetPOIList(APIRequestParams filter)
 {
     try
     {
         return(await CacheProviderMongoDB.DefaultInstance.GetPOIListAsync(filter));
     }
     catch (Exception)
     {
         return(null);
     }
 }
Example #24
0
        public string GetTotalsPerCountrySummary(bool outputAsFunction, string functionName, APIRequestParams filterSettings)
        {
            //FIXME: move caching to caller
            string output = "function " + functionName + "() { var ocm_summary = new Array(); \r\n";

            var list = GetAllCountryStats();

            list.OrderByDescending(i => i.ItemCount).ToList();

            foreach (var item in list)
            {
                output += "ocm_summary[ocm_summary.length]={\"country\":\"" + item.CountryName + "\", \"isocode\":\"" + item.ISOCode + "\", \"itemcount\":" + item.LocationCount + ", \"locationcount\":" + item.LocationCount + ", \"stationcount\":" + item.StationCount + "}; \r\n";
            }
            output += " return ocm_summary; }";
            return(output);
        }
Example #25
0
        /// <summary>
        /// Output Core Reference Data (lookup lists, default objects)
        /// </summary>
        /// <param name="outputProvider"></param>
        /// <param name="context"></param>
        /// <param name="filter"></param>
        private void OutputCoreReferenceData(IOutputProvider outputProvider, HttpContext context, APIRequestParams filter)
        {
            //get core reference data
            var refDataManager     = new ReferenceDataManager();
            CoreReferenceData data = null;

            //cache result
            if (HttpContext.Current.Cache["CoreRefData"] != null && filter.EnableCaching)
            {
                data = (CoreReferenceData)HttpContext.Current.Cache["CoreRefData"];
            }
            else
            {
                data = refDataManager.GetCoreReferenceData();

                HttpContext.Current.Cache.Add("CoreRefData", data, null, Cache.NoAbsoluteExpiration, new TimeSpan(1, 0, 0), CacheItemPriority.Normal, null);
            }

            //populate non-cached fragments (user profile)
            data.UserProfile = new InputProviderBase().GetUserFromAPICall(context);

            //send response
            outputProvider.GetOutput(context.Response.OutputStream, data, filter);
        }
 public void GetOutput(Stream outputStream, Common.Model.CoreReferenceData data, APIRequestParams settings)
 {
     throw new NotImplementedException();
 }
Example #27
0
        private void OutputAvailabilityResult(IOutputProvider outputProvider, HttpContext context, APIRequestParams filter)
        {
            //TODO: provider specific availability check with result caching
            var results = new List <object>();

            foreach (var poiId in filter.ChargePointIDs)
            {
                results.Add(new { id = filter.ChargePointIDs, status = StandardStatusTypes.Unknown, timestamp = DateTime.UtcNow });
            }
            //send API response
            if (filter.IsEnvelopedResponse)
            {
                var responseEnvelope = new APIResponseEnvelope();
                responseEnvelope.Data = results;
                outputProvider.GetOutput(context.Response.OutputStream, responseEnvelope, filter);
            }
            else
            {
                outputProvider.GetOutput(context.Response.OutputStream, results, filter);
            }
        }
Example #28
0
        public string GetTotalsPerCountrySummary(bool outputAsFunction, string functionName, APIRequestParams filterSettings)
        {
            //TODO: optionally output as normal JSON
            string output = "function " + functionName + "() { var ocm_summary = new Array(); \r\n";

            if (HttpContext.Current.Cache["ocm_summary"] == null)
            {
                var list = GetAllCountryStats();
                HttpContext.Current.Cache["ocm_summary"] = list.OrderByDescending(i => i.ItemCount).ToList();
            }
            var cachedresults = (List <CountrySummary>)HttpContext.Current.Cache["ocm_summary"];

            foreach (var item in cachedresults)
            {
                output += "ocm_summary[ocm_summary.length]={\"country\":\"" + item.CountryName + "\", \"isocode\":\"" + item.ISOCode + "\", \"itemcount\":" + item.LocationCount + ", \"locationcount\":" + item.LocationCount + ", \"stationcount\":" + item.StationCount + "}; \r\n";
            }
            output += " return ocm_summary; }";
            return(output);
        }
Example #29
0
        private void OutputGeocodingResult(IOutputProvider outputProvider, HttpContext context, APIRequestParams filter)
        {
            GeocodingResult result = null;

            //get or get and cache result
            if (HttpContext.Current.Cache["Geocoding_" + filter.HashKey] != null && filter.EnableCaching)
            {
                result = (GeocodingResult)HttpContext.Current.Cache["Geocoding_" + filter.HashKey];
            }
            else
            {
                var geocoder = new GeocodingHelper();
                geocoder.IncludeExtendedData = true;

                //result = geocoder.GeolocateAddressInfo_OSM(filter.Address);
                result = geocoder.GeolocateAddressInfo_Google(filter.Address);

                HttpContext.Current.Cache.Add("Geocoding_" + filter.HashKey, result, null, Cache.NoAbsoluteExpiration, new TimeSpan(1, 0, 0), CacheItemPriority.Normal, null);
            }

            //send API response
            if (filter.IsEnvelopedResponse)
            {
                var responseEnvelope = new APIResponseEnvelope();
                responseEnvelope.Data = result;
                outputProvider.GetOutput(context.Response.OutputStream, responseEnvelope, filter);
            }
            else
            {
                outputProvider.GetOutput(context.Response.OutputStream, result, filter);
            }
        }
Example #30
0
        /// <summary>
        /// Output standard POI List results
        /// </summary>
        /// <param name="outputProvider"></param>
        /// <param name="context"></param>
        /// <param name="filter"></param>
        private async Task OutputPOIList(IOutputProvider outputProvider, HttpContext context, APIRequestParams filter)
        {
#if DEBUG
            var stopwatch = Stopwatch.StartNew();
#endif
            IEnumerable <OCM.API.Common.Model.ChargePoint> dataList = null;

            //get list of charge points for output:
            var poiManager = new POIManager();
            dataList = await poiManager.GetPOIListAsync(filter);

#if DEBUG
            System.Diagnostics.Debug.WriteLine("OutputPOIList: Time for Query/Conversion: " + stopwatch.ElapsedMilliseconds + "ms");
            stopwatch.Restart();
#endif
            //send response
            await outputProvider.GetOutput(context, context.Response.Body, dataList, filter);

#if DEBUG
            System.Diagnostics.Debug.WriteLine("OutputPOIList: Time for Output to stream: " + stopwatch.ElapsedMilliseconds + "ms");
#endif
        }
Example #31
0
 public Task GetOutput(HttpContext context, Stream outputStream, Common.Model.CoreReferenceData data, APIRequestParams settings)
 {
     throw new NotImplementedException();
 }
Example #32
0
        /// <summary>
        /// Output Core Reference Data (lookup lists, default objects)
        /// </summary>
        /// <param name="outputProvider"></param>
        /// <param name="context"></param>
        /// <param name="filter"></param>
        private async Task OutputCoreReferenceData(IOutputProvider outputProvider, HttpContext context, APIRequestParams filter)
        {
            //get core reference data
            using (var refDataManager = new ReferenceDataManager())
            {
                if (_settings.IsCacheOnlyMode)
                {
                    filter.AllowDataStoreDB = false;
                }

                var data = await refDataManager.GetCoreReferenceDataAsync(filter);

                if (data != null)
                {
                    //send response
                    await outputProvider.GetOutput(context, context.Response.Body, data, filter);
                }
                else
                {
                    // failed
                    await new JSONOutputProvider().GetOutput(context, context.Response.Body, new { Status = "Error", Message = "Cache not ready, canoot return results" }, filter);
                }
            }
        }