pyproj4 / pyproj

Python interface to PROJ (cartographic projections and coordinate transformations library)
https://pyproj4.github.io/pyproj
MIT License
1.04k stars 210 forks source link

Add JSON serializeability with PROJJSON? #1361

Open hobu opened 9 months ago

hobu commented 9 months ago

CRS objects are not JSON serializable:

import pyproj
import json

crs = pyproj.CRS.from_user_input("EPSG:3857")

json.dumps(crs) #throws exception

I would have expected this to Just Work ™️ by using PROJJSON as the JSON i/o capability. This should work as lossless i/o in all be the rarest/weirdest situations, right @rouault?

rouault commented 9 months ago

This should work as lossless i/o in all be the rarest/weirdest situations, right @rouault?

yes

jjimenezshaw commented 9 months ago

@hobu Can json.dumps(crs) work without passing an encoder in the cls parameter?

meliber commented 9 months ago

The CRS has to_json and to_json_dict methods which can return JSON string or dict which is consistent with PROJJSON.

snowman2 commented 6 months ago

Summary of options I have thought of:

Option 1: Use CRS.to_json https://github.com/pyproj4/pyproj/issues/1361#issuecomment-1830640237

Option 2: Use encoder https://github.com/pyproj4/pyproj/issues/1361#issuecomment-1820732094

import json
from pyproj import CRS

class PROJEncoder(json.JSONEncoder):
    def default(self, obj):
        try:
            return crs.to_json_dict()
        except AttributeError:
            pass 
        return super().default(obj)

crs = CRS.from_user_input("EPSG:3857")
json.dumps(crs, cls=PROJEncoder)

Option 3: Ask Python json library to support a class method like __json__ so encoders are not needed anymore (possibly with a PEP) and then update pyproj to support it....

djhoese commented 6 months ago

The __json__ solution would need to be split into an encode and decode method, right?

snowman2 commented 6 months ago

The __json__ solution would need to be split into an encode and decode method, right?

Possiblity. Only thinking about one-way to encode to JSON at the moment as I don't think some things round-trip easily.

hobu commented 6 months ago

I suppose Option #3 has been asked many times and there's some good reason for not implementing something like it over the years.

Hopefully this ticket generates enough google juice for the next person and points them to use CRS.to_json(). I'm happy to close this if there's no action to be taken on the pyproj side.