예제 #1
0
        /// <summary>
        /// Converts from Mapsui Geometry type to NetTopologySuite Geometry type, then converts to GeoJSON.
        /// Writes the point list to wkt format, the uses Geometry2GeoJSON to convert to geojson
        /// </summary>
        /// <param name="pointList"></param>
        /// <returns>GeoJSON</returns>
        public static string CoordinatesToGeoJSON(List <Mapsui.Geometries.Point> pointList)
        {
            var wkt = "";

            if (pointList.Count == 1)
            {
                var point = pointList[0];
                wkt = Mapsui.Geometries.WellKnownText.GeometryToWKT.Write(point);
            }
            else if (pointList[0] == pointList[pointList.Count - 1])
            {
                var polygon = new Mapsui.Geometries.Polygon();

                foreach (var coord in pointList)
                {
                    polygon.ExteriorRing.Vertices.Add(new Mapsui.Geometries.Point(coord.X, coord.Y));
                }
                wkt = Mapsui.Geometries.WellKnownText.GeometryToWKT.Write(polygon);
            }
            else
            {
                var line = new Mapsui.Geometries.LineString(pointList);
                wkt = Mapsui.Geometries.WellKnownText.GeometryToWKT.Write(line);
            }

            WKTReader reader = new WKTReader();

            NetTopologySuite.Geometries.Geometry geom = reader.Read(wkt);
            var geojson = DataDAO.Geometry2GeoJSON(geom);

            return(geojson);
        }
예제 #2
0
        /// <summary>
        /// Find the centroid of the geometry
        /// </summary>
        /// <param name="geometryId"></param>
        /// <returns>A point object representing the centroid</returns>
        public static Mapsui.Geometries.Point GetCentreOfGeometry(int geometryId)
        {
            var items = DataDAO.getDataForMap(App.CurrentProjectId);

            foreach (var item in items)
            {
                if (item.geomId == geometryId)
                {
                    var coords = item.shapeGeom.Centroid;
                    var centre = SphericalMercator.FromLonLat(coords.X, coords.Y);
                    return(centre);
                }
            }
            return(null);
        }
예제 #3
0
        /// <summary>
        /// Deserialise the json returned from the connector and update the database with the parameters read
        /// </summary>
        /// <param name="json"></param>
        /// <returns></returns>
        public static string GetProjectDataFromJSON(string json)
        {
            try
            {
                //Parse JSON
                var settings = new JsonSerializerSettings
                {
                    NullValueHandling    = NullValueHandling.Ignore,
                    StringEscapeHandling = StringEscapeHandling.EscapeHtml
                };
                var projectRoot = JsonConvert.DeserializeObject <Project>(json, settings);

                DataDAO.ProcessJSON((Project)projectRoot);

                return("Data successfully downloaded");
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                return("Error parsing data" + e);
            }
        }
