public void RotatePoint() { var map = new MapSurface(); map.SetRotation(Math.PI / 2); // Rotate about center point 500, 500 -> 0, 0 map.Rotate_point(1000.0, 0.0, out var toX, out var toY); toX.Should().BeApproximately(0.0, 0.0000001); toY.Should().BeApproximately(0.0, 0.0000001); }
public void ZeroRotationDoesNotMovepoint(double testX, double testY) { var map = new MapSurface(); map.SetRotation(0); // Rotate/unrotate about center point 500, 500 map.Rotate_point(testX, testY, out var toX, out var toY); toX.Should().BeApproximately(testX, 0.0000001); toY.Should().BeApproximately(testY, 0.0000001); }
public void RotatePointRoundtrip(double testX, double testY) { var map = new MapSurface(); map.SetRotation(Math.PI / 2); // Rotate/unrotate about center point 500, 500 -> 1000, 0 map.Rotate_point(testX, testY, out var toX, out var toY); map.Un_rotate_point(toX, toY, out var toX2, out var toY2); toX2.Should().BeApproximately(testX, 0.0000001); toY2.Should().BeApproximately(testY, 0.0000001); }
/* TODO ColorPaletteClassType() * private TICDisplayPaletteBaseClass ColorPaletteClassType() * { * case FMode of * ...Height : Result = TICDisplayPalette_Height; * ...CCV : Result = TICDisplayPalette_CCV; * ...CCVPercent : Result = TICDisplayPalette_CCVPercent; * ...Latency : Result = TICDisplayPalette_RadioLatency; * ...PassCount : Result = TICDisplayPalette_PassCount; * ...PassCountSummary : Result = TICDisplayPalette_PassCountSummary; // Palettes are fixed three color palettes - display will use direct transitions * ...RMV : Result = TICDisplayPalette_RMV; * ...Frequency : Result = TICDisplayPalette_Frequency; * ...Amplitude : Result = TICDisplayPalette_Amplitude; * ...CutFill : Result = TICDisplayPalette_CutFill; * ...Moisture : Result = TICDisplayPalette_Moisture; * ...TemperatureSummary : Result = TICDisplayPaletteBase; //TICDisplayPalette_Temperature; * ...GPSMode : Result = TICDisplayPaletteBase; //TICDisplayPalette_GPSMode; * ...CCVSummary : Result = TICDisplayPaletteBase; //TICDisplayPalette_CCVSummary; * ...CCVPercentSummary : Result = TICDisplayPalette_CCVPercent; * ...CompactionCoverage : Result = TICDisplayPalette_CoverageOverlay; * ...VolumeCoverage : Result = TICDisplayPalette_VolumeOverlay; * ...MDP : Result = TICDisplayPalette_MDP; // ajr15167 * ...MDPSummary : Result = TICDisplayPaletteBase; * ...MDPPercent : Result = TICDisplayPalette_MDPPercent; * ...MDPPercentSummary : Result = TICDisplayPalette_MDPPercent; * ...MachineSpeed : Result = TICDisplayPalette_MachineSpeed; * ...CCVPercentChange : Result = TICDisplayPalette_CCVPercent; * ...TargetThicknessSummary : Result = TICDisplayPalette_VolumeOverlay; * ...TargetSpeedSummary : Result = TICDisplayPalette_SpeedSummary; * ...CCVChange : Result = TICDisplayPalette_CCVChange; * ...CCA : Result = TICDisplayPalette_CCA; * ...CCASummary : Result = TICDisplayPalette_CCASummary; * * else * SIGLogMessage.PublishNoODS(Self, Format('ColorPaletteClassType: Unknown display type: %d', [Ord(FMode)]), ...Assert); * Result = TICDisplayPaletteBase; * end; * end; */ /* TODO: ComputeCCAPalette * function ComputeCCAPalette :Boolean; * var * I, J, K :Integer; * ResponseVerb :...VerbBase; * ServerResult :TICServerRequestResult; * ResponseDataStream :TStream; * CCAMinimumPasses :...CCAMinPassesValue; * CCAColorScale :...CCAColorScale; * CCAPalette :TColorPalettes; * * begin * Result = False; * * ResponseVerb = nil; * try * if Length(FFilter1.Machines) > 0 then * FMachineID = FFilter1.Machines[0].ID // Must be set by caller * else * FMachineID = -1; // will fail call * if not Assigned(ASNodeImplInstance) or ASNodeImplInstance.ServiceStopped then * begin * SIGLogMessage.PublishNoODS(Self, Format('%s.Execute: Aborting request as service has been stopped', [Self.ClassName]), ...Warning); * Exit; * end; * * ASNodeImplInstance.PSLoadBalancer.LoadBalancedPSService.GetMachineCCAMinimumPassesValue(FDataModelID, FMachineID, FFilter1.StartTime, FFilter1.EndTime, FFilter1.LayerID, ResponseVerb); * if Assigned(ResponseVerb) then * with ResponseVerb as ...Verb_SendResponse do * begin * ServerResult = TICServerRequestResult(ResponseCode); * ResponseDataStream = ResponseData; * if (ServerResult = ...NoError) and assigned(ResponseData) then * begin * CCAMinimumPasses = ReadSmallIntFromStream(ResponseDataStream); * * Result = CCAMinimumPasses > 0; * * if not Result then * Exit; * * CCAColorScale = ...CCAColorScaleManager.CreateCoverageScale(CCAMinimumPasses); * try * SetLength(CCAPalette.Transitions, CCAColorScale.TotalColors); * * J = Low(CCAPalette.Transitions); * k = High(CCAPalette.Transitions); * for I = J to K do * begin * CCAPalette.Transitions[I].Color = CCAColorScale.ColorSegments[K - I].Color; * CCAPalette.Transitions[I].Value = I+1; * end; * CCAPalette.ConvertRGBToBGR; // gets done again but needed to match Anatoli palette test :) * WorkingColorPalette.PopulateFromPaletteColors(CCAPalette); * WorkingColorPalette.TransitionColors.ValuesCount = Length(CCAPalette.Transitions); * finally * if Assigned(CCAColorScale) then * FreeAndNil(CCAColorScale); * end; * end * else * SIGLogMessage.PublishNoODS(Self, Format('%s.Execute: GetMachineCCAMinimumPassesValue Failed for InternalSiteModelMachineIndex: %d. ReturnCode:%d', [Self.ClassName, FMachineID, Ord(ServerResult)]), ...Warning); * end; * finally * if Assigned(ResponseVerb) then * FreeAndNil(ResponseVerb); * end; * end; */ /* TODO: CreateAndInitialiseWorkingColorPalette * function CreateAndInitialiseWorkingColorPalette :Boolean; * begin * Result = True; * * // Create a scaled palette to use when rendering the data * try * if ColorPaletteClassType<> Nil then * begin * * WorkingColorPalette = ColorPaletteClassType.Create; * WorkingColorPalette.SmoothPalette = FMode = ...CutFill; * * // CCASummary is done per machine id * if FMode in [...CCA, ...CCASummary] * then * Result = ComputeCCAPalette * else * begin * if Length(FColorPalettes.Transitions) = 0 then * WorkingColorPalette.SetToDefaults * else * WorkingColorPalette.PopulateFromPaletteColors(FColorPalettes); * end; * * if Result then * WorkingColorPalette.ComputePalette; * end * else * WorkingColorPalette = Nil; * * Except * On e:Exception do * SIGLogMessage.PublishNoODS(Self, Format('%s.Execute: Error: %s ', [Self.ClassName, e.Message]), ...Exception); * end; * end; */ /// <summary> /// Renders all sub grids in a representational style that indicates where there is data, but nothing else. This is used for large scale displays /// (zoomed out a lot) where meaningful detail cannot be drawn on the tile /// </summary> private SKBitmap RenderTileAsRepresentationalDueToScale(ISubGridTreeBitMask overallExistenceMap) { using (var RepresentationalDisplay = PVMDisplayerFactory.GetDisplayer(Mode /*, FICOptions*/)) { using (var mapView = new MapSurface { SquareAspect = false }) { mapView.SetRotation(TileRotation); RepresentationalDisplay.MapView = mapView; RepresentationalDisplay.MapView.SetBounds(NPixelsX, NPixelsY); RepresentationalDisplay.MapView.SetWorldBounds(NEECoords[0].X, NEECoords[0].Y, NEECoords[0].X + WorldTileWidth, NEECoords[0].Y + WorldTileHeight, 0); // Iterate over all the bits in the sub grids drawing a rectangle for each one on the tile being rendered if (overallExistenceMap.ScanSubGrids(RotatedTileBoundingExtents, leaf => { leaf.CalculateWorldOrigin(out var WorldOriginX, out var WorldOriginY); (leaf as SubGridTreeLeafBitmapSubGrid)?.Bits.ForEachSetBit((x, y) => { RepresentationalDisplay.MapView.DrawRect(WorldOriginX + (x * overallExistenceMap.CellSize), WorldOriginY + (y * overallExistenceMap.CellSize), overallExistenceMap.CellSize, overallExistenceMap.CellSize, true, RepresentColor); }); return(true); })) { // Remove the canvas from the map view to prevent it's disposal (it's being returned to the caller) var canvas = RepresentationalDisplay.MapView.BitmapCanvas; RepresentationalDisplay.MapView.BitmapCanvas = null; return(canvas); } } } return(null); // It did not work out... }