mapnik / node-mapnik

Bindings to mapnik for node.js
http://mapnik.org/documentation/node-mapnik
BSD 3-Clause "New" or "Revised" License
531 stars 165 forks source link

Polar Projection issues - missing countries #997

Closed rayhammond closed 1 month ago

rayhammond commented 3 months ago

I use mapnik (v4.5.8) for plotting flights paths. I am trying to use a projection to show flight's path over the North Pole. The projection I am using is Polar Stereographic (epsg:3995). When mapnik renders the image some countries are missing (Iceand being the most noticeable). The graticule is also cropped. Example image following

image

I have created a gist to assist https://gist.github.com/rayhammond/7590c558fcd7bcf4c1a65200de4746c4

Oddly, if we add each polygon to a seperate layer of their own the they render. But, this is very inefficient and not viable.
Can anyone advise if I am doing anything wrong? Or whether there is an alternates projection that I should be using?

artemp commented 2 months ago

@rayhammond - thanks for reporting and the test case. Could you try using node-mapnik v4.6.0-rc1 and report back here? Latest node-mapnik uses proj-9.4.0 which is a big upgrade from proj4

rayhammond commented 2 months ago

Thanks @artemp we'll try that version and feedback

rayhammond commented 2 months ago

@artemp the link provided returns a 404. I dug a little in the project but I cannot work out how I get my hands on v4.6.0-rc1. Any assistance would be greatly appreciated.

artemp commented 2 months ago

@artemp the link provided returns a 404. I dug a little in the project but I cannot work out how I get my hands on v4.6.0-rc1. Any assistance would be greatly appreciated.

Oops sorry, correct link is https://github.com/mapnik/node-mapnik/pkgs/npm/mapnik

You will also need a github PAT (personal access token) with 'read packages' and ~/.npmrc containing -

//npm.pkg.github.com/:_authToken=<GITHUB-TOKEN>
@mapnik:registry=https://npm.pkg.github.com/

Then npm install @mapnik/mapnik will fetch latest 4.6.0-rc1

In your test case you need change couple things e.g

var mapnik =require("@mapnik/mapnik"); 

and update projection initialisation strings to be compatible with libproj 4.9 (https://proj.org/en/9.4/)

Consult https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-npm-registry

@rayhammond

rayhammond commented 2 months ago

@artemp many thanks for the information. I've manage to get 4.6.0-rc1 installed. And I've changed the code as suggested, The proj init string I am using now is the one cited here 'https://proj.org/en/9.4/operations/projections/stere.html'. I've got an image being produced but now it has no content (just a white image)

artemp commented 2 months ago

@rayhammond I'll take a look, thanks for testing.

artemp commented 2 months ago

OK I see some issues. In libproj >= 6 you need to create ProjTransform object passing from and to Projection objects and use this transform e.g

.....
const p1 = new mapnik.Projection("epsg:4326");
const p2 = new mapnik.Projection("epsg:3995");
const tr = new mapnik.ProjTransform(p1, p2);

const extentOfRouteWgs84 = [
  -60, 30,
  60, 90
];

map.extent = tr.forward(extentOfRouteWgs84);
map.zoomToBox(map.extent);

....

I'm getting following image output (??)

myimage

artemp commented 2 months ago

@rayhammond I see Iceland is missing, so this issue persists in 4.6.0-rc1 and needs fixing. Could you share your graticule.shp (assuming it's a small dataset) ?

rayhammond commented 2 months ago

@artemp I've uploaded the graticule to dropbox link here. It's only 1.5Mb. If you cannot access that link please let me know and I'll supply the file another way.

artemp commented 2 months ago

@rayhammond thanks ^ I can't access dropbox link without sign-in but no worries I found plenty of graticules on https://www.naturalearthdata.com/ This is not a node-mapnik but rather mapnik core issue. Specifically how bounding boxes are calculated when re-projected I think.

artemp commented 2 months ago

@rayhammond https://github.com/mapnik/mapnik/pull/4468

rayhammond commented 2 months ago

@artemp That change looks like it fixes the issue! Many thanks. Do you know when that will be available to use in npm?

artemp commented 2 months ago

@artemp That change looks like it fixes the issue! Many thanks. Do you know when that will be available to use in npm?

@rayhammond This PR needs some more work and testing. Then I'll release mapnik v4.0.1 and node-mapnik v4.6.0-rc2. So hopefully next week 🤞

artemp commented 2 months ago

@rayhammond https://github.com/mapnik/node-mapnik/pkgs/npm/mapnik/251924981 Could you give it a go? (TIP: use epsg:4326 as geographic projection)

rayhammond commented 2 months ago

@artemp I will try tomorrow and feedback. Thanks for message.

rayhammond commented 2 months ago

graticule.zip Good morning @artemp here is the result of running that RC image

The land looks great, but, as you can see the graticule is a little odd. I've zipped and attached our graticule for reference. I believe the graticule is valid as it loads in QGIS without issue.

artemp commented 2 months ago

@rayhammond Could you try replacing

srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs" with src="epsg:4326" for graticule layer. It should fix the issue with missing lines ^^

You can also use srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs +type=crs" <-- note +type=crs

artemp commented 2 months ago

@rayhammond - I also notices your graticule has -179deg and 179deg which result in visible arrtifacts

image

rayhammond commented 2 months ago

@rayhammond Could you try replacing

srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs" with src="epsg:4326" for graticule layer. It should fix the issue with missing lines ^^

You can also use srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs +type=crs" <-- note +type=crs

It does indeed fix the missing line issue

image

rayhammond commented 2 months ago

@rayhammond - I also notices your graticule has -179deg and 179deg which result in visible arrtifacts

image

Never noticed that before and we've used that graticule for years :-)

rayhammond commented 2 months ago

srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs" with src="epsg:4326" for graticule layer. It should fix the issue with missing lines ^^

I have a question on this, I was having a think over the weekend and I must be miss-understanding how this works. I thought the srs we set on the XML for the layer was the format of the data within the layers source file. With your request to change this to epsg:4326, does this means the srs is the format we are projecting too?

artemp commented 1 month ago

@rayhammond

I have a question on this, I was having a think over the weekend and I must be miss-understanding how this works. I thought the srs we set on the XML for the layer was the format of the data within the layers source file.

Yes, Layer.srs is a reference system for the <Layer> data. If not specified it inherits it's value from Map.srs.

With your request to change this to epsg:4326, does this means the srs is the format we are projecting too?

In this case epsg:4326 is SRS of your data (e.g source). epsg:3995 is Map.srs is a destination SRS As I mentioned Mapnik is using proj v9.4.0 which encourages use of ESPG codes to define SRS but you can use full expanded strings just make sure they are compatible with libproj 9.

epsg:4326 == "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs +type=crs"

Internally Mapnik uses libproj APIs to construct proj_transform object -> https://proj.org/en/9.4/development/reference/functions.html#c.proj_create_crs_to_crs HTH

rayhammond commented 1 month ago

@artemp many thanks for fixing this. I am not entirely sure how the eco system works with core mapnik. Does this mean the fix will be available via installing node-mapnik from npm? Or, do we need to wait for something to be published?

artemp commented 1 month ago

@rayhammond - I'm planning to go ahead with GiHub npm package registry for >=v4.6.0.

Use npmjs for node-mapnik <= v4.5.9 e.g.

npm install mapnik@4.5.9

otherwise

npm install @mapnik/mapnik@4.6.0

^ when it will be released

Meanwhile I suggest you use RC2

npm install @mapnik/mapnik@4.6.0-rc2