private bool isShapeRecordInBounds(GeographicBoundingBox geoBB, ShapeRecord 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); }
private void loadShapeFile(string shapeFilePath) { FileInfo shapeFile = new FileInfo(shapeFilePath); FileInfo dbaseFile = new FileInfo(shapeFile.FullName.Replace(".shp", ".dbf")); System.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()), System.Text.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)) { System.Drawing.Color newColor = System.Drawing.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(); ShapeRecord newRecord = new ShapeRecord(); 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++; } } } }
//Loads a Zipped Shapefile without extracting //return==true means it was successfull private void loadZippedShapeFile(string shapeFilePath) { //ZipFileIndexes int shpIndex = -1; int dbfIndex = -1; try { //Navigate the Zip to find the files and update their index ZipFile zFile = new ZipFile(shapeFilePath); foreach (ZipEntry ze in zFile) { if(ze.Name.ToLower().EndsWith(".shp")) shpIndex=ze.ZipFileIndex; else if(ze.Name.ToLower().EndsWith(".dbf")) dbfIndex=ze.ZipFileIndex; } } catch { /* Ignore */ } if((dbfIndex == -1)||(shpIndex == -1)) return ; System.Random random = new Random(Path.GetFileName(shapeFilePath).GetHashCode()); ArrayList metaValues = new ArrayList(); if(m_ShapeTileArgs.DataKey != null) { ExtendedZipInputStream dbfReader = new ExtendedZipInputStream(File.OpenRead(shapeFilePath)); ZipEntry dbfEntry= null; dbfEntry = dbfReader.GetNextEntry(); for(int p=0;p<dbfIndex;p++) { dbfEntry = dbfReader.GetNextEntry(); } if(!dbfEntry.IsFile) return; 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); 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); } 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)) { System.Drawing.Color newColor = System.Drawing.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; } } dbfReader.Close(); } ExtendedZipInputStream shpReader= new ExtendedZipInputStream(File.OpenRead(shapeFilePath)); ZipEntry shpEntry= null; shpEntry = shpReader.GetNextEntry(); for(int p=0;p<shpIndex;p++) { shpEntry = shpReader.GetNextEntry(); } if(!shpEntry.IsFile) return ; //get file header info // Big-Endian Integer File Type byte[] fileTypeBytes = shpReader.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 = shpReader.ReadBytes(5 * 4); byte[] fileLengthBytes = shpReader.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 = shpReader.ReadInt32(); int shapeType = shpReader.ReadInt32(); m_BoundingBoxXMin = shpReader.ReadDouble(); m_BoundingBoxYMin = shpReader.ReadDouble(); m_BoundingBoxXMax = shpReader.ReadDouble(); m_BoundingBoxYMax = shpReader.ReadDouble(); m_BoundingBoxZMin = shpReader.ReadDouble(); m_BoundingBoxZMax = shpReader.ReadDouble(); m_BoundingBoxMMin = shpReader.ReadDouble(); m_BoundingBoxMMax = shpReader.ReadDouble(); //start reading records... int bytesRead = 100; int counter = 0; while (bytesRead < shpEntry.Size) { ArrayList pendingPoints = new ArrayList(); //read record header byte[] recordNumberBytes = shpReader.ReadBytes(4); byte[] contentLengthBytes = shpReader.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 = shpReader.ReadInt32(); ShapeRecord newRecord = new ShapeRecord(); 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 = shpReader.ReadDouble(); newRecord.Point.Y = shpReader.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 = shpReader.ReadDouble(); newRecord.MultiPoint.BoundingBox.South = shpReader.ReadDouble(); newRecord.MultiPoint.BoundingBox.East = shpReader.ReadDouble(); newRecord.MultiPoint.BoundingBox.North = shpReader.ReadDouble(); newRecord.MultiPoint.NumPoints = shpReader.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 = shpReader.ReadDouble(); newRecord.MultiPoint.Points[i].Y = shpReader.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 = shpReader.ReadDouble(); newRecord.PolyLine.BoundingBox.South = shpReader.ReadDouble(); newRecord.PolyLine.BoundingBox.East = shpReader.ReadDouble(); newRecord.PolyLine.BoundingBox.North = shpReader.ReadDouble(); newRecord.PolyLine.NumParts = shpReader.ReadInt32(); newRecord.PolyLine.NumPoints = shpReader.ReadInt32(); newRecord.PolyLine.Parts = new int[newRecord.PolyLine.NumParts]; for (int i = 0; i < newRecord.PolyLine.Parts.Length; i++) { newRecord.PolyLine.Parts[i] = shpReader.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 = shpReader.ReadDouble(); newRecord.PolyLine.Points[i].Y = shpReader.ReadDouble(); } } else if(recordShapeType == 5) { newRecord.Polygon = new Shapefile_Polygon(); newRecord.Polygon.BoundingBox.West = shpReader.ReadDouble(); newRecord.Polygon.BoundingBox.South = shpReader.ReadDouble(); newRecord.Polygon.BoundingBox.East = shpReader.ReadDouble(); newRecord.Polygon.BoundingBox.North = shpReader.ReadDouble(); newRecord.Polygon.NumParts = shpReader.ReadInt32(); newRecord.Polygon.NumPoints = shpReader.ReadInt32(); newRecord.Polygon.Parts = new int[newRecord.Polygon.NumParts]; for (int i = 0; i < newRecord.Polygon.Parts.Length; i++) { newRecord.Polygon.Parts[i] = shpReader.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(); byte[] temp=new byte[16]; for(int t=0;t<16;t++) { temp[t]=shpReader.ReadByte(); } newRecord.Polygon.Points[i].X=BitConverter.ToDouble(temp,0); newRecord.Polygon.Points[i].Y=BitConverter.ToDouble(temp,8); } } 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++; } }
private bool isShapeRecordInBounds(GeographicBoundingBox geoBB, ShapeRecord 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; }
private Renderable.ImageLayer CreateImageLayer(double north, double south, double west, double east, DrawArgs drawArgs, string imagePath) { Bitmap b = null; Graphics g = null; Renderable.ImageLayer imageLayer = null; GeographicBoundingBox geoBB = new GeographicBoundingBox(north, south, west, east); int numberPolygonsInTile = 0; FileInfo imageFile = new FileInfo(imagePath); FileInfo shapeFile = new FileInfo(m_ShapeTileArgs.ParentShapeFileLayer.ShapeFilePath); FileInfo shapeXmlFile = null; if (m_ShapeTileArgs.ParentShapeFileLayer.MetaData.Contains("SourceXml")) { string sourceXml = (string)m_ShapeTileArgs.ParentShapeFileLayer.MetaData["SourceXml"]; if (!sourceXml.ToLower().StartsWith("http://")) { shapeXmlFile = new FileInfo(sourceXml); } } if (!m_ShapeTileArgs.ParentShapeFileLayer.EnableCaching || !imageFile.Exists || shapeXmlFile == null || shapeXmlFile.LastWriteTimeUtc > imageFile.LastWriteTimeUtc || shapeFile.LastWriteTimeUtc > imageFile.LastWriteTimeUtc ) { for (int i = 0; i < m_ShapeTileArgs.ShapeRecords.Count; i++) { ShapeRecord currentRecord = (ShapeRecord)m_ShapeTileArgs.ShapeRecords[i]; if (currentRecord.Null != null || currentRecord.Point != null || currentRecord.MultiPoint != null || !isShapeRecordInBounds(geoBB, currentRecord)) { continue; } else { if (b == null) { b = new Bitmap(m_ShapeTileArgs.TilePixelSize.Width, m_ShapeTileArgs.TilePixelSize.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); } if (g == null) { g = Graphics.FromImage(b); } System.Drawing.Color color = m_ShapeTileArgs.PolygonColor; //Fix Black Tiles g.DrawLine(new Pen(color), 0, 0, 1, 1); if (m_ShapeTileArgs.UseScalar && m_ShapeTileArgs.ScaleColors) { double red = 1.0; double green = 1.0; double blue = 1.0; try { //TODO: make this a function and abstract to allow multiple gradient mappings double dv; double curScalar = double.Parse(currentRecord.Value.ToString()); if (curScalar < m_ShapeTileArgs.ScaleMin) { curScalar = m_ShapeTileArgs.ScaleMin; } if (curScalar > m_ShapeTileArgs.ScaleMax) { curScalar = m_ShapeTileArgs.ScaleMax; } dv = m_ShapeTileArgs.ScaleMax - m_ShapeTileArgs.ScaleMin; if (curScalar < (m_ShapeTileArgs.ScaleMin + 0.25 * dv)) { red = 0; green = 4 * (curScalar - m_ShapeTileArgs.ScaleMin) / dv; } else if (curScalar < (m_ShapeTileArgs.ScaleMin + 0.5 * dv)) { red = 0; blue = 1 + 4 * (m_ShapeTileArgs.ScaleMin + 0.25 * dv - curScalar) / dv; } else if (curScalar < (m_ShapeTileArgs.ScaleMin + 0.75 * dv)) { red = 4 * (curScalar - m_ShapeTileArgs.ScaleMin - 0.5 * dv) / dv; blue = 0; } else { green = 1 + 4 * (m_ShapeTileArgs.ScaleMin + 0.75 * dv - curScalar) / dv; blue = 0; } color = System.Drawing.Color.FromArgb((int)(255 * red), (int)(255 * green), (int)(255 * blue)); } catch (Exception) { // Utility.Log.Write((string)currentPoly.ScalarHash[m_ShapeTileArgs.ColorKey]); // Utility.Log.Write(String.Format("Min: {0}, Max: {1}", m_ShapeTileArgs.ScaleMin, m_ShapeTileArgs.ScaleMax)); // Utility.Log.Write(String.Format("{0},{1},{2}", red, green, blue)); // Utility.Log.Write(ex); } } else { if (m_ShapeTileArgs.ColorAssignments.Count > 0 && m_ShapeTileArgs.ScaleColors) { try { string colorAssignmentKey = (string)currentRecord.Value; foreach (string cak in m_ShapeTileArgs.ColorAssignments.Keys) { if (String.Compare(cak, colorAssignmentKey, true) == 0) { color = (System.Drawing.Color)m_ShapeTileArgs.ColorAssignments[cak]; break; } } } catch (Exception) { } } } if (currentRecord.Polygon != null) { drawPolygon(currentRecord.Polygon, g, color, geoBB, b.Size); } if (m_ShapeTileArgs.ColorAssignments.Count == 0 || !m_ShapeTileArgs.ScaleColors) { color = m_ShapeTileArgs.LineColor; } if (currentRecord.PolyLine != null) { drawPolyLine(currentRecord.PolyLine, g, color, geoBB, b.Size); } numberPolygonsInTile++; } } } if (!m_ShapeTileArgs.ParentShapeFileLayer.EnableCaching) { string id = System.DateTime.Now.Ticks.ToString(); if (b != null) { MemoryStream ms = new MemoryStream(); //must copy original stream into new stream, if not, error occurs, not sure why m_ImageStream = new MemoryStream(ms.GetBuffer()); imageLayer = new WorldWind.Renderable.ImageLayer( id, m_ShapeTileArgs.ParentWorld, 0, m_ImageStream, System.Drawing.Color.Black.ToArgb(), (float)south, (float)north, (float)west, (float)east, (float)m_ShapeTileArgs.ParentShapeFileLayer.Opacity / 255.0f, m_ShapeTileArgs.ParentWorld.TerrainAccessor); ms.Close(); } } else if (imageFile.Exists || numberPolygonsInTile > 0) { string id = System.DateTime.Now.Ticks.ToString(); if (b != null) { MemoryStream ms = new MemoryStream(); b.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp); if (!imageFile.Directory.Exists) { imageFile.Directory.Create(); } //must copy original stream into new stream, if not, error occurs, not sure why m_ImageStream = new MemoryStream(ms.GetBuffer()); ImageHelper.ConvertToDxt3(m_ImageStream, imageFile.FullName); ms.Close(); } imageLayer = new WorldWind.Renderable.ImageLayer( id, m_ShapeTileArgs.ParentWorld, 0, // should be distance above surface imageFile.FullName, //m_ImageStream, //0,//System.Drawing.Color.Black.ToArgb(), (float)south, (float)north, (float)west, (float)east, (float)m_ShapeTileArgs.ParentShapeFileLayer.Opacity / 255.0f, m_ShapeTileArgs.ParentWorld.TerrainAccessor); } if (b != null) { b.Dispose(); } if (g != null) { g.Dispose(); } b = null; g = null; //might not be necessary //GC.Collect(); return(imageLayer); }