Options

Image processing, display online images, and google maps.

Arjan_SomersArjan_Somers Member Posts: 64
edited 2015-05-14 in NAV Tips & Tricks
Some time ago i made a couple of posts in the forum concerning images.

I wanted to display google maps whithin navision. Downloading them on the fly.

This has proven to be quite difficult. First of al, navision cannot import an image from an URL, only from local drives. Next problem was that that the google maps images are PNG's while navision only imports BMP's.
And navision requires a fixed DPI resolution setting.

After that i also wanted to do some image processing to stitch different map parts together.

And i found an nice versatile solution, which i wanted to share.

I accomplished it using ImageMagick. It's a free opensource package with a lot of possibilities, such as conversion between image formats, image resizing, image editing, overlays and much more.

All the utilities in the package are commandline utilities. Therefore you can run everything from navision using the shell command (or a 'Windows Script Host Object Model'.WshShell automation object if you don't want to display a dos-box).

This way i got a nice map in navision.

Screenshot of Map utility

The possibilities are numerous, because you can also create images using this library, making it possible to create graphs for example, or you can use it to store png or jpegs and load them on the fly, reducing disk usage.

Comments

  • Options
    Luc_VanDyckLuc_VanDyck Member, Moderator, Administrator Posts: 3,633
    Do you want to share your code? Feel free to upload your routine to the download pages.
    No support using PM or e-mail - Please use this forum. BC TechDays 2024: 13 & 14 June 2024, Antwerp (Belgium)
  • Options
    Arjan_SomersArjan_Somers Member Posts: 64
    It's not quite finished yet. I can give pieces of code like the way the URL for different map tiles is calculated if somebody is interested.

    And i could post the code once i'm finished.
  • Options
    SavatageSavatage Member Posts: 7,142
    let's link these together
    Google Maps - Show in Map / Show Route
    http://www.mibuso.com/forum/viewtopic.php?t=17225
  • Options
    ATAT Member Posts: 20
    Some time ago i made a couple of posts in the forum concerning images.

    I wanted to display google maps whithin navision. Downloading them on the fly.
    The possibilities are numerous, because you can also create images using this library, making it possible to create graphs for example, or you can use it to store png or jpegs and load them on the fly, reducing disk usage.

    Is it possible to post your example with PM? As you can see in the posted link from Savatage that i am interested in this integration too.

    Thank you.
  • Options
    Arjan_SomersArjan_Somers Member Posts: 64
    Hi AT (Altough his question is quite old, he recently mailed me)

    I missed your question in March, but better late than never i guess :)

    The code is quite messy/ written for a specific purpose and i do not have a generic map form, so i will just try to explain what you have to do.

    First thing to know is that you can access google map tiles using an unique URL for each tile

    An URL could be:

    http://mt1.google.com/mt?n=404&x=329&y=792&zoom=6

    The important things to see here is that you have an X coordinate, and an Y coordinate (or tile number) and a zoom level.

    With
    http://mt1.google.com/mt?n=404&x=0&y=0&zoom=17
    You get a map of the entire world

    By lowering the zoom, you get a more closeup-view of the earth. At zoom level 16 there are 4 tiles to cover the entire earth.

    At zoom lever 15 there are 16 tiles

    etcetera etcetera... (Each tile is split up into 4 tiles at the next level)

    To instantly calculate the x and y coordinate for a position given it's GPS coordinates, you have to do some simple calculations. You should note that google uses a mercator projection, and looking that up on wikipedia should give you the required formula's.

    A small but important snippet of code is the following:
    ldecX := (180.0 + ldecLong) / 360.0;
    ldecY := -ldecLat * Math.Pi / 180; // convert to radians
    ldecY := 0.5 * Math.Ln((1+Math.Sin(ldecY)) / (1 - Math.Sin(ldecY)));
    ldecY *= 1.0/(2 * Math.Pi);// scale factor from radians to normalized
    ldecY += 0.5;
    
    ldecY := Math.Floor(ldecY*POWER(2, 17-lintZoom));
    ldecX := Math.Floor(ldecX*POWER(2, 17-lintZoom));
    

    This basically gives you the x and y's given the GPS coordinates and a zoom level.

    If you want to have a satellite image, you need a different URL. The idea is basically the same, but instead of X and Y coordinates, it uses a string of letters (qtrs).

    You can use this to convert the X and Y numbers to this string of letters:
    convertToSatAddress(x : Integer;y : Integer;zoom : Integer) : Text[30]
    ltxtAddress := '';
    
    FOR i := 1 TO (17-zoom) DO
    BEGIN
       rx := x MOD 2;
       x  := x DIV 2;
       ry := y MOD 2;
       y  := y DIV 2;
       rxry := FORMAT(rx)+FORMAT(ry);
       CASE rxry OF
          '00' : ltxtAddress := 'q' + ltxtAddress;
          '01' : ltxtAddress := 't' + ltxtAddress;
          '10' : ltxtAddress := 'r' + ltxtAddress;
          '11' : ltxtAddress := 's' + ltxtAddress;
        END;
    END;
    ltxtAddress := 't' + ltxtAddress;
    
    EXIT(ltxtAddress);
    

    The resulting string should be appended to:
    http://kh.google.com/kh?v=3&t=

    Creating somthing like:
    http://kh.google.com/kh?v=3&t=tqst

    Where the zoom level is defined by the number of characters in the string.


    After getting the URL, you need to download it to your PC, and since 1 tile is a bit small, i decided to stitch 9 tiles together.
    And after that it has to be coverted to the BMP file format.

    The solution for that is to use the opensource Imagick library.
    Is consists of a couple of very useful commandline utilities, that can, amongs many other things, do exactly what we want.

    You can put the commands in a Batch script file, or use multiple SHELL calls.

    I won't explain this in too much detail because:
    1. Imagick is quite easy to learn, and there are many examples on the website.
    2. I use an outdated version with slightly different syntax.

    ****Important note
    Use the following parameters

    "-units" "PixelsPerInch" "-density" "96x96"

    because this will make Navision use the correct size
    (Navision uses actual size (such as mm or inch) instead of pixel sizes, so this will make sure it is displayed properly)

    But there is still room for improvement:
    1. Crop the image (use more tiles, and cut a bit of at the edges)
    This will center the map at the given GPS position. (Otherwise the center is somewhere in the middle image)
    2. Use a cache. Google bans users which request to many images

    ****Important note
    this is al reverse engineerd, so i don't know what googles view on this is,
    but i guess that if you want to make very heavy or commercial use of it, you should just buy Mappoint. In all cases: i am not responsible, and you should consult the google maps policy.

    3. put icons on top of you map.
    Maybe this will help:
    SatAdressToPixel(ldecLat : Decimal;ldecLong : Decimal)
    ldecX := (180.0 + gdecLong) / 360.0;
    ldecY := -gdecLat * Math.Pi / 180; // convert to radians
    ldecY := 0.5 * Math.Ln((1+Math.Sin(ldecY)) / (1 - Math.Sin(ldecY)));
    ldecY *= 1.0/(2 * Math.Pi);// scale factor from radians to normalized
    ldecY += 0.5;
    
    ldecX2 := (180.0 + ldecLong) / 360.0;
    ldecY2 := -ldecLat * Math.Pi / 180; // convert to radians
    ldecY2 := 0.5 * Math.Ln((1+Math.Sin(ldecY2)) / (1 - Math.Sin(ldecY2)));
    ldecY2 *= 1.0/(2 * Math.Pi);// scale factor from radians to normalized
    ldecY2 += 0.5;
    
    lintX := (Math.Ceil((ldecX2*POWER(2, 17-gintZoom) - (ldecX*POWER(2, 17-gintZoom)))*256)+256);
    lintY := (512-(Math.Ceil((ldecY*POWER(2, 17-gintZoom) - (ldecY2*POWER(2, 17-gintZoom)))*256)+256));
    
    MESSAGE('X:%1, Y:%2', lintX, lintY);
    


    4. Use 'Windows Script Host Object Model'.WshShell to hide the popup
    Finally it is important to know that it won't plot routes.
    And a final note is that the string contains a version number which might be subject to change, just like rest of the URL. Thus altough it has not changed for quite some time, you should never use it for a critical buissness process.
  • Options
    SavatageSavatage Member Posts: 7,142
    Wow!

    Just trying to read that has given me an Idea for that Feature Request post :mrgreen:
  • Options
    ATAT Member Posts: 20
    Thank you for your detailed post. One more question:
    How did you get the images to your PC? Is it necessary to open your browser?
  • Options
    LichtensLichtens Member Posts: 1
    I tried to convert your code in C++, but the tile i get is just the wrong one. Can anyone help me what is wrong with the calculation?
            double decLat = 48.44;
    	double decLong = -9.6;
    
            x = (180.0 + decLong)/360.0;
    	y = -decLat*pi/180;
    	y = 0.5 * log((1+sin(y))/(1-sin(y)));
    	y *= 1.0/(2*pi);
    	y += 0.5;
        
    	y = y*pow( 2, 17 - zoom );
    	x = x*pow( 2, 17 - zoom );
    
    	cout << "X: " << x << " Y: " << y << endl;
    


    The coordinates are from Stuttgart Germany, but the tile I get are anywhere in the ocean.

    Regards
    Lichtens[/code]
  • Options
    Arjan_SomersArjan_Somers Member Posts: 64
    AT wrote:
    Thank you for your detailed post. One more question:
    How did you get the images to your PC? Is it necessary to open your browser?

    I use the 'convert' command from the ImageMagick library. This command can take URL's as parameters, so no browser is required.
    Lichtens wrote:
    tI ried to convert your code in C++, but the tile i get is just the wrong one. Can anyone help me what is wrong with the calculation?

    Not the calculation is wrong, but the coordinates are. If you want to get a tile near stuttgard, your Longitude should be positive (+9.6 instead of -9.6)

    To get coordinates for certain locations, or vice versa, i used the following website. It is in dutch, but it might still be useful:
    http://www.gpscoordinaten.nl/bepaal-gps-coordinaten.php
  • Options
    tinattinat Member Posts: 1
    Hi,

    i want to import an image from url eg: url eg:--> abcd.com/.../test3.png into into NAV 6sp1


    Thanks
Sign In or Register to comment.