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

fix a bug on determining srid when upload a vector layer #437

Conversation

boney-bun
Copy link

fix #289
fix #435

@boney-bun
Copy link
Author

boney-bun commented Jun 21, 2018

This PR is addressing what i believe as a bug at uploading a vector layer.
The problem lies at determining the layer's srid.
It returned EPSG:None.
In the case of Africa Volcano layer, the SRS is:

GEOGCS["GCS_WGS_1984",
    DATUM["WGS_1984",
        SPHEROID["WGS_84",6378137,298.257223563]],
    PRIMEM["Greenwich",0],
    UNIT["Degree",0.017453292519943295]]

However, the geonode doesn't recognize this.
The vector layer doesn't use gdal and osr functions to determine the SRS as in raster layer.
So, we expect the SRS to be 4326.
But, the code failed to do so.
So, this PR is basically make sure that if the layer's SRS can't be determined, then it should be set to 4326.

@gubuntu I understand that we should go with 3857 as the default. But, 4326 is what the upstream do.
[Gavin: No @boney-bun we should not go with 3857, you are confusing the data CRS with the web map client request CRS. The data can be stored in any CRS whereas web requests from Leaflet are always in 3857 -- QGIS will project on the fly]

the PR in action:
geonode 437

The first Africa Volcano illustrates the original behaviour when uploading a vector layer (no thumbnail and can't see the layer detail).
The second one denotes another bug on upstream (can't see the layer detail).
The last illustration indicates the PR in action (no errors).

@codecov
Copy link

codecov bot commented Jun 21, 2018

Codecov Report

Merging #437 into 2.8.x-qgis_server will not change coverage.
The diff coverage is 100%.

Impacted file tree graph

@@                Coverage Diff                 @@
##           2.8.x-qgis_server     #437   +/-   ##
==================================================
  Coverage              41.04%   41.04%           
==================================================
  Files                    403      403           
  Lines                  28706    28706           
  Branches                3648     3648           
==================================================
  Hits                   11782    11782           
  Misses                 16202    16202           
  Partials                 722      722
Impacted Files Coverage Δ
geonode/layers/utils.py 56.29% <100%> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 0ea02f2...df3faf2. Read the comment docs.

Copy link

@myarjunar myarjunar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍 thanks!

@@ -375,7 +377,8 @@ def get_bbox(filename):
bbox_y0 = min(ext[0][1], ext[2][1])
bbox_x1 = max(ext[0][0], ext[2][0])
bbox_y1 = max(ext[0][1], ext[2][1])
srid = srs.GetAuthorityCode(None) if srs else 'EPSG:4326'
# eliminate default EPSG srid as it will be added when this function returned
srid = srs.GetAuthorityCode(None) if srs else '4326'

return [bbox_x0, bbox_x1, bbox_y0, bbox_y1, "EPSG:%s" % str(srid)]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

even an expert geonode developer can miss this 😂

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should have been tested by unittest. If not, then we should add.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also we need to submit PR to upstream GeoNode for issues like this.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@boney-bun cc @lucernae we should be doing all GeoNode PRs directly upstream.

Also why is this merged when we decided to not assume 4326 if no projection defined?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gubuntu i merged this PR so others can start working on upload (including me) in the testing.
the new PR for checking the range within 4326 is in #442.
could you kindly verify it?
once satisfied, i'm going to make PR to upstream.

@NyakudyaA
Copy link

@boney-bun cc @myarjunar I think it is wrong to say if layer's SRS can't be determined, then it should be set to 4326.
This would result in problems later because the layer will render in a different place on the globe. I think what you should rather be doing is let the upload fail with an error message when the SRS cannot be determined.

NB: Not all projections are entered in the EPSG database but the important thing is the projection string

cape.zip
I have attached a sample dataset which is in South African local Transverse Mercator - This projection is not added in the EPSG database so you won't find the EPSG code for that but the proj string is still valid.

@myarjunar
Copy link

@NyakudyaA I reckon what @boney-bun did here is only to fix programming error that causes the method returned EPSG:None with the original logic is still following what upstream already did.

@boney-bun
Copy link
Author

thanks @myarjunar you've got my point.

@NyakudyaA @gubuntu this is where i need an opinion from a GIS expert :)

technically speaking, the original code:
srid = layer.srs.srid if layer.srs else '4326'
is basically checking if layer.srs is empty.
in the case of Africa Volcano layer, layer.srs is not empty.
but when executing layer.srs.srid, it returned None.
geonode doesn't recognize the projection info from the vector layer.
in fact, layer.srs returned the following information:
(cmiiw, I expect the layer.srs.srid return something like: EPSG:4326 because the below info is equal to WGS84)

GEOGCS["GCS_WGS_1984",
    DATUM["WGS_1984",
        SPHEROID["WGS_84",6378137,298.257223563]],
    PRIMEM["Greenwich",0],
    UNIT["Degree",0.017453292519943295]]

so to accomodate @NyakudyaA comment, our options are:

  • teach geonode to recognize the above info from the vector layer, or
  • use gdal and osr as in raster layer.
  • leave it as it's from the upstream

we may need to make a PR to the upstream.

which one do you prefer @NyakudyaA @gubuntu ?

@NyakudyaA
Copy link

@boney-bun I think the best way you could do is do a PR against upstream with your changes.
I think you might need to consider the following:

  • How does the EPSG: Code gets used in the front end to render the layer.
  • Instead of using the EPSG: Code can you use layer.srs.proj4. This should cover all cases where the EPSG code is not defined in the projection file.
  • I know when using gdal to project layers to different formats you can use either the EPSG code or the proj4 string and still the results will generate the layer in the same position.

@codecov-io
Copy link

codecov-io commented Jun 23, 2018

Codecov Report

Merging #437 into 2.8.x-qgis_server will increase coverage by 0.01%.
The diff coverage is 81.81%.

Impacted file tree graph

@@                  Coverage Diff                  @@
##           2.8.x-qgis_server     #437      +/-   ##
=====================================================
+ Coverage              41.04%   41.05%   +0.01%     
=====================================================
  Files                    403      403              
  Lines                  28706    28715       +9     
  Branches                3648     3648              
=====================================================
+ Hits                   11782    11789       +7     
- Misses                 16202    16204       +2     
  Partials                 722      722
Impacted Files Coverage Δ
geonode/layers/utils.py 56.66% <81.81%> (+0.36%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 0ea02f2...45e0ec4. Read the comment docs.

@boney-bun
Copy link
Author

Hi @NyakudyaA

I've changed the code a bit.
It seems that gdal's DataSource is unreliable to determine the epsg code (the function reads the shapefile).
So, I change to reading a prj file and it can now detect the epsg code properly.
This PR seems to partially solve #395 too as illustrated below:
uploadlayer-1

For 4326 it can also be uploaded successfully:
uploadlayer-2

@NyakudyaA @gubuntu please review the code from the GIS perspective. then, i could make a pr to the upstream.

Copy link

@NyakudyaA NyakudyaA left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When EPSG: code is not found it should not be assumed to be 4326. Let's rather default to using the proj4 text to define the projection. See how the EPSG:Code is being used by the front end.

Copy link

@lucernae lucernae left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. On a side note, does the previous code works with GeoNode dataset? Because it's hard to imagine that this passed their unittest.

@@ -375,7 +377,8 @@ def get_bbox(filename):
bbox_y0 = min(ext[0][1], ext[2][1])
bbox_x1 = max(ext[0][0], ext[2][0])
bbox_y1 = max(ext[0][1], ext[2][1])
srid = srs.GetAuthorityCode(None) if srs else 'EPSG:4326'
# eliminate default EPSG srid as it will be added when this function returned
srid = srs.GetAuthorityCode(None) if srs else '4326'

return [bbox_x0, bbox_x1, bbox_y0, bbox_y1, "EPSG:%s" % str(srid)]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should have been tested by unittest. If not, then we should add.

@@ -375,7 +377,8 @@ def get_bbox(filename):
bbox_y0 = min(ext[0][1], ext[2][1])
bbox_x1 = max(ext[0][0], ext[2][0])
bbox_y1 = max(ext[0][1], ext[2][1])
srid = srs.GetAuthorityCode(None) if srs else 'EPSG:4326'
# eliminate default EPSG srid as it will be added when this function returned
srid = srs.GetAuthorityCode(None) if srs else '4326'

return [bbox_x0, bbox_x1, bbox_y0, bbox_y1, "EPSG:%s" % str(srid)]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also we need to submit PR to upstream GeoNode for issues like this.

@boney-bun
Copy link
Author

thanks for the review @NyakudyaA @myarjunar @lucernae
it has passed the travis so I'm going to merge them.

@boney-bun boney-bun merged commit 30828ab into kartoza:2.8.x-qgis_server Jun 30, 2018
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 this pull request may close these issues.

6 participants