예제 #4
0
        public static Dictionary <string, ILayer> CreateShapes()
        {
            var layerDic = new Dictionary <string, ILayer>();
            var items    = DataDAO.getDataForMap(App.CurrentProjectId);

            if (items != null && items.Count > 0)
            {
                var points    = new List <Feature>();
                var polygons  = new List <Feature>();
                var lines     = new List <Feature>();
                var allShapes = new List <Feature>();

                foreach (Shape item in items)
                {
                    var coords     = item.shapeGeom.Coordinates;
                    var coordCount = item.shapeGeom.Coordinates.Length;
                    if (coordCount > 0)
                    {
                        if (coordCount == 1)
                        {
                            //Point
                            var coord = coords[0];

                            var point = SphericalMercator.FromLonLat(coord.X, coord.Y);

                            var feature = new Feature
                            {
                                Geometry  = point,
                                ["Name"]  = item.geomId.ToString(),
                                ["Label"] = item.title
                            };
                            feature.Styles.Add(new LabelStyle
                            {
                                Text                = item.title,
                                BackColor           = new Mapsui.Styles.Brush(Mapsui.Styles.Color.White),
                                HorizontalAlignment = LabelStyle.HorizontalAlignmentEnum.Left,
                                Offset              = new Offset(20, 0, false)
                            });
                            points.Add(feature);
                            allShapes.Add(feature);
                        }
                        else
                        {
                            var coord0 = coords[0];
                            var coordx = coords[coordCount - 1];
                            if (coord0.X == coordx.X && coord0.Y == coordx.Y)
                            {
                                //Polygon
                                var polygon = new Polygon();

                                var localCoords = coords;
                                foreach (NetTopologySuite.Geometries.Coordinate coord in localCoords)
                                {
                                    var pt = SphericalMercator.FromLonLat(coord.X, coord.Y);
                                    polygon.ExteriorRing.Vertices.Add(new Mapsui.Geometries.Point(pt.X, pt.Y));
                                }
                                var feature = new Feature {
                                    Geometry  = polygon,
                                    ["Name"]  = item.geomId.ToString(),
                                    ["Label"] = item.title
                                };
                                feature.Styles.Add(new LabelStyle
                                {
                                    Text                = item.title,
                                    BackColor           = new Mapsui.Styles.Brush(Mapsui.Styles.Color.White),
                                    HorizontalAlignment = LabelStyle.HorizontalAlignmentEnum.Center
                                });

                                polygons.Add(feature);
                                allShapes.Add(feature);
                            }
                            else
                            {
                                //Line
                                var line        = new LineString();
                                var localCoords = coords;
                                foreach (NetTopologySuite.Geometries.Coordinate coord in localCoords)
                                {
                                    var pt = SphericalMercator.FromLonLat(coord.X, coord.Y);
                                    line.Vertices.Add(new Mapsui.Geometries.Point(pt.X, pt.Y));
                                }
                                var feature = new Feature
                                {
                                    Geometry  = line,
                                    ["Name"]  = item.geomId.ToString(),
                                    ["Label"] = item.title
                                };
                                feature.Styles.Add(new LabelStyle
                                {
                                    Text                = item.title,
                                    BackColor           = new Mapsui.Styles.Brush(Mapsui.Styles.Color.White),
                                    HorizontalAlignment = LabelStyle.HorizontalAlignmentEnum.Center
                                });
                                lines.Add(feature);
                                allShapes.Add(feature);
                            }
                        }
                    }
                }

                ILayer polygonLayer   = CreatePolygonLayer(polygons, new Mapsui.Styles.Color(0, 0, 200, 255), new Mapsui.Styles.Color(0, 0, 200, 32));
                ILayer pointLayer     = CreatePointLayer(points);
                ILayer lineLayer      = CreateLineLayer(lines, new Mapsui.Styles.Color(0, 0, 200, 255));
                ILayer allShapesLayer = CreatePolygonLayer(allShapes, new Mapsui.Styles.Color(0, 0, 200, 255), new Mapsui.Styles.Color(0, 0, 200, 32)); //AllShapes layer is created merely to get bounding box of all shapes. It does not have the correct styles for showing all the shapes


                layerDic.Add("polygons", polygonLayer);
                layerDic.Add("lines", lineLayer);
                layerDic.Add("points", pointLayer);
                layerDic.Add("all", allShapesLayer);
            }
            return(layerDic);
        }
