예제 #1
0
		/// <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();	
		}
예제 #2
0
        /// <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));
        }
예제 #3
0
		/// <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);
		}
예제 #4
0
        /// <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();
            }
        }
예제 #5
0
		/// <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);
        }
예제 #6
0
		/// <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);
		}
예제 #7
0
        /// <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));
        }
예제 #8
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="beReader"></param>
 private void ReadFeatureHeader(BigEndianBinaryReader beReader)
 {
     int recordNumber = beReader.ReadInt32BE();
     int contentLength = beReader.ReadInt32BE();
     int shapeType = beReader.ReadInt32();
 }        
예제 #9
0
 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;
 }
예제 #10
0
 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;
 }
예제 #11
0
 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;
 }
예제 #12
0
 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;
 }
예제 #13
0
 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;
 }
예제 #14
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="beReader"></param>
 private void ReadFeatureHeader(BigEndianBinaryReader beReader)
 {
     int recordNumber  = beReader.ReadInt32BE();
     int contentLength = beReader.ReadInt32BE();
     int shapeType     = beReader.ReadInt32();
 }
예제 #15
0
        /// <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));
        }
예제 #16
0
		/// <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);
		}