diff --git a/examples/scaleline-indiana-east.html b/examples/scaleline-indiana-east.html new file mode 100644 index 0000000000..250efbd3a9 --- /dev/null +++ b/examples/scaleline-indiana-east.html @@ -0,0 +1,11 @@ +--- +layout: example.html +title: OpenStreetMap Reprojection with ScaleLine Control +shortdesc: Demonstrates client-side reprojection of OpenStreetMap to NAD83 Indiana East. +docs: > + This example shows client-side reprojection of OpenStreetMap to NAD83 Indiana East, including a ScaleLine control with US units. +tags: "reprojection, projection, openstreetmap, nad83, tile, scaleline" +resources: + - http://cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.6/proj4.js +--- +
diff --git a/examples/scaleline-indiana-east.js b/examples/scaleline-indiana-east.js new file mode 100644 index 0000000000..eb5449e390 --- /dev/null +++ b/examples/scaleline-indiana-east.js @@ -0,0 +1,35 @@ +goog.require('ol.Map'); +goog.require('ol.View'); +goog.require('ol.control.ScaleLine'); +goog.require('ol.layer.Tile'); +goog.require('ol.proj'); +goog.require('ol.source.OSM'); + +proj4.defs('Indiana-East', 'PROJCS["IN83-EF",GEOGCS["LL83",DATUM["NAD83",' + + 'SPHEROID["GRS1980",6378137.000,298.25722210]],PRIMEM["Greenwich",0],' + + 'UNIT["Degree",0.017453292519943295]],PROJECTION["Transverse_Mercator"],' + + 'PARAMETER["false_easting",328083.333],' + + 'PARAMETER["false_northing",820208.333],' + + 'PARAMETER["scale_factor",0.999966666667],' + + 'PARAMETER["central_meridian",-85.66666666666670],' + + 'PARAMETER["latitude_of_origin",37.50000000000000],' + + 'UNIT["Foot_US",0.30480060960122]]'); + +var map = new ol.Map({ + layers: [ + new ol.layer.Tile({ + source: new ol.source.OSM() + }) + ], + target: 'map', + view: new ol.View({ + projection: 'Indiana-East', + center: ol.proj.fromLonLat([-85.685, 39.891], 'Indiana-East'), + zoom: 7, + extent: ol.proj.transformExtent([-172.54, 23.81, -47.74, 86.46], + 'EPSG:4326', 'Indiana-East'), + minZoom: 6 + }) +}); + +map.addControl(new ol.control.ScaleLine({units: 'us'})); diff --git a/src/ol/control/scalelinecontrol.js b/src/ol/control/scalelinecontrol.js index c5880528c3..fdb61c2227 100644 --- a/src/ol/control/scalelinecontrol.js +++ b/src/ol/control/scalelinecontrol.js @@ -8,14 +8,10 @@ goog.require('goog.events'); goog.require('goog.style'); goog.require('ol'); goog.require('ol.Object'); -goog.require('ol.TransformFunction'); goog.require('ol.control.Control'); goog.require('ol.css'); -goog.require('ol.math'); -goog.require('ol.proj'); goog.require('ol.proj.METERS_PER_UNIT'); goog.require('ol.proj.Units'); -goog.require('ol.sphere.NORMAL'); /** @@ -106,12 +102,6 @@ ol.control.ScaleLine = function(opt_options) { */ this.renderedHTML_ = ''; - /** - * @private - * @type {?ol.TransformFunction} - */ - this.toEPSG4326_ = null; - var render = options.render ? options.render : ol.control.ScaleLine.render; goog.base(this, { @@ -203,61 +193,21 @@ ol.control.ScaleLine.prototype.updateElement_ = function() { var center = viewState.center; var projection = viewState.projection; + var metersPerUnit = projection.getMetersPerUnit(); var pointResolution = - projection.getPointResolution(viewState.resolution, center); - var projectionUnits = projection.getUnits(); - - var cosLatitude; - var units = this.getUnits(); - if (projectionUnits == ol.proj.Units.DEGREES && - (units == ol.control.ScaleLineUnits.METRIC || - units == ol.control.ScaleLineUnits.IMPERIAL || - units == ol.control.ScaleLineUnits.US || - units == ol.control.ScaleLineUnits.NAUTICAL)) { - - // Convert pointResolution from degrees to meters - this.toEPSG4326_ = null; - cosLatitude = Math.cos(ol.math.toRadians(center[1])); - pointResolution *= Math.PI * cosLatitude * ol.sphere.NORMAL.radius / 180; - projectionUnits = ol.proj.Units.METERS; - - } else if (projectionUnits != ol.proj.Units.DEGREES && - units == ol.control.ScaleLineUnits.DEGREES) { - - // Convert pointResolution from other units to degrees - if (!this.toEPSG4326_) { - this.toEPSG4326_ = ol.proj.getTransformFromProjections( - projection, ol.proj.get('EPSG:4326')); - } - cosLatitude = Math.cos(ol.math.toRadians(this.toEPSG4326_(center)[1])); - var radius = ol.sphere.NORMAL.radius; - goog.asserts.assert(ol.proj.METERS_PER_UNIT[projectionUnits], - 'Meters per unit should be defined for the projection unit'); - radius /= ol.proj.METERS_PER_UNIT[projectionUnits]; - pointResolution *= 180 / (Math.PI * cosLatitude * radius); - projectionUnits = ol.proj.Units.DEGREES; - - } else { - this.toEPSG4326_ = null; - } - - goog.asserts.assert( - ((units == ol.control.ScaleLineUnits.METRIC || - units == ol.control.ScaleLineUnits.IMPERIAL || - units == ol.control.ScaleLineUnits.US || - units == ol.control.ScaleLineUnits.NAUTICAL) && - projectionUnits == ol.proj.Units.METERS) || - (units == ol.control.ScaleLineUnits.DEGREES && - projectionUnits == ol.proj.Units.DEGREES), - 'Scale line units and projection units should match'); + projection.getPointResolution(viewState.resolution, center) * + metersPerUnit; var nominalCount = this.minWidth_ * pointResolution; var suffix = ''; + var units = this.getUnits(); if (units == ol.control.ScaleLineUnits.DEGREES) { - if (nominalCount < 1 / 60) { + var metersPerDegree = ol.proj.METERS_PER_UNIT[ol.proj.Units.DEGREES]; + pointResolution /= metersPerDegree; + if (nominalCount < metersPerDegree / 60) { suffix = '\u2033'; // seconds pointResolution *= 3600; - } else if (nominalCount < 1) { + } else if (nominalCount < metersPerDegree) { suffix = '\u2032'; // minutes pointResolution *= 60; } else { @@ -306,7 +256,7 @@ ol.control.ScaleLine.prototype.updateElement_ = function() { Math.log(this.minWidth_ * pointResolution) / Math.log(10)); var count, width; while (true) { - count = ol.control.ScaleLine.LEADING_DIGITS[i % 3] * + count = ol.control.ScaleLine.LEADING_DIGITS[((i % 3) + 3) % 3] * Math.pow(10, Math.floor(i / 3)); width = Math.round(count / pointResolution); if (isNaN(width)) { diff --git a/src/ol/view.js b/src/ol/view.js index 473da2d4e2..6aebea294f 100644 --- a/src/ol/view.js +++ b/src/ol/view.js @@ -682,7 +682,7 @@ ol.View.createResolutionConstraint_ = function(options) { var size = !extent ? // use an extent that can fit the whole world if need be 360 * ol.proj.METERS_PER_UNIT[ol.proj.Units.DEGREES] / - ol.proj.METERS_PER_UNIT[projection.getUnits()] : + projection.getMetersPerUnit() : Math.max(ol.extent.getWidth(extent), ol.extent.getHeight(extent)); var defaultMaxResolution = size / ol.DEFAULT_TILE_SIZE / Math.pow(