Beispiel #1
0
        /// <summary>
        /// TODO:
        /// Create the SQL string to insert this map directly into the MapTube maps database.
        /// </summary>
        /// <param name="baseUrl">root url of where all the descriptors are going to be copied to e.g. http://www.maptube.org/census2011 </param>
        /// <param name="DescriptorRelativeUrl">Descriptor url relative to the base e.g. UV01EW/UV01EW_01_desc.xml</param>
        /// <returns></returns>
        public string CreateSQLInsert(Uri CSVUri, string GeometryName, string username, string Title, string Keywords, string ShortDescription, string Information, string DescriptorRelativeUrl, MapTubeD.ColourScale cs)
        {
            /*
             * CREATE TABLE[dbo].[maps](
             * [mapid] [int] IDENTITY(1,1) NOT NULL,
             * [username] [nvarchar](24) NULL,
             * [mapdescription] [nvarchar](255) NULL,
             * [url] [nvarchar](255) NULL,
             * [keywords] [nvarchar](255) NULL,
             * [maptitle] [nvarchar](64) NULL,
             * [tileurl] [nvarchar](255) NULL,
             * [maxzoomlevel] [tinyint] NULL,
             * [minlat] [float] NULL,
             * [minlon] [float] NULL,
             * [maxlat] [float] NULL,
             * [maxlon] [float] NULL,
             * [colourscale] [nvarchar](max) NULL,
             * [hits] [int] NULL,
             * [creationdate] [datetime] NULL,
             * [lastviewdate] [datetime] NULL,
             * [information] [nvarchar](max) NULL,
             * [maptype] [tinyint] NULL,
             * [isclickable] [bit] NOT NULL,
             * [timetag] [nvarchar](6) NULL,
             * [topicality] [real] NULL
             * )
             */
            string SQLPattern = "insert into maps (username,mapdescription,url,keywords,maptitle,tileurl,maxzoomlevel,minlat,minlon,maxlat,maxlon,colourscale,hits,creationdate,lastviewdate,information,maptype,isclickable,timetag,topicality)"
                                + " values ('{0}','{1}','{2}','{3}','{4}','{5}',{6},{7},{8},{9},{10},'{11}',{12},'{13}','{14}','{15}',{16},{17},{18},{19});";
            float minlat = 0, minlon = 0, maxlat = 0, maxlon = 0;

            GetExtentsForGeometry(GeometryName, out minlat, out minlon, out maxlat, out maxlon); //note - this does return success or failure...
            //extract the colourThresholds part from the colourscale
            XmlDocument doc = new XmlDocument();

            doc.LoadXml(cs.toXML());
            XmlNode node     = doc.SelectSingleNode("/colourscale/colourThresholds");
            string  csString = node.OuterXml;

            //todo: data extents and test descriptor url and base url
            string DescriptorUrl = new Uri(Path.Combine(_baseURL, DescriptorRelativeUrl)).ToString();
            string TileUrl       = ""; //this could be a pointer to a MapTubeD instance, but nothing uses the default

            //dates need to be in the format 2016-05-15 21:50:00

            return(string.Format(SQLPattern, username, ShortDescription, DescriptorUrl, Keywords, Title, TileUrl, 17, minlat, minlon, maxlat, maxlon, csString, 0, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), Information, 2, 1, "NULL", "NULL"));
        }
