Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

erroneous behavior on different machine (Windows) #45

Closed
mattijn opened this issue Aug 12, 2019 · 4 comments
Closed

erroneous behavior on different machine (Windows) #45

mattijn opened this issue Aug 12, 2019 · 4 comments

Comments

@mattijn
Copy link
Owner

mattijn commented Aug 12, 2019

While testing on a different (windows) PC, I run into errors and different results:
Observe that the simplification only seems to have happened in Madagaskar:

Windows PC:
afbeelding

My Development PC:
afbeelding
From: https://nbviewer.jupyter.org/github/mattijn/topojson/blob/master/notebooks/ipywidgets_interaction.ipynb

Also this code from #43

import geopandas
import topojson

data = geopandas.read_file(geopandas.datasets.get_path("naturalearth_lowres"))
data = data[(data.continent == "North America")]

tj = topojson.Topology(data)
tj.to_widget()

Results in an error in the dedup step:

c:\programdata\miniconda3\lib\site-packages\topojson\core\dedup.py in __init__(self, data, options)
     26 
     27         # execute main function of Dedup
---> 28         self.output = self.deduper(self.output)
     29 
     30     def __repr__(self):

c:\programdata\miniconda3\lib\site-packages\topojson\core\dedup.py in deduper(self, data)
     75             # apply linemerge on geoms containing contigious arcs and maintain
     76             # bookkeeping
---> 77             self.merge_contigious_arcs(data, sliced_array_bk_ndp)
     78 
     79             # pop the merged contigious arcs and maintain bookkeeping.

c:\programdata\miniconda3\lib\site-packages\topojson\core\dedup.py in merge_contigious_arcs(self, data, sliced_array_bk_ndp)
    217 
    218                 # replace linestring of idx_keep with merged linestring
--> 219                 data["linestrings"][idx_keep] = ndp_arcs[idx_merg_arc]
    220                 self.merged_arcs_idx.append(idx_pop)
    221 

c:\programdata\miniconda3\lib\site-packages\shapely\geometry\base.py in __getitem__(self, index)
    828     def __getitem__(self, index):
    829         if not self.is_empty:
--> 830             return self.geoms[index]
    831         else:
    832             return ()[index]

c:\programdata\miniconda3\lib\site-packages\shapely\geometry\base.py in __getitem__(self, key)
    930             return type(self.__p__)(res or None)
    931         else:
--> 932             raise TypeError("key must be an index or slice")
    933 
    934     @property

TypeError: key must be an index or slice

..

@mattijn
Copy link
Owner Author

mattijn commented Aug 14, 2019

This are the packages on my Mac, where all works:

import numpy
import shapely 
import simplification
import fiona
import geopandas
import json
import IPython
import altair
import ipywidgets
# %load https://gist.github.com/kinverarity1/6038316/raw/loaded_modules.py
'''List loaded modules and packages, and show their version numbers
and/or Git repository's HEAD commit SHA.

'''
# Standard library modules
import types
import os

# Third-party packages
import git      # GitPython


def module_path(mod):
    '''Returns path to the file that module *mod* comes from.
    If it doesn't come from a file, return None.'''
    if hasattr(mod, '__file__'):
        return os.path.abspath(os.path.dirname(mod.__file__))
    else:
        return None

    
def from_git_repo(mod):
    '''Does the module *mod* reside in a Git repository?'''
    path = module_path(mod)
    if path:
        try:
            repo = git.Repo(path)
        except:
            return False
        else:
            return True
    else:
        return False

    
def git_path_sha(mod, slice=slice(0, 8, 1)):
    '''Return SHA hash for the HEAD commit for the repository
    that the module *mod* resides in.'''
    repo = git.Repo(module_path(mod))
    return repo.git_dir, repo.head.commit.hexsha[:8]


def module_version(mod):
    '''Return version string for module *mod*, or nothing if
    it doesn't have a "version" or "__version__" attribute.'''
    version = []
    if hasattr(mod, '__dict__'):
        keys = []
        for key in mod.__dict__.keys():
            if key.lower() == 'version' or key.lower() == '__version__':
                v = mod.__dict__[key]
                if isinstance(v, str):
                    version.append(v)
        if keys:
            print(mod, keys)
    if version:
        return ', '.join(version)
    else:
        return ''

    
def find_loaded_modules(only_versioned_modules=True):
    '''Return list of loaded modules for which there is a version
    number or a Git repository commit SHA.
    
    Return a list of *(name, version, path_to_git_repo, git_head_sha)*,
    which has an HTML property for pretty display in IPython Notebooks.
        
    '''
    def list_of_lists_to_HTML(lists, header_row=None):
        '''Convert a list of a list of strings to a HTML table.'''
        s = '<table>'
        if header_row:
            s += '\n\t<tr>\n\t\t'
            s += ''.join(['<th>%s</th>' % item for item in header_row])
            s += '\n\t</tr>'
        for inner_list in lists:
            s += '\n\t<tr>\n\t\t'
            s += ''.join(['<td>%s</td>' % item for item in inner_list])
            s += '\n\t</tr>'
        s += '\n</table>'
        return s
    
    class LoadedModules(list):
        '''Very simple wrapper for a list of lists of strings, with an attribute
        for display in IPython Notebooks.'''
        def __init__(self, *args, **kwargs):
            list.__init__(self, *args, **kwargs)
            
        @property
        def HTML(self):
            from IPython.display import HTML
            return HTML(
                    list_of_lists_to_HTML(
                            self, header_row=['Name', 'Version', 'Path', 'SHA']))
                    
    objs = LoadedModules()
    for i, mod in enumerate(globals().values()):
        if isinstance(mod, types.ModuleType):
            if hasattr(mod, '__name__'):
                name = mod.__name__
            else:
                name = ''
            
            if from_git_repo(mod):
                path, sha = git_path_sha(mod)
            else:
                path = ''
                sha = ''
            
            version = module_version(mod)
            
            if only_versioned_modules:
                flag = version or (path and sha)
            else:
                flag = True
            
            if flag:
                objs.append([mod.__name__, version, path, sha])
    objs.sort(key=lambda r: r[0])
    return objs
find_loaded_modules().HTML
NameVersionPathSHA
IPython7.5.0
altair3.0.0dev2
fiona1.8.6
geopandas0.5.0
git3.0.0
ipywidgets7.4.2
json2.0.9
numpy1.17.0
shapely1.6.4.post2

Let me check later how this look like on the different machine

@mattijn
Copy link
Owner Author

mattijn commented Aug 15, 2019

Some observations:
geopandas 0.5.0 is important to get the latest naturalearth_lowres Shapefile, which solves the last problem.
And on windows if I do

tj = topojson.Topology(data, prequantize=False, topology=True)
tj.toposimplify(1).topoquantize(1e5).to_alt()

So using prequantize=False the output is correctly simplified.

@mattijn
Copy link
Owner Author

mattijn commented Aug 16, 2019

Without prequantization the widget also works on windows in jupyter-lab, if ipywidgets is correctly build.
See gif:
topojson_widget

Only need to find out why using the prequantize option will result in different behavior on Windows.

@mattijn
Copy link
Owner Author

mattijn commented Aug 19, 2019

See #49. The int behaves platform specific.
Changing all to np.int64 makes all tests pass on windows, including the figure as above:
image

@mattijn mattijn closed this as completed Aug 19, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant