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; }
public ShapeTile(GeographicBoundingBox geoBB, ShapeTileArgs shapeTileArgs) { m_GeoBB = geoBB; m_ShapeTileArgs = shapeTileArgs; BoundingBox = new BoundingBox((float) geoBB.South, (float) geoBB.North, (float) geoBB.West, (float) geoBB.East, (float) m_ShapeTileArgs.LayerRadius, (float) m_ShapeTileArgs.LayerRadius + 300000f); }
private Point[] getScreenPoints(Shapefile_Point[] sourcePoints, int offset, int length, GeographicBoundingBox dstBB, Size dstImageSize) { double degreesPerPixelX = (dstBB.East - dstBB.West)/(double) dstImageSize.Width; double degreesPerPixelY = (dstBB.North - dstBB.South)/(double) dstImageSize.Height; ArrayList screenPointList = new ArrayList(); for (int i = offset; i < offset + length; i++) { double screenX = (sourcePoints[i].X - dstBB.West)/degreesPerPixelX; double screenY = (dstBB.North - sourcePoints[i].Y)/degreesPerPixelY; if (screenPointList.Count > 0) { Point v = (Point) screenPointList[screenPointList.Count - 1]; if (v.X == (int) screenX && v.Y == (int) screenY) { continue; } } screenPointList.Add(new Point((int) screenX, (int) screenY)); } if (screenPointList.Count <= 1) { return new Point[] {new Point(0, 0), new Point(0, 0)}; } return (Point[]) screenPointList.ToArray(typeof (Point)); }
private void drawPolyLine(Shapefile_PolyLine polyLine, Graphics g, Color c, GeographicBoundingBox dstBB, Size imageSize) { using (Pen p = new Pen(c, m_ShapeTileArgs.LineWidth)) { p.Color = c; if (polyLine.Parts.Length > 1) { for (int partsItr = 0; partsItr < polyLine.Parts.Length - 1; partsItr++) { g.DrawLines(p, getScreenPoints(polyLine.Points, polyLine.Parts[partsItr], polyLine.Parts[partsItr + 1] - polyLine.Parts[partsItr], dstBB, imageSize)); } g.DrawLines(p, getScreenPoints(polyLine.Points, polyLine.Parts[polyLine.Parts.Length - 1], polyLine.Points.Length - polyLine.Parts[polyLine.Parts.Length - 1], dstBB, imageSize)); } else { g.DrawLines(p, getScreenPoints(polyLine.Points, 0, polyLine.Points.Length, dstBB, imageSize)); } } }
public ShapeFileLayer(string id, World parentWorld, string shapeFilePath, double minimumViewingAltitude, double maximumViewingAltitude, float lztsd, GeographicBoundingBox bounds, string dataKey, bool scaleColorsToData, double scalarFilterMin, double scalarFilterMax, double scaleMin, double scaleMax, string[] noDataValues, string[] activeDataValues, bool polygonFill, bool outlinePolygons, Color polygonFillColor, ShapeFillStyle shapeFillHatchStyle, Color lineColor, float lineWidth, bool showLabels, Color labelColor, string iconFilePath, int iconWidth, int iconHeight, byte iconOpacity) : base(id, parentWorld.Position, parentWorld.Orientation) { m_MinimumViewingAltitude = minimumViewingAltitude; m_MaximumViewingAltitude = maximumViewingAltitude; m_lztsd = lztsd; m_ShapeTileArgs = new ShapeTileArgs(parentWorld, new Size(256, 256), parentWorld.EquatorialRadius, this, dataKey, scaleColorsToData, scaleMin, scaleMax, noDataValues, activeDataValues, polygonFill, outlinePolygons, polygonFillColor, shapeFillHatchStyle, lineColor, labelColor, lineWidth, showLabels); m_ScalarFilterMin = scalarFilterMin; m_ScalarFilterMax = scalarFilterMax; m_ShapeFilePath = shapeFilePath; m_IconFilePath = iconFilePath; m_IconWidth = iconWidth; m_IconHeight = iconHeight; m_IconOpacity = iconOpacity; /*Produces tile tree for whole earth*/ /*Need to implement clipping*/ m_NumberRootTilesHigh = (int) (180.0f/m_lztsd); double tileSize = 180.0f/m_NumberRootTilesHigh; m_RootTiles = new ShapeTile[m_NumberRootTilesHigh*(m_NumberRootTilesHigh*2)]; //System.Console.WriteLine("North:{0} South:{1} East:{2} West:{3}", // bounds.North,bounds.South,bounds.East,bounds.West); int istart = 0; int iend = m_NumberRootTilesHigh; int jstart = 0; int jend = m_NumberRootTilesHigh*2; int createdtiles = 0; for (int i = istart; i < iend; i++) { for (int j = jstart; j < jend; j++) { double north = (i + 1)*tileSize - 90.0f; double south = i*tileSize - 90.0f; double west = j*tileSize - 180.0f; double east = (j + 1)*tileSize - 180.0f; m_RootTiles[i*m_NumberRootTilesHigh*2 + j] = new ShapeTile(new GeographicBoundingBox(north, south, west, east), m_ShapeTileArgs); m_RootTiles[i*m_NumberRootTilesHigh*2 + j].Level = 0; m_RootTiles[i*m_NumberRootTilesHigh*2 + j].Row = i; m_RootTiles[i*m_NumberRootTilesHigh*2 + j].Col = j; createdtiles++; } } //Console.WriteLine("Created Tiles "+createdtiles); }
private void drawPolygon(Shapefile_Polygon polygon, Graphics g, Color c, GeographicBoundingBox dstBB, Size imageSize) { if (polygon.Parts.Length > 1) { if (m_ShapeTileArgs.PolygonFill) { if (m_ShapeTileArgs.ShapeFillStyle == ShapeFillStyle.Solid) { using (SolidBrush brush = new SolidBrush(c)) { g.FillPolygon(brush, getScreenPoints(polygon.Points, 0, polygon.Parts[1], dstBB, imageSize)); } } else { using (HatchBrush brush = new HatchBrush(getGDIHatchStyle(m_ShapeTileArgs.ShapeFillStyle), c, Color.Black)) { g.FillPolygon(brush, getScreenPoints(polygon.Points, 0, polygon.Parts[1], dstBB, imageSize)); } } } if (m_ShapeTileArgs.OutlinePolygons) { using (Pen p = new Pen(m_ShapeTileArgs.LineColor, m_ShapeTileArgs.LineWidth)) { for (int partsItr = 0; partsItr < polygon.Parts.Length - 1; partsItr++) { g.DrawPolygon(p, getScreenPoints(polygon.Points, polygon.Parts[partsItr], polygon.Parts[partsItr + 1] - polygon.Parts[partsItr], dstBB, imageSize)); } g.DrawPolygon(p, getScreenPoints(polygon.Points, polygon.Parts[polygon.Parts.Length - 1], polygon.Points.Length - polygon.Parts[polygon.Parts.Length - 1], dstBB, imageSize)); } } if (m_ShapeTileArgs.PolygonFill) { if (m_ShapeTileArgs.ShapeFillStyle == ShapeFillStyle.Solid) { using (SolidBrush brush = new SolidBrush(Color.Black)) { for (int partsItr = 1; partsItr < polygon.Parts.Length - 1; partsItr++) { g.FillPolygon(brush, getScreenPoints(polygon.Points, polygon.Parts[partsItr], polygon.Parts[partsItr + 1] - polygon.Parts[partsItr], dstBB, imageSize)); } g.FillPolygon(brush, getScreenPoints(polygon.Points, polygon.Parts[polygon.Parts.Length - 1], polygon.Points.Length - polygon.Parts[polygon.Parts.Length - 1], dstBB, imageSize)); } } else { using (HatchBrush brush = new HatchBrush(getGDIHatchStyle(m_ShapeTileArgs.ShapeFillStyle), c, Color.Black)) { for (int partsItr = 1; partsItr < polygon.Parts.Length - 1; partsItr++) { g.FillPolygon(brush, getScreenPoints(polygon.Points, polygon.Parts[partsItr], polygon.Parts[partsItr + 1] - polygon.Parts[partsItr], dstBB, imageSize)); } g.FillPolygon(brush, getScreenPoints(polygon.Points, polygon.Parts[polygon.Parts.Length - 1], polygon.Points.Length - polygon.Parts[polygon.Parts.Length - 1], dstBB, imageSize)); } } } } else { if (m_ShapeTileArgs.PolygonFill) { if (m_ShapeTileArgs.ShapeFillStyle == ShapeFillStyle.Solid) { using (SolidBrush brush = new SolidBrush(c)) { g.FillPolygon(brush, getScreenPoints(polygon.Points, 0, polygon.Points.Length, dstBB, imageSize)); } } else { using (HatchBrush brush = new HatchBrush(getGDIHatchStyle(m_ShapeTileArgs.ShapeFillStyle), c, Color.Black)) { g.FillPolygon(brush, getScreenPoints(polygon.Points, 0, polygon.Points.Length, dstBB, imageSize)); } } } if (m_ShapeTileArgs.OutlinePolygons) { using (Pen p = new Pen(m_ShapeTileArgs.LineColor, m_ShapeTileArgs.LineWidth)) { g.DrawPolygon(p, getScreenPoints(polygon.Points, 0, polygon.Points.Length, dstBB, imageSize)); } } } }
private ImageLayer CreateImageLayer(double north, double south, double west, double east, DrawArgs drawArgs, string imagePath) { Bitmap b = null; Graphics g = null; 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++) { ShapeFileRecord currentRecord = (ShapeFileRecord) 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, PixelFormat.Format32bppArgb); } if (g == null) { g = Graphics.FromImage(b); } 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 = 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 = (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 = 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 ImageLayer(id, m_ShapeTileArgs.ParentWorld, 0, m_ImageStream, 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 = DateTime.Now.Ticks.ToString(); if (b != null) { MemoryStream ms = new MemoryStream(); b.Save(ms, 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 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; }