ThinkGeo.com    |     Documentation    |     Premium Support

Migrating from 4.5 to 12 Adornment Overlay

Frank, thanks
Rotation and Pan resolved. Issue was in several overrides for Pan
(double, double) shift by X,Y screen coordinate
(float, int) shift by angle and second param persantage.
Very easy to do mistake, my case…

Next issue, labels croped
image
set DrawingMarginInPixel = 256; do not helped

PS. I would like ask all question in one thread, please

Question to Ben. Ben, could you write me when issue with shifting and sizing images in AdornmentLayer will be solved?

Thanks Andras,
Looks like the upper left and the low right tile not draw. Or they are come from the old cache. Could you clear the cache or disable the cache and try again?

Thanks

Frank

Frank, thanks
Labels still cropped. I don’t know how to clear or disable cache

Hi Andras,

We cannot just make the map Control itself not respecting the system DPI while the other parts in the application does. Instead you can programmatically override the High DPI scaling behavior, like this:

[DllImport("user32.dll", SetLastError = true)]
internal static extern bool SetProcessDpiAwarenessContext(int dpiFlag);

public Form1()
    {
        SetProcessDpiAwarenessContext(-5);
        InitializeComponent();
    }

The app then looks like this without manually setting the DPI awareness:

Check out here for the detail:
windows 10 - Programmatically override the High DPI awareness - Stack Overflow

This API works for Windows 10 +, for Windows 8 checkout here:
c# - DPI Awareness - Unaware in one Release, System Aware in the Other - Stack Overflow

Thanks,
Ben

Andras,
Could you send us the sample code/project. We could looked into the details. Looks like you didn’t set DrawingMarginInPixel = 256 for the label layer. The crop happen on the edge of the tile.

Thanks

Frank

Thanks Frank and Ben
We bought full version of ThinkGeo 12
Sample project
WindowsFormsApp18.zip (38.5 KB)

Ben, I couldn’t get it to work. The images still shifted and bigger. I think it do not take effect on yours library, which used WPF

Thanks Andras,
I found you have a override for the DrawCore in PointsTextStyle.cs. If you remove this override the result will be correct.

base on your comment “Draw all the feature which presents in ExtentRect”. I think you only draw the feature in current extent. So if the feature belong to the current extent but the label not belong to current extent you won’t draw it. That will case the label only draw in one tile.

@Ben will answer the image issue.

Thanks

Frank

Thanks Frank
Now I figured out which reason
this line of code caused this effect
if (FieldContainsPointShape(ExtentRect, FeaturePointShape))
This was made when in version 4.5 labels drawing very slowly

Hi Andras,

Here is a quick demo for you. It’s based on your Desktop Sample using Winforms Edition

CustomAdornmentLayer-12102020.zip (23.1 KB)

Run it on my computer with scaling = 200%, I got the following:

Thanks,
Ben

Ben
What I missing?
I add this code to my application
[DllImport(“user32.dll”, SetLastError = true)]
internal static extern bool SetProcessDpiAwarenessContext(int dpiFlag);
public Form1()
{
SetProcessDpiAwarenessContext(-5);
InitializeComponent();
}
In your example project it worked well, In my - don’t take effect

Also I would like the sytem settings make 120 DPI instead 96 in my program when I set system scaling to medium. Interface of my program was developed for medium and normal font size. It was a big work. Only issue with WPF part connected with ThinkGeo. Map do scale images and shift them in adornment overlay in V12
I don’t understand why you can not add flag DPI_Unware in your initialization process

Thanks

   Ben

Some clarification of my problem with scaling and offset
I used function
canvas.DrawWorldImageWithoutScaling (anImage, location.X, location.Y, DrawingLevel, 0, 0, 0);
in Adornment overlay in DrawCore,
I need that this function render the image without scaling in X, Y coordinates
Thanks

Hi Andras,

Do you mean the same code works in the demo but not working on your project on the same machine? Does your app work fine if you manually override the High DPI Scaling (please check my reply on December 1st for the detail)?

Also I want to make sure you now only have issues for AdornmentOverlay or you have issues in other overlay controls as well? After changing the system scaling, all the controls in your application will change accordingly, such as the zoom bar control on the map, the font size in your app menu, is that your case? As it sounds the other parts are fine but AdornmentOverlay is the only part with issues. Can you give me a screenshot of your application?

Also I’m wondering how you changed the DPI to 120? can you give me a screenshot as well.

Last but not least, Merry Christmas and Happy Holidays!

Thanks,
Ben

Ben
First of all, Merry Christmas and Happy Holidays! )))

Issues there is for AdornmentOverlay only, please look at the theme of the post ))
Other overlay controls ok.
I not using zoom bar control on the map, not using menu


I am using adornment overlay. All the images bigger and shifted in V12

When I say about Dpi, I mean CurrentAutoScaleDimensions.Width
and sorry, i mistaked, 96 instead 120. If set scale in system to medium it has value 96
I check it this way in each dialog window when it initialized
It allow set form view for dialog in different scale
AutoScaleMode = AutoScaleMode.Dpi;
if (this.CurrentAutoScaleDimensions.Width == 96)
{
laDestinationPoint.Font = new Font(“Microsoft Sans Serif”, 10);
laLine.Font = new Font(“Microsoft Sans Serif”, 10);
}

I need only one function DrawImageWithoutScale , than it render image without scaling in X,Y location on the screen, PLEASE )))

I not find another way do buttons and control on the map with transparent background

Thanks

