Understanding map projections and bounding boxes

1,138 views
Skip to first unread message

Yang Zhang

unread,
Oct 14, 2011, 10:04:18 PM10/14/11
to d3...@googlegroups.com
I'm plotting a US map using the default d3.geo.path. I'd like to
center and scale this within an outer rectangular box. In order to do
so, I have to understand what projection is taking place - what the
pixels are that are matching up.

I've been trying to use d3.geo.bounds() by calculating the bounds for
each state and then finding the extrema of these bounds, but this
returns latitudes and longitudes, which I can't seem to decipher in
terms of pixels. I thought maybe .pointRadius() would help, but that
returns me a function. I also tried invoking path() on e.g. { "type":
"Point", "coordinates": [gbounds.left, gbounds.bottom] }, but this
gives me some strange path results.

I've also tried just plotting the map first and then using
jQuery.width/.height to find the dimensions of each polygon, but for
some reason Alaska has a ginormous bounding box (which the default
projection - AlbersUSA? - doesn't even try to include in the visible
projected area).

For now I'm just eyeballing the dimensions of the drawn map at scale 1
and using these hardcoded values in my code, but I'm wondering if
there's a Better Way.

Thanks in advance.

--
Yang Zhang
http://yz.mit.edu/

Yang Zhang

unread,
Oct 14, 2011, 10:13:35 PM10/14/11
to d3...@googlegroups.com
BTW, for posterity, the map draws out to be about 500px high and 880px
wide, but with about 10-20px of empty space on top (and around -300px
of space on the left, all due to Alaska).

Mike Bostock

unread,
Oct 18, 2011, 7:32:49 AM10/18/11
to d3...@googlegroups.com
The origin of the projection will be at the projection's translate
position. For example, with d3.geo.albers (which is a good choice for
showing the U.S. map), the origin is [-98, 38] in longitude, latitude.
The translate is [480, 250] because it is designed to fit in a 960x500
area by default. If you want a bigger or smaller map, you can change
the scale and translate accordingly. If you want to center on a
different part of the U.S., change the origin.

Also, use the albers, azimuthal, mercator, etc. examples in the git
repository to play with the parameters interactively.

Mike

wimdows

unread,
Oct 19, 2011, 3:00:53 AM10/19/11
to d3-js
And how does one prevent a map from being scrolled or zoomed
completely out of view?
(This is annoying, becuase it leads to the map being lost all
together.)
I have looked for an example of a map with a restricted view, but I
couldn´t find one.

wim

Bixente

unread,
Oct 19, 2011, 5:36:06 PM10/19/11
to d3-js
I agree with wim. If someone had an example with restricted pan/zoom,
that would be very helpful.

Bixente

Mike Bostock

unread,
Oct 19, 2011, 10:19:44 PM10/19/11
to d3...@googlegroups.com
> I agree with wim. If someone had an example with restricted pan/zoom,
> that would be very helpful.

I agree. We've been discussing it:

https://github.com/mbostock/d3/issues/341

Probably there will be a change to the d3.behavior.zoom that is not
strictly-backwards compatible, and which will provide more flexibility
in terms of restricting the viewable range and manually adjusting the
viewport.

Mike

Stephen Bannasch

unread,
Oct 19, 2011, 10:32:16 PM10/19/11
to d3...@googlegroups.com
To get better performance graphing the Avalanche model I have been working on I created a canvas overlay object to plot into
the same size as the plotting area for the D3.js graph.

When plotting real-time data I move this canvas object above the SVG content and plot lines there until the data-collection
stops. When stopped I move the canvas object behind the D3 SVG graph and draw the completed data set once with D3.

real-time graphing now uses a canvas overlay
https://github.com/stepheneb/avalanche2d-js/commit/2f8ed4b52cba

I am using the D3 scales to generate the points to plot into the Canvas object:

https://github.com/stepheneb/avalanche2d-js/blob/master/src/grapher.js#L150

This is still a rough first hack ... but I think it works well for my purposes.

Compared to plotting 5000 points into SVG using D3 this is now between 5 and 15x faster.

Latest benchmarks:

