Merge pull request #4629 from ahocevar/scaleline
Simplify scaleline calculation
This commit is contained in:
11
examples/scaleline-indiana-east.html
Normal file
11
examples/scaleline-indiana-east.html
Normal 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>
|
||||||
35
examples/scaleline-indiana-east.js
Normal file
35
examples/scaleline-indiana-east.js
Normal 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'}));
|
||||||
@@ -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)) {
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
Reference in New Issue
Block a user