예제 #5
0
        /// <summary>
        /// Downloads the json from the connector for a particular project id. Includes authorisation.
        /// </summary>
        /// <param name="projectId">Specifies project</param>
        /// <param name="time">Specifies the earliest time from which the changes should be downloaded</param>
        public static void GetJsonStringForProject(string projectId, string time)
        {
            //Refresh token, then synchronise
            var auth = Authentication.AuthParams;

            auth.ShowErrors  = false;
            auth.AllowCancel = false;

            auth.Completed += async(sender, eventArgs) =>
            {
                if (eventArgs.IsAuthenticated == true)
                {
                    Dictionary <String, String> props = eventArgs.Account.Properties;

                    Authentication.SaveTokens(props);

                    string url = "";
                    if (time != null && time != "")
                    {
                        url = App.ServerURL + "/api/Project/" + projectId + "/" + time;
                    }
                    else
                    {
                        url = App.ServerURL + "/api/Project/" + projectId;
                    }

                    var through = false;
                    try
                    {
                        var json = "";
                        using (HttpClient client = new HttpClient())
                        {
                            client.Timeout = TimeSpan.FromSeconds(600); // 10 minutes
                            var token = Preferences.Get("AccessToken", "");
                            client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);

                            //MessagingCenter.Send(new DataDAO(), "SyncMessage", "Waiting for data");
                            var response = await client.GetAsync(url);

                            var jsonbytes = await response.Content.ReadAsByteArrayAsync();

                            var utf8 = Encoding.UTF8;
                            json = utf8.GetString(jsonbytes, 0, jsonbytes.Length);

                            through = true; // Check that we got through all the code
                        }

                        string success = "false";

                        if (json.ToLower() == "error downloading data")
                        {
                            MessagingCenter.Send(new Project(), "DataDownloadError", json);
                        }

                        if (json.ToLower() != "error downloading data" && json.ToLower() != "error parsing data")
                        {
                            success = DataDAO.GetProjectDataFromJSON(json);
                            App.CurrentProjectId = projectId;
                            App.SetProject(projectId);
                            ShowSyncCompleteMessage(success);
                            MessagingCenter.Send(new Project(), "DataDownloadSuccess", success);
                        }

                        MessagingCenter.Send(Application.Current, "DownloadComplete", json);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e);
                        if (through == false)
                        {
                            MessagingCenter.Send(Application.Current, "DownloadComplete", "Error Downloading Data");
                            MessagingCenter.Send <Application, string>(Application.Current, "SyncMessage", "");
                        }
                    }
                }
                else
                {
                    MessagingCenter.Send <Xamarin.Forms.Application>(Xamarin.Forms.Application.Current, "LoginUnsuccessful");
                }
            };

            auth.Error += (sender, eventArgs) =>
            {
                //Careful! This triggers on the iPhone even when login is successful
            };

            auth.RequestRefreshTokenAsync(Preferences.Get("RefreshToken", ""));
        }
