示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#3
0
        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);
        }
示例#4
0
        /* 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...
        }