Example #1
0
        private void loadShapeFile(string shapeFilePath)
        {
            FileInfo shapeFile = new FileInfo(shapeFilePath);
            FileInfo dbaseFile = new FileInfo(shapeFile.FullName.Replace(".shp", ".dbf"));

            Random random = new Random(shapeFile.Name.GetHashCode());

            ArrayList metaValues = new ArrayList();

            if (m_ShapeTileArgs.DataKey != null
                && dbaseFile.Exists) {
                using (BinaryReader dbfReader = new BinaryReader(new BufferedStream(dbaseFile.OpenRead()), Encoding.ASCII)) {
                    // First Read 32-byte file header
                    int bytesRead = 0;
                    byte dbfVersion = dbfReader.ReadByte();

                    byte updateYear = dbfReader.ReadByte();
                    byte updateMonth = dbfReader.ReadByte();
                    byte updateDay = dbfReader.ReadByte();

                    int numberRecords = dbfReader.ReadInt32();
                    short headerLength = dbfReader.ReadInt16();

                    short recordLength = dbfReader.ReadInt16();
                    byte[] reserved = dbfReader.ReadBytes(20);

                    bytesRead += 32;
                    int numberFields = (headerLength - 33)/32;

                    // Read Field Descriptor Array
                    DBF_Field_Header[] fieldHeaders = new DBF_Field_Header[numberFields];

                    for (int i = 0; i < numberFields; i++) {
                        char[] fieldNameChars = dbfReader.ReadChars(10);
                        char fieldNameTerminator = dbfReader.ReadChar();
                        string fn = new string(fieldNameChars);
                        fieldHeaders[i].FieldName = fn.Trim().Replace(" ", "");

                        fieldHeaders[i].FieldType = dbfReader.ReadChar();
                        byte[] reserved1 = dbfReader.ReadBytes(4);

                        if (String.Compare(fieldHeaders[i].FieldName.Trim(), m_ShapeTileArgs.DataKey, true) == 0) {
                            m_ShapeTileArgs.DataKey = fieldHeaders[i].FieldName;

                            if (fieldHeaders[i].FieldType == 'N') {
                                m_ShapeTileArgs.UseScalar = true;
                            }
                            else {
                                m_ShapeTileArgs.UseScalar = false;
                            }
                        }

                        fieldHeaders[i].FieldLength = dbfReader.ReadByte();

                        byte[] reserved2 = dbfReader.ReadBytes(15);
                        bytesRead += 32;
                    }
                    byte headerTerminator = dbfReader.ReadByte();

                    double scalarMin = double.MaxValue;
                    double scalarMax = double.MinValue;
                    for (int i = 0; i < numberRecords; i++) {
                        //	Shapefile_Polygon curPoly = (Shapefile_Polygon)this.m_ShapeTileArgs.ShapeRecords[i];

                        byte isValid = dbfReader.ReadByte();
                        for (int j = 0; j < fieldHeaders.Length; j++) {
                            char[] fieldDataChars = dbfReader.ReadChars(fieldHeaders[j].FieldLength);
                            string fieldData = new string(fieldDataChars);

                            if (fieldHeaders[j].FieldName
                                == m_ShapeTileArgs.DataKey) {
                                metaValues.Add(fieldData);

                                if (fieldHeaders[j].FieldType == 'N') {
                                    try {
                                        if (m_ShapeTileArgs.ScaleMin == double.NaN
                                            || m_ShapeTileArgs.ScaleMax == double.NaN) {
                                            double data = double.Parse(fieldData);
                                            if (m_ShapeTileArgs.ScaleMin == double.NaN
                                                && data < scalarMin) {
                                                scalarMin = data;
                                            }

                                            if (m_ShapeTileArgs.ScaleMax == double.NaN
                                                && data > scalarMax) {
                                                scalarMax = data;
                                            }
                                        }
                                    }
                                    catch (Exception ex) {
                                        Log.Write(ex);
                                    }
                                }
                                else {
                                    if (!m_ShapeTileArgs.ColorAssignments.Contains(fieldData)) {
                                        Color newColor = Color.FromArgb(1 + random.Next(254), 1 + random.Next(254), 1 + random.Next(254));

                                        m_ShapeTileArgs.ColorAssignments.Add(fieldData, newColor);
                                    }
                                }
                            }
                        }

                        if (m_ShapeTileArgs.UseScalar
                            && m_ShapeTileArgs.ScaleMin == double.NaN) {
                            m_ShapeTileArgs.ScaleMin = scalarMin;
                        }
                        if (m_ShapeTileArgs.UseScalar
                            && m_ShapeTileArgs.ScaleMax == double.NaN) {
                            m_ShapeTileArgs.ScaleMax = scalarMax;
                        }
                    }
                }
            }

            FileInfo shapeFileInfo = new FileInfo(shapeFilePath);

            using (FileStream fs = File.OpenRead(shapeFileInfo.FullName)) {
                using (BinaryReader reader = new BinaryReader(new BufferedStream(fs))) {
                    //get file header info
                    // Big-Endian Integer File Type
                    byte[] fileTypeBytes = reader.ReadBytes(4);
                    int fileType = 16*16*16*16*16*16*fileTypeBytes[0] + 16*16*16*16*fileTypeBytes[1] + 16*16*fileTypeBytes[2] + fileTypeBytes[3];

                    byte[] unused1 = reader.ReadBytes(5*4);

                    byte[] fileLengthBytes = reader.ReadBytes(4);
                    int fileLength = 16*16*16*16*16*16*fileLengthBytes[0] + 16*16*16*16*fileLengthBytes[1] + 16*16*fileLengthBytes[2] + fileLengthBytes[3];

                    int version = reader.ReadInt32();
                    int shapeType = reader.ReadInt32();

                    m_BoundingBoxXMin = reader.ReadDouble();
                    m_BoundingBoxYMin = reader.ReadDouble();
                    m_BoundingBoxXMax = reader.ReadDouble();
                    m_BoundingBoxYMax = reader.ReadDouble();
                    m_BoundingBoxZMin = reader.ReadDouble();
                    m_BoundingBoxZMax = reader.ReadDouble();
                    m_BoundingBoxMMin = reader.ReadDouble();
                    m_BoundingBoxMMax = reader.ReadDouble();

                    //start reading records...
                    int bytesRead = 100;
                    int counter = 0;

                    while (bytesRead < shapeFileInfo.Length) {
                        ArrayList pendingPoints = new ArrayList();

                        //read record header
                        byte[] recordNumberBytes = reader.ReadBytes(4);
                        byte[] contentLengthBytes = reader.ReadBytes(4);

                        int recordNumber = 16*16*16*16*16*16*recordNumberBytes[0] + 16*16*16*16*recordNumberBytes[1] + 16*16*recordNumberBytes[2] + recordNumberBytes[3];
                        int contentLength = 16*16*16*16*16*16*contentLengthBytes[0] + 16*16*16*16*contentLengthBytes[1] + 16*16*contentLengthBytes[2] + contentLengthBytes[3];

                        //read shape type to determine record structure and content
                        int recordShapeType = reader.ReadInt32();

                        ShapeFileRecord newRecord = new ShapeFileRecord();

                        if (recordShapeType == 0) //Null shape type -- generally used as a placeholder
                        {
                            newRecord.Null = new Shapefile_Null();
                        }
                        else if (recordShapeType == 1) //Point shape type
                        {
                            newRecord.Point = new Shapefile_Point();
                            newRecord.Point.X = reader.ReadDouble();
                            newRecord.Point.Y = reader.ReadDouble();

                            pendingPoints.Add(MathEngine.SphericalToCartesian(newRecord.Point.Y, newRecord.Point.X, m_ShapeTileArgs.LayerRadius));
                        }
                        else if (recordShapeType == 8) //Multi-point shape type
                        {
                            newRecord.MultiPoint = new Shapefile_MultiPoint();
                            newRecord.MultiPoint.BoundingBox.West = reader.ReadDouble();
                            newRecord.MultiPoint.BoundingBox.South = reader.ReadDouble();
                            newRecord.MultiPoint.BoundingBox.East = reader.ReadDouble();
                            newRecord.MultiPoint.BoundingBox.North = reader.ReadDouble();

                            newRecord.MultiPoint.NumPoints = reader.ReadInt32();
                            newRecord.MultiPoint.Points = new Shapefile_Point[newRecord.MultiPoint.NumPoints];
                            for (int i = 0; i < newRecord.MultiPoint.NumPoints; i++) {
                                newRecord.MultiPoint.Points[i] = new Shapefile_Point();
                                newRecord.MultiPoint.Points[i].X = reader.ReadDouble();
                                newRecord.MultiPoint.Points[i].Y = reader.ReadDouble();

                                pendingPoints.Add(MathEngine.SphericalToCartesian(newRecord.MultiPoint.Points[i].Y, newRecord.MultiPoint.Points[i].X, m_ShapeTileArgs.LayerRadius));
                            }
                        }
                        else if (recordShapeType == 3) {
                            newRecord.PolyLine = new Shapefile_PolyLine();

                            newRecord.PolyLine.BoundingBox.West = reader.ReadDouble();
                            newRecord.PolyLine.BoundingBox.South = reader.ReadDouble();
                            newRecord.PolyLine.BoundingBox.East = reader.ReadDouble();
                            newRecord.PolyLine.BoundingBox.North = reader.ReadDouble();

                            newRecord.PolyLine.NumParts = reader.ReadInt32();
                            newRecord.PolyLine.NumPoints = reader.ReadInt32();
                            newRecord.PolyLine.Parts = new int[newRecord.PolyLine.NumParts];

                            for (int i = 0; i < newRecord.PolyLine.Parts.Length; i++) {
                                newRecord.PolyLine.Parts[i] = reader.ReadInt32();
                            }

                            newRecord.PolyLine.Points = new Shapefile_Point[newRecord.PolyLine.NumPoints];
                            for (int i = 0; i < newRecord.PolyLine.Points.Length; i++) {
                                newRecord.PolyLine.Points[i] = new Shapefile_Point();
                                newRecord.PolyLine.Points[i].X = reader.ReadDouble();
                                newRecord.PolyLine.Points[i].Y = reader.ReadDouble();
                            }
                        }
                        else if (recordShapeType == 5) {
                            newRecord.Polygon = new Shapefile_Polygon();

                            newRecord.Polygon.BoundingBox.West = reader.ReadDouble();
                            newRecord.Polygon.BoundingBox.South = reader.ReadDouble();
                            newRecord.Polygon.BoundingBox.East = reader.ReadDouble();
                            newRecord.Polygon.BoundingBox.North = reader.ReadDouble();

                            newRecord.Polygon.NumParts = reader.ReadInt32();
                            newRecord.Polygon.NumPoints = reader.ReadInt32();
                            newRecord.Polygon.Parts = new int[newRecord.Polygon.NumParts];

                            for (int i = 0; i < newRecord.Polygon.Parts.Length; i++) {
                                newRecord.Polygon.Parts[i] = reader.ReadInt32();
                            }

                            newRecord.Polygon.Points = new Shapefile_Point[newRecord.Polygon.NumPoints];
                            for (int i = 0; i < newRecord.Polygon.Points.Length; i++) {
                                newRecord.Polygon.Points[i] = new Shapefile_Point();
                                newRecord.Polygon.Points[i].X = reader.ReadDouble();
                                newRecord.Polygon.Points[i].Y = reader.ReadDouble();
                            }
                        }

                        bool ignoreRecord = false;

                        if (metaValues != null
                            && metaValues.Count > 0) {
                            newRecord.Value = metaValues[counter];

                            if (m_ShapeTileArgs.ActiveDataValues != null) {
                                ignoreRecord = true;
                                if (m_ShapeTileArgs.UseScalar) {
                                    double currentValue = double.Parse(newRecord.Value.ToString());
                                    foreach (string activeValueString in m_ShapeTileArgs.ActiveDataValues) {
                                        double activeValue = double.Parse(activeValueString);
                                        if (activeValue == currentValue) {
                                            ignoreRecord = false;
                                            break;
                                        }
                                    }
                                }
                                else {
                                    string currentValue = (string) newRecord.Value;
                                    foreach (string activeValue in m_ShapeTileArgs.ActiveDataValues) {
                                        if (String.Compare(activeValue.Trim(), currentValue.Trim(), true) == 0) {
                                            ignoreRecord = false;
                                            break;
                                        }
                                    }
                                }
                            }
                            else {
                                if (m_ShapeTileArgs.UseScalar) {
                                    double currentValue = double.Parse(newRecord.Value.ToString());
                                    if (m_ScalarFilterMin != double.NaN) {
                                        if (currentValue < m_ScalarFilterMin) {
                                            ignoreRecord = true;
                                        }
                                    }

                                    if (m_ScalarFilterMax != double.NaN) {
                                        if (currentValue > m_ScalarFilterMax) {
                                            ignoreRecord = true;
                                        }
                                    }

                                    if (m_ShapeTileArgs.NoDataValues != null) {
                                        foreach (string noDataValueString in m_ShapeTileArgs.NoDataValues) {
                                            double noDataValue = double.Parse(noDataValueString);
                                            //TODO: might consider using epsilon if floating point errors occur
                                            if (noDataValue == currentValue) {
                                                ignoreRecord = true;
                                                break;
                                            }
                                        }
                                    }
                                }
                                else {
                                    string currentValue = (string) newRecord.Value;
                                    if (m_ShapeTileArgs.NoDataValues != null) {
                                        foreach (string noDataValue in m_ShapeTileArgs.NoDataValues) {
                                            if (String.Compare(currentValue.Trim(), noDataValue.Trim(), true) == 0) {
                                                ignoreRecord = true;
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        if (!ignoreRecord) {
                            m_ShapeTileArgs.ShapeRecords.Add(newRecord);

                            if (pendingPoints.Count > 0) {
                                foreach (Vector3 v in pendingPoints) {
                                    m_PointList.Add(v);
                                }
                            }
                        }

                        bytesRead += 8 + contentLength*2;
                        counter++;
                    }
                }
            }
        }
Example #2
0
        private bool isShapeRecordInBounds(GeographicBoundingBox geoBB, ShapeFileRecord record)
        {
            if (record.Point != null) {
                if (record.Point.X < geoBB.West || record.Point.X > geoBB.East || record.Point.Y > geoBB.North
                    || record.Point.Y < geoBB.South) {
                    return false;
                }
                else {
                    return true;
                }
            }
            else if (record.MultiPoint != null) {
                if (record.MultiPoint.BoundingBox.North <= geoBB.South || record.MultiPoint.BoundingBox.South >= geoBB.North || record.MultiPoint.BoundingBox.West >= geoBB.East
                    || record.MultiPoint.BoundingBox.East <= geoBB.West) {
                    return false;
                }
                else {
                    return true;
                }
            }
            else if (record.PolyLine != null) {
                if (record.PolyLine.BoundingBox.North <= geoBB.South || record.PolyLine.BoundingBox.South >= geoBB.North || record.PolyLine.BoundingBox.West >= geoBB.East
                    || record.PolyLine.BoundingBox.East <= geoBB.West) {
                    return false;
                }
                else {
                    return true;
                }
            }
            else if (record.Polygon != null) {
                if (record.Polygon.BoundingBox.North <= geoBB.South || record.Polygon.BoundingBox.South >= geoBB.North || record.Polygon.BoundingBox.West >= geoBB.East
                    || record.Polygon.BoundingBox.East <= geoBB.West) {
                    return false;
                }
                else {
                    return true;
                }
            }

            return false;
        }