Using Log Math to Solve Iterative Problems
Premise: You have a map of infinite resolution, but finite viewing space. You have points on that map that have a fixed foot print.
Question: How much do you need to zoom before the points are clearly distinguishable?
Let us arbitrarily define the criteria for distinguishability as an icon of 25 pixels in size. This icon, it can be said, has a radius of 13 pixels. In reality, icon size is a function of your viewport’s size. I leave that up to you to calculate.
Let us define the scale of the map as the absolute width of the map (in map units) divided by the width of the view port. As an example, let’s use the Earth’s longitude range: -180 to +180 degrees, but in a global Mercator projection. The coordinate range of longitude for this map is [-20037508,+20037508) meters. Our viewport has a range of [0,255] pixels (viewport units). The scale of this map in this viewport is (2*20037508)/256. Be careful not to double-count +20037508, as -20037508 = +20037508 and would yield an improper scale. The viewport size is an integer and does not wrap; there are no fractions of a pixel in a viewport.
We shall now define a target scale. The target scale is the desired scale of the map that allows our icons to become viewable. Our example will use buildings having a foot print of 300 meters (map units) in width and depth. Our target scale, therefore, is 300/25 = 12 meters per pixel.
Question: How much do we need to zoom in before our buildings are distinguishable?
Implementation 1 (naive, iterative):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | function zoomLevel( $maprange, $viewport, $distFactor=0.10, $zoomFactor=2 ) { // $viewport = 256; // $maprange = 2*M_PI*6378137; $scale = $maprange / $viewport; // 10% of viewport required to distinguish an icon. $target = $distFactor * $viewport; $zoom = 0; while ( $scale > $target ) { $zoom += 1; $scale /= $zoomFactor; } return $zoom; } |
Implementations 2, 3 and 4:
1 2 3 4 5 6 7 8 9 10 11 12 13 | function zoomLevel( $maprange, $viewport, $distFactor=0.10, $zoomFactor=2 ) { $scale = $maprange / $viewport; $target = $distFactor * $viewport; // naive log return ceil( (log($scale)/log($zoomFactor) - log($target)/log($zoomFactor)) ); // commutative log return ceil( (log($scale) - log($target)) / log($zoomFactor) ); // subtraction property of logs (best implementation) return ceil( log($scale/$target)/log($zoomFactor) ); } |
Tags: conversion, earth, log, maps, math, mercator, php, projection, viewport, zoom
-
Related Posts
- Set crontab to sync via NTP
- PHP 5.3.1 Error Logging and Display of Said Errors
- PHP 5.1+ Date vs Strftime Timezone Annoyance
- Installing a DLNA-compliant media server for use with Samsung LN46B650 TV
- Mapping Projections with proj4
- Change hostname in RHEL5
- The little known PHP htmlspecialchars
- Compiling Datascope.so for PHP
- Calculation of RSI
- Git: Recovering a file that you deleted
tail -7 brain.log
- Git: Recovering a file that you deleted
- PHP 5.1+ Date vs Strftime Timezone Annoyance
- The little known PHP htmlspecialchars
- PHP 5.3.1 Error Logging and Display of Said Errors
- OpenVPN behind US Government Proxy
- On the Millennials and Having Children
- Think and Grow Rich: Don't read it, imagine what it would say.
Commonly Keyed
antelope aspire awk bash beethovan bug cache command line compile configure creativity datascope desire dl dns exploring flush git goals hwclock install java JDK lesson linux mercator mysql Napoleon Hill php proj4 questions redirect reflect RHEL5 sbin sccoos stocks success sysadmin sysconfig Think and Grow Rich thinking timezone wkt writingFiled Under
- Gotchas (1)
- Lessons (7)
- Quotes (8)
- Reference (14)
- Scripts, Tricks and Hacks (6)
- Socratic deductions (1)
- Synopses (5)
- System Administration (9)
- Thought Fragments (4)