browser model steps/s for 5000 model steps
--------------------------------------------------------------
Chrome 14.0.835.186 1400
Safari 5.1.1 (6534.51.22) 383
FireFox 7.0.1 191 **

I think this now represents well the performance capabilities of modern browsers.

To get higher performance would require re-coding the model and visualization to run on the GPU using webgl -- that's much
harder.

** There is a Canvas bug in FireFox I am looking for a work-around for

Executing the canvas stroke() command to render the line onto the canvas drawing surface causes the canvas drawing to
disappear.

gctx.stroke();

https://github.com/stepheneb/avalanche2d-js/blob/master/src/grapher.js#L159

The canvas itself is still layered above the SVG elements as show by the presence of the red border.

Stephen Bannasch

unread,
Oct 19, 2011, 11:01:34 PM10/19/11
to d3...@googlegroups.com
At 10:32 PM -0400 10/19/11, Stephen Bannasch wrote:
>To get better performance graphing the Avalanche model I have been working on I created a canvas overlay object to plot into the same size as the plotting area for the D3.js graph.
>
>When plotting real-time data I move this canvas object above the SVG content and plot lines there until the data-collection stops. When stopped I move the canvas object behind the D3 SVG graph and draw the completed data set once with D3.

And the app itself is here: http://stepheneb.github.com/avalanche2d-js/avalanche2d.html

Jon Frost

unread,
Oct 20, 2011, 8:34:14 AM10/20/11
to d3...@googlegroups.com
Thanks for sharing.
This week I am attending the Svg Open conference w/ Mike B. and other
bright guys and gals, and from the presentations and conversations
over the last few days it is apparent that a number of projects would
benefit from tools and libraries that integrate svg and canvas.

There is discussion about integrating canvas a little better into the
svg language, but there is talk about all sorts of things, and it
would be a ways off yet before browsers support the ideas and syntax
that were recently proposed, so keep up the good work.

Jon

Jason Davies

unread,
Oct 20, 2011, 8:35:56 AM10/20/11
to d3...@googlegroups.com

A potential extents implementation for d3.behavior.zoom:

https://github.com/mbostock/d3/pull/345

I imagine we can make it more flexible, but hopefully that'll get things
started.

--
Jason Davies, http://www.jasondavies.com/

Stephen Bannasch

unread,
Oct 23, 2011, 2:34:09 AM10/23/11
to d3...@googlegroups.com
At 7:34 AM -0500 10/20/11, Jon Frost wrote:
>Thanks for sharing.

I just updated avalanche2d-js so that the graph drawn into the canvas overlay during real-time data collection re-scales properly when the axes are changed while graphing.

http://stepheneb.github.com/avalanche2d-js/avalanche2d.html

Because of how D3 is designed this was quite easy.

In my Canvas drawing benchmark on Chrome I can draw a Canvas line with 5000 segments (1 moveTo, the rest lineTo) in about 6ms -- so I always just draw the Canvas line even when not doing real-time graphing and the Canvas is layer under the SVG content.

Here's the 14 lines of code:

update real-time canvas graph when scales change
https://github.com/stepheneb/avalanche2d-js/commit/32c826955575

The speed up using Canvas when plotting large numbers of points is quite remarkable.

If you try avalanche2d-js in Chrome you'll need to change the Desk Array Size from 100x100 to 200x200 just to keep the graph plotting long enough to try and change a scale.

The graph supports panning/translation by dragging in the plot canvas proper ... but I haven't modified the canvas overlay feature to pass mouse events through yet so this feature won't work while graphing real-time data.

I made a large set of changes in the last week to make both the scheduling of the computational model and and canvas heat map and the rendering of the graph run faster. Using Canvas for the real-time graphing was both easy and a huge performance increase.

I created this graph showing the change in performance. The Canvas change occurred on Oct 19.

https://img.skitch.com/20111023-q8rkqfkhynifqhtj6yefm86aaw.jpg

Note: the Y-axis that measures performance is a log scale.

** it feels pretty silly sharing a jpg image of a graph on this list ;-)

Reply all
Reply to author
Forward
0 new messages