/// <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); }
/// <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); }
/// <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); } }
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); }
/// <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", "")); }
/// <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", "")); }