/// <summary> /// Initializes a new instance of the ShapefileHeader class with values read in from the stream. /// </summary> /// <remarks>Reads the header information from the stream.</remarks> /// <param name="shpBinaryReader">BigEndianBinaryReader stream to the shapefile.</param> public ShapefileHeader(BigEndianBinaryReader shpBinaryReader) { if (shpBinaryReader == null) throw new ArgumentNullException("shpBinaryReader"); _fileCode = shpBinaryReader.ReadInt32BE(); if (_fileCode != Shapefile.ShapefileId) throw new ShapefileException("The first four bytes of this file indicate this is not a shape file."); // skip 5 unsed bytes shpBinaryReader.ReadInt32BE(); shpBinaryReader.ReadInt32BE(); shpBinaryReader.ReadInt32BE(); shpBinaryReader.ReadInt32BE(); shpBinaryReader.ReadInt32BE(); _fileLength = shpBinaryReader.ReadInt32BE(); _version = shpBinaryReader.ReadInt32(); Debug.Assert(_version == 1000, "Shapefile version", String.Format("Expecting only one version (1000), but got {0}",_version)); int shapeType = shpBinaryReader.ReadInt32(); _shapeType = (ShapeGeometryType) Enum.Parse(typeof(ShapeGeometryType), shapeType.ToString()); //read in and store the bounding box double[] coords = new double[4]; for (int i = 0; i < 4; i++) coords[i] = shpBinaryReader.ReadDouble(); _bounds = new Envelope(coords[0], coords[2], coords[1], coords[3]); // skip z and m bounding boxes. for (int i = 0; i < 4; i++) shpBinaryReader.ReadDouble(); }
/// <summary> /// Reads a stream and converts the shapefile record to an equilivent geometry object. /// </summary> /// <param name="file">The stream to read.</param> /// <param name="geometryFactory">The geometry factory to use when making the object.</param> /// <returns>The Geometry object that represents the shape file record.</returns> public override IGeometry Read(BigEndianBinaryReader file, IGeometryFactory geometryFactory) { int shapeTypeNum = file.ReadInt32(); ShapeGeometryTypes shapeType = (ShapeGeometryTypes)Enum.Parse(typeof(ShapeGeometryTypes), shapeTypeNum.ToString()); if (!(shapeType == ShapeGeometryTypes.LineString || shapeType == ShapeGeometryTypes.LineStringM || shapeType == ShapeGeometryTypes.LineStringZ || shapeType == ShapeGeometryTypes.LineStringZM)) { throw new ShapefileException("Attempting to load a non-arc as arc."); } //read and for now ignore bounds. double[] box = new double[4]; for (int i = 0; i < 4; i++) { double d = file.ReadDouble(); box[i] = d; } int numParts = file.ReadInt32(); int numPoints = file.ReadInt32(); int[] partOffsets = new int[numParts]; for (int i = 0; i < numParts; i++) { partOffsets[i] = file.ReadInt32(); } ILineString[] lines = new ILineString[numParts]; int start, finish, length; for (int part = 0; part < numParts; part++) { start = partOffsets[part]; if (part == numParts - 1) { finish = numPoints; } else { finish = partOffsets[part + 1]; } length = finish - start; CoordinateList points = new CoordinateList(); points.Capacity = length; ICoordinate external; for (int i = 0; i < length; i++) { external = new Coordinate(file.ReadDouble(), file.ReadDouble()); geometryFactory.PrecisionModel.MakePrecise(external); points.Add(external); } lines[part] = geometryFactory.CreateLineString(points.ToArray()); } return(geometryFactory.CreateMultiLineString(lines)); }
/// <summary> /// Reads a stream and converts the shapefile record to an equilivent geometry object. /// </summary> /// <param name="file">The stream to read.</param> /// <param name="geometryFactory">The geometry factory to use when making the object.</param> /// <returns>The Geometry object that represents the shape file record.</returns> public override IGeometry Read(BigEndianBinaryReader file, IGeometryFactory geometryFactory) { int shapeTypeNum = file.ReadInt32(); ShapeGeometryTypes shapeType = (ShapeGeometryTypes)Enum.Parse(typeof(ShapeGeometryTypes), shapeTypeNum.ToString()); if( ! ( shapeType == ShapeGeometryTypes.LineString || shapeType == ShapeGeometryTypes.LineStringM || shapeType == ShapeGeometryTypes.LineStringZ || shapeType == ShapeGeometryTypes.LineStringZM )) throw new ShapefileException("Attempting to load a non-arc as arc."); //read and for now ignore bounds. double[] box = new double[4]; for (int i = 0; i < 4; i++) { double d= file.ReadDouble(); box[i] =d; } int numParts = file.ReadInt32(); int numPoints = file.ReadInt32(); int[] partOffsets = new int[numParts]; for (int i = 0; i < numParts; i++) partOffsets[i] = file.ReadInt32(); ILineString[] lines = new ILineString[numParts]; int start, finish, length; for (int part = 0; part < numParts; part++) { start = partOffsets[part]; if (part == numParts - 1) finish = numPoints; else finish = partOffsets[part + 1]; length = finish - start; CoordinateList points = new CoordinateList(); points.Capacity=length; ICoordinate external; for (int i = 0; i < length; i++) { external = new Coordinate(file.ReadDouble(),file.ReadDouble()); geometryFactory.PrecisionModel.MakePrecise( external); points.Add(external); } lines[part] = geometryFactory.CreateLineString(points.ToArray()); } return geometryFactory.CreateMultiLineString(lines); }
/// <summary> /// Initializes a new instance of the ShapefileHeader class with values read in from the stream. /// </summary> /// <remarks>Reads the header information from the stream.</remarks> /// <param name="shpBinaryReader">BigEndianBinaryReader stream to the shapefile.</param> public ShapefileHeader(BigEndianBinaryReader shpBinaryReader) { if (shpBinaryReader == null) { throw new ArgumentNullException("shpBinaryReader"); } _fileCode = shpBinaryReader.ReadInt32BE(); if (_fileCode != Shapefile.ShapefileId) { throw new ShapefileException("The first four bytes of this file indicate this is not a shape file."); } // skip 5 unsed bytes shpBinaryReader.ReadInt32BE(); shpBinaryReader.ReadInt32BE(); shpBinaryReader.ReadInt32BE(); shpBinaryReader.ReadInt32BE(); shpBinaryReader.ReadInt32BE(); _fileLength = shpBinaryReader.ReadInt32BE(); _version = shpBinaryReader.ReadInt32(); Debug.Assert(_version == 1000, "Shapefile version", String.Format("Expecting only one version (1000), but got {0}", _version)); int shapeType = shpBinaryReader.ReadInt32(); _shapeType = (ShapeGeometryTypes)Enum.Parse(typeof(ShapeGeometryTypes), shapeType.ToString()); //read in and store the bounding box double[] coords = new double[4]; for (int i = 0; i < 4; i++) { coords[i] = shpBinaryReader.ReadDouble(); } _bounds = new Envelope(coords[0], coords[2], coords[1], coords[3]); // skip z and m bounding boxes. for (int i = 0; i < 4; i++) { shpBinaryReader.ReadDouble(); } }
/// <summary> /// Reads a stream and converts the shapefile record to an equilivant geometry object. /// </summary> /// <param name="file">The stream to read.</param> /// <param name="geometryFactory">The geometry factory to use when making the object.</param> /// <returns>The Geometry object that represents the shape file record.</returns> public override IGeometry Read(BigEndianBinaryReader file, IGeometryFactory geometryFactory) { int shapeTypeNum = file.ReadInt32(); ShapeGeometryTypes shapeType = (ShapeGeometryTypes) Enum.Parse(typeof(ShapeGeometryTypes), shapeTypeNum.ToString()); if ( ! ( shapeType == ShapeGeometryTypes.MultiPoint || shapeType == ShapeGeometryTypes.MultiPointM || shapeType == ShapeGeometryTypes.MultiPointZ || shapeType == ShapeGeometryTypes.MultiPointZM)) throw new ShapefileException("Attempting to load a non-multipoint as multipoint."); // Read and for now ignore bounds. double[] box = new double[4]; for (int i = 0; i < 4; i++) box[i] = file.ReadDouble(); // Read points int numPoints = file.ReadInt32(); IPoint[] points = new IPoint[numPoints]; for (int i = 0; i < numPoints; i++) points[i] = geometryFactory.CreatePoint(new Coordinate(file.ReadDouble(), file.ReadDouble())); return geometryFactory.CreateMultiPoint(points); }
/// <summary> /// Reads a stream and converts the shapefile record to an equilivent geometry object. /// </summary> /// <param name="file">The stream to read.</param> /// <param name="geometryFactory">The geometry factory to use when making the object.</param> /// <returns>The Geometry object that represents the shape file record.</returns> public override IGeometry Read(BigEndianBinaryReader file, IGeometryFactory geometryFactory) { int shapeTypeNum = file.ReadInt32(); ShapeGeometryTypes shapeType = (ShapeGeometryTypes) Enum.Parse(typeof(ShapeGeometryTypes), shapeTypeNum.ToString()); if ( ! ( shapeType == ShapeGeometryTypes.Point || shapeType == ShapeGeometryTypes.PointM || shapeType == ShapeGeometryTypes.PointZ || shapeType == ShapeGeometryTypes.PointZM )) throw new ShapefileException("Attempting to load a point as point."); double x= file.ReadDouble(); double y= file.ReadDouble(); ICoordinate external = new Coordinate(x,y); geometryFactory.PrecisionModel.MakePrecise( external); return geometryFactory.CreatePoint(external); }
/// <summary> /// Reads a stream and converts the shapefile record to an equilivent geometry object. /// </summary> /// <param name="file">The stream to read.</param> /// <param name="geometryFactory">The geometry factory to use when making the object.</param> /// <returns>The Geometry object that represents the shape file record.</returns> public override IGeometry Read(BigEndianBinaryReader file, IGeometryFactory geometryFactory) { int shapeTypeNum = file.ReadInt32(); ShapeGeometryTypes shapeType = (ShapeGeometryTypes)Enum.Parse(typeof(ShapeGeometryTypes), shapeTypeNum.ToString()); if (!(shapeType == ShapeGeometryTypes.Point || shapeType == ShapeGeometryTypes.PointM || shapeType == ShapeGeometryTypes.PointZ || shapeType == ShapeGeometryTypes.PointZM)) { throw new ShapefileException("Attempting to load a point as point."); } double x = file.ReadDouble(); double y = file.ReadDouble(); ICoordinate external = new Coordinate(x, y); geometryFactory.PrecisionModel.MakePrecise(external); return(geometryFactory.CreatePoint(external)); }
/// <summary> /// /// </summary> /// <param name="beReader"></param> private void ReadFeatureHeader(BigEndianBinaryReader beReader) { int recordNumber = beReader.ReadInt32BE(); int contentLength = beReader.ReadInt32BE(); int shapeType = beReader.ReadInt32(); }
public static ItemConfig[] ParseItemConfig(byte[] data, byte[] index) { BigEndianBinaryReader dataReader = new BigEndianBinaryReader(new MemoryStream(data)); BigEndianBinaryReader indexReader = new BigEndianBinaryReader(new MemoryStream(index)); int totalItems = indexReader.ReadUInt16(); int[] streamIndices = new int[totalItems]; ItemConfig[] itemConfig = new ItemConfig[totalItems]; int i = 2; for (int j = 0; j < totalItems; j++) { streamIndices[j] = i; i += indexReader.ReadUInt16(); } for (int x = 0; x < totalItems; x++) { dataReader.BaseStream.Position = streamIndices[x]; ItemConfig item = new ItemConfig(); do { int opCode = dataReader.ReadByte(); if (opCode == 0) break; if (opCode == 1) item.modelID = dataReader.ReadUInt16(); else if (opCode == 2) item.name = dataReader.ReadString().TrimEnd('\n'); else if (opCode == 3) item.description = dataReader.ReadString().TrimEnd('\n'); else if (opCode == 4) item.modelInvZoom = dataReader.ReadUInt16(); else if (opCode == 5) item.modelInvRotationY = dataReader.ReadUInt16(); else if (opCode == 6) item.modelInvRotationX = dataReader.ReadUInt16(); else if (opCode == 7) { item.modelInvPosOffsetX = dataReader.ReadUInt16(); if (item.modelInvPosOffsetX > 32767) item.modelInvPosOffsetX -= 0x10000; } else if (opCode == 8) { item.modelInvPosOffsetY = dataReader.ReadUInt16(); if (item.modelInvPosOffsetY > 32767) item.modelInvPosOffsetY -= 0x10000; } else if (opCode == 10) dataReader.ReadUInt16(); else if (opCode == 11) item.stackable = true; else if (opCode == 12) item.value = dataReader.ReadInt32(); else if (opCode == 16) item.membersObject = true; else if (opCode == 23) { item.maleWornModelID = dataReader.ReadUInt16(); item.maleYOffset = dataReader.ReadByte(); } else if (opCode == 24) item.maleArmsID = dataReader.ReadUInt16(); else if (opCode == 25) { item.femaleWornModelID = dataReader.ReadUInt16(); item.femaleYOffset = dataReader.ReadByte(); } else if (opCode == 26) item.femaleArmsID = dataReader.ReadUInt16(); else if (opCode >= 30 && opCode < 35) { if (item.groundActions == null) item.groundActions = new string[5]; item.groundActions[opCode - 30] = dataReader.ReadString().TrimEnd('\n'); if (item.groundActions[opCode - 30].ToLower() == "hidden") item.groundActions[opCode - 30] = null; } else if (opCode >= 35 && opCode < 40) { if (item.actions == null) item.actions = new string[5]; item.actions[opCode - 35] = dataReader.ReadString().TrimEnd('\n'); } else if (opCode == 40) { int colors = dataReader.ReadByte(); item.originalModelColors = new int[colors]; item.modifiedModelColors = new int[colors]; for (int colorPtr = 0; colorPtr < colors; colorPtr++) { item.originalModelColors[colorPtr] = dataReader.ReadUInt16(); item.modifiedModelColors[colorPtr] = dataReader.ReadUInt16(); } } else if (opCode == 78) item.maleEmblem = dataReader.ReadUInt16(); else if (opCode == 79) item.femaleEmblem = dataReader.ReadUInt16(); else if (opCode == 90) item.maleDialog = dataReader.ReadUInt16(); else if (opCode == 91) item.femaleDialog = dataReader.ReadUInt16(); else if (opCode == 92) item.maleDialogHat = dataReader.ReadUInt16(); else if (opCode == 93) item.femaleDialogHat = dataReader.ReadUInt16(); else if (opCode == 95) item.diagonalRotation = dataReader.ReadUInt16(); else if (opCode == 97) item.certID = dataReader.ReadUInt16(); else if (opCode == 98) item.certTemplateID = dataReader.ReadUInt16(); else if (opCode >= 100 && opCode < 110) { if (item.stackIDs == null) { item.stackIDs = new int[10]; item.stackAmounts = new int[10]; } item.stackIDs[opCode - 100] = dataReader.ReadUInt16(); item.stackAmounts[opCode - 100] = dataReader.ReadUInt16(); } else if (opCode == 110) item.modelSizeX = dataReader.ReadUInt16(); else if (opCode == 111) item.modelSizeY = dataReader.ReadUInt16(); else if (opCode == 112) item.modelSizeZ = dataReader.ReadUInt16(); else if (opCode == 113) item.lightModifier = dataReader.ReadUInt16(); else if (opCode == 114) item.shadowModifier = dataReader.ReadByte() * 5; else if (opCode == 115) item.team = dataReader.ReadByte(); else if (opCode == 116) item.lendID = dataReader.ReadUInt16(); else if (opCode == 117) item.lentItemID = dataReader.ReadUInt16(); else Logger.Log("Unknown Item Opcode: " + opCode, LogType.Error); } while (true); itemConfig[x] = item; } return itemConfig; }
public static string[] ParseTldList(byte[] tldenc) { BigEndianBinaryReader br = new BigEndianBinaryReader(new MemoryStream(tldenc)); int length = br.ReadInt32(); List<char[]> tldList = new List<char[]>(); int[] tldArray = new int[length]; for(int id = 0; id < length; id++) { tldArray[id] = br.ReadByte(); char[] tld = new char[br.ReadByte()]; for (int charID = 0; charID < tld.Length; charID++) tld[charID] = (char)br.ReadByte(); tldList.Add(tld); } string[] s = new string[tldList.Count]; for (int c = 0; c < s.Length; c++) s[c] = new string(tldList[c]); return s; }
public static int[] ParseFragmentsEnc(byte[] fragenc) { BigEndianBinaryReader br = new BigEndianBinaryReader(new MemoryStream(fragenc)); int length = br.ReadInt32(); int[] fragmentsEnc = new int[length]; for (int i = 0; i < length; i++) fragmentsEnc[i] = br.ReadInt16(); return fragmentsEnc; }
public static string[] ParseDomainEnc(byte[] domainenc) { BigEndianBinaryReader br = new BigEndianBinaryReader(new MemoryStream(domainenc)); int length = br.ReadInt32(); List<char[]> domains = new List<char[]>(); for (int j = 0; j < length; j++) { char[] val = new char[br.ReadByte()]; for (int k = 0; k < val.GetLength(0); k++) val[k] = (char)br.ReadChar(); domains.Add(val); } string[] s = new string[domains.Count]; for (int c = 0; c < s.Length; c++) s[c] = new string(domains[c]); return s; }
public static string[] ParseBadEnc(byte[] badenc) { BigEndianBinaryReader br = new BigEndianBinaryReader(new MemoryStream(badenc)); int length = br.ReadInt32(); List<char[]> bads = new List<char[]>(); for (int i = 0; i < length; i++) { char[] val = new char[br.ReadChar()]; for (int charid = 0; charid < val.Length; charid++) val[charid] = (char)br.ReadChar(); bads.Add(val); byte[,] b1 = new byte[br.ReadByte(), 2]; for (int l = 0; l < b1.Length/2; l++) { b1[l, 0] = (byte)br.ReadByte(); b1[l, 1] = (byte)br.ReadByte(); } } string[] s = new string[bads.Count]; for(int c=0;c<s.Length;c++) s[c] = new string(bads[c]); return s; }
/// <summary> /// /// </summary> /// <param name="beReader"></param> private void ReadFeatureHeader(BigEndianBinaryReader beReader) { int recordNumber = beReader.ReadInt32BE(); int contentLength = beReader.ReadInt32BE(); int shapeType = beReader.ReadInt32(); }
/// <summary> /// Reads a stream and converts the shapefile record to an equilivent geometry object. /// </summary> /// <param name="file">The stream to read.</param> /// <param name="geometryFactory">The geometry factory to use when making the object.</param> /// <returns>The Geometry object that represents the shape file record.</returns> public override IGeometry Read(BigEndianBinaryReader file, IGeometryFactory geometryFactory) { int shapeTypeNum = file.ReadInt32(); ShapeGeometryTypes shapeType = (ShapeGeometryTypes)Enum.Parse(typeof(ShapeGeometryTypes), shapeTypeNum.ToString()); if (!(shapeType == ShapeGeometryTypes.Polygon || shapeType == ShapeGeometryTypes.PolygonM || shapeType == ShapeGeometryTypes.PolygonZ || shapeType == ShapeGeometryTypes.PolygonZM)) { throw new ShapefileException("Attempting to load a non-polygon as polygon."); } // Read and for now ignore bounds. double[] box = new double[4]; for (int i = 0; i < 4; i++) { box[i] = file.ReadDouble(); } int[] partOffsets; int numParts = file.ReadInt32(); int numPoints = file.ReadInt32(); partOffsets = new int[numParts]; for (int i = 0; i < numParts; i++) { partOffsets[i] = file.ReadInt32(); } ArrayList shells = new ArrayList(); ArrayList holes = new ArrayList(); int start, finish, length; for (int part = 0; part < numParts; part++) { start = partOffsets[part]; if (part == numParts - 1) { finish = numPoints; } else { finish = partOffsets[part + 1]; } length = finish - start; CoordinateList points = new CoordinateList(); points.Capacity = length; for (int i = 0; i < length; i++) { ICoordinate external = new Coordinate(file.ReadDouble(), file.ReadDouble()); geometryFactory.PrecisionModel.MakePrecise(external); ICoordinate internalCoord = external; // Thanks to Abhay Menon! if (!Double.IsNaN(internalCoord.Y) && !Double.IsNaN(internalCoord.X)) { points.Add(internalCoord, false); } } if (points.Count > 2) // Thanks to Abhay Menon! { try { if (points[0].Distance(points[points.Count - 1]) > .00001) { points.Add(new Coordinate(points[0])); } else if (points[0].Distance(points[points.Count - 1]) > 0.0) { points[points.Count - 1].CoordinateValue = points[0]; } ILinearRing ring = geometryFactory.CreateLinearRing(points.ToArray()); // If shape have only a part, jump orientation check and add to shells if (numParts == 1) { shells.Add(ring); } else { // Orientation check if (CGAlgorithms.IsCCW(points.ToArray())) { holes.Add(ring); } else { shells.Add(ring); } } } catch (Exception ex) { Debug.WriteLine(ex.Message); } } } // Now we have a list of all shells and all holes ArrayList holesForShells = new ArrayList(shells.Count); for (int i = 0; i < shells.Count; i++) { holesForShells.Add(new ArrayList()); } // Find holes for (int i = 0; i < holes.Count; i++) { ILinearRing testRing = (ILinearRing)holes[i]; ILinearRing minShell = null; IEnvelope minEnv = null; IEnvelope testEnv = testRing.EnvelopeInternal; ICoordinate testPt = testRing.GetCoordinateN(0); ILinearRing tryRing; for (int j = 0; j < shells.Count; j++) { tryRing = (ILinearRing)shells[j]; IEnvelope tryEnv = tryRing.EnvelopeInternal; if (minShell != null) { minEnv = minShell.EnvelopeInternal; } bool isContained = false; CoordinateList coordList = new CoordinateList(tryRing.Coordinates); if (tryEnv.Contains(testEnv) && (CGAlgorithms.IsPointInRing(testPt, coordList.ToArray()) || (PointInList(testPt, coordList)))) { isContained = true; } // Check if this new containing ring is smaller than the current minimum ring if (isContained) { if (minShell == null || minEnv.Contains(tryEnv)) { minShell = tryRing; } // Suggested by Brian Macomber and added 3/28/2006: // holes were being found but never added to the holesForShells array // so when converted to geometry by the factory, the inner rings were never created. ArrayList holesForThisShell = (ArrayList)holesForShells[j]; holesForThisShell.Add(testRing); } } } IPolygon[] polygons = new IPolygon[shells.Count]; for (int i = 0; i < shells.Count; i++) { polygons[i] = (geometryFactory.CreatePolygon((ILinearRing)shells[i], (ILinearRing[])((ArrayList)holesForShells[i]).ToArray(typeof(ILinearRing)))); } if (polygons.Length == 1) { return(polygons[0]); } // It's a multi part return(geometryFactory.CreateMultiPolygon(polygons)); }
/// <summary> /// Reads a stream and converts the shapefile record to an equilivent geometry object. /// </summary> /// <param name="file">The stream to read.</param> /// <param name="geometryFactory">The geometry factory to use when making the object.</param> /// <returns>The Geometry object that represents the shape file record.</returns> public override IGeometry Read(BigEndianBinaryReader file, IGeometryFactory geometryFactory) { int shapeTypeNum = file.ReadInt32(); ShapeGeometryTypes shapeType = (ShapeGeometryTypes)Enum.Parse(typeof(ShapeGeometryTypes), shapeTypeNum.ToString()); if ( ! ( shapeType == ShapeGeometryTypes.Polygon || shapeType == ShapeGeometryTypes.PolygonM || shapeType == ShapeGeometryTypes.PolygonZ || shapeType == ShapeGeometryTypes.PolygonZM)) throw new ShapefileException("Attempting to load a non-polygon as polygon."); // Read and for now ignore bounds. double[] box = new double[4]; for (int i = 0; i < 4; i++) box[i] = file.ReadDouble(); int[] partOffsets; int numParts = file.ReadInt32(); int numPoints = file.ReadInt32(); partOffsets = new int[numParts]; for (int i = 0; i < numParts; i++) partOffsets[i] = file.ReadInt32(); ArrayList shells = new ArrayList(); ArrayList holes = new ArrayList(); int start, finish, length; for (int part = 0; part < numParts; part++) { start = partOffsets[part]; if (part == numParts - 1) finish = numPoints; else finish = partOffsets[part + 1]; length = finish - start; CoordinateList points = new CoordinateList(); points.Capacity = length; for (int i = 0; i < length; i++) { ICoordinate external = new Coordinate(file.ReadDouble(), file.ReadDouble() ); geometryFactory.PrecisionModel.MakePrecise( external); ICoordinate internalCoord = external; // Thanks to Abhay Menon! if (!Double.IsNaN(internalCoord.Y) && !Double.IsNaN(internalCoord.X)) points.Add(internalCoord, false); } if (points.Count > 2) // Thanks to Abhay Menon! { try { if (points[0].Distance(points[points.Count - 1]) > .00001) points.Add(new Coordinate(points[0])); else if (points[0].Distance(points[points.Count - 1]) > 0.0) points[points.Count - 1].CoordinateValue = points[0]; ILinearRing ring = geometryFactory.CreateLinearRing(points.ToArray()); // If shape have only a part, jump orientation check and add to shells if (numParts == 1) shells.Add(ring); else { // Orientation check if (CGAlgorithms.IsCCW(points.ToArray())) holes.Add(ring); else shells.Add(ring); } } catch (Exception ex) { Debug.WriteLine(ex.Message); } } } // Now we have a list of all shells and all holes ArrayList holesForShells = new ArrayList(shells.Count); for (int i = 0; i < shells.Count; i++) holesForShells.Add(new ArrayList()); // Find holes for (int i = 0; i < holes.Count; i++) { ILinearRing testRing = (ILinearRing) holes[i]; ILinearRing minShell = null; IEnvelope minEnv = null; IEnvelope testEnv = testRing.EnvelopeInternal; ICoordinate testPt = testRing.GetCoordinateN(0); ILinearRing tryRing; for (int j = 0; j < shells.Count; j++) { tryRing = (ILinearRing) shells[j]; IEnvelope tryEnv = tryRing.EnvelopeInternal; if (minShell != null) minEnv = minShell.EnvelopeInternal; bool isContained = false; CoordinateList coordList = new CoordinateList(tryRing.Coordinates); if (tryEnv.Contains(testEnv) && (CGAlgorithms.IsPointInRing(testPt, coordList.ToArray()) || (PointInList(testPt, coordList)))) isContained = true; // Check if this new containing ring is smaller than the current minimum ring if (isContained) { if (minShell == null || minEnv.Contains(tryEnv)) minShell = tryRing; // Suggested by Brian Macomber and added 3/28/2006: // holes were being found but never added to the holesForShells array // so when converted to geometry by the factory, the inner rings were never created. ArrayList holesForThisShell = (ArrayList) holesForShells[j]; holesForThisShell.Add(testRing); } } } IPolygon[] polygons = new IPolygon[shells.Count]; for (int i = 0; i < shells.Count; i++) polygons[i] = (geometryFactory.CreatePolygon((ILinearRing) shells[i], (ILinearRing[]) ((ArrayList)holesForShells[i]).ToArray(typeof(ILinearRing)))); if (polygons.Length == 1) return polygons[0]; // It's a multi part return geometryFactory.CreateMultiPolygon(polygons); }