-
-
Notifications
You must be signed in to change notification settings - Fork 372
g.proj: use PROJJSON as json output format #6614
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
base: main
Are you sure you want to change the base?
Conversation
|
Very nice to see a standards-based approach improving inter compatibility |
nilason
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great improvement!
|
I think after merging #6579, it would be a good idea to merge main into this PR and check one last time, since it also plays into the tests of the same subject. |
petrasovaa
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great! We were originally thinking this would be separate format though, to keep it consistent with the rest of the JSON implementations in other tools. So I would argue we should add option format=projjson, especially since that is the official name of that format. If the version doesn't allow to print it, it would stop with some helpful error message. Currently with this PR the format=json gives you completely different schema depending on you proj version, which doesn't seem right.
PROJJSON has been available since PROJ 6, as well as WKT2. That means your test Considering that 1) all currently maintained linux distros have at least PROJ 6 and 2) the minimum required PROJ version for GRASS 8.5 is likely to be bumped to PROJ 8 there is practically no chance that an unexpected output is generated by |
|
json output has been added to |
|
For above reasons, I would argue to replace the The reason is that WKT2 (PROJJSON is the json version of WKT) is now the preferred format for CRS definitions (works also correctly in the absence of authority name and code) and the traditional GRASS format for CRS definitons should be retired because superseded by PROJ 6+ CRS definition and coordinate transformation management. |
|
In that case I would keep only "projjson" option, since that is the name of the format. The documentation then needs to be updated. In case of XY projects, it prints: which is technically not projjson format. |
OK
In this case nothing should be printed, conforming to |
Behavior with no CRS aka XYThere are multiple ways how to handle no projection or print "nothing". JSON null literalJSON has a null value. A >>> import json
>>> json.loads("null")
>>> json.loads("null") is None
TrueOther empty valuesThere are other "empty" values which translate to >>> json.loads("{}")
{}
>>> json.loads('""')
''
>>> bool(json.loads("{}"))
False
>>> bool(json.loads('""'))
FalseNo text outputAn empty string is not a valid JSON. An attempt to load an empty string ends with a traceback. When calling json.loads, you need to know if the input is valid JSON or get ready for tracebacks. >>> json.loads("")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.10/json/__init__.py", line 346, in loads
return _default_decoder.decode(s)
File "/usr/lib/python3.10/json/decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python3.10/json/decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)So, literally printing nothing would either end with traceback in case case of XY or it would require users to put additional checking code to figure out the if it is XY or not. Current behavior with the custom JSONWith EPSG, this works as expected: export PYTHONPATH="$(grass --config python-path)"
pythongs.create_project("/tmp/project_epsg", crs="EPSG:3358")
gs.setup.init("/tmp/project_epsg")
print(tools.g_proj(flags="p", format="json").text){
"name": "NAD83(HARN) \/ North Carolina",
"datum": "nad83harn",
"ellps": "grs80",
"proj": "lcc",
"lat_0": "33.75",
"lon_0": "-79",
"lat_1": "36.1666666666667",
"lat_2": "34.3333333333333",
"x_0": "609601.22",
"y_0": "0",
"no_defs": "defined",
"srid": "EPSG:3358",
"unit": "meter",
"units": "meters",
"meters": "1"
}With XY project: gs.create_project("/tmp/project_xy")
gs.setup.init("/tmp/project_xy")
print(tools.g_proj(flags="p", format="json").text){
"name": "xy_location_unprojected"
}I'm not excited about the output, but it is a valid JSON. The check for XY vs others is possible and explicit, although not ideal: >>> tools.g_proj(flags="p", format="json")["name"] == "xy_location_unprojected"
TrueSpecial xy_location_unprojected value as a nameThe reason for the >>> tools.g_proj(flags="g").keyval["name"] == "xy_location_unprojected"
True
>>> tools.g_proj(flags="p", format="shell").keyval["name"] == "xy_location_unprojected"
TrueFinal considerations
|
|
Considering that PROJJSON is supposed to be compatible with WKT, PROJJSON and WKT output for a XY GRASS project, no CRS set, should be similar. For WKT it is the POJJSON equivalent would be This gives valid (PROJ)JSON output, equivalent to WKT output and the information that a CRS is not defined for the given input to |
JSON output has been added to
g.projwith PR 5419 . However, this converts GRASS native projection information to JSON which is not supported outside GRASS and even in GRASS, becoming rather useless with the changes introduced since PROJ 6.PROJJSON is a standard representation for coordinate reference systems (CRS) in JSON format, used in various geospatial applications, including GeoParquet for storing CRS information.
The Schema for the PROJJSON format is defined at: https://proj.org/en/latest/schemas/v0.7/projjson.schema.json
From https://proj.org/en/stable/specifications/projjson.html
This PR replaces the JSON output of
g.projwith the PROJJSON standard.