예제 #6
0
        /// <summary>
        /// Synchronises the specified project: Uploads data which do not yet exist on the server, then downloads all changes since the last synchronisation.
        /// This includes authorisation
        /// </summary>
        /// <param name="projectId"></param>
        public async static void SynchroniseDataForProject(string projectId)
        {
            //Refresh token, then synchronise
            var auth = Authentication.AuthParams;

            auth.ShowErrors  = false;
            auth.AllowCancel = false;

            auth.Completed += async(sender, eventArgs) =>
            {
                if (eventArgs.IsAuthenticated == true)
                {
                    Dictionary <String, String> props = eventArgs.Account.Properties;
                    Authentication.SaveTokens(props);

                    string time     = "0000-01-01T00:00:00";
                    var    lastSync = DateTime.Now;
                    DateTime.TryParse(time, out lastSync);
                    var project = Project.FetchProject(projectId);
                    if (project.lastSync != null)
                    {
                        lastSync = project.lastSync.ToUniversalTime();
                        time     = lastSync.ToString("yyyy-MM-ddTHH:mm:ss" + "Z");
                    }
                    var json = DataDAO.PrepareJSONForUpload(lastSync); // Prepare data for upload

                    string url = App.ServerURL + "/api/Project/" + time + "?iamgod=true";

                    try
                    {
                        using (HttpClient client = new HttpClient())
                        {
                            client.Timeout = TimeSpan.FromSeconds(6000); // 10 minutes
                            var token = Preferences.Get("AccessToken", "");
                            client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);

                            MessagingCenter.Send(new DataDAO(), "SyncMessage", "Waiting for data");
                            var response = await client.PostAsync(url, new StringContent(json, Encoding.UTF8, "application/json"));  //UPLOAD

                            var jsonbytes = await response.Content.ReadAsByteArrayAsync();

                            var utf8         = Encoding.UTF8;
                            var jsonResponse = utf8.GetString(jsonbytes, 0, jsonbytes.Length); //Response contains updates to data since last sync

                            var settings = new JsonSerializerSettings
                            {
                                NullValueHandling    = NullValueHandling.Ignore,
                                StringEscapeHandling = StringEscapeHandling.EscapeHtml
                            };
                            var returnedObject = JsonConvert.DeserializeObject <ProjectSyncDTO>(jsonResponse, settings);  //Deserialise response


                            if (returnedObject.success == true)
                            {
                                DataDAO.ProcessJSON(returnedObject.projectUpdate); //Update database with downloaded data

                                using (SQLiteConnection conn = new SQLiteConnection(Preferences.Get("databaseLocation", "")))
                                {
                                    project.lastSync = DateTime.Now;
                                    conn.Update(project);

                                    var error               = returnedObject.error;
                                    var deletedRecords      = returnedObject.records.deleted;
                                    var deletedRecords2     = returnedObject.geometries.geometryRecords.deleted;
                                    var deletedRecordsTotal = deletedRecords.Concat(deletedRecords2).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
                                    var skippedRecords      = returnedObject.records.skipped;
                                    var skippedRecords2     = returnedObject.geometries.geometryRecords.skipped;
                                    var skippedRecordsTotal = skippedRecords.Concat(skippedRecords2).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
                                    var deletedGeometries   = returnedObject.geometries.deleted;
                                    var skippedGeometries   = returnedObject.geometries.skipped;

                                    if (error == null || error == String.Empty)
                                    {
                                        error = "Data successfully downloaded";
                                    }

                                    foreach (var deletedRecord in deletedRecordsTotal)
                                    {
                                        //Delete records from device which have been confirmed by the connector as 'deleted' in the central db
                                        var uid        = deletedRecord.Key.ToString();
                                        var queriedRec = conn.Table <Record>().Where(r => r.recordId == uid).FirstOrDefault();
                                        conn.Delete(queriedRec, true);
                                    }
                                    foreach (var deletedGeometry in deletedGeometries)
                                    {
                                        //Delete geometries from device which have been confirmed by the connector as 'deleted' in the central db
                                        var uid         = deletedGeometry.Key.ToString();
                                        var queriedGeom = conn.Table <ReferenceGeometry>().Where(g => g.geometryId == uid).FirstOrDefault();
                                        conn.Delete(queriedGeom, true);
                                    }

                                    foreach (var skippedGeom in skippedGeometries)
                                    {
                                        if (!skippedGeom.Value.Contains("Changes were made to the associated records"))
                                        {
                                            error = error + System.Environment.NewLine;
                                            error = error + skippedGeom.Key.ToString() + ", " + skippedGeom.Value;
                                        }
                                    }

                                    foreach (var skippedRec in skippedRecordsTotal)
                                    {
                                        error = error + System.Environment.NewLine;
                                        error = error + skippedRec.Key.ToString() + ", " + skippedRec.Value;
                                    }


                                    ShowSyncCompleteMessage(error); //Show any errors in the sync confirmation message
                                }
                            }
                        }
                        MessagingCenter.Send(new Project(), "DataDownloadError", "Data successfully synchronised");
                        App.SetProject(projectId);
                        MessagingCenter.Send <Application, string>(Application.Current, "SyncMessage", "");
                    }
                    catch (Exception e)
                    {
                        // Re Log in
                        Console.WriteLine(e);
                        MessagingCenter.Send(new Project(), "DataDownloadError", @"Error synchronising data");
                        App.Current.MainPage = Login.GetPageToView();
                    }
                }
                else
                {
                    MessagingCenter.Send(new Project(), "DataDownloadError", @"Login failed");
                }
            };

            auth.Error += (sender, eventArgs) =>
            {
                //Careful! This triggers on the iPhone even when login is successful
            };

            await auth.RequestRefreshTokenAsync(Preferences.Get("RefreshToken", ""));
        }