public static void Resample(GraphicsEngine.Abstraction.IBitmap dest, IDisplay destDisplay, GraphicsEngine.Abstraction.IBitmap source, IDisplay sourceDisplay) { GraphicsEngine.BitmapPixelData destData = null, sourceData = null; using (var transformer = gView.Framework.Geometry.GeometricTransformerFactory.Create()) { try { transformer.SetSpatialReferences(sourceDisplay.SpatialReference, destDisplay.SpatialReference); destData = dest.LockBitmapPixelData(GraphicsEngine.BitmapLockMode.WriteOnly, GraphicsEngine.PixelFormat.Rgba32); sourceData = source.LockBitmapPixelData(GraphicsEngine.BitmapLockMode.ReadOnly, GraphicsEngine.PixelFormat.Rgba32); int sWidth = source.Width, sHeight = source.Height; int dWidth = dest.Width, dHeight = dest.Height; unsafe { byte *ptr = (byte *)destData.Scan0; for (int y = 0; y < dHeight; y++) { for (int x = 0; x < dWidth; x++) { double xx = x, yy = y; destDisplay.Image2World(ref xx, ref yy); gView.Framework.Geometry.IPoint point = (gView.Framework.Geometry.IPoint)transformer.InvTransform2D(new gView.Framework.Geometry.Point(xx, yy)); xx = point.X; yy = point.Y; sourceDisplay.World2Image(ref xx, ref yy); int x_ = (int)xx, y_ = (int)yy; if (x_ >= 0 && x_ < sWidth && y_ >= 0 && y_ < sHeight) { byte *p = (byte *)sourceData.Scan0; p += (y_ * destData.Stride + x_ * 4); if (p[3] != 0) // Transparenz!!! { ptr[0] = p[0]; ptr[1] = p[1]; ptr[2] = p[2]; ptr[3] = p[3]; } } ptr += 4; } ptr += destData.Stride - destData.Width * 4; } } } catch { } finally { if (destData != null) { dest.UnlockBitmapPixelData(destData); } if (sourceData != null) { source.UnlockBitmapPixelData(sourceData); } } } }
async public Task <IRasterPaintContext> BeginPaint(gView.Framework.Carto.IDisplay display, ICancelTracker cancelTracker) { IntPtr bufferData = (IntPtr)0; GraphicsEngine.BitmapPixelData bitmapData = null; double mag = 1f; // mag immer als float, läuft stabiler!!! int x = 0; int y = 0; int iWidth = 0; int iHeight = 0; GraphicsEngine.Abstraction.IBitmap bitmap = null; try { if (_reader == (IntPtr)0) { if (!InitReader()) { return(null); } } if (!(_polygon is ITopologicalOperation) || _reader == (IntPtr)0) { return(null); } TFWFile tfw = this.GeoCoord as TFWFile; if (tfw == null) { return(null); } IEnvelope dispEnvelope = display.DisplayTransformation.TransformedBounds(display); //display.Envelope; if (display.GeometricTransformer != null) { dispEnvelope = ((IGeometry)display.GeometricTransformer.InvTransform2D(dispEnvelope)).Envelope; } IGeometry clipped; ((ITopologicalOperation)_polygon).Clip(dispEnvelope, out clipped); if (!(clipped is IPolygon)) { return(null); } IPolygon cPolygon = (IPolygon)clipped; if (cPolygon.RingCount == 0 || cPolygon[0].Area == 0D) { return(null); } // geclipptes Polygon transformieren -> Bild vector2[] vecs = new vector2[cPolygon[0].PointCount]; for (int i = 0; i < cPolygon[0].PointCount; i++) { vecs[i] = new vector2(cPolygon[0][i].X, cPolygon[0][i].Y); } if (!tfw.ProjectInv(vecs)) { return(null); } IEnvelope picEnv = vector2.IntegerEnvelope(vecs); picEnv.minx = Math.Max(0, picEnv.minx); picEnv.miny = Math.Max(0, picEnv.miny); picEnv.maxx = Math.Min(picEnv.maxx, _geoCoord.iWidth); picEnv.maxy = Math.Min(picEnv.maxy, _geoCoord.iHeight); // Ecken zurücktransformieren -> Welt vecs = new vector2[3]; vecs[0] = new vector2(picEnv.minx, picEnv.miny); vecs[1] = new vector2(picEnv.maxx, picEnv.miny); vecs[2] = new vector2(picEnv.minx, picEnv.maxy); tfw.Project(vecs); _p1 = new gView.Framework.Geometry.Point(vecs[0].x, vecs[0].y); _p2 = new gView.Framework.Geometry.Point(vecs[1].x, vecs[1].y); _p3 = new gView.Framework.Geometry.Point(vecs[2].x, vecs[2].y); double pix = display.mapScale / (display.dpi / 0.0254); // [m] double c1 = Math.Sqrt(_geoCoord.xRes * _geoCoord.xRes + _geoCoord.xRot * _geoCoord.xRot); double c2 = Math.Sqrt(_geoCoord.yRes * _geoCoord.yRes + _geoCoord.yRot * _geoCoord.yRot); mag = Math.Round((Math.Min(c1, c2) / pix), 8); // Immer in auf float runden! Läuft stabiler!!! //mag = (float)mag; //1.03; if (mag > 1f) { mag = 1f; } if (mag < _geoCoord.MinMagnification) { mag = (float)_geoCoord.MinMagnification; } x = (int)(picEnv.minx * mag); y = (int)(picEnv.miny * mag); iWidth = (int)((picEnv.Width - 1) * mag); iHeight = (int)((picEnv.Height - 1) * mag); bufferData = MrSidWrapper.Read(_reader, x, y, iWidth, iHeight, mag); if (bufferData == (IntPtr)0) { return(null); } int totalWidth = MrSidWrapper.GetTotalCols(bufferData); int totalHeight = MrSidWrapper.GetTotalRows(bufferData); bitmap = GraphicsEngine.Current.Engine.CreateBitmap(totalWidth, totalHeight, GraphicsEngine.PixelFormat.Rgb24); bitmapData = bitmap.LockBitmapPixelData(GraphicsEngine.BitmapLockMode.WriteOnly, GraphicsEngine.PixelFormat.Rgb24); MrSidWrapper.ReadBandData(bufferData, bitmapData.Scan0, 3, (uint)bitmapData.Stride); return(new RasterPaintContext(bitmap)); } catch (Exception ex) { //string errMsg = ex.Message; if (display is IServiceMap && ((IServiceMap)display).MapServer != null) { IMapServer mapServer = ((IServiceMap)display).MapServer; await mapServer.LogAsync( ((IServiceMap)display).Name, "RenderRasterLayerThread", loggingMethod.error, ex.Message + "\n" + ex.Source + "\n" + ex.StackTrace + "\n" + "filename=" + _filename + "\n" + "x=" + x.ToString() + "\n" + "y=" + y.ToString() + "\n" + "iWidth=" + iWidth.ToString() + "\n" + "iHeight=" + iHeight.ToString() + "\n" + "mag=" + mag.ToString() + "\n"); } else { throw ex; } return(null); } finally { if (bitmapData != null) { bitmap.UnlockBitmapPixelData(bitmapData); } MrSidWrapper.ReleaseBandData(bufferData); ReleaseReader(); } }