GithubHelp home page GithubHelp logo

Comments (13)

LorenzoMattia avatar LorenzoMattia commented on June 9, 2024

Hi @hanselmoovita sorry for late answer. You are probably having an exception raising in the try block at line 494 of the map_widget.py file that results in one of the except blocks which is returning self.empty_tile_image.
Could you please provide further details?

from tkintermapview.

hanselmoovita avatar hanselmoovita commented on June 9, 2024

@LorenzoMattia

Can I clarify with you, if I would like to apply overlay layer on top of Main Tile layer, is this the correct way to do it? See screenshot below, right window for highlighted portion:

Screenshot from 2023-12-18 14-13-57

The current problem I faced is that when I added this line, the tkinter application goes blank when I made the selection with overlay (ie: Google satellite)

For this scenario, I have not made modifications to map_widget.py I have tried to modify the definition for but have not been successful either

For your kind advice please

from tkintermapview.

LorenzoMattia avatar LorenzoMattia commented on June 9, 2024

@hanselmoovita

Yes, you are doing right in setting the overlay_tile_server.

The problem I think you are facing is in the block I mentioned in my previous answer.

I suggest you to execute the code in debug mode or trivially to temporarily remove the try except block at line 494 in map_widget.py to see what exception is raised.
My intuition is that a certain problem is causing that block to fall in on of the except blocks in which the empty_tile_image is being returned and that is probably the blank image you are seeing in the screen.

I'm talking about this piece of code

        try:
            url = self.tile_server.replace("{x}", str(x)).replace("{y}", str(y)).replace("{z}", str(zoom))
            image = Image.open(requests.get(url, stream=True, headers={"User-Agent": "TkinterMapView"}).raw)

            if self.overlay_tile_server is not None:
                url = self.overlay_tile_server.replace("{x}", str(x)).replace("{y}", str(y)).replace("{z}", str(zoom))
                image_overlay = Image.open(requests.get(url, stream=True, headers={"User-Agent": "TkinterMapView"}).raw)
                image = image.convert("RGBA")
                image_overlay = image_overlay.convert("RGBA")

                if image_overlay.size is not (self.tile_size, self.tile_size):
                    image_overlay = image_overlay.resize((self.tile_size, self.tile_size), Image.ANTIALIAS)

                image.paste(image_overlay, (0, 0), image_overlay)

            if self.running:
                image_tk = ImageTk.PhotoImage(image)
            else:
                return self.empty_tile_image

            self.tile_image_cache[f"{zoom}{x}{y}"] = image_tk
            return image_tk

        except PIL.UnidentifiedImageError:  # image does not exist for given coordinates
            self.tile_image_cache[f"{zoom}{x}{y}"] = self.empty_tile_image
            return self.empty_tile_image

        except requests.exceptions.ConnectionError:
            return self.empty_tile_image

        except Exception:
            return self.empty_tile_image

Keep me updated once you have tried!

from tkintermapview.

hanselmoovita avatar hanselmoovita commented on June 9, 2024

I've removed the entire try-except code block starting from line 494 in map_widget.py, and when the app is launched, the default selection OpenStreetMap shows a blank grey screen, and many exception errors were returned in the debugger in one go:

Screenshot from 2023-12-19 09-08-51

No other modifications were made other than the one you've suggested above. The full log of exception errors are found below:

Error log.txt

from tkintermapview.

LorenzoMattia avatar LorenzoMattia commented on June 9, 2024

Hi @hanselmoovita, sorry, I did not explain myself well.

You do not have to completely remove the try catch block, but only to remove the try, leaving the block of code inside it, and all the catches. So this code:

        try:
            url = self.tile_server.replace("{x}", str(x)).replace("{y}", str(y)).replace("{z}", str(zoom))
            image = Image.open(requests.get(url, stream=True, headers={"User-Agent": "TkinterMapView"}).raw)

            if self.overlay_tile_server is not None:
                url = self.overlay_tile_server.replace("{x}", str(x)).replace("{y}", str(y)).replace("{z}", str(zoom))
                image_overlay = Image.open(requests.get(url, stream=True, headers={"User-Agent": "TkinterMapView"}).raw)
                image = image.convert("RGBA")
                image_overlay = image_overlay.convert("RGBA")

                if image_overlay.size is not (self.tile_size, self.tile_size):
                    image_overlay = image_overlay.resize((self.tile_size, self.tile_size), Image.ANTIALIAS)

                image.paste(image_overlay, (0, 0), image_overlay)

            if self.running:
                image_tk = ImageTk.PhotoImage(image)
            else:
                return self.empty_tile_image

            self.tile_image_cache[f"{zoom}{x}{y}"] = image_tk
            return image_tk

        except PIL.UnidentifiedImageError:  # image does not exist for given coordinates
            self.tile_image_cache[f"{zoom}{x}{y}"] = self.empty_tile_image
            return self.empty_tile_image

        except requests.exceptions.ConnectionError:
            return self.empty_tile_image

        except Exception:
            return self.empty_tile_image