Hi Andras,

Please use the following code to get the Scale Factor, which is the scale you set in Windows:

Graphics graphics = this.CreateGraphics();
float dpiX = graphics.DpiX;
scaleFactor = dpiX / 96f;

And instead of calling DrawImageWithoutScale, call DrawImage and pass in CurrentWidth/scaleFactor as the target width.

 canvas.DrawScreenImage(needleImage, Xloc, Yloc, imageWidth/scaleFactor, imageHeight / scaleFactor, DrawingLevel.LevelFour, 0, 0, rotateAngle);

I included this code (but commented it out) in the demo I sent over on December 10th because I was thinking of setting it to DPI unawareness makes more sense. Please have a try and see if it works for you.

Thanks,
Ben

Ben
Yes it is worked for me, thanks very much. Solved
One more issue with GoogleMap. In V4.5 was googleMapsLayer.GetGoogleMapsImage function
I uderstand that google don’t allow ThinkGeo use this service, but it is open for using. We need to create right string and send it to google. Could you help me with code, how to create this string. In V4.5 it worked very well. Or I should create ticket?

Thanks

Hi Andras,

Happy New Year!

Frank’s reply on Nov 10th showed how to use GoogleMapsLayer to draw an image in a specific area. And you can get the requested link we send to Google Server by hooking up SendingWebRequest event like the following:

    googleMapsLayer.SendingWebRequest += GoogleMapsLayer_SendingWebRequest;

    private void GoogleMapsLayer_SendingWebRequest(object sender, SendingWebRequestEventArgs e)
    {
       //  You can get the requested URI from e.WebRequest
    }

Thanks,
Ben

Ben
Happy New Year!

googleMapsLayer.SendingWebRequest - ok, I done it
Please look in my code.
I need load image by tiles from google

            using (Graphics g = Graphics.FromImage(bitmap))
            {
                for (int i = 0; i < BitmapWidth / TileSize + 1; i++)
                {
                    for (int j = 0; j < BitmapHeight / TileSize + 1; j++)
                    {
                        PointShape RequestPoint = MapUtil.ToWorldCoordinate(ImageExtent, new 
                            ScreenPointF(i * TileSize + TileSize / 2, j * TileSize + TileSize / 2), Map1.Width,   Map1.Height);
                        googleMapsLayer.GetGoogleMapsImage(RequestPoint.X, RequestPoint.Y,ScaleIndex, TileSize, TileSize);
                        g.DrawImage(TileBmp, i * TileSize, j * TileSize);
                        ProgressValue = 100 * ProcessedTiles++ / NumTiles;
                    }
                }
            }

Thanks

Andras,

Here below is how we generate Google Request link in Map Suite 9 (which is compatible with v4.5).

      private string GetRequestImageUrl(double lon, double lat, int zoomLevelNumber, double tileWidth, double tileHeight)
    {
        string regionInfoParameters = GetRegionInfoParameters(tileWidth, tileHeight, zoomLevelNumber, lon, lat);
        StringBuilder requestStringBuilder = new StringBuilder("http://maps.googleapis.com/maps/api/staticmap?");
        requestStringBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}&", regionInfoParameters);
        requestStringBuilder.AppendFormat(CultureInfo.InvariantCulture, "maptype={0}&", GetMapType());
        requestStringBuilder.AppendFormat(CultureInfo.InvariantCulture, "format={0}&", GetPictureFormat());
        requestStringBuilder.Append("sensor=false");
        if (!string.IsNullOrEmpty(clientId) && !string.IsNullOrEmpty(privateKey))
        {
            requestStringBuilder.AppendFormat(CultureInfo.InvariantCulture, "&client={0}", clientId);
            requestStringBuilder.AppendFormat(CultureInfo.InvariantCulture, "&signature={0}", GetSignature(requestStringBuilder.ToString()));
        }

        if(!string.IsNullOrEmpty(Language))
        {
            requestStringBuilder.AppendFormat(CultureInfo.InvariantCulture, "&language={0}", Language);
        }

        return requestStringBuilder.ToString();
    }

    private static string GetRegionInfoParameters(double newWidth, double newHeight, int zoomLevelNumber, double longitude, double latitude)
    {
        StringBuilder regionInfo = new StringBuilder();
        regionInfo.AppendFormat(CultureInfo.InvariantCulture, "center={0},{1}&", Math.Round(latitude, 6), Math.Round(longitude, 6));
        regionInfo.AppendFormat(CultureInfo.InvariantCulture, "zoom={0}&", zoomLevelNumber);
        regionInfo.AppendFormat(CultureInfo.InvariantCulture, "size={0}x{1}", (int)newWidth, (int)newHeight);
        return regionInfo.ToString();
    }

The only thing to be aware of is Google recommended to use ApiKey now instead of ClientID/PrivateKey, so you can simply remove the ClientId/PrivateKey and attach the ApiKey to the URI if what you are using for authentication is ApiKey. Check out Google’s doc Overview | Maps Static API | Google Developers for the detail.

Thanks,
Ben

Ben
Ok, I solved this issue with google map, thanks you

Next issue with scales. I turn mouse wheel to increase map scale, and map scale became very big digits. At some point, the adornment layers will no longer be rendered. How I can limit increasing scale by mouse wheel?

Hi Andras, can you create another thread? This one is too long, takes time to load and it’s hard to search in the future as well.

And I’m a bit confused. The adornment layer is not supposed to zoom in/out when scrolling the mouse wheel, can you share some pictures?