-
Notifications
You must be signed in to change notification settings - Fork 548
ENH: Add CRS PROJ JSON support #2212
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
Conversation
e393b1a to
f56ef8d
Compare
|
As always, the code is impeccable! Thank you, @snowman2. We could make this feature more idiomatically "Pythonic" by shoehorning it into the existing CRS.from_dict and CRS.to_dict methods with the help of a |
|
@sgillies, that is a good idea. The current design is to match how it was done with
I am understanding this to mean that we replace
Ideally, I would like to see the PROJ dict replaced by the PROJ JSON dict as the default for the rasterio CRS class as it better represents the CRS and is less lossy. I think making |
Correct. Meaning that in CRS.to_dict we deserialize the PROJ JSON and return a dict and in CRS.from_dict we serialize a dict and pass JSON to GDAL's OSR method. There's a little bit of waste, but unless it's significantly slower, we should accept it. |
|
I made the suggested changes above, however I did keep in
>>> from rasterio.crs import CRS
>>> cc = CRS.from_epsg(4326)
>>> from pprint import pprint
>>> pprint(cc.to_dict(proj_json=True))
{'$schema': 'https://proj.org/schemas/v0.2/projjson.schema.json',
'area': 'World.',
'bbox': {'east_longitude': 180,
'north_latitude': 90,
'south_latitude': -90,
'west_longitude': -180},
'coordinate_system': {'axis': [{'abbreviation': 'Lat',
'direction': 'north',
'name': 'Geodetic latitude',
'unit': 'degree'},
{'abbreviation': 'Lon',
'direction': 'east',
'name': 'Geodetic longitude',
'unit': 'degree'}],
'subtype': 'ellipsoidal'},
'datum_ensemble': {'accuracy': '2.0',
'ellipsoid': {'inverse_flattening': 298.257223563,
'name': 'WGS 84',
'semi_major_axis': 6378137},
'id': {'authority': 'EPSG', 'code': 6326},
'members': [{'id': {'authority': 'EPSG', 'code': 1166},
'name': 'World Geodetic System 1984 '
'(Transit)'},
{'id': {'authority': 'EPSG', 'code': 1152},
'name': 'World Geodetic System 1984 (G730)'},
{'id': {'authority': 'EPSG', 'code': 1153},
'name': 'World Geodetic System 1984 (G873)'},
{'id': {'authority': 'EPSG', 'code': 1154},
'name': 'World Geodetic System 1984 (G1150)'},
{'id': {'authority': 'EPSG', 'code': 1155},
'name': 'World Geodetic System 1984 (G1674)'},
{'id': {'authority': 'EPSG', 'code': 1156},
'name': 'World Geodetic System 1984 (G1762)'}],
'name': 'World Geodetic System 1984 ensemble'},
'id': {'authority': 'EPSG', 'code': 4326},
'name': 'WGS 84',
'scope': 'Horizontal component of 3D system.',
'type': 'GeographicCRS'}
>>> print(cc.to_json(pretty=True))
{
"$schema": "https://proj.org/schemas/v0.2/projjson.schema.json",
"type": "GeographicCRS",
"name": "WGS 84",
"datum_ensemble": {
"name": "World Geodetic System 1984 ensemble",
"members": [
{
"name": "World Geodetic System 1984 (Transit)",
"id": {
"authority": "EPSG",
"code": 1166
}
},
{
"name": "World Geodetic System 1984 (G730)",
"id": {
"authority": "EPSG",
"code": 1152
}
},
{
"name": "World Geodetic System 1984 (G873)",
"id": {
"authority": "EPSG",
"code": 1153
}
},
{
"name": "World Geodetic System 1984 (G1150)",
"id": {
"authority": "EPSG",
"code": 1154
}
},
{
"name": "World Geodetic System 1984 (G1674)",
"id": {
"authority": "EPSG",
"code": 1155
}
},
{
"name": "World Geodetic System 1984 (G1762)",
"id": {
"authority": "EPSG",
"code": 1156
}
}
],
"ellipsoid": {
"name": "WGS 84",
"semi_major_axis": 6378137,
"inverse_flattening": 298.257223563
},
"accuracy": "2.0",
"id": {
"authority": "EPSG",
"code": 6326
}
},
"coordinate_system": {
"subtype": "ellipsoidal",
"axis": [
{
"name": "Geodetic latitude",
"abbreviation": "Lat",
"direction": "north",
"unit": "degree"
},
{
"name": "Geodetic longitude",
"abbreviation": "Lon",
"direction": "east",
"unit": "degree"
}
]
},
"scope": "Horizontal component of 3D system.",
"area": "World.",
"bbox": {
"south_latitude": -90,
"west_longitude": -180,
"north_latitude": 90,
"east_longitude": 180
},
"id": {
"authority": "EPSG",
"code": 4326
}
} |
|
@snowman2 I'm sorry, but I can't get behind a |
|
Sounds good. Does having |
|
I'm giving this another review. Let's do it for 1.3a2. |
| @staticmethod | ||
| def from_dict(initialdata=None, **kwargs): | ||
| """Make a CRS from a PROJ dict | ||
| """Make a CRS from a dict of PROJ parameters or PROJ JSON |
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.
| """Make a CRS from a dict of PROJ parameters or PROJ JSON | |
| """Make a CRS from a PROJ4 or PROJJSON style dict. | |
| PROJJSON text is not accepted. |
| def to_dict(self): | ||
| """Convert CRS to a PROJ4 dict | ||
| def to_dict(self, proj_json=False): | ||
| """Convert CRS to a PROJ dict |
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.
| """Convert CRS to a PROJ dict | |
| """Convert CRS to a PROJ4 or PROJJSON style dict. |
| except CRSError: | ||
| return {} | ||
|
|
||
| def to_json(self, pretty: bool=False, indentation: int=2) -> str: |
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.
Let's remove this method. Python's json module is perfectly adequate and json.dumps(crs.to_dict(proj_json=True)) is easy to write.
| raise CRSError("Undefined CRS has no dict representation") | ||
|
|
||
| if proj_json: | ||
| proj_json = self.to_json() |
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.
| proj_json = self.to_json() | |
| proj_json = self._crs.to_json() |
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.
@snowman2 A couple of changes requested inline. Look forward to having this in 1.3a2!
|
Hi @sgillies, thanks for the review 👍. When do you need this updated by? (If you need changes soon, feel free to make any changes you would like to this PR). |
|
@snowman2 I'd like to do 1.3a2 early next week. I'd be happy to make the changes myself if that doesn't fit your schedule. |
|
I am uncertain whether I would be able to meet that timeline. I think it would be safer for you to finish this off to ensure it is done in time. Thanks @sgillies 👍 |
|
Superseded by #2317. |
|
Thanks @sgillies 👍 |
Closes #2134