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

Support any projection #29

Merged
merged 9 commits into from
Apr 14, 2018
Merged

Support any projection #29

merged 9 commits into from
Apr 14, 2018

Conversation

Nakaner
Copy link
Contributor

@Nakaner Nakaner commented Jan 10, 2018

This is work in progress.

This pull request aims to make it possible to render maps in any projection Proj4 supports.

This is work in progress.
@Zverik
Copy link
Owner

Zverik commented Jan 10, 2018

Thanks for working on this!
Please try not to complicate the source code too much :)

@Nakaner
Copy link
Contributor Author

Nakaner commented Jan 10, 2018

@Zverik wrote:

Please try not to complicate the source code too much :)

Test cases are welcome. My personal use of Nik4 is limited to --bbox, --ppi, --zoom and --factor. I have not used everything around paper size, fitting to layers and routes, paddings and margins.

Projection does only project geographical coordinates but ProjTransform
takes also care of datum shifts
@Nakaner
Copy link
Contributor Author

Nakaner commented Jan 15, 2018

--center and --fit-layers works now (including a bug fix)

@Nakaner
Copy link
Contributor Author

Nakaner commented Jan 15, 2018

@Zverik Is it ok to disable the generation of OZI explorer files if the new option --projection <value> is used? If this option is missing, the default (EPSG:3857) is assumed.

@Nakaner Nakaner changed the title [WIP] Support any projection Support any projection Jan 15, 2018
@Zverik
Copy link
Owner

Zverik commented Jan 15, 2018

Yes, I guess so. OziExplorer supports many projections, but converting their names would be non-trivial.

@Nakaner
Copy link
Contributor Author

Nakaner commented Feb 12, 2018

@Zverik I think that this pull request could be merged. Or are there any issues I should fix?

nik4.py Outdated
lbbox = layer.envelope().inverse(p).forward(p3857)
layer_proj = mapnik.Projection(layer.srs)
box_trans = mapnik.ProjTransform(layer_proj, proj_target)
lbbox = box_trans.forward(mapnik.Box2d.from_string('995585 6291591 998380 6293955'))
Copy link
Owner

Choose a reason for hiding this comment

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

What do these numbers mean? You are not using layer.envelope() now, as far as I see.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh yeah, my stupidity. I fixed it.

nik4.py Outdated
@@ -199,6 +209,8 @@ def add_fonts(path):
parser.add_argument('--add-layers', help='Map layers to include, comma-separated')
parser.add_argument('--hide-layers', help='Map layers to hide, comma-separated')

parser.add_argument('-P', '--projection', help='EPSG code as EPSG:1234 or Proj4 string', default='+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs +over')
Copy link
Owner

Choose a reason for hiding this comment

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

This string is used three times in the code — could you make it a constant please?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

nik4.py Outdated
@@ -219,6 +231,9 @@ def add_fonts(path):
bbox = None
rotate = not options.norotate

if options.ozi and options.projection:
raise Exception('ozi map file output is only supported for Web Mercator (EPSG:3857). Please remove --projection.')
Copy link
Owner

Choose a reason for hiding this comment

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

Since options.projection has a default value, it is always set. Maybe do not set default and check for None here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

nik4.py Outdated

# output projection
if options.projection.lower().startswith('epsg:'):
proj_target = mapnik.Projection('+init={}'.format(options.projection.lower()))
Copy link
Owner

Choose a reason for hiding this comment

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

If the code understands epsg numbers, why not initialize projections above with epsg:3857 and epsg:4326?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't understand what you mean. If --projection epsg:1234 was used, I initialise mapnik.Projection with +init=epsg:1234. But if a Proj4 string was specified, I have to initialise mapnik.Projection with the string. It is not possible to just use mapnik.Projection("epsg:4326"). You have to prefix it with +init= but I decided not to force users to always type +init= if they want to use --projection.

Copy link
Owner

Choose a reason for hiding this comment

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

No, I mean first lines in the file, EPSG_4326 and such. Why expand these projections when you can just do +init=epsg:4326?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If I remember correctly, I had an issue with Mapnik some time ago. When I only specified +init=epsg:1234 it failed. But it worked when I used the full Proj4 string.

Copy link
Owner

Choose a reason for hiding this comment

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

Okay, let's leave that as is.

@Zverik
Copy link
Owner

Zverik commented Feb 12, 2018

@Nakaner sorry I didn't review it earlier. There are some issues, I think.

nik4.py Outdated
@@ -219,6 +233,9 @@ def add_fonts(path):
bbox = None
rotate = not options.norotate

if options.ozi and (options.projection.lower() != 'epsg:3857' or options.projection != EPSG_3857):
Copy link
Owner

Choose a reason for hiding this comment

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

I think it should be ... and ... and ...

nik4.py Outdated
@@ -199,6 +211,8 @@ def add_fonts(path):
parser.add_argument('--add-layers', help='Map layers to include, comma-separated')
parser.add_argument('--hide-layers', help='Map layers to hide, comma-separated')

parser.add_argument('-P', '--projection', help='EPSG code as EPSG:1234 or Proj4 string', default=EPSG_3857)
Copy link
Owner

Choose a reason for hiding this comment

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

What do you think of omitting EPSG: for numeric EPSG projections? E.g. using -P 1234 in this case?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't have a strong opinion on that. I used "EPSG:1234" because ogr2ogr uses it. But I am aware that the command line user interface of ogr2ogr is – well – strange. Having "EPSG:" at the beginning makes it easy to decide whether I have to prefix it with +init= before I hand it over to Mapnik, or not.

Copy link
Owner

Choose a reason for hiding this comment

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

To me, it would just look better. Users won't type espg by mistake, like I always do, and you would need to do only .isdigit() instead of .lower().startswith().

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok, fixed

nik4.py Outdated
p3857 = mapnik.Projection('+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs +over')
p4326 = mapnik.Projection('+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs')
transform = mapnik.ProjTransform(p4326, p3857)
proj_target = mapnik.Projection(EPSG_3857)
Copy link
Owner

Choose a reason for hiding this comment

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

proj_target and transform are always set below, so maybe they are not needed here now?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are right. I fixed it.

@Zverik Zverik merged commit 3980c3c into Zverik:master Apr 14, 2018
@Nakaner Nakaner deleted the any-projection branch June 25, 2018 15:56
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.

2 participants