2

I am using Openlayers 5 (modules from NPM) and I am having a problem with a scaleline in my map.

// from https://epsg.io/2264.js
proj4.defs('EPSG:2264', '+proj=lcc +lat_1=36.16666666666666 +lat_2=34.33333333333334 +lat_0=33.75 +lon_0=-79 +x_0=609601.2192024384 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=us-ft +no_defs');

register(proj4)

opts = {
  extent: extent,
  center: [
    (extent[0] + extent[2]) / 2,
    (extent[1] + extent[3]) / 2
  ],
  maxResolution: 1777.77777777778,
  minZoom: 2,
  maxZoom: 22,
  zoomFactor: 2,
  zoom: 2.5
}

// ---------------
// I get different results in scaleline depending
// upon which of these projection lines is used

opts.projection = 'EPSG:2264';
//opts.projection = new Projection({code: 'EPSG:2264'});

// -------------

let view = new View(opts);
let map = new Map({
  view: view,
  layers: []
});
map.addControl(new ScaleLine({
    units: 'us'
}));

I get different scaleline results depending upon which projection line above that I comment out.

When the map first appears, using the first projection line above gives a 2 mile scaleline. Using the second one gives a 5 mile scaleline. This is the same length scaleline and map extent but a different distance label on the scaleline. The second seems to be the correct one.

Shouldn't these give the same results?

Am I doing something wrong or should I be filing an issue?

  • The first is correct. If you set an OSM layer in the map it reprojects correctly. new Projection() is used to set up custom projections and requires other options such as a point resolution function. – Mike Feb 5 at 23:16
  • But the first gives me an incorrect scalebar distance label. I guess this is a bug? – Worth Lutz Feb 6 at 13:25
1

It may be a bug, if you check this OpenLayers example https://openlayers.org/en/latest/examples/scaleline-indiana-east.html which opens at 20 miles it's a very long 20 miles on the ground. There seems to be a problem when projection units are in feet, I've checked meter projections and there was no problem.

I've found two solutions

  1. Use your first method, but add a getPointResolution function to the projection returned by proj4 and assume (unlike web mercator) that resolution doesn't vary across the projection:

import {get as getProjection} from 'ol/proj.js';

getProjection('EPSG:2264').setGetPointResolution(function(r) { return r; });

  1. Use your second method, but for it to work in all cases (e.g. reprojection) it needs more options:

opts.projection = new Projection({ code: 'EPSG:2264', units: 'us-ft', getPointResolution: function(r) { return r; } });

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.