/// <summary> /// Read one double from compressed geometry string by using passed position. /// Re-writes startPos for the next integer. /// </summary> /// <param name="geometryString">String with compact geometry.</param> /// <param name="startPos">Start position from reading should be begin.</param> /// <param name="result)">Double, extracted from the string.</param> /// <returns>Extracted double or null if there is nothing to extract.</returns> public static bool ReadDouble(string geometry, ref int startPos, ref double result) { var temp = CompactGeometryStringWorker.ReadInt(geometry, ref startPos); if (temp == null) { return(false); } result = (double)temp; return(true); }
/// <summary> /// Converts the specified collection of points into compact geometry. /// </summary> /// <param name="points">Collection of points to be converted to a compact geometry.</param> /// <returns>A string containing specified points in a compact geometry format.</returns> public static string Convert(IEnumerable <Point> points) { // Compute XY multiplier. var maxValue = points.Max(point => Math.Max(Math.Abs(point.X), Math.Abs(point.Y))); var multByXY = maxValue == 0.0 ? 1 : (int)(Int32.MaxValue / maxValue); var result = new StringBuilder(); // Append info about geometry format. CompactGeometryStringWorker.AppendValue(POST_93_FORMAT, result); CompactGeometryStringWorker.AppendValue(CURRENT_VERSION, result); CompactGeometryStringWorker.AppendValue(FLAG_HAS_M, result); // Append XY multiplier. CompactGeometryStringWorker.AppendValue(multByXY, result); var lastX = default(int); var lastY = default(int); var lastM = default(int); foreach (var point in points) { lastX = CompactGeometryStringWorker.AppendValue(point.X, lastX, multByXY, result); lastY = CompactGeometryStringWorker.AppendValue(point.Y, lastY, multByXY, result); } // Write separtor to string. result.Append(CompactGeometryStringWorker.AdditionalPartsSeparator); // Calculate M multiplier. var multByM = (int)(1 / M_PRESICION); // Write M multiplier. CompactGeometryStringWorker.AppendValue(multByM, result); foreach (var point in points) { lastM = CompactGeometryStringWorker.AppendValue(point.M, lastM, multByM, result); } return(result.ToString()); }
/////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Converts compact geometry string to array of points. /// </summary> /// <param name="geometry">Compact geometry string.</param> /// <param name="points">Output parameter that contains array of points if conversion succeeded.</param> /// <returns>Returns <c>true</c> if conversion succeeded or <c>false</c> otherwise.</returns> public static bool Convert(string geometry, out Point[] points) { Debug.Assert(geometry != null); points = null; List <Point> ptList = new List <Point>(); int? flags = 0; int indexXY = 0; double multBy_XY = 0; var firstElement = CompactGeometryStringWorker.ReadInt(geometry, ref indexXY); // If we couldn't read first element - return false. if (firstElement == null) { return(false); } // Check that string is in post 9.3 format. if (firstElement == POST_93_FORMAT) { // Read version and check that it is current. var version = CompactGeometryStringWorker.ReadInt(geometry, ref indexXY); if (version != CURRENT_VERSION) { return(false); } // Flags showing what additional info string contains. flags = CompactGeometryStringWorker.ReadInt(geometry, ref indexXY); // Read XY multiplier. var succeeded = CompactGeometryStringWorker.ReadDouble(geometry, ref indexXY, ref multBy_XY); if (!succeeded) { return(false); } } // If it isnt - first element is XY multiplier. else { multBy_XY = (double)firstElement; } int nLength; int index_M = 0; int index_Z = 0; double multBy_M = 0; // If geometry has no additional info. if (flags == 0) { nLength = geometry.Length; } // If it has - read info about Z and M coordinates. else { nLength = geometry.IndexOf(CompactGeometryStringWorker.AdditionalPartsSeparator); // Check that compressed geometry has Z coordinate. if ((flags & FLAG_HAS_Z) == FLAG_HAS_Z) { index_Z = nLength + 1; CompactGeometryStringWorker.ReadInt(geometry, ref index_Z); } // Check that it has M coordinate. if ((flags & FLAG_HAS_M) == FLAG_HAS_M) { index_M = geometry.IndexOf( CompactGeometryStringWorker.AdditionalPartsSeparator, index_Z) + 1; // Read M multiplier. var succeded = CompactGeometryStringWorker.ReadDouble(geometry, ref index_M, ref multBy_M); if (!succeded) { return(false); } } } // Create readers for coordinates. var xReader = new CoordinateReader(geometry, multBy_XY); var yReader = new CoordinateReader(geometry, multBy_XY); var mReader = new CoordinateReader(geometry, multBy_M); while (indexXY != nLength) { // Read X and Y coordinates. double xCoordinate = 0; double yCoordinate = 0; if (!xReader.ReadNextCoordinate(ref indexXY, ref xCoordinate) || !yReader.ReadNextCoordinate(ref indexXY, ref yCoordinate)) { return(false); } // If it has M coordinate. if ((flags & FLAG_HAS_M) == FLAG_HAS_M) { // Read M coordinate. double mCoordinate = 0; if (!mReader.ReadNextCoordinate(ref index_M, ref mCoordinate)) { return(false); } // Add point with M coordinate. ptList.Add(new Point(xCoordinate, yCoordinate, mCoordinate)); } // If point has no M coordinate - add default point. else { ptList.Add(new Point(xCoordinate, yCoordinate)); } } points = ptList.ToArray(); return(true); }