Beispiel #2
0
        /// <summary>
        /// This takes the data for a map and returns the MapTubeD descriptor and settings for it.
        /// </summary>
        public bool CreateMapDescriptor(Uri CSVUri, string UniqueKey, string AreaKey, string GeometryName, string DataField,
                                        out MapTubeD.DBJoinDescriptorFile desc, out MapTubeD.ColourScale cs, out MapTubeD.RenderStyle rs)
        {
            desc                = new MapTubeD.DBJoinDescriptorFile();
            desc.AreaKey        = AreaKey;
            desc.Geometry       = GeometryName;
            desc.DataField      = DataField;
            desc.DataURL        = UniqueKey + ".csv";
            desc.RenderStyleURL = UniqueKey + "_settings.xml";

            cs = new MapTubeD.ColourScale();

            //we don't actually do anything with the style at this point, so just create and return a new one
            rs = new MapTubeD.RenderStyle();

            //OK, now we need a style...
            //the rest of this is 'borrowed' from the webmapcreator
            string[] Headers;
            MapTube.GIS.DataLoader            loader  = new MapTube.GIS.DataLoader();
            MapTube.GIS.DataLoader.StatusCode Success = loader.LoadCSVData(CSVUri.ToString(), DataField, out Headers);
            if (Success != MapTube.GIS.DataLoader.StatusCode.FAIL)
            {
                bool IsDiscreteData = loader.IsDiscreteData;
                if (IsDiscreteData)
                {
                    cs.deleteAllColours();
                    List <float> Values = loader.GetDiscreteValues;
                    Color[]      cols   = MapTube.GIS.Colours.FindNamedColours(DiscreteScheme, Values.Count);
                    for (int i = 0; i < Values.Count; i++)
                    {
                        cs.addColour(cols[i], Values[i], Convert.ToString(Values[i]));
                    }
                }
                else
                {
                    //For continuous you need an extra colour
                    float[] breaksvalues  = null;
                    int     NumClass      = 5;
                    bool    IsMissingData = false;
                    float   MissingValue  = 0;
                    //breaksvalues = MapTube.GIS.Jenks.GetBreaks(NumClass, IsMissingData, MissingValue, loader.DataSet);
                    breaksvalues = MapTube.GIS.Quantiles.GetBreaks(NumClass, IsMissingData, MissingValue, loader.DataSet);

                    cs.deleteAllColours();
                    //This is a really nasty hack and I would like to get rid of it. If two thresholds in the colourscale are equal,
                    //then their positions flip randomly as the list is re-sorted and the colours and descriptions move.
                    //The only way round this is to have a sortable list that maintains the order colours were added in the event that
                    //two thresholds are equal. Here we get around it by moving the threshold by the smallest possible amount we can
                    //get away with.
                    for (int i = 1; i < breaksvalues.Length; i++)
                    {
                        if (breaksvalues[i - 1] == breaksvalues[i])
                        {
                            //Add small amount to threshold. Remember -ve values and the fact that there are limited bits of precision.
                            breaksvalues[i] = (float)((double)breaksvalues[i] + (Math.Abs((double)breaksvalues[i]) * 0.00000003d));
                        }
                    }
                    //now assign colours the existing colours to the breaks
                    int     MissingDataIndex = -1; //might need it in the future - all this comes from the webmapcreator
                    Color[] cols             = MapTube.GIS.Colours.FindNamedColours(SequentialScheme, breaksvalues.Length);
                    for (int i = 0; i < breaksvalues.Length; i++)
                    {
                        string text = "";
                        //with a continuous colourscale, a colour only represents a specific data value
                        //text = "Q" + i + " : " + breaksvalues[i];
                        if (i == MissingDataIndex)
                        {
                            text = "Missing Data (x=" + breaksvalues[i] + ")";
                        }
                        //minimum breaks value condition taking into account missing data might be below it (i.e. i=0 or i=1)
                        else if (((i == 0) && (MissingDataIndex == -1)) || ((i == 1) && (MissingDataIndex == 0)))
                        {
                            text = breaksvalues[i] + " (min) <= x < " + breaksvalues[i + 1];
                        }
                        //maximum break taking into account missing data might be above it (NOTE i==MissingDataIndex handled above)
                        else if ((i == breaksvalues.Length - 1) || ((i == breaksvalues.Length - 2) && (MissingDataIndex == i + 1)))
                        {
                            text = "x = " + breaksvalues[i] + " (max)";
                        }
                        //somewhere in the middle case
                        else
                        {
                            text = breaksvalues[i] + " <= x < " + breaksvalues[i + 1];
                        }
                        cs.addColour(cols[i], breaksvalues[i], text);
                    }
                }

                return(true);
            }

            return(false); //failed, data not valid
        }