will be:

url = self.tile_server.replace("{x}", str(x)).replace("{y}", str(y)).replace("{z}", str(zoom))
image = Image.open(requests.get(url, stream=True, headers={"User-Agent": "TkinterMapView"}).raw)

if self.overlay_tile_server is not None:
    url = self.overlay_tile_server.replace("{x}", str(x)).replace("{y}", str(y)).replace("{z}", str(zoom))
    image_overlay = Image.open(requests.get(url, stream=True, headers={"User-Agent": "TkinterMapView"}).raw)
    image = image.convert("RGBA")
    image_overlay = image_overlay.convert("RGBA")

    if image_overlay.size is not (self.tile_size, self.tile_size):
         image_overlay = image_overlay.resize((self.tile_size, self.tile_size), Image.ANTIALIAS)

    image.paste(image_overlay, (0, 0), image_overlay)

if self.running:
     image_tk = ImageTk.PhotoImage(image)
else:
     return self.empty_tile_image

 self.tile_image_cache[f"{zoom}{x}{y}"] = image_tk
return image_tk

Obviously, this operation only aimes at understanding the error that is causing the display of blank images, indeed using the try catch, the error is never shown in the console. Morever, even if this approach works, the best way to do this would be to use the debugger and not to modify the code.
Once you will understand why that part of code is generating an exception you will probably closer to the solution.

Let me know!

from tkintermapview.

hanselmoovita avatar hanselmoovita commented on June 9, 2024

Hi,

The change is able to work based on the modification to if-else conditional as you have suggested:

Screenshot from 2023-12-21 10-12-59

For the above test, I used OpenStreetMap as base layer with Railway lines as overlay.

Please note that the Antialias class seems to have been removed, I have replaced it with LANCZOS as per: https://stackoverflow.com/questions/76616042/attributeerror-module-pil-image-has-no-attribute-antialias

Do note that there are warning issued:

/usr/lib/python3/dist-packages/requests/init.py:89: RequestsDependencyWarning: urllib3 (2.1.0) or chardet (3.0.4) doesn't match a supported version!
warnings.warn("urllib3 ({}) or chardet ({}) doesn't match a supported "
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python3.8/threading.py", line 932, in _bootstrap_inner
self.run()
File "/usr/lib/python3.8/threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "/home/han/Documents/TkinterMapView-MY/src/map_widget.py", line 436, in pre_cache
self.request_image(zoom, x, self.pre_cache_position[1] + radius, db_cursor=db_cursor)
File "/home/han/Documents/TkinterMapView-MY/src/map_widget.py", line 495, in request_image
image = Image.open(requests.get(url, stream=True, headers={"User-Agent": "TkinterMapView"}).raw)
File "/home/han/.local/lib/python3.8/site-packages/PIL/Image.py", line 3305, in open
raise UnidentifiedImageError(msg)
PIL.UnidentifiedImageError: cannot identify image file <_io.BytesIO object at 0x7f8be06630e0>

from tkintermapview.

hanselmoovita avatar hanselmoovita commented on June 9, 2024

However, can I also ask, if Tkintermapview is able to support Openstreetmap/Google maps as base layer, with local map tiles as overlay layer?

With the latest update to implementation, only the map tile layer (overlay) is loaded, and the base layer with Openstreetmap doesn't load:

Conditions to which this issue is attempted:

  1. Replacing try-except loop with if-else loop to the map_widget as you have suggested
  2. On local map tile folder, terminal was started and I entered <python3 -m http.server 8080> so as to be able to retrieve local map tile images
  3. The local map tiles have coordinates pre-marked:

Screenshot from 2023-12-21 10-18-32

The intended implementation is to look like this:

Screenshot from 2023-12-21 10-22-35

How do you suggest map_widget.py maybe further modified to support this implementation?

from tkintermapview.

LorenzoMattia avatar LorenzoMattia commented on June 9, 2024

Hi @hanselmoovita, cool! Removing the try revealed that the error that was causing the blank image to be returned in one of those catch blocks was related to that Image.LANCZOS.

So now you can actually reintroduce the try and bring back the code to its original version, obviously keeping the fix of the LANCZOS.
I would suggest this to you, because using try catches will prevent the program to crash when, for instance, the server from which you download the images is not available.

Concerning your second question, this is surely possible, but it is necessary to change something in the request_image method. Are you using a db created with the offline_loading.py file to load offline the overlays?

from tkintermapview.

hanselmoovita avatar hanselmoovita commented on June 9, 2024

Hi @LorenzoMattia Yes, if I revert the code back to its original version, and keeping the fix for LANCZOS, the crash issue disappears.

No....I did not create db using offline_loading.py; I set up a local HTTP server by opening an Ubuntu terminal, screenshot shown below. 0 to 19 indicates the zoom level:

Screenshot from 2023-12-22 20-28-58

While I am able to load the local tiles using set_tile_server as the sole layer, I am not able to display the local tiles if it is an overlay layer, with OSM as base layer with the original mplementation (only change applied is changing line 504 ANTIALIAS-->LANCZOS):

Screenshot from 2023-12-22 20-39-56

Would like to ask how def set_overlay_tile_server (or any other related functions) can be modified to support image tile overlay.....

from tkintermapview.

LorenzoMattia avatar LorenzoMattia commented on June 9, 2024

Hi @hanselmoovita, first of all I want to clarify that in my answer I am supposing your self.database_path to be unspecified (None).

Starting from this assumption, what I can tell you is that problems are probably again in that try catch block. So, I would suggest you again to remove that try, as you already did to discover the LANCZOS problem, and see what is the error that is causing this problem. Indeed, that part of code should actually work, and the behavior you are obtaining is really strange.

Lastly, just to be sure, are your overlay images .png with no bacground?

Keep me updated!

from tkintermapview.

hanselmoovita avatar hanselmoovita commented on June 9, 2024

Hi @LorenzoMattia I have once again attempted to replace the try-except block with the if-else block at Line 494 which you have suggested.

For this scenario, selecting option with the OSM base layer + overlay doesn't work either. Additionally, I noticed the following issues:

  1. Multiple traceback errors of this type returned:
    AttributeError: 'PhotoImage' object has no attribute '_PhotoImage__photo'
    Exception ignored in: <function PhotoImage.del at 0x7fc227a2d280>
    Traceback (most recent call last):
    File "/home/han/.local/lib/python3.8/site-packages/PIL/ImageTk.py", line 132, in del

  2. Location would default to Berlin, even though I have specified self.map_widget.set_address to Singapore

  3. The default location would go into the highest resolution; sometimes, when I attempted to change the map selection to Google, a black tile appears instead:

Scenario illustrated in screenshot below:

Screenshot from 2023-12-25 17-40-52

The overlay_images.png have no background; the background intended to be used would be either OSM or Google streetmap. If you would like to have a copy of the overlay images, you can email me at [email protected]

Hope to hear from you again, wishing you a Merry Christmas!

from tkintermapview.

LorenzoMattia avatar LorenzoMattia commented on June 9, 2024

Hi @hanselmoovita, thank you and I hope you had a really Merry Christmas!

Answering to your points:

  1. I have already seen those "Exception ignored" in my application. In my case, they happened sometimes when the tiles loading was running while the application is not already completely initialized. Meaning that your init() function is not ended when the tiles are loading. However, the not loaded tiles referred by those exceptions were then loaded zooming in/out on the map.
  2. Concerning the default location, I would suggest you to look for the (latitude, longitude) coordinates on Google maps or wherever you prefer and use them in the set_position function instead of using the set_address, it can fail sometimes. However, if you prefer to use set_address pay attention to the fact that at line 153 the map sets its position to Berlin, so note that yout set_address should be done before it.
  3. I actually do not know, I should inspect your code for this.

Hoping to be helpful, let me know!

from tkintermapview.

hanselmoovita avatar hanselmoovita commented on June 9, 2024

@LorenzoMattia Good day, I am happy to share my code with you, is it possible you send me a private message at [email protected] so that I can share it with you?

Wishing you a Happy New Year

from tkintermapview.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.