Merge pull request #4629 from ahocevar/scaleline

Simplify scaleline calculation
This commit is contained in:
Andreas Hocevar
2016-01-11 10:12:53 +01:00
4 changed files with 56 additions and 60 deletions

View File

@@ -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
---
<div id="map" class="map"></div>

View File

@@ -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'}));

View File

@@ -8,14 +8,10 @@ goog.require('goog.events');
goog.require('goog.style'); goog.require('goog.style');
goog.require('ol'); goog.require('ol');
goog.require('ol.Object'); goog.require('ol.Object');
goog.require('ol.TransformFunction');
goog.require('ol.control.Control'); goog.require('ol.control.Control');
goog.require('ol.css'); goog.require('ol.css');
goog.require('ol.math');
goog.require('ol.proj');
goog.require('ol.proj.METERS_PER_UNIT'); goog.require('ol.proj.METERS_PER_UNIT');
goog.require('ol.proj.Units'); goog.require('ol.proj.Units');
goog.require('ol.sphere.NORMAL');
/** /**
@@ -106,12 +102,6 @@ ol.control.ScaleLine = function(opt_options) {
*/ */
this.renderedHTML_ = ''; this.renderedHTML_ = '';
/**
* @private
* @type {?ol.TransformFunction}
*/
this.toEPSG4326_ = null;
var render = options.render ? options.render : ol.control.ScaleLine.render; var render = options.render ? options.render : ol.control.ScaleLine.render;
goog.base(this, { goog.base(this, {
@@ -203,61 +193,21 @@ ol.control.ScaleLine.prototype.updateElement_ = function() {
var center = viewState.center; var center = viewState.center;
var projection = viewState.projection; var projection = viewState.projection;
var metersPerUnit = projection.getMetersPerUnit();
var pointResolution = var pointResolution =
projection.getPointResolution(viewState.resolution, center); projection.getPointResolution(viewState.resolution, center) *
var projectionUnits = projection.getUnits(); metersPerUnit;
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');
var nominalCount = this.minWidth_ * pointResolution; var nominalCount = this.minWidth_ * pointResolution;
var suffix = ''; var suffix = '';
var units = this.getUnits();
if (units == ol.control.ScaleLineUnits.DEGREES) { 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 suffix = '\u2033'; // seconds
pointResolution *= 3600; pointResolution *= 3600;
} else if (nominalCount < 1) { } else if (nominalCount < metersPerDegree) {
suffix = '\u2032'; // minutes suffix = '\u2032'; // minutes
pointResolution *= 60; pointResolution *= 60;
} else { } else {
@@ -306,7 +256,7 @@ ol.control.ScaleLine.prototype.updateElement_ = function() {
Math.log(this.minWidth_ * pointResolution) / Math.log(10)); Math.log(this.minWidth_ * pointResolution) / Math.log(10));
var count, width; var count, width;
while (true) { 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)); Math.pow(10, Math.floor(i / 3));
width = Math.round(count / pointResolution); width = Math.round(count / pointResolution);
if (isNaN(width)) { if (isNaN(width)) {

View File

@@ -682,7 +682,7 @@ ol.View.createResolutionConstraint_ = function(options) {
var size = !extent ? var size = !extent ?
// use an extent that can fit the whole world if need be // use an extent that can fit the whole world if need be
360 * ol.proj.METERS_PER_UNIT[ol.proj.Units.DEGREES] / 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)); Math.max(ol.extent.getWidth(extent), ol.extent.getHeight(extent));
var defaultMaxResolution = size / ol.DEFAULT_TILE_SIZE / Math.pow( var defaultMaxResolution = size / ol.DEFAULT_TILE_SIZE / Math.pow(