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

Converting a quantized topojson string to geojson fails to dequantize the coordinates #124

Closed
karimbahgat opened this issue Jul 20, 2021 · 1 comment · Fixed by #128
Closed

Comments

@karimbahgat
Copy link

First, thanks a lot for your work on this library, I love how lightweight and easy to use it is!

I believe I have encountered an issue however. It appears to be me that much of the library and docs is geared towards converting geojson to topojson, e.g. Topology(geojsondata). However, my use-case is more the other way, if I have data stored as a topojson string and want to convert it to geojson. After some digging, I ended up using the utils.geometry function, which works great for non-quantized topojsons.

def geometry(obj, tp_arcs, transform=None):

My issue however is when using utils.geometry for topojsons with quantized coordinates, the output geojson remains in quantized form even though I supplied the transform arg. I looked into the source code and it appears that while the dequantize function is applied for Point and MultiPoint types, it is not applied for the geometry types in the else-statement as well as the GeometryCollection case. I could perhaps submit a PR for this, but wanted to just confirm that I've understood it right?

As an aside, I think it would be useful if the use case of topojson-to-geojson was specifically listed in the docs (or the functionality made more prominent, e.g. by loading a Topology object from a topojson string directly), as I think this would be a pretty common use-case.

@mattijn
Copy link
Owner

mattijn commented Jul 20, 2021

Thanks for your words. You are right that it is currently geared towards geographical data to topojson. Better support for the other direction would be much welcome indeed.

There is already some within the code that makes this possible, but this could probably much improved. PR's definitely welcome!

Two possibilities:
First, if you parse a string into Topology(), where the string contains "type": "Topology" it is tried to serialise as geojson, and then convert to topojson again:

https://github.com/mattijn/topojson/blob/master/topojson/core/extract.py#L585

I can imagine that that is cumbersome. Based on some tests I also get strange outputs.

Second, there is another route. Parse your topojson as a dict and then use the serialise_as_geojson function:

import topojson as tp
from topojson.utils import serialize_as_geojson
import geopandas as gpd

# create a topojson dictionary
data = tp.utils.example_data_africa()
topo = tp.Topology(data)
topojson_dict = topo.to_dict()

?topojson_dict
Type:        dict
String form: {'type': 'Topology', 'objects': {'data': {'geometries': [{'id': '1', 'type': 'Polygon', 'properti <...> [750884, 541353], [-8944, -6372], [-10232, 32], [-11708, -3243], [-9248, 3099], [-5987, -3779]]]}
Length:      5
Docstring:  
dict() -> new empty dictionary
dict(mapping) -> new dictionary initialized from a mapping object's
    (key, value) pairs
dict(iterable) -> new dictionary initialized as if via:
    d = {}
    for k, v in iterable:
        d[k] = v
dict(**kwargs) -> new dictionary initialized with the name=value pairs
    in the keyword argument list.  For example:  dict(one=1, two=2)
# objectname is specific in each topojson file
geojson_dict = serialize_as_geojson(topojson_dict, objectname='data') 

# check if it is correct geojson
gdf = gpd.GeoDataFrame.from_features(geojson_dict["features"])
gdf.plot()
image

Btw, the dequantization on arcs happens here:

https://github.com/mattijn/topojson/blob/master/topojson/utils.py#L445

The reason why there is a dequantization of multi(points) in the geometry function is because there is only a top-level storage of arcs in the topojson specification and strangely not for the (multi)point.

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

Successfully merging a pull request may close this issue.

2 participants